');mask-image:url('data:image/svg+xml;charset=utf-8,');width:16px}div#p>svg>foreignObject>section details,div#p>svg>foreignObject>section figcaption,div#p>svg>foreignObject>section figure{display:block}div#p>svg>foreignObject>section summary{display:list-item}div#p>svg>foreignObject>section [hidden]{display:none!important}div#p>svg>foreignObject>section a{background-color:transparent;color:var(--color-accent-fg);text-decoration:none}div#p>svg>foreignObject>section abbr[title]{border-bottom:none;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}div#p>svg>foreignObject>section b,div#p>svg>foreignObject>section strong{font-weight:var(--base-text-weight-semibold,600)}div#p>svg>foreignObject>section dfn{font-style:italic}div#p>svg>foreignObject>section:is(h1,marp-h1){border-bottom:1px solid var(--color-border-muted);font-size:2em;font-weight:var(--base-text-weight-semibold,600);margin:.67em 0;padding-bottom:.3em}div#p>svg>foreignObject>section mark{background-color:var(--color-attention-subtle);color:var(--color-fg-default)}div#p>svg>foreignObject>section small{font-size:90%}div#p>svg>foreignObject>section sub,div#p>svg>foreignObject>section sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}div#p>svg>foreignObject>section sub{bottom:-.25em}div#p>svg>foreignObject>section sup{top:-.5em}div#p>svg>foreignObject>section img{background-color:var(--color-canvas-default);border-style:none;box-sizing:content-box;max-width:100%}div#p>svg>foreignObject>section:is(pre,marp-pre),div#p>svg>foreignObject>section code,div#p>svg>foreignObject>section kbd,div#p>svg>foreignObject>section samp{font-family:monospace;font-size:1em}div#p>svg>foreignObject>section figure{margin:1em 40px}div#p>svg>foreignObject>section hr{background:transparent;background-color:var(--color-border-default);border:0;box-sizing:content-box;height:.25em;margin:24px 0;overflow:hidden;padding:0}div#p>svg>foreignObject>section input{font:inherit;font-family:inherit;font-size:inherit;line-height:inherit;margin:0;overflow:visible}div#p>svg>foreignObject>section [type=button],div#p>svg>foreignObject>section [type=reset],div#p>svg>foreignObject>section [type=submit]{-webkit-appearance:button}div#p>svg>foreignObject>section [type=checkbox],div#p>svg>foreignObject>section [type=radio]{box-sizing:border-box;padding:0}div#p>svg>foreignObject>section [type=number]::-webkit-inner-spin-button,div#p>svg>foreignObject>section [type=number]::-webkit-outer-spin-button{height:auto}div#p>svg>foreignObject>section [type=search]::-webkit-search-cancel-button,div#p>svg>foreignObject>section [type=search]::-webkit-search-decoration{-webkit-appearance:none}div#p>svg>foreignObject>section::-webkit-input-placeholder{color:inherit;opacity:.54}div#p>svg>foreignObject>section::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}div#p>svg>foreignObject>section a:hover{text-decoration:underline}div#p>svg>foreignObject>section::-moz-placeholder{color:var(--color-fg-subtle);opacity:1}div#p>svg>foreignObject>section::placeholder{color:var(--color-fg-subtle);opacity:1}div#p>svg>foreignObject>section hr:after,div#p>svg>foreignObject>section hr:before{content:"";display:table}div#p>svg>foreignObject>section hr:after{clear:both}div#p>svg>foreignObject>section table{border-collapse:collapse;border-spacing:0;display:block;max-width:100%;overflow:auto;width:-moz-max-content;width:max-content}div#p>svg>foreignObject>section td,div#p>svg>foreignObject>section th{padding:0}div#p>svg>foreignObject>section details summary{cursor:pointer}div#p>svg>foreignObject>section details:not([open])>:not(summary){display:none!important}div#p>svg>foreignObject>section [role=button]:focus,div#p>svg>foreignObject>section a:focus,div#p>svg>foreignObject>section input[type=checkbox]:focus,div#p>svg>foreignObject>section input[type=radio]:focus{box-shadow:none;outline:2px solid var(--color-accent-fg);outline-offset:-2px}div#p>svg>foreignObject>section [role=button]:focus:not(:focus-visible),div#p>svg>foreignObject>section a:focus:not(:focus-visible),div#p>svg>foreignObject>section input[type=checkbox]:focus:not(:focus-visible),div#p>svg>foreignObject>section input[type=radio]:focus:not(:focus-visible){outline:1px solid transparent}div#p>svg>foreignObject>section [role=button]:focus-visible,div#p>svg>foreignObject>section a:focus-visible,div#p>svg>foreignObject>section input[type=checkbox]:focus-visible,div#p>svg>foreignObject>section input[type=radio]:focus-visible{box-shadow:none;outline:2px solid var(--color-accent-fg);outline-offset:-2px}div#p>svg>foreignObject>section a:not([class]):focus,div#p>svg>foreignObject>section a:not([class]):focus-visible,div#p>svg>foreignObject>section input[type=checkbox]:focus,div#p>svg>foreignObject>section input[type=checkbox]:focus-visible,div#p>svg>foreignObject>section input[type=radio]:focus,div#p>svg>foreignObject>section input[type=radio]:focus-visible{outline-offset:0}div#p>svg>foreignObject>section kbd{background-color:var(--color-canvas-subtle);border-bottom-color:var(--color-neutral-muted);border:1px solid var(--color-neutral-muted);border-radius:6px;box-shadow:inset 0 -1px 0 var(--color-neutral-muted);color:var(--color-fg-default);display:inline-block;font:11px ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;line-height:10px;padding:3px 5px;vertical-align:middle}div#p>svg>foreignObject>section:is(h1,marp-h1),div#p>svg>foreignObject>section:is(h2,marp-h2),div#p>svg>foreignObject>section:is(h3,marp-h3),div#p>svg>foreignObject>section:is(h4,marp-h4),div#p>svg>foreignObject>section:is(h5,marp-h5),div#p>svg>foreignObject>section:is(h6,marp-h6){font-weight:var(--base-text-weight-semibold,600);line-height:1.25;margin-bottom:16px;margin-top:24px}div#p>svg>foreignObject>section:is(h2,marp-h2){border-bottom:1px solid var(--color-border-muted);font-size:1.5em;padding-bottom:.3em}div#p>svg>foreignObject>section:is(h2,marp-h2),div#p>svg>foreignObject>section:is(h3,marp-h3){font-weight:var(--base-text-weight-semibold,600)}div#p>svg>foreignObject>section:is(h3,marp-h3){font-size:1.25em}div#p>svg>foreignObject>section:is(h4,marp-h4){font-size:1em}div#p>svg>foreignObject>section:is(h4,marp-h4),div#p>svg>foreignObject>section:is(h5,marp-h5){font-weight:var(--base-text-weight-semibold,600)}div#p>svg>foreignObject>section:is(h5,marp-h5){font-size:.875em}div#p>svg>foreignObject>section:is(h6,marp-h6){color:var(--color-fg-muted);font-size:.85em;font-weight:var(--base-text-weight-semibold,600)}div#p>svg>foreignObject>section p{margin-bottom:10px;margin-top:0}div#p>svg>foreignObject>section blockquote{border-left:.25em solid var(--color-border-default);color:var(--color-fg-muted);margin:0;padding:0 1em}div#p>svg>foreignObject>section ol,div#p>svg>foreignObject>section ul{margin-bottom:0;margin-top:0;padding-left:2em}div#p>svg>foreignObject>section ol ol,div#p>svg>foreignObject>section ul ol{list-style-type:lower-roman}div#p>svg>foreignObject>section ol ol ol,div#p>svg>foreignObject>section ol ul ol,div#p>svg>foreignObject>section ul ol ol,div#p>svg>foreignObject>section ul ul ol{list-style-type:lower-alpha}div#p>svg>foreignObject>section dd{margin-left:0}div#p>svg>foreignObject>section:is(pre,marp-pre),div#p>svg>foreignObject>section code,div#p>svg>foreignObject>section samp,div#p>svg>foreignObject>section tt{font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;font-size:12px}div#p>svg>foreignObject>section:is(pre,marp-pre){word-wrap:normal;margin-bottom:0;margin-top:0}div#p>svg>foreignObject>section .octicon{fill:currentColor;display:inline-block;overflow:visible!important;vertical-align:text-bottom}div#p>svg>foreignObject>section input::-webkit-inner-spin-button,div#p>svg>foreignObject>section input::-webkit-outer-spin-button{-webkit-appearance:none;appearance:none;margin:0}div#p>svg>foreignObject>section:after,div#p>svg>foreignObject>section:before{display:table}div#p>svg>foreignObject>section:after{clear:both}div#p>svg>foreignObject>section>:first-child{margin-top:0!important}div#p>svg>foreignObject>section>:last-child{margin-bottom:0!important}div#p>svg>foreignObject>section a:not([href]){color:inherit;text-decoration:none}div#p>svg>foreignObject>section .absent{color:var(--color-danger-fg)}div#p>svg>foreignObject>section .anchor{float:left;line-height:1;margin-left:-20px;padding-right:4px}div#p>svg>foreignObject>section .anchor:focus{outline:none}div#p>svg>foreignObject>section:is(pre,marp-pre),div#p>svg>foreignObject>section blockquote,div#p>svg>foreignObject>section details,div#p>svg>foreignObject>section dl,div#p>svg>foreignObject>section ol,div#p>svg>foreignObject>section p,div#p>svg>foreignObject>section table,div#p>svg>foreignObject>section ul{margin-bottom:16px;margin-top:0}div#p>svg>foreignObject>section blockquote>:first-child{margin-top:0}div#p>svg>foreignObject>section blockquote>:last-child{margin-bottom:0}div#p>svg>foreignObject>section:is(h1,marp-h1) .octicon-link,div#p>svg>foreignObject>section:is(h2,marp-h2) .octicon-link,div#p>svg>foreignObject>section:is(h3,marp-h3) .octicon-link,div#p>svg>foreignObject>section:is(h4,marp-h4) .octicon-link,div#p>svg>foreignObject>section:is(h5,marp-h5) .octicon-link,div#p>svg>foreignObject>section:is(h6,marp-h6) .octicon-link{color:var(--color-fg-default);vertical-align:middle;visibility:hidden}div#p>svg>foreignObject>section:is(h1,marp-h1):hover .anchor,div#p>svg>foreignObject>section:is(h2,marp-h2):hover .anchor,div#p>svg>foreignObject>section:is(h3,marp-h3):hover .anchor,div#p>svg>foreignObject>section:is(h4,marp-h4):hover .anchor,div#p>svg>foreignObject>section:is(h5,marp-h5):hover .anchor,div#p>svg>foreignObject>section:is(h6,marp-h6):hover .anchor{text-decoration:none}div#p>svg>foreignObject>section:is(h1,marp-h1):hover .anchor .octicon-link,div#p>svg>foreignObject>section:is(h2,marp-h2):hover .anchor .octicon-link,div#p>svg>foreignObject>section:is(h3,marp-h3):hover .anchor .octicon-link,div#p>svg>foreignObject>section:is(h4,marp-h4):hover .anchor .octicon-link,div#p>svg>foreignObject>section:is(h5,marp-h5):hover .anchor .octicon-link,div#p>svg>foreignObject>section:is(h6,marp-h6):hover .anchor .octicon-link{visibility:visible}div#p>svg>foreignObject>section:is(h1,marp-h1) code,div#p>svg>foreignObject>section:is(h1,marp-h1) tt,div#p>svg>foreignObject>section:is(h2,marp-h2) code,div#p>svg>foreignObject>section:is(h2,marp-h2) tt,div#p>svg>foreignObject>section:is(h3,marp-h3) code,div#p>svg>foreignObject>section:is(h3,marp-h3) tt,div#p>svg>foreignObject>section:is(h4,marp-h4) code,div#p>svg>foreignObject>section:is(h4,marp-h4) tt,div#p>svg>foreignObject>section:is(h5,marp-h5) code,div#p>svg>foreignObject>section:is(h5,marp-h5) tt,div#p>svg>foreignObject>section:is(h6,marp-h6) code,div#p>svg>foreignObject>section:is(h6,marp-h6) tt{font-size:inherit;padding:0 .2em}div#p>svg>foreignObject>section summary:is(h1,marp-h1),div#p>svg>foreignObject>section summary:is(h2,marp-h2),div#p>svg>foreignObject>section summary:is(h3,marp-h3),div#p>svg>foreignObject>section summary:is(h4,marp-h4),div#p>svg>foreignObject>section summary:is(h5,marp-h5),div#p>svg>foreignObject>section summary:is(h6,marp-h6){display:inline-block}div#p>svg>foreignObject>section summary:is(h1,marp-h1) .anchor,div#p>svg>foreignObject>section summary:is(h2,marp-h2) .anchor,div#p>svg>foreignObject>section summary:is(h3,marp-h3) .anchor,div#p>svg>foreignObject>section summary:is(h4,marp-h4) .anchor,div#p>svg>foreignObject>section summary:is(h5,marp-h5) .anchor,div#p>svg>foreignObject>section summary:is(h6,marp-h6) .anchor{margin-left:-40px}div#p>svg>foreignObject>section summary:is(h1,marp-h1),div#p>svg>foreignObject>section summary:is(h2,marp-h2){border-bottom:0;padding-bottom:0}div#p>svg>foreignObject>section ol.no-list,div#p>svg>foreignObject>section ul.no-list{list-style-type:none;padding:0}div#p>svg>foreignObject>section ol[type=a]{list-style-type:lower-alpha}div#p>svg>foreignObject>section ol[type=A]{list-style-type:upper-alpha}div#p>svg>foreignObject>section ol[type=i]{list-style-type:lower-roman}div#p>svg>foreignObject>section ol[type=I]{list-style-type:upper-roman}div#p>svg>foreignObject>section div>ol:not([type]),div#p>svg>foreignObject>section ol[type="1"]{list-style-type:decimal}div#p>svg>foreignObject>section ol ol,div#p>svg>foreignObject>section ol ul,div#p>svg>foreignObject>section ul ol,div#p>svg>foreignObject>section ul ul{margin-bottom:0;margin-top:0}div#p>svg>foreignObject>section li>p{margin-top:16px}div#p>svg>foreignObject>section li+li{margin-top:.25em}div#p>svg>foreignObject>section dl{padding:0}div#p>svg>foreignObject>section dl dt{font-size:1em;font-style:italic;font-weight:var(--base-text-weight-semibold,600);margin-top:16px;padding:0}div#p>svg>foreignObject>section dl dd{margin-bottom:16px;padding:0 16px}div#p>svg>foreignObject>section table th{font-weight:var(--base-text-weight-semibold,600)}div#p>svg>foreignObject>section table td,div#p>svg>foreignObject>section table th{border:1px solid var(--color-border-default);padding:6px 13px}div#p>svg>foreignObject>section table tr{background-color:var(--color-canvas-default);border-top:1px solid var(--color-border-muted)}div#p>svg>foreignObject>section table tr:nth-child(2n){background-color:var(--color-canvas-subtle)}div#p>svg>foreignObject>section table img{background-color:transparent}div#p>svg>foreignObject>section img[align=right]{padding-left:20px}div#p>svg>foreignObject>section img[align=left]{padding-right:20px}div#p>svg>foreignObject>section .emoji{background-color:transparent;max-width:none;vertical-align:text-top}div#p>svg>foreignObject>section:is(span,marp-span).frame,div#p>svg>foreignObject>section:is(span,marp-span).frame>:is(span,marp-span){display:block;overflow:hidden}div#p>svg>foreignObject>section:is(span,marp-span).frame>:is(span,marp-span){border:1px solid var(--color-border-default);float:left;margin:13px 0 0;padding:7px;width:auto}div#p>svg>foreignObject>section:is(span,marp-span).frame:is(span,marp-span) img{display:block;float:left}div#p>svg>foreignObject>section:is(span,marp-span).frame:is(span,marp-span):is(span,marp-span){clear:both;color:var(--color-fg-default);display:block;padding:5px 0 0}div#p>svg>foreignObject>section:is(span,marp-span).align-center{clear:both;display:block;overflow:hidden}div#p>svg>foreignObject>section:is(span,marp-span).align-center>:is(span,marp-span){display:block;margin:13px auto 0;overflow:hidden;text-align:center}div#p>svg>foreignObject>section:is(span,marp-span).align-center:is(span,marp-span) img{margin:0 auto;text-align:center}div#p>svg>foreignObject>section:is(span,marp-span).align-right{clear:both;display:block;overflow:hidden}div#p>svg>foreignObject>section:is(span,marp-span).align-right>:is(span,marp-span){display:block;margin:13px 0 0;overflow:hidden;text-align:right}div#p>svg>foreignObject>section:is(span,marp-span).align-right:is(span,marp-span) img{margin:0;text-align:right}div#p>svg>foreignObject>section:is(span,marp-span).float-left{display:block;float:left;margin-right:13px;overflow:hidden}div#p>svg>foreignObject>section:is(span,marp-span).float-left:is(span,marp-span){margin:13px 0 0}div#p>svg>foreignObject>section:is(span,marp-span).float-right{display:block;float:right;margin-left:13px;overflow:hidden}div#p>svg>foreignObject>section:is(span,marp-span).float-right>:is(span,marp-span){display:block;margin:13px auto 0;overflow:hidden;text-align:right}div#p>svg>foreignObject>section code,div#p>svg>foreignObject>section tt{background-color:var(--color-neutral-muted);border-radius:6px;font-size:85%;margin:0;padding:.2em .4em;white-space:break-spaces}div#p>svg>foreignObject>section code br,div#p>svg>foreignObject>section tt br{display:none}div#p>svg>foreignObject>section del code{text-decoration:inherit}div#p>svg>foreignObject>section samp{font-size:85%}div#p>svg>foreignObject>section:is(pre,marp-pre) code{font-size:100%}div#p>svg>foreignObject>section:is(pre,marp-pre)>code{background:transparent;border:0;margin:0;padding:0;white-space:pre;word-break:normal}div#p>svg>foreignObject>section .highlight{margin-bottom:16px}div#p>svg>foreignObject>section .highlight:is(pre,marp-pre){margin-bottom:0;word-break:normal}div#p>svg>foreignObject>section:is(pre,marp-pre){background-color:var(--color-canvas-subtle);border-radius:6px;font-size:85%;line-height:1.45;overflow:auto;padding:16px}div#p>svg>foreignObject>section:is(pre,marp-pre) code,div#p>svg>foreignObject>section:is(pre,marp-pre) tt{word-wrap:normal;background-color:transparent;border:0;display:inline;line-height:inherit;margin:0;max-width:auto;overflow:visible;padding:0}div#p>svg>foreignObject>section .csv-data td,div#p>svg>foreignObject>section .csv-data th{font-size:12px;line-height:1;overflow:hidden;padding:5px;text-align:left;white-space:nowrap}div#p>svg>foreignObject>section .csv-data .blob-num{background:var(--color-canvas-default);border:0;padding:10px 8px 9px;text-align:right}div#p>svg>foreignObject>section .csv-data tr{border-top:0}div#p>svg>foreignObject>section .csv-data th{background:var(--color-canvas-subtle);border-top:0;font-weight:var(--base-text-weight-semibold,600)}div#p>svg>foreignObject>section [data-footnote-ref]:before{content:"["}div#p>svg>foreignObject>section [data-footnote-ref]:after{content:"]"}div#p>svg>foreignObject>section .footnotes{border-top:1px solid var(--color-border-default);color:var(--color-fg-muted);font-size:12px}div#p>svg>foreignObject>section div#p>svg>foreignObject>section section.footnotes{--marpit-root-font-size:12px}div#p>svg>foreignObject>section .footnotes ol{padding-left:16px}div#p>svg>foreignObject>section .footnotes ol ul{display:inline-block;margin-top:16px;padding-left:16px}div#p>svg>foreignObject>section .footnotes li{position:relative}div#p>svg>foreignObject>section .footnotes li:target:before{border:2px solid var(--color-accent-emphasis);border-radius:6px;bottom:-8px;content:"";left:-24px;pointer-events:none;position:absolute;right:-8px;top:-8px}div#p>svg>foreignObject>section .footnotes li:target{color:var(--color-fg-default)}div#p>svg>foreignObject>section .footnotes .data-footnote-backref g-emoji{font-family:monospace}div#p>svg>foreignObject>section .pl-c{color:var(--color-prettylights-syntax-comment)}div#p>svg>foreignObject>section .pl-c1,div#p>svg>foreignObject>section .pl-s .pl-v{color:var(--color-prettylights-syntax-constant)}div#p>svg>foreignObject>section .pl-e,div#p>svg>foreignObject>section .pl-en{color:var(--color-prettylights-syntax-entity)}div#p>svg>foreignObject>section .pl-s .pl-s1,div#p>svg>foreignObject>section .pl-smi{color:var(--color-prettylights-syntax-storage-modifier-import)}div#p>svg>foreignObject>section .pl-ent{color:var(--color-prettylights-syntax-entity-tag)}div#p>svg>foreignObject>section .pl-k{color:var(--color-prettylights-syntax-keyword)}div#p>svg>foreignObject>section .pl-pds,div#p>svg>foreignObject>section .pl-s,div#p>svg>foreignObject>section .pl-s .pl-pse .pl-s1,div#p>svg>foreignObject>section .pl-sr,div#p>svg>foreignObject>section .pl-sr .pl-cce,div#p>svg>foreignObject>section .pl-sr .pl-sra,div#p>svg>foreignObject>section .pl-sr .pl-sre{color:var(--color-prettylights-syntax-string)}div#p>svg>foreignObject>section .pl-smw,div#p>svg>foreignObject>section .pl-v{color:var(--color-prettylights-syntax-variable)}div#p>svg>foreignObject>section .pl-bu{color:var(--color-prettylights-syntax-brackethighlighter-unmatched)}div#p>svg>foreignObject>section .pl-ii{background-color:var(--color-prettylights-syntax-invalid-illegal-bg);color:var(--color-prettylights-syntax-invalid-illegal-text)}div#p>svg>foreignObject>section .pl-c2{background-color:var(--color-prettylights-syntax-carriage-return-bg);color:var(--color-prettylights-syntax-carriage-return-text)}div#p>svg>foreignObject>section .pl-sr .pl-cce{color:var(--color-prettylights-syntax-string-regexp);font-weight:700}div#p>svg>foreignObject>section .pl-ml{color:var(--color-prettylights-syntax-markup-list)}div#p>svg>foreignObject>section .pl-mh,div#p>svg>foreignObject>section .pl-mh .pl-en,div#p>svg>foreignObject>section .pl-ms{color:var(--color-prettylights-syntax-markup-heading);font-weight:700}div#p>svg>foreignObject>section .pl-mi{color:var(--color-prettylights-syntax-markup-italic);font-style:italic}div#p>svg>foreignObject>section .pl-mb{color:var(--color-prettylights-syntax-markup-bold);font-weight:700}div#p>svg>foreignObject>section .pl-md{background-color:var(--color-prettylights-syntax-markup-deleted-bg);color:var(--color-prettylights-syntax-markup-deleted-text)}div#p>svg>foreignObject>section .pl-mi1{background-color:var(--color-prettylights-syntax-markup-inserted-bg);color:var(--color-prettylights-syntax-markup-inserted-text)}div#p>svg>foreignObject>section .pl-mc{background-color:var(--color-prettylights-syntax-markup-changed-bg);color:var(--color-prettylights-syntax-markup-changed-text)}div#p>svg>foreignObject>section .pl-mi2{background-color:var(--color-prettylights-syntax-markup-ignored-bg);color:var(--color-prettylights-syntax-markup-ignored-text)}div#p>svg>foreignObject>section .pl-mdr{color:var(--color-prettylights-syntax-meta-diff-range);font-weight:700}div#p>svg>foreignObject>section .pl-ba{color:var(--color-prettylights-syntax-brackethighlighter-angle)}div#p>svg>foreignObject>section .pl-sg{color:var(--color-prettylights-syntax-sublimelinter-gutter-mark)}div#p>svg>foreignObject>section .pl-corl{color:var(--color-prettylights-syntax-constant-other-reference-link);text-decoration:underline}div#p>svg>foreignObject>section g-emoji{display:inline-block;font-family:Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;font-size:1em;font-style:normal!important;font-weight:var(--base-text-weight-normal,400);line-height:1;min-width:1ch;vertical-align:-.075em}div#p>svg>foreignObject>section g-emoji img{height:1em;width:1em}div#p>svg>foreignObject>section .task-list-item{list-style-type:none}div#p>svg>foreignObject>section .task-list-item label{font-weight:var(--base-text-weight-normal,400)}div#p>svg>foreignObject>section .task-list-item.enabled label{cursor:pointer}div#p>svg>foreignObject>section .task-list-item+.task-list-item{margin-top:4px}div#p>svg>foreignObject>section .task-list-item .handle{display:none}div#p>svg>foreignObject>section .task-list-item-checkbox{margin:0 .2em .25em -1.4em;vertical-align:middle}div#p>svg>foreignObject>section .contains-task-list:dir(rtl) .task-list-item-checkbox{margin:0 -1.6em .25em .2em}div#p>svg>foreignObject>section .contains-task-list{position:relative}div#p>svg>foreignObject>section .contains-task-list:focus-within .task-list-item-convert-container,div#p>svg>foreignObject>section .contains-task-list:hover .task-list-item-convert-container{clip:auto;display:block;height:24px;overflow:visible;width:auto}div#p>svg>foreignObject>section::-webkit-calendar-picker-indicator{filter:invert(50%)}div#p>svg>foreignObject>section:is(h1,marp-h1){color:var(--h1-color);font-size:1.6em}div#p>svg>foreignObject>section:is(h1,marp-h1),div#p>svg>foreignObject>section:is(h2,marp-h2){border-bottom:none}div#p>svg>foreignObject>section:is(h2,marp-h2){font-size:1.3em}div#p>svg>foreignObject>section:is(h3,marp-h3){font-size:1.1em}div#p>svg>foreignObject>section:is(h4,marp-h4){font-size:1.05em}div#p>svg>foreignObject>section:is(h5,marp-h5){font-size:1em}div#p>svg>foreignObject>section:is(h6,marp-h6){font-size:.9em}div#p>svg>foreignObject>section:is(h1,marp-h1) strong,div#p>svg>foreignObject>section:is(h2,marp-h2) strong,div#p>svg>foreignObject>section:is(h3,marp-h3) strong,div#p>svg>foreignObject>section:is(h4,marp-h4) strong,div#p>svg>foreignObject>section:is(h5,marp-h5) strong,div#p>svg>foreignObject>section:is(h6,marp-h6) strong{color:var(--heading-strong-color);font-weight:inherit}div#p>svg>foreignObject>section:is(h1,marp-h1)::part(auto-scaling),div#p>svg>foreignObject>section:is(h2,marp-h2)::part(auto-scaling),div#p>svg>foreignObject>section:is(h3,marp-h3)::part(auto-scaling),div#p>svg>foreignObject>section:is(h4,marp-h4)::part(auto-scaling),div#p>svg>foreignObject>section:is(h5,marp-h5)::part(auto-scaling),div#p>svg>foreignObject>section:is(h6,marp-h6)::part(auto-scaling){max-height:563px}div#p>svg>foreignObject>section hr{height:0;padding-top:.25em}div#p>svg>foreignObject>section:is(pre,marp-pre){border:1px solid var(--color-border-default);line-height:1.15;overflow:visible}div#p>svg>foreignObject>section:is(pre,marp-pre)::part(auto-scaling){max-height:529px}div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs){color:var(--color-prettylights-syntax-storage-modifier-import)}div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-doctag),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-keyword),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-meta .hljs-keyword),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-template-tag),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-template-variable),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-type),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-variable.language_){color:var(--color-prettylights-syntax-keyword)}div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-title),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-title.class_),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-title.class_.inherited__),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-title.function_){color:var(--color-prettylights-syntax-entity)}div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-attr),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-attribute),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-literal),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-meta),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-number),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-operator),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-selector-attr),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-selector-class),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-selector-id),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-variable){color:var(--color-prettylights-syntax-constant)}div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-meta .hljs-string),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-regexp),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-string){color:var(--color-prettylights-syntax-string)}div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-built_in),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-symbol){color:var(--color-prettylights-syntax-variable)}div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-code),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-comment),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-formula){color:var(--color-prettylights-syntax-comment)}div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-name),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-quote),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-selector-pseudo),div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-selector-tag){color:var(--color-prettylights-syntax-entity-tag)}div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-subst){color:var(--color-prettylights-syntax-storage-modifier-import)}div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-section){color:var(--color-prettylights-syntax-markup-heading);font-weight:700}div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-bullet){color:var(--color-prettylights-syntax-markup-list)}div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-emphasis){color:var(--color-prettylights-syntax-markup-italic);font-style:italic}div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-strong){color:var(--color-prettylights-syntax-markup-bold);font-weight:700}div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-addition){background-color:var(--color-prettylights-syntax-markup-inserted-bg);color:var(--color-prettylights-syntax-markup-inserted-text)}div#p>svg>foreignObject>section:is(pre,marp-pre):where(.hljs-deletion){background-color:var(--color-prettylights-syntax-markup-deleted-bg);color:var(--color-prettylights-syntax-markup-deleted-text)}div#p>svg>foreignObject>section footer,div#p>svg>foreignObject>section header{color:var(--header-footer-color);font-size:18px;left:30px;margin:0;position:absolute}div#p>svg>foreignObject>section header{top:21px}div#p>svg>foreignObject>section footer{bottom:21px}div#p>svg>foreignObject>section{--h1-color:#246;--header-footer-color:hsla(0,0%,40%,.75);--heading-strong-color:#48c;--paginate-color:#777;align-items:stretch;display:flex;flex-flow:column nowrap;font-size:29px;height:720px;justify-content:center;padding:78.5px;width:1280px}div#p>svg>foreignObject>section{--marpit-root-font-size:29px}div#p>svg>foreignObject>section:where(.invert){--h1-color:#cee7ff;--header-footer-color:hsla(0,0%,60%,.75);--heading-strong-color:#7bf;--paginate-color:#999}div#p>svg>foreignObject>section>:last-child,div#p>svg>foreignObject>section[data-footer]>:nth-last-child(2){margin-bottom:0}div#p>svg>foreignObject>section>:first-child,div#p>svg>foreignObject>section>header:first-child+*{margin-top:0}div#p>svg>foreignObject>section:after{bottom:21px;color:var(--paginate-color);font-size:24px;padding:0;position:absolute;right:30px}div#p>svg>foreignObject>section:after{--marpit-root-font-size:24px}div#p>svg>foreignObject>section[data-color]:is(h1,marp-h1),div#p>svg>foreignObject>section[data-color]:is(h2,marp-h2),div#p>svg>foreignObject>section[data-color]:is(h3,marp-h3),div#p>svg>foreignObject>section[data-color]:is(h4,marp-h4),div#p>svg>foreignObject>section[data-color]:is(h5,marp-h5),div#p>svg>foreignObject>section[data-color]:is(h6,marp-h6){color:currentcolor}div#p>svg>foreignObject>section[data-marpit-advanced-background=background]{columns:initial!important;display:block!important;padding:0!important}div#p>svg>foreignObject>section[data-marpit-advanced-background=background]:after,div#p>svg>foreignObject>section[data-marpit-advanced-background=background]:before,div#p>svg>foreignObject>section[data-marpit-advanced-background=content]:after,div#p>svg>foreignObject>section[data-marpit-advanced-background=content]:before{display:none!important}div#p>svg>foreignObject>section[data-marpit-advanced-background=background]>div[data-marpit-advanced-background-container]{all:initial;display:flex;flex-direction:row;height:100%;overflow:hidden;width:100%}div#p>svg>foreignObject>section[data-marpit-advanced-background=background]>div[data-marpit-advanced-background-container][data-marpit-advanced-background-direction=vertical]{flex-direction:column}div#p>svg>foreignObject>section[data-marpit-advanced-background=background][data-marpit-advanced-background-split]>div[data-marpit-advanced-background-container]{width:var(--marpit-advanced-background-split,50%)}div#p>svg>foreignObject>section[data-marpit-advanced-background=background][data-marpit-advanced-background-split=right]>div[data-marpit-advanced-background-container]{margin-left:calc(100% - var(--marpit-advanced-background-split,50%))}div#p>svg>foreignObject>section[data-marpit-advanced-background=background]>div[data-marpit-advanced-background-container]>figure{all:initial;background-position:center;background-repeat:no-repeat;background-size:cover;flex:auto;margin:0}div#p>svg>foreignObject>section[data-marpit-advanced-background=content],div#p>svg>foreignObject>section[data-marpit-advanced-background=pseudo]{background:transparent!important}div#p>svg>foreignObject>section[data-marpit-advanced-background=pseudo],div#p>svg[data-marpit-svg]>foreignObject[data-marpit-advanced-background=pseudo]{pointer-events:none!important}div#p>svg>foreignObject>section[data-marpit-advanced-background-split]{width:100%;height:100%}
情况 | 内核行为 | 当无可用内存时 |
---|---|---|
硬内存保护 | OOM killer | |
尽最大努力保护内存 | ||
常规状态 | ||
尽可能维持更小内存 | ||
尽可能回收自身 | OOM killer |
内存回收压力(memory reclaim pressure) 指操作系统在内存不足时,通过回收内存来释放更多的空闲内存页。这个过程中,数据会从 RAM 中删除(如果可以重新获取)或复制到交换文件中(以便数据可以重新获取)。
pids.xxx
线程数限制io.xxx
硬盘读写限制cpuset.xxx
NUMA 节点限制rdma.xxx
RDMA 资源限制infalloc.cpp
#include <bits/stdc++.h>
using namespace std;
int total;
int main(){
while (char* f=(char*)malloc(1024*1024)){
for (int i=0;i<1024*1024;i++)
f[i]=rand();
total++;
cout<<total<<"mb in total"<<endl;
}
cout<<strerror(errno)<<endl;
}
loop.cpp
#include <bits/stdc++.h>
using namespace std;
void loop(){
while (1);
}
int main(){
vector<jthread> threads;
for (int i=0;i<32;i++)
threads.emplace_back(loop);
}
g++ infalloc.cpp -o infalloc
g++ loop.cpp -o loop
echo $$ #查看当前终端进程PID
cd /sys/fs/cgroup
mkdir test #创建cgroups
cd test
sudo bash -c "echo $PID >> cgroup.procs" #分配进程至/test
vim cpu.max
vim memory.max
使用 top 等工具查看资源占用吧
cgroup namespace隔离cgroup挂载和设施,在创建cgroup ns时会将当前进程的cgroup控制器设为新cgroup ns的父亲。/proc/self/cgroup
变成0::/
以隔离cgroup设施。但是原先的cgroup控制器也对新的cgroup ns的所有进程生效。
namespace 解决了资源隔离问题;
cgroups 解决了资源配额问题;
但是这仅仅解决了容器如何运行起来的问题,既然容器还是一个“软件”,我们还需要为容器添加版本控制。
对文件系统进行版本控制,怎么实现?
一图胜千言
mount -t overlay overlay -o lowerdir=/lower1:/lower2,upperdir=/upper,workdir=/work /merged
/merge=
/upper
/lower2
/lower1
lower层只读,对/merge的修改集中在upper上,work为临时目录。
秒级启动
运行一个软件=目录结构+共享库文件+可执行文件+配置文件
传统 Linux 发行版
改配置文件麻烦,软件包版本管理更麻烦...
万一哪一天出错了还不能回滚配置文件...
How to improve?
用户级包管理器,内部使用namespace+cgroup维护软件沙箱环境,达成跨不同发行版运行软件。
将这一切文本化,并辅以可选的版本控制。configuration.nix
:
{ config, ...}: {
services.nginx = {
enable = true;
virtualHosts."blog.example.com" = {
enableACME = true;
forceSSL = true;
root = "/var/www/blog";
locations."~ \.php$".extraConfig = ''
fastcgi_pass unix:${config.services.phpfpm.pools.mypool.socket};
fastcgi_index index.php;
'';
};
};
services.mysql = {
enable = true;
package = pkgs.mariadb;
};
services.phpfpm.pools.mypool = {
user = "nobody";
settings = {
pm = "dynamic";
"listen.owner" = config.services.nginx.user;
"pm.max_children" = 5;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 1;
"pm.max_spare_servers" = 3;
"pm.max_requests" = 500;
};
};
cgroups+namespace+overlayfs
docker pull <Image> #下载一个镜像
docker run --it --rm <Image> #运行一个容器并分配终端tty设备,结束后就销毁
docker run -d <Image> #后台运行一个容器
docker ps -a #查看所有容器
docker start/stop <Container> #启动一个容器
docker exec <Conatiner> #在容器中运行命令(Ctrl+C退出;Ctrl+P Ctrl+Q分离)
其中Image格式为NAME[:TAG|@DIGEST]
,tag为版本号。常见如debian:latest
表示最新版本的debian镜像。
FROM python:3
WORKDIR /usr/src/app
COPY requirements.txt ./
ENV http_proxy=http://127.0.0.1:7890
ENV https_proxy=http://127.0.0.1:7890
RUN pip install --no-cache-dir \
-r requirements.txt \
-i https://pypi.tuna.tsinghua.edu.cn/simple
#shell-like命令行
COPY . .
CMD [ "uvicorn" , "webui:app" , "--reload" , "--host" , "0.0.0.0" ]
docker build 'https://github.com/docker/rootfs.git#branch:docker'
SQL-like语法,带缓存
version: '3'
services:
rsshub: #实际容器名为动态分配,用户无需管理
image: diygod/rsshub
restart: always
ports: #端口映射,主机:容器
- '1200:1200'
environment: #环境变量
NODE_ENV: production
CACHE_TYPE: redis
REDIS_URL: 'redis://redis:6379/'
PUPPETEER_WS_ENDPOINT: 'ws://browserless:3000'
depends_on: #依赖其他容器
- redis
- browserless
browserless:
image: browserless/chrome
restart: always
ulimits:
core:
hard: 0
soft: 0
redis:
image: redis:alpine
restart: always
volumes: #映射存储
- redis-data:/data
volumes:
redis-data:
docker volume create redis-data #创建redis-data介质
docker-compose up -d #使用当前目录的docker-compose.yml创建镜像
docker-compose down -d
搭建容器集群以实现分布式系统。
namespace/cgroup/overlayfs is everywhere!
namespace
cgroups
overlayfs