meanas/standalone.html
2026-04-19 00:22:42 -07:00

13182 lines
No EOL
928 KiB
HTML

<!DOCTYPE html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8"/>
<meta content="width=device-width,initial-scale=1" name="viewport"/>
<meta content="Electromagnetic simulation tools" name="description"/>
<link href="https://mpxd.net/docs/meanas/print_page/" rel="canonical"/>
<link href="../assets/images/favicon.png" rel="icon"/>
<meta content="mkdocs-1.6.1, mkdocs-material-9.7.6" name="generator"/>
<title>Print Site - meanas</title>
<link href="data:text/css,%40charset%20%22UTF-8%22%3Bhtml%7B-webkit-text-size-adjust%3Anone%3B-moz-text-size-adjust%3Anone%3Btext-size-adjust%3Anone%3Bbox-sizing%3Aborder-box%7D%2A%2C%3Aafter%2C%3Abefore%7Bbox-sizing%3Ainherit%7D%40media%20%28prefers-reduced-motion%29%7B%2A%2C%3Aafter%2C%3Abefore%7Btransition%3Anone%21important%7D%7Dbody%7Bmargin%3A0%7Da%2Cbutton%2Cinput%2Clabel%7B-webkit-tap-highlight-color%3Atransparent%7Da%7Bcolor%3Ainherit%3Btext-decoration%3Anone%7Dhr%7Bborder%3A0%3Bbox-sizing%3Ainitial%3Bdisplay%3Ablock%3Bheight%3A.05rem%3Boverflow%3Avisible%3Bpadding%3A0%7Dsmall%7Bfont-size%3A80%25%7Dsub%2Csup%7Bline-height%3A1em%7Dimg%7Bborder-style%3Anone%7Dtable%7Bborder-collapse%3Ainitial%3Bborder-spacing%3A0%7Dtd%2Cth%7Bfont-weight%3A400%3Bvertical-align%3Atop%7Dbutton%7Bbackground%3A%230000%3Bborder%3A0%3Bfont-family%3Ainherit%3Bfont-size%3Ainherit%3Bmargin%3A0%3Bpadding%3A0%7Dinput%7Bborder%3A0%3Boutline%3Anone%7D%3Aroot%7B--md-primary-fg-color%3A%234051b5%3B--md-primary-fg-color--light%3A%235d6cc0%3B--md-primary-fg-color--dark%3A%23303fa1%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%3B--md-accent-fg-color%3A%23526cfe%3B--md-accent-fg-color--transparent%3A%23526cfe1a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-scheme%3Ddefault%5D%7Bcolor-scheme%3Alight%7D%5Bdata-md-color-scheme%3Ddefault%5D%20img%5Bsrc%24%3D%22%23gh-dark-mode-only%22%5D%2C%5Bdata-md-color-scheme%3Ddefault%5D%20img%5Bsrc%24%3D%22%23only-dark%22%5D%7Bdisplay%3Anone%7D%3Aroot%2C%5Bdata-md-color-scheme%3Ddefault%5D%7B--md-hue%3A225deg%3B--md-default-fg-color%3A%23000000de%3B--md-default-fg-color--light%3A%230000008a%3B--md-default-fg-color--lighter%3A%2300000052%3B--md-default-fg-color--lightest%3A%2300000012%3B--md-default-bg-color%3A%23fff%3B--md-default-bg-color--light%3A%23ffffffb3%3B--md-default-bg-color--lighter%3A%23ffffff4d%3B--md-default-bg-color--lightest%3A%23ffffff1f%3B--md-code-fg-color%3A%2336464e%3B--md-code-bg-color%3A%23f5f5f5%3B--md-code-bg-color--light%3A%23f5f5f5b3%3B--md-code-bg-color--lighter%3A%23f5f5f54d%3B--md-code-hl-color%3A%234287ff%3B--md-code-hl-color--light%3A%234287ff1a%3B--md-code-hl-number-color%3A%23d52a2a%3B--md-code-hl-special-color%3A%23db1457%3B--md-code-hl-function-color%3A%23a846b9%3B--md-code-hl-constant-color%3A%236e59d9%3B--md-code-hl-keyword-color%3A%233f6ec6%3B--md-code-hl-string-color%3A%231c7d4d%3B--md-code-hl-name-color%3Avar%28--md-code-fg-color%29%3B--md-code-hl-operator-color%3Avar%28--md-default-fg-color--light%29%3B--md-code-hl-punctuation-color%3Avar%28--md-default-fg-color--light%29%3B--md-code-hl-comment-color%3Avar%28--md-default-fg-color--light%29%3B--md-code-hl-generic-color%3Avar%28--md-default-fg-color--light%29%3B--md-code-hl-variable-color%3Avar%28--md-default-fg-color--light%29%3B--md-typeset-color%3Avar%28--md-default-fg-color%29%3B--md-typeset-a-color%3Avar%28--md-primary-fg-color%29%3B--md-typeset-del-color%3A%23f5503d26%3B--md-typeset-ins-color%3A%230bd57026%3B--md-typeset-kbd-color%3A%23fafafa%3B--md-typeset-kbd-accent-color%3A%23fff%3B--md-typeset-kbd-border-color%3A%23b8b8b8%3B--md-typeset-mark-color%3A%23ffff0080%3B--md-typeset-table-color%3A%230000001f%3B--md-typeset-table-color--light%3Argba%280%2C0%2C0%2C.035%29%3B--md-admonition-fg-color%3Avar%28--md-default-fg-color%29%3B--md-admonition-bg-color%3Avar%28--md-default-bg-color%29%3B--md-warning-fg-color%3A%23000000de%3B--md-warning-bg-color%3A%23ff9%3B--md-footer-fg-color%3A%23fff%3B--md-footer-fg-color--light%3A%23ffffffb3%3B--md-footer-fg-color--lighter%3A%23ffffff73%3B--md-footer-bg-color%3A%23000000de%3B--md-footer-bg-color--dark%3A%2300000052%3B--md-shadow-z1%3A0%200.2rem%200.5rem%20%230000000d%2C0%200%200.05rem%20%230000001a%3B--md-shadow-z2%3A0%200.2rem%200.5rem%20%230000001a%2C0%200%200.05rem%20%2300000040%3B--md-shadow-z3%3A0%200.2rem%200.5rem%20%230003%2C0%200%200.05rem%20%2300000059%7D.md-icon%20svg%7Bfill%3Acurrentcolor%3Bdisplay%3Ablock%3Bheight%3A1.2rem%3Bwidth%3A1.2rem%7Dbody%7B-webkit-font-smoothing%3Aantialiased%3B-moz-osx-font-smoothing%3Agrayscale%3B--md-text-font-family%3Avar%28--md-text-font%2C_%29%2C-apple-system%2CBlinkMacSystemFont%2CHelvetica%2CArial%2Csans-serif%3B--md-code-font-family%3Avar%28--md-code-font%2C_%29%2CSFMono-Regular%2CConsolas%2CMenlo%2Cmonospace%7Daside%2Cbody%2Cinput%7Bfont-feature-settings%3A%22kern%22%2C%22liga%22%3Bcolor%3Avar%28--md-typeset-color%29%3Bfont-family%3Avar%28--md-text-font-family%29%7Dcode%2Ckbd%2Cpre%7Bfont-feature-settings%3A%22kern%22%3Bfont-family%3Avar%28--md-code-font-family%29%7D%3Aroot%7B--md-typeset-table-sort-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22m18%2021-4-4h3V7h-3l4-4%204%204h-3v10h3M2%2019v-2h10v2M2%2013v-2h7v2M2%207V5h4v2z%22/%3E%3C/svg%3E%27%29%3B--md-typeset-table-sort-icon--asc%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M19%2017h3l-4%204-4-4h3V3h2M2%2017h10v2H2M6%205v2H2V5m0%206h7v2H2z%22/%3E%3C/svg%3E%27%29%3B--md-typeset-table-sort-icon--desc%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M19%207h3l-4-4-4%204h3v14h2M2%2017h10v2H2M6%205v2H2V5m0%206h7v2H2z%22/%3E%3C/svg%3E%27%29%7D.md-typeset%7B-webkit-print-color-adjust%3Aexact%3Bcolor-adjust%3Aexact%3Bfont-size%3A.8rem%3Bline-height%3A1.6%3Boverflow-wrap%3Abreak-word%7D%40media%20print%7B.md-typeset%7Bfont-size%3A.68rem%7D%7D.md-typeset%20blockquote%2C.md-typeset%20dl%2C.md-typeset%20figure%2C.md-typeset%20ol%2C.md-typeset%20pre%2C.md-typeset%20ul%7Bmargin-bottom%3A1em%3Bmargin-top%3A1em%7D.md-typeset%20h1%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bfont-size%3A2em%3Bline-height%3A1.3%3Bmargin%3A0%200%201.25em%7D.md-typeset%20h1%2C.md-typeset%20h2%7Bfont-weight%3A300%3Bletter-spacing%3A-.01em%7D.md-typeset%20h2%7Bfont-size%3A1.5625em%3Bline-height%3A1.4%3Bmargin%3A1.6em%200%20.64em%7D.md-typeset%20h3%7Bfont-size%3A1.25em%3Bfont-weight%3A400%3Bletter-spacing%3A-.01em%3Bline-height%3A1.5%3Bmargin%3A1.6em%200%20.8em%7D.md-typeset%20h2%2Bh3%7Bmargin-top%3A.8em%7D.md-typeset%20h4%7Bfont-weight%3A700%3Bletter-spacing%3A-.01em%3Bmargin%3A1em%200%7D.md-typeset%20h5%2C.md-typeset%20h6%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bfont-size%3A.8em%3Bfont-weight%3A700%3Bletter-spacing%3A-.01em%3Bmargin%3A1.25em%200%7D.md-typeset%20h5%7Btext-transform%3Auppercase%7D.md-typeset%20h5%20code%7Btext-transform%3Anone%7D.md-typeset%20hr%7Bborder-bottom%3A.05rem%20solid%20var%28--md-default-fg-color--lightest%29%3Bdisplay%3Aflow-root%3Bmargin%3A1.5em%200%7D.md-typeset%20a%7Bcolor%3Avar%28--md-typeset-a-color%29%3Bword-break%3Abreak-word%7D.md-typeset%20a%2C.md-typeset%20a%3Abefore%7Btransition%3Acolor%20125ms%7D.md-typeset%20a%3Afocus%2C.md-typeset%20a%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-typeset%20a%3Afocus%20code%2C.md-typeset%20a%3Ahover%20code%7Bbackground-color%3Avar%28--md-accent-fg-color--transparent%29%3Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-typeset%20a%20code%7Bcolor%3Avar%28--md-typeset-a-color%29%7D.md-typeset%20a.focus-visible%7Boutline-color%3Avar%28--md-accent-fg-color%29%3Boutline-offset%3A.2rem%7D.md-typeset%20code%2C.md-typeset%20kbd%2C.md-typeset%20pre%7Bcolor%3Avar%28--md-code-fg-color%29%3Bdirection%3Altr%3Bfont-variant-ligatures%3Anone%3Btransition%3Abackground-color%20125ms%7D%40media%20print%7B.md-typeset%20code%2C.md-typeset%20kbd%2C.md-typeset%20pre%7Bwhite-space%3Apre-wrap%7D%7D.md-typeset%20code%7Bbackground-color%3Avar%28--md-code-bg-color%29%3Bborder-radius%3A.1rem%3B-webkit-box-decoration-break%3Aclone%3Bbox-decoration-break%3Aclone%3Bfont-size%3A.85em%3Bpadding%3A0%20.2941176471em%3Btransition%3Acolor%20125ms%2Cbackground-color%20125ms%3Bword-break%3Abreak-word%7D.md-typeset%20code%3Anot%28.focus-visible%29%7B-webkit-tap-highlight-color%3Atransparent%3Boutline%3Anone%7D.md-typeset%20pre%7Bdisplay%3Aflow-root%3Bline-height%3A1.4%3Bposition%3Arelative%7D.md-typeset%20pre%3Ecode%7B-webkit-box-decoration-break%3Aslice%3Bbox-decoration-break%3Aslice%3Bbox-shadow%3Anone%3Bdisplay%3Ablock%3Bmargin%3A0%3Boutline-color%3Avar%28--md-accent-fg-color%29%3Boverflow%3Aauto%3Bpadding%3A.7720588235em%201.1764705882em%3Bscrollbar-color%3Avar%28--md-default-fg-color--lighter%29%20%230000%3Bscrollbar-width%3Athin%3Btouch-action%3Aauto%3Bword-break%3Anormal%7D.md-typeset%20pre%3Ecode%3Ahover%7Bscrollbar-color%3Avar%28--md-accent-fg-color%29%20%230000%7D.md-typeset%20pre%3Ecode%3A%3A-webkit-scrollbar%7Bheight%3A.2rem%3Bwidth%3A.2rem%7D.md-typeset%20pre%3Ecode%3A%3A-webkit-scrollbar-thumb%7Bbackground-color%3Avar%28--md-default-fg-color--lighter%29%7D.md-typeset%20pre%3Ecode%3A%3A-webkit-scrollbar-thumb%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color%29%7D.md-typeset%20kbd%7Bbackground-color%3Avar%28--md-typeset-kbd-color%29%3Bborder-radius%3A.1rem%3Bbox-shadow%3A0%20.1rem%200%20.05rem%20var%28--md-typeset-kbd-border-color%29%2C0%20.1rem%200%20var%28--md-typeset-kbd-border-color%29%2C0%20-.1rem%20.2rem%20var%28--md-typeset-kbd-accent-color%29%20inset%3Bcolor%3Avar%28--md-default-fg-color%29%3Bdisplay%3Ainline-block%3Bfont-size%3A.75em%3Bpadding%3A0%20.6666666667em%3Bvertical-align%3Atext-top%3Bword-break%3Abreak-word%7D.md-typeset%20mark%7Bbackground-color%3Avar%28--md-typeset-mark-color%29%3B-webkit-box-decoration-break%3Aclone%3Bbox-decoration-break%3Aclone%3Bcolor%3Ainherit%3Bword-break%3Abreak-word%7D.md-typeset%20abbr%7Bcursor%3Ahelp%3Btext-decoration%3Anone%7D.md-typeset%20%5Bdata-preview%5D%2C.md-typeset%20abbr%7Bborder-bottom%3A.05rem%20dotted%20var%28--md-default-fg-color--light%29%7D.md-typeset%20small%7Bopacity%3A.75%7D%5Bdir%3Dltr%5D%20.md-typeset%20sub%2C%5Bdir%3Dltr%5D%20.md-typeset%20sup%7Bmargin-left%3A.078125em%7D%5Bdir%3Drtl%5D%20.md-typeset%20sub%2C%5Bdir%3Drtl%5D%20.md-typeset%20sup%7Bmargin-right%3A.078125em%7D%5Bdir%3Dltr%5D%20.md-typeset%20blockquote%7Bpadding-left%3A.6rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20blockquote%7Bpadding-right%3A.6rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20blockquote%7Bborder-left%3A.2rem%20solid%20var%28--md-default-fg-color--lighter%29%7D%5Bdir%3Drtl%5D%20.md-typeset%20blockquote%7Bborder-right%3A.2rem%20solid%20var%28--md-default-fg-color--lighter%29%7D.md-typeset%20blockquote%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bmargin-left%3A0%3Bmargin-right%3A0%7D.md-typeset%20ul%7Blist-style-type%3Adisc%7D.md-typeset%20ul%5Btype%5D%7Blist-style-type%3Arevert-layer%7D%5Bdir%3Dltr%5D%20.md-typeset%20ol%2C%5Bdir%3Dltr%5D%20.md-typeset%20ul%7Bmargin-left%3A.625em%7D%5Bdir%3Drtl%5D%20.md-typeset%20ol%2C%5Bdir%3Drtl%5D%20.md-typeset%20ul%7Bmargin-right%3A.625em%7D.md-typeset%20ol%2C.md-typeset%20ul%7Bpadding%3A0%7D.md-typeset%20ol%3Anot%28%5Bhidden%5D%29%2C.md-typeset%20ul%3Anot%28%5Bhidden%5D%29%7Bdisplay%3Aflow-root%7D.md-typeset%20ol%20ol%2C.md-typeset%20ul%20ol%7Blist-style-type%3Alower-alpha%7D.md-typeset%20ol%20ol%20ol%2C.md-typeset%20ul%20ol%20ol%7Blist-style-type%3Alower-roman%7D.md-typeset%20ol%20ol%20ol%20ol%2C.md-typeset%20ul%20ol%20ol%20ol%7Blist-style-type%3Aupper-alpha%7D.md-typeset%20ol%20ol%20ol%20ol%20ol%2C.md-typeset%20ul%20ol%20ol%20ol%20ol%7Blist-style-type%3Aupper-roman%7D.md-typeset%20ol%5Btype%5D%2C.md-typeset%20ul%5Btype%5D%7Blist-style-type%3Arevert-layer%7D%5Bdir%3Dltr%5D%20.md-typeset%20ol%20li%2C%5Bdir%3Dltr%5D%20.md-typeset%20ul%20li%7Bmargin-left%3A1.25em%7D%5Bdir%3Drtl%5D%20.md-typeset%20ol%20li%2C%5Bdir%3Drtl%5D%20.md-typeset%20ul%20li%7Bmargin-right%3A1.25em%7D.md-typeset%20ol%20li%2C.md-typeset%20ul%20li%7Bmargin-bottom%3A.5em%7D.md-typeset%20ol%20li%20blockquote%2C.md-typeset%20ol%20li%20p%2C.md-typeset%20ul%20li%20blockquote%2C.md-typeset%20ul%20li%20p%7Bmargin%3A.5em%200%7D.md-typeset%20ol%20li%3Alast-child%2C.md-typeset%20ul%20li%3Alast-child%7Bmargin-bottom%3A0%7D%5Bdir%3Dltr%5D%20.md-typeset%20ol%20li%20ol%2C%5Bdir%3Dltr%5D%20.md-typeset%20ol%20li%20ul%2C%5Bdir%3Dltr%5D%20.md-typeset%20ul%20li%20ol%2C%5Bdir%3Dltr%5D%20.md-typeset%20ul%20li%20ul%7Bmargin-left%3A.625em%7D%5Bdir%3Drtl%5D%20.md-typeset%20ol%20li%20ol%2C%5Bdir%3Drtl%5D%20.md-typeset%20ol%20li%20ul%2C%5Bdir%3Drtl%5D%20.md-typeset%20ul%20li%20ol%2C%5Bdir%3Drtl%5D%20.md-typeset%20ul%20li%20ul%7Bmargin-right%3A.625em%7D.md-typeset%20ol%20li%20ol%2C.md-typeset%20ol%20li%20ul%2C.md-typeset%20ul%20li%20ol%2C.md-typeset%20ul%20li%20ul%7Bmargin-bottom%3A.5em%3Bmargin-top%3A.5em%7D%5Bdir%3Dltr%5D%20.md-typeset%20dd%7Bmargin-left%3A1.875em%7D%5Bdir%3Drtl%5D%20.md-typeset%20dd%7Bmargin-right%3A1.875em%7D.md-typeset%20dd%7Bmargin-bottom%3A1.5em%3Bmargin-top%3A1em%7D.md-typeset%20img%2C.md-typeset%20svg%2C.md-typeset%20video%7Bheight%3Aauto%3Bmax-width%3A100%25%7D.md-typeset%20img%5Balign%3Dleft%5D%7Bmargin%3A1em%201em%201em%200%7D.md-typeset%20img%5Balign%3Dright%5D%7Bmargin%3A1em%200%201em%201em%7D.md-typeset%20img%5Balign%5D%3Aonly-child%7Bmargin-top%3A0%7D.md-typeset%20figure%7Bdisplay%3Aflow-root%3Bmargin%3A1em%20auto%3Bmax-width%3A100%25%3Btext-align%3Acenter%3Bwidth%3Afit-content%7D.md-typeset%20figure%20img%7Bdisplay%3Ablock%3Bmargin%3A0%20auto%7D.md-typeset%20figcaption%7Bfont-style%3Aitalic%3Bmargin%3A1em%20auto%3Bmax-width%3A24rem%7D.md-typeset%20iframe%7Bmax-width%3A100%25%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder%3A.05rem%20solid%20var%28--md-typeset-table-color%29%3Bborder-radius%3A.1rem%3Bdisplay%3Ainline-block%3Bfont-size%3A.64rem%3Bmax-width%3A100%25%3Boverflow%3Aauto%3Btouch-action%3Aauto%7D%40media%20print%7B.md-typeset%20table%3Anot%28%5Bclass%5D%29%7Bdisplay%3Atable%7D%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%2B%2A%7Bmargin-top%3A1.5em%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%20td%3E%3Afirst-child%2C.md-typeset%20table%3Anot%28%5Bclass%5D%29%20th%3E%3Afirst-child%7Bmargin-top%3A0%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%20td%3E%3Alast-child%2C.md-typeset%20table%3Anot%28%5Bclass%5D%29%20th%3E%3Alast-child%7Bmargin-bottom%3A0%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%20td%3Anot%28%5Balign%5D%29%2C.md-typeset%20table%3Anot%28%5Bclass%5D%29%20th%3Anot%28%5Balign%5D%29%7Btext-align%3Aleft%7D%5Bdir%3Drtl%5D%20.md-typeset%20table%3Anot%28%5Bclass%5D%29%20td%3Anot%28%5Balign%5D%29%2C%5Bdir%3Drtl%5D%20.md-typeset%20table%3Anot%28%5Bclass%5D%29%20th%3Anot%28%5Balign%5D%29%7Btext-align%3Aright%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%20th%7Bfont-weight%3A700%3Bmin-width%3A5rem%3Bpadding%3A.9375em%201.25em%3Bvertical-align%3Atop%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%20td%7Bborder-top%3A.05rem%20solid%20var%28--md-typeset-table-color%29%3Bpadding%3A.9375em%201.25em%3Bvertical-align%3Atop%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%20tbody%20tr%7Btransition%3Abackground-color%20125ms%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%20tbody%20tr%3Ahover%7Bbackground-color%3Avar%28--md-typeset-table-color--light%29%3Bbox-shadow%3A0%20.05rem%200%20var%28--md-default-bg-color%29%20inset%7D.md-typeset%20table%3Anot%28%5Bclass%5D%29%20a%7Bword-break%3Anormal%7D.md-typeset%20table%20th%5Brole%3Dcolumnheader%5D%7Bcursor%3Apointer%7D%5Bdir%3Dltr%5D%20.md-typeset%20table%20th%5Brole%3Dcolumnheader%5D%3Aafter%7Bmargin-left%3A.5em%7D%5Bdir%3Drtl%5D%20.md-typeset%20table%20th%5Brole%3Dcolumnheader%5D%3Aafter%7Bmargin-right%3A.5em%7D.md-typeset%20table%20th%5Brole%3Dcolumnheader%5D%3Aafter%7Bcontent%3A%22%22%3Bdisplay%3Ainline-block%3Bheight%3A1.2em%3B-webkit-mask-image%3Avar%28--md-typeset-table-sort-icon%29%3Bmask-image%3Avar%28--md-typeset-table-sort-icon%29%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Btransition%3Abackground-color%20125ms%3Bvertical-align%3Atext-bottom%3Bwidth%3A1.2em%7D.md-typeset%20table%20th%5Brole%3Dcolumnheader%5D%3Ahover%3Aafter%7Bbackground-color%3Avar%28--md-default-fg-color--lighter%29%7D.md-typeset%20table%20th%5Brole%3Dcolumnheader%5D%5Baria-sort%3Dascending%5D%3Aafter%7Bbackground-color%3Avar%28--md-default-fg-color--light%29%3B-webkit-mask-image%3Avar%28--md-typeset-table-sort-icon--asc%29%3Bmask-image%3Avar%28--md-typeset-table-sort-icon--asc%29%7D.md-typeset%20table%20th%5Brole%3Dcolumnheader%5D%5Baria-sort%3Ddescending%5D%3Aafter%7Bbackground-color%3Avar%28--md-default-fg-color--light%29%3B-webkit-mask-image%3Avar%28--md-typeset-table-sort-icon--desc%29%3Bmask-image%3Avar%28--md-typeset-table-sort-icon--desc%29%7D.md-typeset__scrollwrap%7Bmargin%3A1em%20-.8rem%3Boverflow-x%3Aauto%3Btouch-action%3Aauto%7D.md-typeset__table%7Bdisplay%3Ainline-block%3Bmargin-bottom%3A.5em%3Bpadding%3A0%20.8rem%7D%40media%20print%7B.md-typeset__table%7Bdisplay%3Ablock%7D%7Dhtml%20.md-typeset__table%20table%7Bdisplay%3Atable%3Bmargin%3A0%3Boverflow%3Ahidden%3Bwidth%3A100%25%7D%40media%20screen%20and%20%28max-width%3A44.984375em%29%7B.md-content__inner%3Epre%7Bmargin%3A1em%20-.8rem%7D.md-content__inner%3Epre%20code%7Bborder-radius%3A0%7D%7D.md-typeset%20.md-author%7Bborder-radius%3A100%25%3Bdisplay%3Ablock%3Bflex-shrink%3A0%3Bheight%3A1.6rem%3Boverflow%3Ahidden%3Bposition%3Arelative%3Btransition%3Acolor%20125ms%2Ctransform%20125ms%3Bwidth%3A1.6rem%7D.md-typeset%20.md-author%20img%7Bdisplay%3Ablock%7D.md-typeset%20.md-author--more%7Bbackground%3Avar%28--md-default-fg-color--lightest%29%3Bcolor%3Avar%28--md-default-fg-color--lighter%29%3Bfont-size%3A.6rem%3Bfont-weight%3A700%3Bline-height%3A1.6rem%3Btext-align%3Acenter%7D.md-typeset%20.md-author--long%7Bheight%3A2.4rem%3Bwidth%3A2.4rem%7D.md-typeset%20a.md-author%7Btransform%3Ascale%281%29%7D.md-typeset%20a.md-author%20img%7Bborder-radius%3A100%25%3Bfilter%3Agrayscale%28100%25%29%20opacity%2875%25%29%3Btransition%3Afilter%20125ms%7D.md-typeset%20a.md-author%3Afocus%2C.md-typeset%20a.md-author%3Ahover%7Btransform%3Ascale%281.1%29%3Bz-index%3A1%7D.md-typeset%20a.md-author%3Afocus%20img%2C.md-typeset%20a.md-author%3Ahover%20img%7Bfilter%3Agrayscale%280%29%7D.md-banner%7Bbackground-color%3Avar%28--md-footer-bg-color%29%3Bcolor%3Avar%28--md-footer-fg-color%29%3Boverflow%3Aauto%7D%40media%20print%7B.md-banner%7Bdisplay%3Anone%7D%7D.md-banner--warning%7Bbackground-color%3Avar%28--md-warning-bg-color%29%3Bcolor%3Avar%28--md-warning-fg-color%29%7D.md-banner__inner%7Bfont-size%3A.7rem%3Bmargin%3A.6rem%20auto%3Bpadding%3A0%20.8rem%7D%5Bdir%3Dltr%5D%20.md-banner__button%7Bfloat%3Aright%7D%5Bdir%3Drtl%5D%20.md-banner__button%7Bfloat%3Aleft%7D.md-banner__button%7Bcolor%3Ainherit%3Bcursor%3Apointer%3Btransition%3Aopacity%20.25s%7D.no-js%20.md-banner__button%7Bdisplay%3Anone%7D.md-banner__button%3Ahover%7Bopacity%3A.7%7Dhtml%7Bfont-size%3A125%25%3Bheight%3A100%25%3Boverflow-x%3Ahidden%7D%40media%20screen%20and%20%28min-width%3A100em%29%7Bhtml%7Bfont-size%3A137.5%25%7D%7D%40media%20screen%20and%20%28min-width%3A125em%29%7Bhtml%7Bfont-size%3A150%25%7D%7Dbody%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bdisplay%3Aflex%3Bflex-direction%3Acolumn%3Bfont-size%3A.5rem%3Bmin-height%3A100%25%3Bposition%3Arelative%3Bwidth%3A100%25%7D%40media%20print%7Bbody%7Bdisplay%3Ablock%7D%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7Bbody%5Bdata-md-scrolllock%5D%7Bposition%3Afixed%7D%7D.md-grid%7Bmargin-left%3Aauto%3Bmargin-right%3Aauto%3Bmax-width%3A61rem%7D.md-container%7Bdisplay%3Aflex%3Bflex-direction%3Acolumn%3Bflex-grow%3A1%7D%40media%20print%7B.md-container%7Bdisplay%3Ablock%7D%7D.md-main%7Bflex-grow%3A1%7D.md-main__inner%7Bdisplay%3Aflex%3Bheight%3A100%25%3Bmargin-top%3A1.5rem%7D.md-ellipsis%7Boverflow%3Ahidden%3Btext-overflow%3Aellipsis%7D.md-toggle%7Bdisplay%3Anone%7D.md-option%7Bheight%3A0%3Bopacity%3A0%3Bposition%3Aabsolute%3Bwidth%3A0%7D.md-option%3Achecked%2Blabel%3Anot%28%5Bhidden%5D%29%7Bdisplay%3Ablock%7D.md-option.focus-visible%2Blabel%7Boutline-color%3Avar%28--md-accent-fg-color%29%3Boutline-style%3Aauto%7D.md-skip%7Bbackground-color%3Avar%28--md-default-fg-color%29%3Bborder-radius%3A.1rem%3Bcolor%3Avar%28--md-default-bg-color%29%3Bfont-size%3A.64rem%3Bmargin%3A.5rem%3Bopacity%3A0%3Boutline-color%3Avar%28--md-accent-fg-color%29%3Bpadding%3A.3rem%20.5rem%3Bposition%3Afixed%3Btransform%3AtranslateY%28.4rem%29%3Bz-index%3A-1%7D.md-skip%3Afocus%7Bopacity%3A1%3Btransform%3AtranslateY%280%29%3Btransition%3Atransform%20.25s%20cubic-bezier%28.4%2C0%2C.2%2C1%29%2Copacity%20175ms%2075ms%3Bz-index%3A10%7D%40page%7Bmargin%3A25mm%7D%3Aroot%7B--md-clipboard-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M19%2021H8V7h11m0-2H8a2%202%200%200%200-2%202v14a2%202%200%200%200%202%202h11a2%202%200%200%200%202-2V7a2%202%200%200%200-2-2m-3-4H4a2%202%200%200%200-2%202v14h2V3h12z%22/%3E%3C/svg%3E%27%29%7D.md-clipboard%7Bborder-radius%3A.1rem%3Bcolor%3Avar%28--md-default-fg-color--lightest%29%3Bcursor%3Apointer%3Bheight%3A1.5em%3Boutline-color%3Avar%28--md-accent-fg-color%29%3Boutline-offset%3A.1rem%3Btransition%3Acolor%20.25s%3Bwidth%3A1.5em%3Bz-index%3A1%7D%40media%20print%7B.md-clipboard%7Bdisplay%3Anone%7D%7D.md-clipboard%3Anot%28.focus-visible%29%7B-webkit-tap-highlight-color%3Atransparent%3Boutline%3Anone%7D%3Ahover%3E.md-clipboard%7Bcolor%3Avar%28--md-default-fg-color--light%29%7D.md-clipboard%3Afocus%2C.md-clipboard%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-clipboard%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A1.125em%3Bmargin%3A0%20auto%3B-webkit-mask-image%3Avar%28--md-clipboard-icon%29%3Bmask-image%3Avar%28--md-clipboard-icon%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bwidth%3A1.125em%7D.md-clipboard--inline%7Bcursor%3Apointer%7D.md-clipboard--inline%20code%7Btransition%3Acolor%20.25s%2Cbackground-color%20.25s%7D.md-clipboard--inline%3Afocus%20code%2C.md-clipboard--inline%3Ahover%20code%7Bbackground-color%3Avar%28--md-accent-fg-color--transparent%29%3Bcolor%3Avar%28--md-accent-fg-color%29%7D%3Aroot%7B--md-code-select-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M19%2019h-4v2h4c1.1%200%202-.9%202-2v-4h-2m0-12h-4v2h4v4h2V5c0-1.1-.9-2-2-2M5%205h4V3H5c-1.1%200-2%20.9-2%202v4h2m0%206H3v4c0%201.1.9%202%202%202h4v-2H5zm2-4h2v2H7zm4%200h2v2h-2zm4%200h2v2h-2zM7%207h2v2H7zm4%200h2v2h-2zm4%200h2v2h-2zm-8%208h2v2H7zm4%200h2v2h-2zm4%200h2v2h-2z%22/%3E%3C/svg%3E%27%29%3B--md-code-copy-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M19%2021H8V7h11m0-2H8a2%202%200%200%200-2%202v14a2%202%200%200%200%202%202h11a2%202%200%200%200%202-2V7a2%202%200%200%200-2-2m-3-4H4a2%202%200%200%200-2%202v14h2V3h12z%22/%3E%3C/svg%3E%27%29%7D.md-typeset%20.md-code__content%7Bdisplay%3Agrid%7D.md-code__nav%7Bbackground-color%3Avar%28--md-code-bg-color--lighter%29%3Bborder-radius%3A.1rem%3Bdisplay%3Aflex%3Bgap%3A.2rem%3Bpadding%3A.2rem%3Bposition%3Aabsolute%3Bright%3A.25em%3Btop%3A.25em%3Btransition%3Abackground-color%20.25s%3Bz-index%3A1%7D%3Ahover%3E.md-code__nav%7Bbackground-color%3Avar%28--md-code-bg-color--light%29%7D.md-code__button%7Bcolor%3Avar%28--md-default-fg-color--lightest%29%3Bcursor%3Apointer%3Bdisplay%3Ablock%3Bheight%3A1.5em%3Boutline-color%3Avar%28--md-accent-fg-color%29%3Boutline-offset%3A.1rem%3Btransition%3Acolor%20.25s%3Bwidth%3A1.5em%7D%3Ahover%3E%2A%3E.md-code__button%7Bcolor%3Avar%28--md-default-fg-color--light%29%7D.md-code__button.focus-visible%2C.md-code__button%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-code__button--active%7Bcolor%3Avar%28--md-default-fg-color%29%21important%7D.md-code__button%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A1.125em%3Bmargin%3A0%20auto%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bwidth%3A1.125em%7D.md-code__button%5Bdata-md-type%3Dselect%5D%3Aafter%7B-webkit-mask-image%3Avar%28--md-code-select-icon%29%3Bmask-image%3Avar%28--md-code-select-icon%29%7D.md-code__button%5Bdata-md-type%3Dcopy%5D%3Aafter%7B-webkit-mask-image%3Avar%28--md-code-copy-icon%29%3Bmask-image%3Avar%28--md-code-copy-icon%29%7D%40keyframes%20consent%7B0%25%7Bopacity%3A0%3Btransform%3AtranslateY%28100%25%29%7Dto%7Bopacity%3A1%3Btransform%3AtranslateY%280%29%7D%7D%40keyframes%20overlay%7B0%25%7Bopacity%3A0%7Dto%7Bopacity%3A1%7D%7D.md-consent__overlay%7Banimation%3Aoverlay%20.25s%20both%3B-webkit-backdrop-filter%3Ablur%28.1rem%29%3Bbackdrop-filter%3Ablur%28.1rem%29%3Bbackground-color%3A%230000008a%3Bheight%3A100%25%3Bopacity%3A1%3Bposition%3Afixed%3Btop%3A0%3Bwidth%3A100%25%3Bz-index%3A5%7D.md-consent__inner%7Banimation%3Aconsent%20.5s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%20both%3Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder%3A0%3Bborder-radius%3A.1rem%3Bbottom%3A0%3Bbox-shadow%3A0%200%20.2rem%20%230000001a%2C0%20.2rem%20.4rem%20%230003%3Bmax-height%3A100%25%3Boverflow%3Aauto%3Bpadding%3A0%3Bposition%3Afixed%3Bwidth%3A100%25%3Bz-index%3A5%7D.md-consent__form%7Bpadding%3A.8rem%7D.md-consent__settings%7Bdisplay%3Anone%3Bmargin%3A1em%200%7Dinput%3Achecked%2B.md-consent__settings%7Bdisplay%3Ablock%7D.md-consent__controls%7Bmargin-bottom%3A.8rem%7D.md-typeset%20.md-consent__controls%20.md-button%7Bdisplay%3Ainline%7D%40media%20screen%20and%20%28max-width%3A44.984375em%29%7B.md-typeset%20.md-consent__controls%20.md-button%7Bdisplay%3Ablock%3Bmargin-top%3A.4rem%3Btext-align%3Acenter%3Bwidth%3A100%25%7D%7D.md-consent%20label%7Bcursor%3Apointer%7D.md-content%7Bflex-grow%3A1%3Bmin-width%3A0%7D.md-content__inner%7Bmargin%3A0%20.8rem%201.2rem%3Bpadding-top%3A.6rem%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B%5Bdir%3Dltr%5D%20.md-sidebar--primary%3Anot%28%5Bhidden%5D%29~.md-content%3E.md-content__inner%7Bmargin-left%3A1.2rem%7D%5Bdir%3Dltr%5D%20.md-sidebar--secondary%3Anot%28%5Bhidden%5D%29~.md-content%3E.md-content__inner%2C%5Bdir%3Drtl%5D%20.md-sidebar--primary%3Anot%28%5Bhidden%5D%29~.md-content%3E.md-content__inner%7Bmargin-right%3A1.2rem%7D%5Bdir%3Drtl%5D%20.md-sidebar--secondary%3Anot%28%5Bhidden%5D%29~.md-content%3E.md-content__inner%7Bmargin-left%3A1.2rem%7D%7D.md-content__inner%3Abefore%7Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A.4rem%7D.md-content__inner%3E%3Alast-child%7Bmargin-bottom%3A0%7D%5Bdir%3Dltr%5D%20.md-content__button%7Bfloat%3Aright%7D%5Bdir%3Drtl%5D%20.md-content__button%7Bfloat%3Aleft%7D%5Bdir%3Dltr%5D%20.md-content__button%7Bmargin-left%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-content__button%7Bmargin-right%3A.4rem%7D.md-content__button%7Bmargin%3A.4rem%200%3Bpadding%3A0%7D%40media%20print%7B.md-content__button%7Bdisplay%3Anone%7D%7D.md-typeset%20.md-content__button%7Bcolor%3Avar%28--md-default-fg-color--lighter%29%7D.md-content__button%20svg%7Bdisplay%3Ainline%3Bvertical-align%3Atop%7D%5Bdir%3Drtl%5D%20.md-content__button%20svg%7Btransform%3AscaleX%28-1%29%7D%5Bdir%3Dltr%5D%20.md-dialog%7Bright%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-dialog%7Bleft%3A.8rem%7D.md-dialog%7Bbackground-color%3Avar%28--md-default-fg-color%29%3Bborder-radius%3A.1rem%3Bbottom%3A.8rem%3Bbox-shadow%3Avar%28--md-shadow-z3%29%3Bmin-width%3A11.1rem%3Bopacity%3A0%3Bpadding%3A.4rem%20.6rem%3Bpointer-events%3Anone%3Bposition%3Afixed%3Btransform%3AtranslateY%28100%25%29%3Btransition%3Atransform%200ms%20.4s%2Copacity%20.4s%3Bz-index%3A4%7D%40media%20print%7B.md-dialog%7Bdisplay%3Anone%7D%7D.md-dialog--active%7Bopacity%3A1%3Bpointer-events%3Aauto%3Btransform%3AtranslateY%280%29%3Btransition%3Atransform%20.4s%20cubic-bezier%28.075%2C.85%2C.175%2C1%29%2Copacity%20.4s%7D.md-dialog__inner%7Bcolor%3Avar%28--md-default-bg-color%29%3Bfont-size%3A.7rem%7D.md-feedback%7Bmargin%3A2em%200%201em%3Btext-align%3Acenter%7D.md-feedback%20fieldset%7Bborder%3Anone%3Bmargin%3A0%3Bpadding%3A0%7D.md-feedback__title%7Bfont-weight%3A700%3Bmargin%3A1em%20auto%7D.md-feedback__inner%7Bposition%3Arelative%7D.md-feedback__list%7Bdisplay%3Aflex%3Bflex-wrap%3Awrap%3Bplace-content%3Abaseline%20center%3Bposition%3Arelative%7D.md-feedback__list%3Ahover%20.md-icon%3Anot%28%3Adisabled%29%7Bcolor%3Avar%28--md-default-fg-color--lighter%29%7D%3Adisabled%20.md-feedback__list%7Bmin-height%3A1.8rem%7D.md-feedback__icon%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bcursor%3Apointer%3Bflex-shrink%3A0%3Bmargin%3A0%20.1rem%3Btransition%3Acolor%20125ms%7D.md-feedback__icon%3Anot%28%3Adisabled%29.md-icon%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-feedback__icon%3Adisabled%7Bcolor%3Avar%28--md-default-fg-color--lightest%29%3Bpointer-events%3Anone%7D.md-feedback__note%7Bopacity%3A0%3Bposition%3Arelative%3Btransform%3AtranslateY%28.4rem%29%3Btransition%3Atransform%20.4s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%2Copacity%20.15s%7D.md-feedback__note%3E%2A%7Bmargin%3A0%20auto%3Bmax-width%3A16rem%7D%3Adisabled%20.md-feedback__note%7Bopacity%3A1%3Btransform%3AtranslateY%280%29%7D%40media%20print%7B.md-feedback%7Bdisplay%3Anone%7D%7D.md-footer%7Bbackground-color%3Avar%28--md-footer-bg-color%29%3Bcolor%3Avar%28--md-footer-fg-color%29%7D%40media%20print%7B.md-footer%7Bdisplay%3Anone%7D%7D.md-footer__inner%7Bjustify-content%3Aspace-between%3Boverflow%3Aauto%3Bpadding%3A.2rem%7D.md-footer__inner%3Anot%28%5Bhidden%5D%29%7Bdisplay%3Aflex%7D.md-footer__link%7Balign-items%3Aend%3Bdisplay%3Aflex%3Bflex-grow%3A0.01%3Bmargin-bottom%3A.4rem%3Bmargin-top%3A1rem%3Bmax-width%3A100%25%3Boutline-color%3Avar%28--md-accent-fg-color%29%3Boverflow%3Ahidden%3Btransition%3Aopacity%20.25s%7D.md-footer__link%3Afocus%2C.md-footer__link%3Ahover%7Bopacity%3A.7%7D%5Bdir%3Drtl%5D%20.md-footer__link%20svg%7Btransform%3AscaleX%28-1%29%7D%40media%20screen%20and%20%28max-width%3A44.984375em%29%7B.md-footer__link--prev%7Bflex-shrink%3A0%7D.md-footer__link--prev%20.md-footer__title%7Bdisplay%3Anone%7D%7D%5Bdir%3Dltr%5D%20.md-footer__link--next%7Bmargin-left%3Aauto%7D%5Bdir%3Drtl%5D%20.md-footer__link--next%7Bmargin-right%3Aauto%7D.md-footer__link--next%7Btext-align%3Aright%7D%5Bdir%3Drtl%5D%20.md-footer__link--next%7Btext-align%3Aleft%7D.md-footer__title%7Bflex-grow%3A1%3Bfont-size%3A.9rem%3Bmargin-bottom%3A.7rem%3Bmax-width%3Acalc%28100%25%20-%202.4rem%29%3Bpadding%3A0%201rem%3Bwhite-space%3Anowrap%7D.md-footer__button%7Bmargin%3A.2rem%3Bpadding%3A.4rem%7D.md-footer__direction%7Bfont-size%3A.64rem%3Bopacity%3A.7%7D.md-footer-meta%7Bbackground-color%3Avar%28--md-footer-bg-color--dark%29%7D.md-footer-meta__inner%7Bdisplay%3Aflex%3Bflex-wrap%3Awrap%3Bjustify-content%3Aspace-between%3Bpadding%3A.2rem%7Dhtml%20.md-footer-meta.md-typeset%20a%7Bcolor%3Avar%28--md-footer-fg-color--light%29%7Dhtml%20.md-footer-meta.md-typeset%20a%3Afocus%2Chtml%20.md-footer-meta.md-typeset%20a%3Ahover%7Bcolor%3Avar%28--md-footer-fg-color%29%7D.md-copyright%7Bcolor%3Avar%28--md-footer-fg-color--lighter%29%3Bfont-size%3A.64rem%3Bmargin%3Aauto%20.6rem%3Bpadding%3A.4rem%200%3Bwidth%3A100%25%7D%40media%20screen%20and%20%28min-width%3A45em%29%7B.md-copyright%7Bwidth%3Aauto%7D%7D.md-copyright__highlight%7Bcolor%3Avar%28--md-footer-fg-color--light%29%7D.md-social%7Bdisplay%3Ainline-flex%3Bgap%3A.2rem%3Bmargin%3A0%20.4rem%3Bpadding%3A.2rem%200%20.6rem%7D%40media%20screen%20and%20%28min-width%3A45em%29%7B.md-social%7Bpadding%3A.6rem%200%7D%7D.md-social__link%7Bdisplay%3Ainline-block%3Bheight%3A1.6rem%3Btext-align%3Acenter%3Bwidth%3A1.6rem%7D.md-social__link%3Abefore%7Bline-height%3A1.9%7D.md-social__link%20svg%7Bfill%3Acurrentcolor%3Bmax-height%3A.8rem%3Bvertical-align%3A-25%25%7D.md-typeset%20.md-button%7Bborder%3A.1rem%20solid%3Bborder-radius%3A.1rem%3Bcolor%3Avar%28--md-primary-fg-color%29%3Bcursor%3Apointer%3Bdisplay%3Ainline-block%3Bfont-weight%3A700%3Bpadding%3A.625em%202em%3Btransition%3Acolor%20125ms%2Cbackground-color%20125ms%2Cborder-color%20125ms%7D.md-typeset%20.md-button--primary%7Bbackground-color%3Avar%28--md-primary-fg-color%29%3Bborder-color%3Avar%28--md-primary-fg-color%29%3Bcolor%3Avar%28--md-primary-bg-color%29%7D.md-typeset%20.md-button%3Afocus%2C.md-typeset%20.md-button%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color%29%3Bborder-color%3Avar%28--md-accent-fg-color%29%3Bcolor%3Avar%28--md-accent-bg-color%29%7D%5Bdir%3Dltr%5D%20.md-typeset%20.md-input%7Bborder-top-left-radius%3A.1rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20.md-input%2C%5Bdir%3Drtl%5D%20.md-typeset%20.md-input%7Bborder-top-right-radius%3A.1rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.md-input%7Bborder-top-left-radius%3A.1rem%7D.md-typeset%20.md-input%7Bborder-bottom%3A.1rem%20solid%20var%28--md-default-fg-color--lighter%29%3Bbox-shadow%3Avar%28--md-shadow-z1%29%3Bfont-size%3A.8rem%3Bheight%3A1.8rem%3Bpadding%3A0%20.6rem%3Btransition%3Aborder%20.25s%2Cbox-shadow%20.25s%7D.md-typeset%20.md-input%3Afocus%2C.md-typeset%20.md-input%3Ahover%7Bborder-bottom-color%3Avar%28--md-accent-fg-color%29%3Bbox-shadow%3Avar%28--md-shadow-z2%29%7D.md-typeset%20.md-input--stretch%7Bwidth%3A100%25%7D.md-header%7Bbackground-color%3Avar%28--md-primary-fg-color%29%3Bbox-shadow%3A0%200%20.2rem%20%230000%2C0%20.2rem%20.4rem%20%230000%3Bcolor%3Avar%28--md-primary-bg-color%29%3Bdisplay%3Ablock%3Bleft%3A0%3Bposition%3Asticky%3Bright%3A0%3Btop%3A0%3Bz-index%3A4%7D%40media%20print%7B.md-header%7Bdisplay%3Anone%7D%7D.md-header%5Bhidden%5D%7Btransform%3AtranslateY%28-100%25%29%3Btransition%3Atransform%20.25s%20cubic-bezier%28.8%2C0%2C.6%2C1%29%2Cbox-shadow%20.25s%7D.md-header--shadow%7Bbox-shadow%3A0%200%20.2rem%20%230000001a%2C0%20.2rem%20.4rem%20%230003%3Btransition%3Atransform%20.25s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%2Cbox-shadow%20.25s%7D.md-header__inner%7Balign-items%3Acenter%3Bdisplay%3Aflex%3Bpadding%3A0%20.2rem%7D.md-header__button%7Bcolor%3Acurrentcolor%3Bcursor%3Apointer%3Bmargin%3A.2rem%3Boutline-color%3Avar%28--md-accent-fg-color%29%3Bpadding%3A.4rem%3Bposition%3Arelative%3Btransition%3Aopacity%20.25s%3Bvertical-align%3Amiddle%3Bz-index%3A1%7D.md-header__button%3Ahover%7Bopacity%3A.7%7D.md-header__button%3Anot%28%5Bhidden%5D%29%7Bdisplay%3Ainline-block%7D.md-header__button%3Anot%28.focus-visible%29%7B-webkit-tap-highlight-color%3Atransparent%3Boutline%3Anone%7D.md-header__button.md-logo%7Bmargin%3A.2rem%3Bpadding%3A.4rem%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7B.md-header__button.md-logo%7Bdisplay%3Anone%7D%7D.md-header__button.md-logo%20img%2C.md-header__button.md-logo%20svg%7Bfill%3Acurrentcolor%3Bdisplay%3Ablock%3Bheight%3A1.2rem%3Bwidth%3Aauto%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-header__button%5Bfor%3D__search%5D%7Bdisplay%3Anone%7D%7D.no-js%20.md-header__button%5Bfor%3D__search%5D%7Bdisplay%3Anone%7D%5Bdir%3Drtl%5D%20.md-header__button%5Bfor%3D__search%5D%20svg%7Btransform%3AscaleX%28-1%29%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B.md-header__button%5Bfor%3D__drawer%5D%7Bdisplay%3Anone%7D%7D.md-header__topic%7Bdisplay%3Aflex%3Bmax-width%3A100%25%3Bposition%3Aabsolute%3Btransition%3Atransform%20.4s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%2Copacity%20.15s%3Bwhite-space%3Anowrap%7D.md-header__topic%2B.md-header__topic%7Bopacity%3A0%3Bpointer-events%3Anone%3Btransform%3AtranslateX%281.25rem%29%3Btransition%3Atransform%20.4s%20cubic-bezier%281%2C.7%2C.1%2C.1%29%2Copacity%20.15s%3Bz-index%3A-1%7D%5Bdir%3Drtl%5D%20.md-header__topic%2B.md-header__topic%7Btransform%3AtranslateX%28-1.25rem%29%7D.md-header__topic%3Afirst-child%7Bfont-weight%3A700%7D%5Bdir%3Dltr%5D%20.md-header__title%7Bmargin-left%3A1rem%3Bmargin-right%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-header__title%7Bmargin-left%3A.4rem%3Bmargin-right%3A1rem%7D.md-header__title%7Bflex-grow%3A1%3Bfont-size%3A.9rem%3Bheight%3A2.4rem%3Bline-height%3A2.4rem%7D.md-header__title--active%20.md-header__topic%7Bopacity%3A0%3Bpointer-events%3Anone%3Btransform%3AtranslateX%28-1.25rem%29%3Btransition%3Atransform%20.4s%20cubic-bezier%281%2C.7%2C.1%2C.1%29%2Copacity%20.15s%3Bz-index%3A-1%7D%5Bdir%3Drtl%5D%20.md-header__title--active%20.md-header__topic%7Btransform%3AtranslateX%281.25rem%29%7D.md-header__title--active%20.md-header__topic%2B.md-header__topic%7Bopacity%3A1%3Bpointer-events%3Aauto%3Btransform%3AtranslateX%280%29%3Btransition%3Atransform%20.4s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%2Copacity%20.15s%3Bz-index%3A0%7D.md-header__title%3E.md-header__ellipsis%7Bheight%3A100%25%3Bposition%3Arelative%3Bwidth%3A100%25%7D.md-header__option%7Bdisplay%3Aflex%3Bflex-shrink%3A0%3Bmax-width%3A100%25%3Btransition%3Amax-width%200ms%20.25s%2Copacity%20.25s%20.25s%3Bwhite-space%3Anowrap%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-header__option%7Bmax-width%3A0%3Bopacity%3A0%3Btransition%3Amax-width%200ms%2Copacity%200ms%7D.md-header__option%3Einput%7Bbottom%3A0%7D.md-header__source%7Bdisplay%3Anone%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdir%3Dltr%5D%20.md-header__source%7Bmargin-left%3A1rem%7D%5Bdir%3Drtl%5D%20.md-header__source%7Bmargin-right%3A1rem%7D.md-header__source%7Bdisplay%3Ablock%3Bmax-width%3A11.7rem%3Bwidth%3A11.7rem%7D%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B%5Bdir%3Dltr%5D%20.md-header__source%7Bmargin-left%3A1.4rem%7D%5Bdir%3Drtl%5D%20.md-header__source%7Bmargin-right%3A1.4rem%7D%7D.md-meta%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bfont-size%3A.7rem%3Bline-height%3A1.3%7D.md-meta__list%7Bdisplay%3Ainline-flex%3Bflex-wrap%3Awrap%3Blist-style%3Anone%3Bmargin%3A0%3Bpadding%3A0%7D.md-meta__item%3Anot%28%3Alast-child%29%3Aafter%7Bcontent%3A%22%C2%B7%22%3Bmargin-left%3A.2rem%3Bmargin-right%3A.2rem%7D.md-meta__link%7Bcolor%3Avar%28--md-typeset-a-color%29%7D.md-meta__link%3Afocus%2C.md-meta__link%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-draft%7Bbackground-color%3A%23ff1744%3Bborder-radius%3A.125em%3Bcolor%3A%23fff%3Bdisplay%3Ainline-block%3Bfont-weight%3A700%3Bpadding-left%3A.5714285714em%3Bpadding-right%3A.5714285714em%7D%3Aroot%7B--md-nav-icon--prev%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M20%2011v2H8l5.5%205.5-1.42%201.42L4.16%2012l7.92-7.92L13.5%205.5%208%2011z%22/%3E%3C/svg%3E%27%29%3B--md-nav-icon--next%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M8.59%2016.58%2013.17%2012%208.59%207.41%2010%206l6%206-6%206z%22/%3E%3C/svg%3E%27%29%3B--md-toc-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M3%209h14V7H3zm0%204h14v-2H3zm0%204h14v-2H3zm16%200h2v-2h-2zm0-10v2h2V7zm0%206h2v-2h-2z%22/%3E%3C/svg%3E%27%29%7D.md-nav%7Bfont-size%3A.7rem%3Bline-height%3A1.3%7D.md-nav__title%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bdisplay%3Ablock%3Bfont-weight%3A700%3Boverflow%3Ahidden%3Bpadding%3A0%20.6rem%3Btext-overflow%3Aellipsis%7D.md-nav__title%20.md-nav__button%7Bdisplay%3Anone%7D.md-nav__title%20.md-nav__button%20img%7Bheight%3A100%25%3Bwidth%3Aauto%7D.md-nav__title%20.md-nav__button.md-logo%20img%2C.md-nav__title%20.md-nav__button.md-logo%20svg%7Bfill%3Acurrentcolor%3Bdisplay%3Ablock%3Bheight%3A2.4rem%3Bmax-width%3A100%25%3Bobject-fit%3Acontain%3Bwidth%3Aauto%7D.md-nav__list%7Blist-style%3Anone%3Bmargin%3A0%3Bpadding%3A0%7D.md-nav__link%7Balign-items%3Aflex-start%3Bdisplay%3Aflex%3Bgap%3A.4rem%3Bmargin-top%3A.625em%3Bscroll-snap-align%3Astart%3Btransition%3Acolor%20125ms%7D.md-nav__link--passed%2C.md-nav__link--passed%20code%7Bcolor%3Avar%28--md-default-fg-color--light%29%7D.md-nav__item%20.md-nav__link--active%2C.md-nav__item%20.md-nav__link--active%20code%7Bcolor%3Avar%28--md-typeset-a-color%29%7D.md-nav__link%20.md-ellipsis%7Bposition%3Arelative%7D.md-nav__link%20.md-ellipsis%20code%7Bword-break%3Anormal%7D%5Bdir%3Dltr%5D%20.md-nav__link%20.md-icon%3Alast-child%7Bmargin-left%3Aauto%7D%5Bdir%3Drtl%5D%20.md-nav__link%20.md-icon%3Alast-child%7Bmargin-right%3Aauto%7D.md-nav__link%20.md-typeset%7Bfont-size%3A.7rem%3Bline-height%3A1.3%7D.md-nav__link%20svg%7Bfill%3Acurrentcolor%3Bflex-shrink%3A0%3Bheight%3A1.3em%3Bposition%3Arelative%7D.md-nav__link%5Bfor%5D%3Afocus%2C.md-nav__link%5Bfor%5D%3Ahover%2C.md-nav__link%5Bhref%5D%3Afocus%2C.md-nav__link%5Bhref%5D%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%3Bcursor%3Apointer%7D.md-nav__link%5Bfor%5D%3Afocus%20code%2C.md-nav__link%5Bfor%5D%3Ahover%20code%2C.md-nav__link%5Bhref%5D%3Afocus%20code%2C.md-nav__link%5Bhref%5D%3Ahover%20code%7Bbackground-color%3Avar%28--md-accent-fg-color--transparent%29%3Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-nav__link.focus-visible%7Boutline-color%3Avar%28--md-accent-fg-color%29%3Boutline-offset%3A.2rem%7D.md-nav--primary%20.md-nav__link%5Bfor%3D__toc%5D%7Bdisplay%3Anone%7D.md-nav--primary%20.md-nav__link%5Bfor%3D__toc%5D%20.md-icon%3Aafter%7Bbackground-color%3Acurrentcolor%3Bdisplay%3Ablock%3Bheight%3A100%25%3B-webkit-mask-image%3Avar%28--md-toc-icon%29%3Bmask-image%3Avar%28--md-toc-icon%29%3Bwidth%3A100%25%7D.md-nav--primary%20.md-nav__link%5Bfor%3D__toc%5D~.md-nav%7Bdisplay%3Anone%7D.md-nav__container%3E.md-nav__link%7Bmargin-top%3A0%7D.md-nav__container%3E.md-nav__link%3Afirst-child%7Bflex-grow%3A1%3Bmin-width%3A0%7D.md-nav__icon%7Bflex-shrink%3A0%7D.md-nav__source%7Bdisplay%3Anone%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7B.md-nav--primary%2C.md-nav--primary%20.md-nav%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bdisplay%3Aflex%3Bflex-direction%3Acolumn%3Bheight%3A100%25%3Bleft%3A0%3Bposition%3Aabsolute%3Bright%3A0%3Btop%3A0%3Bz-index%3A1%7D.md-nav--primary%20.md-nav__item%2C.md-nav--primary%20.md-nav__title%7Bfont-size%3A.8rem%3Bline-height%3A1.5%7D.md-nav--primary%20.md-nav__title%7Bbackground-color%3Avar%28--md-default-fg-color--lightest%29%3Bcolor%3Avar%28--md-default-fg-color--light%29%3Bcursor%3Apointer%3Bheight%3A5.6rem%3Bline-height%3A2.4rem%3Bpadding%3A3rem%20.8rem%20.2rem%3Bposition%3Arelative%3Bwhite-space%3Anowrap%7D%5Bdir%3Dltr%5D%20.md-nav--primary%20.md-nav__title%20.md-nav__icon%7Bleft%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav__title%20.md-nav__icon%7Bright%3A.4rem%7D.md-nav--primary%20.md-nav__title%20.md-nav__icon%7Bdisplay%3Ablock%3Bheight%3A1.2rem%3Bmargin%3A.2rem%3Bposition%3Aabsolute%3Btop%3A.4rem%3Bwidth%3A1.2rem%7D.md-nav--primary%20.md-nav__title%20.md-nav__icon%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A100%25%3B-webkit-mask-image%3Avar%28--md-nav-icon--prev%29%3Bmask-image%3Avar%28--md-nav-icon--prev%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bwidth%3A100%25%7D.md-nav--primary%20.md-nav__title~.md-nav__list%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bbox-shadow%3A0%20.05rem%200%20var%28--md-default-fg-color--lightest%29%20inset%3Boverflow-y%3Aauto%3Bscroll-snap-type%3Ay%20mandatory%3Btouch-action%3Apan-y%7D.md-nav--primary%20.md-nav__title~.md-nav__list%3E%3Afirst-child%7Bborder-top%3A0%7D.md-nav--primary%20.md-nav__title%5Bfor%3D__drawer%5D%7Bbackground-color%3Avar%28--md-primary-fg-color%29%3Bcolor%3Avar%28--md-primary-bg-color%29%3Bfont-weight%3A700%7D.md-nav--primary%20.md-nav__title%20.md-logo%7Bdisplay%3Ablock%3Bleft%3A.2rem%3Bmargin%3A.2rem%3Bpadding%3A.4rem%3Bposition%3Aabsolute%3Bright%3A.2rem%3Btop%3A.2rem%7D.md-nav--primary%20.md-nav__list%7Bflex%3A1%7D.md-nav--primary%20.md-nav__item%7Bborder-top%3A.05rem%20solid%20var%28--md-default-fg-color--lightest%29%7D.md-nav--primary%20.md-nav__item--active%3E.md-nav__link%7Bcolor%3Avar%28--md-typeset-a-color%29%7D.md-nav--primary%20.md-nav__item--active%3E.md-nav__link%3Afocus%2C.md-nav--primary%20.md-nav__item--active%3E.md-nav__link%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-nav--primary%20.md-nav__link%7Bmargin-top%3A0%3Bpadding%3A.6rem%20.8rem%7D.md-nav--primary%20.md-nav__link%20svg%7Bmargin-top%3A.1em%7D.md-nav--primary%20.md-nav__link%3E.md-nav__link%7Bpadding%3A0%7D%5Bdir%3Dltr%5D%20.md-nav--primary%20.md-nav__link%20.md-nav__icon%7Bmargin-right%3A-.2rem%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav__link%20.md-nav__icon%7Bmargin-left%3A-.2rem%7D.md-nav--primary%20.md-nav__link%20.md-nav__icon%7Bfont-size%3A1.2rem%3Bheight%3A1.2rem%3Bwidth%3A1.2rem%7D.md-nav--primary%20.md-nav__link%20.md-nav__icon%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A100%25%3B-webkit-mask-image%3Avar%28--md-nav-icon--next%29%3Bmask-image%3Avar%28--md-nav-icon--next%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bwidth%3A100%25%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav__icon%3Aafter%7Btransform%3Ascale%28-1%29%7D.md-nav--primary%20.md-nav--secondary%20.md-nav%7Bbackground-color%3Ainitial%3Bposition%3Astatic%7D%5Bdir%3Dltr%5D%20.md-nav--primary%20.md-nav--secondary%20.md-nav%20.md-nav__link%7Bpadding-left%3A1.4rem%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav--secondary%20.md-nav%20.md-nav__link%7Bpadding-right%3A1.4rem%7D%5Bdir%3Dltr%5D%20.md-nav--primary%20.md-nav--secondary%20.md-nav%20.md-nav%20.md-nav__link%7Bpadding-left%3A2rem%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav--secondary%20.md-nav%20.md-nav%20.md-nav__link%7Bpadding-right%3A2rem%7D%5Bdir%3Dltr%5D%20.md-nav--primary%20.md-nav--secondary%20.md-nav%20.md-nav%20.md-nav%20.md-nav__link%7Bpadding-left%3A2.6rem%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav--secondary%20.md-nav%20.md-nav%20.md-nav%20.md-nav__link%7Bpadding-right%3A2.6rem%7D%5Bdir%3Dltr%5D%20.md-nav--primary%20.md-nav--secondary%20.md-nav%20.md-nav%20.md-nav%20.md-nav%20.md-nav__link%7Bpadding-left%3A3.2rem%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav--secondary%20.md-nav%20.md-nav%20.md-nav%20.md-nav%20.md-nav__link%7Bpadding-right%3A3.2rem%7D.md-nav--secondary%7Bbackground-color%3Ainitial%7D.md-nav__toggle~.md-nav%7Bdisplay%3Aflex%3Bopacity%3A0%3Btransform%3AtranslateX%28100%25%29%3Btransition%3Atransform%20.25s%20cubic-bezier%28.8%2C0%2C.6%2C1%29%2Copacity%20125ms%2050ms%7D%5Bdir%3Drtl%5D%20.md-nav__toggle~.md-nav%7Btransform%3AtranslateX%28-100%25%29%7D.md-nav__toggle%3Achecked~.md-nav%7Bopacity%3A1%3Btransform%3AtranslateX%280%29%3Btransition%3Atransform%20.25s%20cubic-bezier%28.4%2C0%2C.2%2C1%29%2Copacity%20125ms%20125ms%7D.md-nav__toggle%3Achecked~.md-nav%3E.md-nav__list%7Bbackface-visibility%3Ahidden%7D%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B.md-nav--primary%20.md-nav__link%5Bfor%3D__toc%5D%7Bdisplay%3Aflex%7D.md-nav--primary%20.md-nav__link%5Bfor%3D__toc%5D%20.md-icon%3Aafter%7Bcontent%3A%22%22%7D.md-nav--primary%20.md-nav__link%5Bfor%3D__toc%5D%2B.md-nav__link%7Bdisplay%3Anone%7D.md-nav--primary%20.md-nav__link%5Bfor%3D__toc%5D~.md-nav%7Bdisplay%3Aflex%7D.md-nav__source%7Bbackground-color%3Avar%28--md-primary-fg-color--dark%29%3Bcolor%3Avar%28--md-primary-bg-color%29%3Bdisplay%3Ablock%3Bpadding%3A0%20.2rem%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%20and%20%28max-width%3A76.234375em%29%7B.md-nav--integrated%20.md-nav__link%5Bfor%3D__toc%5D%7Bdisplay%3Aflex%7D.md-nav--integrated%20.md-nav__link%5Bfor%3D__toc%5D%20.md-icon%3Aafter%7Bcontent%3A%22%22%7D.md-nav--integrated%20.md-nav__link%5Bfor%3D__toc%5D%2B.md-nav__link%7Bdisplay%3Anone%7D.md-nav--integrated%20.md-nav__link%5Bfor%3D__toc%5D~.md-nav%7Bdisplay%3Aflex%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-nav%7Bmargin-bottom%3A-.4rem%7D.md-nav--secondary%20.md-nav__title%7Bbackground%3Avar%28--md-default-bg-color%29%3Bbox-shadow%3A0%200%20.4rem%20.4rem%20var%28--md-default-bg-color%29%3Bposition%3Asticky%3Btop%3A0%3Bz-index%3A1%7D.md-nav--secondary%20.md-nav__title%5Bfor%3D__toc%5D%7Bscroll-snap-align%3Astart%7D.md-nav--secondary%20.md-nav__title%20.md-nav__icon%7Bdisplay%3Anone%7D%5Bdir%3Dltr%5D%20.md-nav--secondary%20.md-nav__list%7Bpadding-left%3A.6rem%7D%5Bdir%3Drtl%5D%20.md-nav--secondary%20.md-nav__list%7Bpadding-right%3A.6rem%7D.md-nav--secondary%20.md-nav__list%7Bpadding-bottom%3A.4rem%7D%5Bdir%3Dltr%5D%20.md-nav--secondary%20.md-nav__item%3E.md-nav__link%7Bmargin-right%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-nav--secondary%20.md-nav__item%3E.md-nav__link%7Bmargin-left%3A.4rem%7D%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B.md-nav%7Bmargin-bottom%3A-.4rem%3Btransition%3Amax-height%20.25s%20cubic-bezier%28.86%2C0%2C.07%2C1%29%7D.md-nav--primary%20.md-nav__title%7Bbackground%3Avar%28--md-default-bg-color%29%3Bbox-shadow%3A0%200%20.4rem%20.4rem%20var%28--md-default-bg-color%29%3Bposition%3Asticky%3Btop%3A0%3Bz-index%3A1%7D.md-nav--primary%20.md-nav__title%5Bfor%3D__drawer%5D%7Bscroll-snap-align%3Astart%7D.md-nav--primary%20.md-nav__title%20.md-nav__icon%7Bdisplay%3Anone%7D%5Bdir%3Dltr%5D%20.md-nav--primary%20.md-nav__list%7Bpadding-left%3A.6rem%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav__list%7Bpadding-right%3A.6rem%7D.md-nav--primary%20.md-nav__list%7Bpadding-bottom%3A.4rem%7D%5Bdir%3Dltr%5D%20.md-nav--primary%20.md-nav__item%3E.md-nav__link%7Bmargin-right%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-nav--primary%20.md-nav__item%3E.md-nav__link%7Bmargin-left%3A.4rem%7D.md-nav__toggle~.md-nav%7Bdisplay%3Agrid%3Bgrid-template-rows%3Aminmax%28.4rem%2C0fr%29%3Bopacity%3A0%3Btransition%3Agrid-template-rows%20.25s%20cubic-bezier%28.86%2C0%2C.07%2C1%29%2Copacity%20.25s%2Cvisibility%200ms%20.25s%3Bvisibility%3Acollapse%7D.md-nav__toggle~.md-nav%3E.md-nav__list%7Boverflow%3Ahidden%7D.md-nav__toggle.md-toggle--indeterminate~.md-nav%2C.md-nav__toggle%3Achecked~.md-nav%7Bgrid-template-rows%3Aminmax%28.4rem%2C1fr%29%3Bopacity%3A1%3Btransition%3Agrid-template-rows%20.25s%20cubic-bezier%28.86%2C0%2C.07%2C1%29%2Copacity%20.15s%20.1s%2Cvisibility%200ms%3Bvisibility%3Avisible%7D.md-nav__toggle.md-toggle--indeterminate~.md-nav%7Btransition%3Anone%7D.md-nav__item--nested%3E.md-nav%3E.md-nav__title%7Bdisplay%3Anone%7D.md-nav__item--section%7Bdisplay%3Ablock%3Bmargin%3A1.25em%200%7D.md-nav__item--section%3Alast-child%7Bmargin-bottom%3A0%7D.md-nav__item--section%3E.md-nav__link%7Bfont-weight%3A700%7D.md-nav__item--section%3E.md-nav__link%5Bfor%5D%7Bcolor%3Avar%28--md-default-fg-color--light%29%7D.md-nav__item--section%3E.md-nav__link%3Anot%28.md-nav__container%29%7Bpointer-events%3Anone%7D.md-nav__item--section%3E.md-nav__link%20.md-icon%2C.md-nav__item--section%3E.md-nav__link%3E%5Bfor%5D%7Bdisplay%3Anone%7D%5Bdir%3Dltr%5D%20.md-nav__item--section%3E.md-nav%7Bmargin-left%3A-.6rem%7D%5Bdir%3Drtl%5D%20.md-nav__item--section%3E.md-nav%7Bmargin-right%3A-.6rem%7D.md-nav__item--section%3E.md-nav%7Bdisplay%3Ablock%3Bopacity%3A1%3Bvisibility%3Avisible%7D.md-nav__item--section%3E.md-nav%3E.md-nav__list%3E.md-nav__item%7Bpadding%3A0%7D.md-nav__icon%7Bborder-radius%3A100%25%3Bheight%3A.9rem%3Btransition%3Abackground-color%20.25s%3Bwidth%3A.9rem%7D.md-nav__icon%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color--transparent%29%7D.md-nav__icon%3Aafter%7Bbackground-color%3Acurrentcolor%3Bborder-radius%3A100%25%3Bcontent%3A%22%22%3Bdisplay%3Ainline-block%3Bheight%3A100%25%3B-webkit-mask-image%3Avar%28--md-nav-icon--next%29%3Bmask-image%3Avar%28--md-nav-icon--next%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Btransition%3Atransform%20.25s%3Bvertical-align%3A-.1rem%3Bwidth%3A100%25%7D%5Bdir%3Drtl%5D%20.md-nav__icon%3Aafter%7Btransform%3Arotate%28180deg%29%7D.md-nav__item--nested%20.md-nav__toggle%3Achecked~.md-nav__link%20.md-nav__icon%3Aafter%2C.md-nav__item--nested%20.md-toggle--indeterminate~.md-nav__link%20.md-nav__icon%3Aafter%7Btransform%3Arotate%2890deg%29%7D.md-nav--lifted%3E.md-nav__list%3E.md-nav__item%2C.md-nav--lifted%3E.md-nav__title%7Bdisplay%3Anone%7D.md-nav--lifted%3E.md-nav__list%3E.md-nav__item--active%7Bdisplay%3Ablock%7D.md-nav--lifted%3E.md-nav__list%3E.md-nav__item--active%3E.md-nav__link%7Bbackground%3Avar%28--md-default-bg-color%29%3Bbox-shadow%3A0%200%20.4rem%20.4rem%20var%28--md-default-bg-color%29%3Bmargin-top%3A0%3Bposition%3Asticky%3Btop%3A0%3Bz-index%3A1%7D.md-nav--lifted%3E.md-nav__list%3E.md-nav__item--active%3E.md-nav__link%3Anot%28.md-nav__container%29%7Bpointer-events%3Anone%7D.md-nav--lifted%3E.md-nav__list%3E.md-nav__item--active.md-nav__item--section%7Bmargin%3A0%7D%5Bdir%3Dltr%5D%20.md-nav--lifted%3E.md-nav__list%3E.md-nav__item%3E.md-nav%3Anot%28.md-nav--secondary%29%7Bmargin-left%3A-.6rem%7D%5Bdir%3Drtl%5D%20.md-nav--lifted%3E.md-nav__list%3E.md-nav__item%3E.md-nav%3Anot%28.md-nav--secondary%29%7Bmargin-right%3A-.6rem%7D.md-nav--lifted%3E.md-nav__list%3E.md-nav__item%3E%5Bfor%5D%7Bcolor%3Avar%28--md-default-fg-color--light%29%7D.md-nav--lifted%20.md-nav%5Bdata-md-level%3D%221%22%5D%7Bgrid-template-rows%3Aminmax%28.4rem%2C1fr%29%3Bopacity%3A1%3Bvisibility%3Avisible%7D%5Bdir%3Dltr%5D%20.md-nav--integrated%3E.md-nav__list%3E.md-nav__item--active%20.md-nav--secondary%7Bborder-left%3A.05rem%20solid%20var%28--md-primary-fg-color%29%7D%5Bdir%3Drtl%5D%20.md-nav--integrated%3E.md-nav__list%3E.md-nav__item--active%20.md-nav--secondary%7Bborder-right%3A.05rem%20solid%20var%28--md-primary-fg-color%29%7D.md-nav--integrated%3E.md-nav__list%3E.md-nav__item--active%20.md-nav--secondary%7Bdisplay%3Ablock%3Bmargin-bottom%3A1.25em%3Bopacity%3A1%3Bvisibility%3Avisible%7D.md-nav--integrated%3E.md-nav__list%3E.md-nav__item--active%20.md-nav--secondary%3E.md-nav__list%7Boverflow%3Avisible%3Bpadding-bottom%3A0%7D.md-nav--integrated%3E.md-nav__list%3E.md-nav__item--active%20.md-nav--secondary%3E.md-nav__title%7Bdisplay%3Anone%7D%7D.md-pagination%7Bfont-size%3A.8rem%3Bfont-weight%3A700%3Bgap%3A.4rem%7D.md-pagination%2C.md-pagination%3E%2A%7Balign-items%3Acenter%3Bdisplay%3Aflex%3Bjustify-content%3Acenter%7D.md-pagination%3E%2A%7Bborder-radius%3A.2rem%3Bheight%3A1.8rem%3Bmin-width%3A1.8rem%3Btext-align%3Acenter%7D.md-pagination__current%7Bbackground-color%3Avar%28--md-default-fg-color--lightest%29%3Bcolor%3Avar%28--md-default-fg-color--light%29%7D.md-pagination__link%7Btransition%3Acolor%20125ms%2Cbackground-color%20125ms%7D.md-pagination__link%3Afocus%2C.md-pagination__link%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color--transparent%29%3Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-pagination__link%3Afocus%20svg%2C.md-pagination__link%3Ahover%20svg%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-pagination__link.focus-visible%7Boutline-color%3Avar%28--md-accent-fg-color%29%3Boutline-offset%3A.2rem%7D.md-pagination__link%20svg%7Bfill%3Acurrentcolor%3Bcolor%3Avar%28--md-default-fg-color--lighter%29%3Bdisplay%3Ablock%3Bmax-height%3A100%25%3Bwidth%3A1.2rem%7D%3Aroot%7B--md-path-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M8.59%2016.58%2013.17%2012%208.59%207.41%2010%206l6%206-6%206z%22/%3E%3C/svg%3E%27%29%7D.md-path%7Bfont-size%3A.7rem%3Bmargin%3A0%20.8rem%3Boverflow%3Aauto%3Bpadding-top%3A1.2rem%7D.md-path%3Anot%28%5Bhidden%5D%29%7Bdisplay%3Ablock%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B.md-path%7Bmargin%3A0%201.2rem%7D%7D.md-path__list%7Balign-items%3Acenter%3Bdisplay%3Aflex%3Bgap%3A.2rem%3Blist-style%3Anone%3Bmargin%3A0%3Bpadding%3A0%7D.md-path__item%3Anot%28%3Afirst-child%29%7Bdisplay%3Ainline-flex%3Bgap%3A.2rem%3Bwhite-space%3Anowrap%7D.md-path__item%3Anot%28%3Afirst-child%29%3Abefore%7Bbackground-color%3Avar%28--md-default-fg-color--lighter%29%3Bcontent%3A%22%22%3Bdisplay%3Ainline%3Bheight%3A.8rem%3B-webkit-mask-image%3Avar%28--md-path-icon%29%3Bmask-image%3Avar%28--md-path-icon%29%3Bwidth%3A.8rem%7D.md-path__link%7Balign-items%3Acenter%3Bcolor%3Avar%28--md-default-fg-color--light%29%3Bdisplay%3Aflex%7D.md-path__link%3Afocus%2C.md-path__link%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D%3Aroot%7B--md-post-pin-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M16%2012V4h1V2H7v2h1v8l-2%202v2h5.2v6h1.6v-6H18v-2z%22/%3E%3C/svg%3E%27%29%7D.md-post__back%7Bborder-bottom%3A.05rem%20solid%20var%28--md-default-fg-color--lightest%29%3Bmargin-bottom%3A1.2rem%3Bpadding-bottom%3A1.2rem%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7B.md-post__back%7Bdisplay%3Anone%7D%7D%5Bdir%3Drtl%5D%20.md-post__back%20svg%7Btransform%3AscaleX%28-1%29%7D.md-post__authors%7Bdisplay%3Aflex%3Bflex-direction%3Acolumn%3Bgap%3A.6rem%3Bmargin%3A0%20.6rem%201.2rem%7D.md-post%20.md-post__meta%20a%7Btransition%3Acolor%20125ms%7D.md-post%20.md-post__meta%20a%3Afocus%2C.md-post%20.md-post__meta%20a%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-post__title%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bfont-weight%3A700%7D.md-post--excerpt%7Bmargin-bottom%3A3.2rem%7D.md-post--excerpt%20.md-post__header%7Balign-items%3Acenter%3Bdisplay%3Aflex%3Bgap%3A.6rem%3Bmin-height%3A1.6rem%7D.md-post--excerpt%20.md-post__authors%7Balign-items%3Acenter%3Bdisplay%3Ainline-flex%3Bflex-direction%3Arow%3Bgap%3A.2rem%3Bmargin%3A0%3Bmin-height%3A2.4rem%7D%5Bdir%3Dltr%5D%20.md-post--excerpt%20.md-post__meta%20.md-meta__list%7Bmargin-right%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-post--excerpt%20.md-post__meta%20.md-meta__list%7Bmargin-left%3A.4rem%7D.md-post--excerpt%20.md-post__content%3E%3Afirst-child%7B--md-scroll-margin%3A6rem%3Bmargin-top%3A0%7D.md-post%3E.md-nav--secondary%7Bmargin%3A1em%200%7D.md-pin%7Bbackground%3Avar%28--md-default-fg-color--lightest%29%3Bborder-radius%3A1rem%3Bmargin-top%3A-.05rem%3Bpadding%3A.2rem%7D.md-pin%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A.6rem%3Bmargin%3A0%20auto%3B-webkit-mask-image%3Avar%28--md-post-pin-icon%29%3Bmask-image%3Avar%28--md-post-pin-icon%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bwidth%3A.6rem%7D.md-profile%7Balign-items%3Acenter%3Bdisplay%3Aflex%3Bfont-size%3A.7rem%3Bgap%3A.6rem%3Bline-height%3A1.4%3Bwidth%3A100%25%7D.md-profile__description%7Bflex-grow%3A1%7D.md-content--post%7Bdisplay%3Aflex%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7B.md-content--post%7Bflex-flow%3Acolumn-reverse%7D%7D.md-content--post%3E.md-content__inner%7Bflex-grow%3A1%3Bmin-width%3A0%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B%5Bdir%3Dltr%5D%20.md-content--post%3E.md-content__inner%7Bmargin-left%3A1.2rem%7D%5Bdir%3Drtl%5D%20.md-content--post%3E.md-content__inner%7Bmargin-right%3A1.2rem%7D%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7B.md-sidebar.md-sidebar--post%7Bpadding%3A0%3Bposition%3Astatic%3Bwidth%3A100%25%7D.md-sidebar.md-sidebar--post%20.md-sidebar__scrollwrap%7Boverflow%3Avisible%7D.md-sidebar.md-sidebar--post%20.md-sidebar__inner%7Bpadding%3A0%7D.md-sidebar.md-sidebar--post%20.md-post__meta%7Bmargin-left%3A.6rem%3Bmargin-right%3A.6rem%7D.md-sidebar.md-sidebar--post%20.md-nav__item%7Bborder%3Anone%3Bdisplay%3Ainline%7D.md-sidebar.md-sidebar--post%20.md-nav__list%7Bdisplay%3Ainline-flex%3Bflex-wrap%3Awrap%3Bgap%3A.6rem%3Bpadding-bottom%3A.6rem%3Bpadding-top%3A.6rem%7D.md-sidebar.md-sidebar--post%20.md-nav__link%7Bpadding%3A0%7D.md-sidebar.md-sidebar--post%20.md-nav%7Bheight%3Aauto%3Bmargin-bottom%3A0%3Bposition%3Astatic%7D%7D%3Aroot%7B--md-progress-value%3A0%3B--md-progress-delay%3A400ms%7D.md-progress%7Bbackground%3Avar%28--md-primary-bg-color%29%3Bheight%3A.075rem%3Bopacity%3Amin%28clamp%280%2Cvar%28--md-progress-value%29%2C1%29%2Cclamp%280%2C100%20-%20var%28--md-progress-value%29%2C1%29%29%3Bposition%3Afixed%3Btop%3A0%3Btransform%3AscaleX%28calc%28var%28--md-progress-value%29%2A1%25%29%29%3Btransform-origin%3Aleft%3Btransition%3Atransform%20.5s%20cubic-bezier%28.19%2C1%2C.22%2C1%29%2Copacity%20.25s%20var%28--md-progress-delay%29%3Bwidth%3A100%25%3Bz-index%3A4%7D%3Aroot%7B--md-search-result-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M14%202H6a2%202%200%200%200-2%202v16a2%202%200%200%200%202%202h7c-.41-.25-.8-.56-1.14-.9-.33-.33-.61-.7-.86-1.1H6V4h7v5h5v1.18c.71.16%201.39.43%202%20.82V8zm6.31%2016.9c1.33-2.11.69-4.9-1.4-6.22-2.11-1.33-4.91-.68-6.22%201.4-1.34%202.11-.69%204.89%201.4%206.22%201.46.93%203.32.93%204.79.02L22%2023.39%2023.39%2022zm-3.81.1a2.5%202.5%200%200%201-2.5-2.5%202.5%202.5%200%200%201%202.5-2.5%202.5%202.5%200%200%201%202.5%202.5%202.5%202.5%200%200%201-2.5%202.5%22/%3E%3C/svg%3E%27%29%7D.md-search%7Bposition%3Arelative%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-search%7Bpadding%3A.2rem%200%7D%7D.no-js%20.md-search%7Bdisplay%3Anone%7D.md-search__overlay%7Bopacity%3A0%3Bz-index%3A1%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B%5Bdir%3Dltr%5D%20.md-search__overlay%7Bleft%3A-2.2rem%7D%5Bdir%3Drtl%5D%20.md-search__overlay%7Bright%3A-2.2rem%7D.md-search__overlay%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder-radius%3A1rem%3Bheight%3A2rem%3Boverflow%3Ahidden%3Bpointer-events%3Anone%3Bposition%3Aabsolute%3Btop%3A-1rem%3Btransform-origin%3Acenter%3Btransition%3Atransform%20.3s%20.1s%2Copacity%20.2s%20.2s%3Bwidth%3A2rem%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__overlay%7Bopacity%3A1%3Btransition%3Atransform%20.4s%2Copacity%20.1s%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdir%3Dltr%5D%20.md-search__overlay%7Bleft%3A0%7D%5Bdir%3Drtl%5D%20.md-search__overlay%7Bright%3A0%7D.md-search__overlay%7Bbackground-color%3A%230000008a%3Bcursor%3Apointer%3Bheight%3A0%3Bposition%3Afixed%3Btop%3A0%3Btransition%3Awidth%200ms%20.25s%2Cheight%200ms%20.25s%2Copacity%20.25s%3Bwidth%3A0%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__overlay%7Bheight%3A200vh%3Bopacity%3A1%3Btransition%3Awidth%200ms%2Cheight%200ms%2Copacity%20.25s%3Bwidth%3A100%25%7D%7D%40media%20screen%20and%20%28max-width%3A29.984375em%29%7B%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__overlay%7Btransform%3Ascale%2845%29%7D%7D%40media%20screen%20and%20%28min-width%3A30em%29%20and%20%28max-width%3A44.984375em%29%7B%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__overlay%7Btransform%3Ascale%2860%29%7D%7D%40media%20screen%20and%20%28min-width%3A45em%29%20and%20%28max-width%3A59.984375em%29%7B%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__overlay%7Btransform%3Ascale%2875%29%7D%7D.md-search__inner%7Bbackface-visibility%3Ahidden%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B%5Bdir%3Dltr%5D%20.md-search__inner%7Bleft%3A0%7D%5Bdir%3Drtl%5D%20.md-search__inner%7Bright%3A0%7D.md-search__inner%7Bheight%3A0%3Bopacity%3A0%3Boverflow%3Ahidden%3Bposition%3Afixed%3Btop%3A0%3Btransform%3AtranslateX%285%25%29%3Btransition%3Awidth%200ms%20.3s%2Cheight%200ms%20.3s%2Ctransform%20.15s%20cubic-bezier%28.4%2C0%2C.2%2C1%29%20.15s%2Copacity%20.15s%20.15s%3Bwidth%3A0%3Bz-index%3A2%7D%5Bdir%3Drtl%5D%20.md-search__inner%7Btransform%3AtranslateX%28-5%25%29%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__inner%7Bheight%3A100%25%3Bopacity%3A1%3Btransform%3AtranslateX%280%29%3Btransition%3Awidth%200ms%200ms%2Cheight%200ms%200ms%2Ctransform%20.15s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%20.15s%2Copacity%20.15s%20.15s%3Bwidth%3A100%25%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdir%3Dltr%5D%20.md-search__inner%7Bfloat%3Aright%7D%5Bdir%3Drtl%5D%20.md-search__inner%7Bfloat%3Aleft%7D.md-search__inner%7Bpadding%3A.1rem%200%3Bposition%3Arelative%3Btransition%3Awidth%20.25s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%3Bwidth%3A11.7rem%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%20and%20%28max-width%3A76.234375em%29%7B%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__inner%7Bwidth%3A23.4rem%7D%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__inner%7Bwidth%3A34.4rem%7D%7D.md-search__form%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bbox-shadow%3A0%200%20.6rem%20%230000%3Bheight%3A2.4rem%3Bposition%3Arelative%3Btransition%3Acolor%20.25s%2Cbackground-color%20.25s%3Bz-index%3A2%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-search__form%7Bbackground-color%3A%2300000042%3Bborder-radius%3A.1rem%3Bheight%3A1.8rem%7D.md-search__form%3Ahover%7Bbackground-color%3A%23ffffff1f%7D%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__form%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder-radius%3A.1rem%20.1rem%200%200%3Bbox-shadow%3A0%200%20.6rem%20%2300000012%3Bcolor%3Avar%28--md-default-fg-color%29%7D%5Bdir%3Dltr%5D%20.md-search__input%7Bpadding-left%3A3.6rem%3Bpadding-right%3A2.2rem%7D%5Bdir%3Drtl%5D%20.md-search__input%7Bpadding-left%3A2.2rem%3Bpadding-right%3A3.6rem%7D.md-search__input%7Bbackground%3A%230000%3Bfont-size%3A.9rem%3Bheight%3A100%25%3Bposition%3Arelative%3Btext-overflow%3Aellipsis%3Bwidth%3A100%25%3Bz-index%3A2%7D.md-search__input%3A%3Aplaceholder%7Btransition%3Acolor%20.25s%7D.md-search__input%3A%3Aplaceholder%2C.md-search__input~.md-search__icon%7Bcolor%3Avar%28--md-default-fg-color--light%29%7D.md-search__input%3A%3A-ms-clear%7Bdisplay%3Anone%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B.md-search__input%7Bfont-size%3A.9rem%3Bheight%3A2.4rem%3Bwidth%3A100%25%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdir%3Dltr%5D%20.md-search__input%7Bpadding-left%3A2.2rem%7D%5Bdir%3Drtl%5D%20.md-search__input%7Bpadding-right%3A2.2rem%7D.md-search__input%7Bcolor%3Ainherit%3Bfont-size%3A.8rem%7D.md-search__input%3A%3Aplaceholder%7Bcolor%3Avar%28--md-primary-bg-color--light%29%7D.md-search__input%2B.md-search__icon%7Bcolor%3Avar%28--md-primary-bg-color%29%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__input%7Btext-overflow%3Aclip%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__input%2B.md-search__icon%7Bcolor%3Avar%28--md-default-fg-color--light%29%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__input%3A%3Aplaceholder%7Bcolor%3A%230000%7D%7D.md-search__icon%7Bcursor%3Apointer%3Bdisplay%3Ainline-block%3Bheight%3A1.2rem%3Btransition%3Acolor%20.25s%2Copacity%20.25s%3Bwidth%3A1.2rem%7D.md-search__icon%3Ahover%7Bopacity%3A.7%7D%5Bdir%3Dltr%5D%20.md-search__icon%5Bfor%3D__search%5D%7Bleft%3A.5rem%7D%5Bdir%3Drtl%5D%20.md-search__icon%5Bfor%3D__search%5D%7Bright%3A.5rem%7D.md-search__icon%5Bfor%3D__search%5D%7Bposition%3Aabsolute%3Btop%3A.3rem%3Bz-index%3A2%7D%5Bdir%3Drtl%5D%20.md-search__icon%5Bfor%3D__search%5D%20svg%7Btransform%3AscaleX%28-1%29%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B%5Bdir%3Dltr%5D%20.md-search__icon%5Bfor%3D__search%5D%7Bleft%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-search__icon%5Bfor%3D__search%5D%7Bright%3A.8rem%7D.md-search__icon%5Bfor%3D__search%5D%7Btop%3A.6rem%7D.md-search__icon%5Bfor%3D__search%5D%20svg%3Afirst-child%7Bdisplay%3Anone%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-search__icon%5Bfor%3D__search%5D%7Bpointer-events%3Anone%7D.md-search__icon%5Bfor%3D__search%5D%20svg%3Alast-child%7Bdisplay%3Anone%7D%7D%5Bdir%3Dltr%5D%20.md-search__options%7Bright%3A.5rem%7D%5Bdir%3Drtl%5D%20.md-search__options%7Bleft%3A.5rem%7D.md-search__options%7Bpointer-events%3Anone%3Bposition%3Aabsolute%3Btop%3A.3rem%3Bz-index%3A2%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B%5Bdir%3Dltr%5D%20.md-search__options%7Bright%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-search__options%7Bleft%3A.8rem%7D.md-search__options%7Btop%3A.6rem%7D%7D%5Bdir%3Dltr%5D%20.md-search__options%3E.md-icon%7Bmargin-left%3A.2rem%7D%5Bdir%3Drtl%5D%20.md-search__options%3E.md-icon%7Bmargin-right%3A.2rem%7D.md-search__options%3E.md-icon%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bopacity%3A0%3Btransform%3Ascale%28.75%29%3Btransition%3Atransform%20.15s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%2Copacity%20.15s%7D.md-search__options%3E.md-icon%3Anot%28.focus-visible%29%7B-webkit-tap-highlight-color%3Atransparent%3Boutline%3Anone%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__input%3Avalid~.md-search__options%3E.md-icon%7Bopacity%3A1%3Bpointer-events%3Aauto%3Btransform%3Ascale%281%29%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__input%3Avalid~.md-search__options%3E.md-icon%3Ahover%7Bopacity%3A.7%7D%5Bdir%3Dltr%5D%20.md-search__suggest%7Bpadding-left%3A3.6rem%3Bpadding-right%3A2.2rem%7D%5Bdir%3Drtl%5D%20.md-search__suggest%7Bpadding-left%3A2.2rem%3Bpadding-right%3A3.6rem%7D.md-search__suggest%7Balign-items%3Acenter%3Bcolor%3Avar%28--md-default-fg-color--lighter%29%3Bdisplay%3Aflex%3Bfont-size%3A.9rem%3Bheight%3A100%25%3Bopacity%3A0%3Bposition%3Aabsolute%3Btop%3A0%3Btransition%3Aopacity%2050ms%3Bwhite-space%3Anowrap%3Bwidth%3A100%25%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdir%3Dltr%5D%20.md-search__suggest%7Bpadding-left%3A2.2rem%7D%5Bdir%3Drtl%5D%20.md-search__suggest%7Bpadding-right%3A2.2rem%7D.md-search__suggest%7Bfont-size%3A.8rem%7D%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__suggest%7Bopacity%3A1%3Btransition%3Aopacity%20.3s%20.1s%7D%5Bdir%3Dltr%5D%20.md-search__output%7Bborder-bottom-left-radius%3A.1rem%7D%5Bdir%3Dltr%5D%20.md-search__output%2C%5Bdir%3Drtl%5D%20.md-search__output%7Bborder-bottom-right-radius%3A.1rem%7D%5Bdir%3Drtl%5D%20.md-search__output%7Bborder-bottom-left-radius%3A.1rem%7D.md-search__output%7Boverflow%3Ahidden%3Bposition%3Aabsolute%3Bwidth%3A100%25%3Bz-index%3A1%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B.md-search__output%7Bbottom%3A0%3Btop%3A2.4rem%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-search__output%7Bopacity%3A0%3Btop%3A1.9rem%3Btransition%3Aopacity%20.4s%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__output%7Bbox-shadow%3Avar%28--md-shadow-z3%29%3Bopacity%3A1%7D%7D.md-search__scrollwrap%7Bbackface-visibility%3Ahidden%3Bbackground-color%3Avar%28--md-default-bg-color%29%3Bheight%3A100%25%3Boverflow-y%3Aauto%3Btouch-action%3Apan-y%7D%40media%20%28-webkit-max-device-pixel-ratio%3A1%29%2C%28max-resolution%3A1dppx%29%7B.md-search__scrollwrap%7Btransform%3AtranslateZ%280%29%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%20and%20%28max-width%3A76.234375em%29%7B.md-search__scrollwrap%7Bwidth%3A23.4rem%7D%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B.md-search__scrollwrap%7Bwidth%3A34.4rem%7D%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-search__scrollwrap%7Bmax-height%3A0%3Bscrollbar-color%3Avar%28--md-default-fg-color--lighter%29%20%230000%3Bscrollbar-width%3Athin%7D%5Bdata-md-toggle%3Dsearch%5D%3Achecked~.md-header%20.md-search__scrollwrap%7Bmax-height%3A75vh%7D.md-search__scrollwrap%3Ahover%7Bscrollbar-color%3Avar%28--md-accent-fg-color%29%20%230000%7D.md-search__scrollwrap%3A%3A-webkit-scrollbar%7Bheight%3A.2rem%3Bwidth%3A.2rem%7D.md-search__scrollwrap%3A%3A-webkit-scrollbar-thumb%7Bbackground-color%3Avar%28--md-default-fg-color--lighter%29%7D.md-search__scrollwrap%3A%3A-webkit-scrollbar-thumb%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color%29%7D%7D.md-search-result%7Bcolor%3Avar%28--md-default-fg-color%29%3Bword-break%3Abreak-word%7D.md-search-result__meta%7Bbackground-color%3Avar%28--md-default-fg-color--lightest%29%3Bcolor%3Avar%28--md-default-fg-color--light%29%3Bfont-size%3A.64rem%3Bline-height%3A1.8rem%3Bpadding%3A0%20.8rem%3Bscroll-snap-align%3Astart%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdir%3Dltr%5D%20.md-search-result__meta%7Bpadding-left%3A2.2rem%7D%5Bdir%3Drtl%5D%20.md-search-result__meta%7Bpadding-right%3A2.2rem%7D%7D.md-search-result__list%7Blist-style%3Anone%3Bmargin%3A0%3Bpadding%3A0%3B-webkit-user-select%3Anone%3Buser-select%3Anone%7D.md-search-result__item%7Bbox-shadow%3A0%20-.05rem%20var%28--md-default-fg-color--lightest%29%7D.md-search-result__item%3Afirst-child%7Bbox-shadow%3Anone%7D.md-search-result__link%7Bdisplay%3Ablock%3Boutline%3Anone%3Bscroll-snap-align%3Astart%3Btransition%3Abackground-color%20.25s%7D.md-search-result__link%3Afocus%2C.md-search-result__link%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color--transparent%29%7D.md-search-result__link%3Alast-child%20p%3Alast-child%7Bmargin-bottom%3A.6rem%7D.md-search-result__more%3Esummary%7Bcursor%3Apointer%3Bdisplay%3Ablock%3Boutline%3Anone%3Bposition%3Asticky%3Bscroll-snap-align%3Astart%3Btop%3A0%3Bz-index%3A1%7D.md-search-result__more%3Esummary%3A%3Amarker%7Bdisplay%3Anone%7D.md-search-result__more%3Esummary%3A%3A-webkit-details-marker%7Bdisplay%3Anone%7D.md-search-result__more%3Esummary%3Ediv%7Bcolor%3Avar%28--md-typeset-a-color%29%3Bfont-size%3A.64rem%3Bpadding%3A.75em%20.8rem%3Btransition%3Acolor%20.25s%2Cbackground-color%20.25s%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdir%3Dltr%5D%20.md-search-result__more%3Esummary%3Ediv%7Bpadding-left%3A2.2rem%7D%5Bdir%3Drtl%5D%20.md-search-result__more%3Esummary%3Ediv%7Bpadding-right%3A2.2rem%7D%7D.md-search-result__more%3Esummary%3Afocus%3Ediv%2C.md-search-result__more%3Esummary%3Ahover%3Ediv%7Bbackground-color%3Avar%28--md-accent-fg-color--transparent%29%3Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-search-result__more%5Bopen%5D%3Esummary%7Bbackground-color%3Avar%28--md-default-bg-color%29%7D.md-search-result__article%7Boverflow%3Ahidden%3Bpadding%3A0%20.8rem%3Bposition%3Arelative%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdir%3Dltr%5D%20.md-search-result__article%7Bpadding-left%3A2.2rem%7D%5Bdir%3Drtl%5D%20.md-search-result__article%7Bpadding-right%3A2.2rem%7D%7D%5Bdir%3Dltr%5D%20.md-search-result__icon%7Bleft%3A0%7D%5Bdir%3Drtl%5D%20.md-search-result__icon%7Bright%3A0%7D.md-search-result__icon%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bheight%3A1.2rem%3Bmargin%3A.5rem%3Bposition%3Aabsolute%3Bwidth%3A1.2rem%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B.md-search-result__icon%7Bdisplay%3Anone%7D%7D.md-search-result__icon%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ainline-block%3Bheight%3A100%25%3B-webkit-mask-image%3Avar%28--md-search-result-icon%29%3Bmask-image%3Avar%28--md-search-result-icon%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bwidth%3A100%25%7D%5Bdir%3Drtl%5D%20.md-search-result__icon%3Aafter%7Btransform%3AscaleX%28-1%29%7D.md-search-result%20.md-typeset%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bfont-size%3A.64rem%3Bline-height%3A1.6%7D.md-search-result%20.md-typeset%20h1%7Bcolor%3Avar%28--md-default-fg-color%29%3Bfont-size%3A.8rem%3Bfont-weight%3A400%3Bline-height%3A1.4%3Bmargin%3A.55rem%200%7D.md-search-result%20.md-typeset%20h1%20mark%7Btext-decoration%3Anone%7D.md-search-result%20.md-typeset%20h2%7Bcolor%3Avar%28--md-default-fg-color%29%3Bfont-size%3A.64rem%3Bfont-weight%3A700%3Bline-height%3A1.6%3Bmargin%3A.5em%200%7D.md-search-result%20.md-typeset%20h2%20mark%7Btext-decoration%3Anone%7D.md-search-result__terms%7Bcolor%3Avar%28--md-default-fg-color%29%3Bdisplay%3Ablock%3Bfont-size%3A.64rem%3Bfont-style%3Aitalic%3Bmargin%3A.5em%200%7D.md-search-result%20mark%7Bbackground-color%3Ainitial%3Bcolor%3Avar%28--md-accent-fg-color%29%3Btext-decoration%3Aunderline%7D.md-select%7Bposition%3Arelative%3Bz-index%3A1%7D.md-select__inner%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder-radius%3A.1rem%3Bbox-shadow%3Avar%28--md-shadow-z2%29%3Bcolor%3Avar%28--md-default-fg-color%29%3Bleft%3A50%25%3Bmargin-top%3A.2rem%3Bmax-height%3A0%3Bopacity%3A0%3Bposition%3Aabsolute%3Btop%3Acalc%28100%25%20-%20.2rem%29%3Btransform%3Atranslate3d%28-50%25%2C.3rem%2C0%29%3Btransition%3Atransform%20.25s%20375ms%2Copacity%20.25s%20.25s%2Cmax-height%200ms%20.5s%7D.md-select%3Afocus-within%20.md-select__inner%2C.md-select%3Ahover%20.md-select__inner%7Bmax-height%3A10rem%3Bopacity%3A1%3Btransform%3Atranslate3d%28-50%25%2C0%2C0%29%3Btransition%3Atransform%20.25s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%2Copacity%20.25s%2Cmax-height%200ms%7D.md-select__inner%3Aafter%7Bborder-bottom%3A.2rem%20solid%20%230000%3Bborder-bottom-color%3Avar%28--md-default-bg-color%29%3Bborder-left%3A.2rem%20solid%20%230000%3Bborder-right%3A.2rem%20solid%20%230000%3Bborder-top%3A0%3Bcontent%3A%22%22%3Bheight%3A0%3Bleft%3A50%25%3Bmargin-left%3A-.2rem%3Bmargin-top%3A-.2rem%3Bposition%3Aabsolute%3Btop%3A0%3Bwidth%3A0%7D.md-select__list%7Bborder-radius%3A.1rem%3Bfont-size%3A.8rem%3Blist-style-type%3Anone%3Bmargin%3A0%3Bmax-height%3Ainherit%3Boverflow%3Aauto%3Bpadding%3A0%7D.md-select__item%7Bline-height%3A1.8rem%7D%5Bdir%3Dltr%5D%20.md-select__link%7Bpadding-left%3A.6rem%3Bpadding-right%3A1.2rem%7D%5Bdir%3Drtl%5D%20.md-select__link%7Bpadding-left%3A1.2rem%3Bpadding-right%3A.6rem%7D.md-select__link%7Bcursor%3Apointer%3Bdisplay%3Ablock%3Boutline%3Anone%3Bscroll-snap-align%3Astart%3Btransition%3Abackground-color%20.25s%2Ccolor%20.25s%3Bwidth%3A100%25%7D.md-select__link%3Afocus%2C.md-select__link%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-select__link%3Afocus%7Bbackground-color%3Avar%28--md-default-fg-color--lightest%29%7D.md-sidebar%7Balign-self%3Aflex-start%3Bflex-shrink%3A0%3Bpadding%3A1.2rem%200%3Bposition%3Asticky%3Btop%3A2.4rem%3Bwidth%3A12.1rem%7D%40media%20print%7B.md-sidebar%7Bdisplay%3Anone%7D%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7B%5Bdir%3Dltr%5D%20.md-sidebar--primary%7Bleft%3A-12.1rem%7D%5Bdir%3Drtl%5D%20.md-sidebar--primary%7Bright%3A-12.1rem%7D.md-sidebar--primary%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bdisplay%3Ablock%3Bheight%3A100%25%3Bposition%3Afixed%3Btop%3A0%3Btransform%3AtranslateX%280%29%3Btransition%3Atransform%20.25s%20cubic-bezier%28.4%2C0%2C.2%2C1%29%2Cbox-shadow%20.25s%3Bwidth%3A12.1rem%3Bz-index%3A5%7D%5Bdata-md-toggle%3Ddrawer%5D%3Achecked~.md-container%20.md-sidebar--primary%7Bbox-shadow%3Avar%28--md-shadow-z3%29%3Btransform%3AtranslateX%2812.1rem%29%7D%5Bdir%3Drtl%5D%20%5Bdata-md-toggle%3Ddrawer%5D%3Achecked~.md-container%20.md-sidebar--primary%7Btransform%3AtranslateX%28-12.1rem%29%7D.md-sidebar--primary%20.md-sidebar__scrollwrap%7Bbottom%3A0%3Bleft%3A0%3Bmargin%3A0%3Boverflow%3Ahidden%3Bposition%3Aabsolute%3Bright%3A0%3Bscroll-snap-type%3Anone%3Btop%3A0%7D%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B.md-sidebar%7Bheight%3A0%7D.no-js%20.md-sidebar%7Bheight%3Aauto%7D.md-header--lifted~.md-container%20.md-sidebar%7Btop%3A4.8rem%7D%7D.md-sidebar--secondary%7Bdisplay%3Anone%3Border%3A2%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-sidebar--secondary%7Bheight%3A0%7D.no-js%20.md-sidebar--secondary%7Bheight%3Aauto%7D.md-sidebar--secondary%3Anot%28%5Bhidden%5D%29%7Bdisplay%3Ablock%7D.md-sidebar--secondary%20.md-sidebar__scrollwrap%7Btouch-action%3Apan-y%7D%7D.md-sidebar__scrollwrap%7Bbackface-visibility%3Ahidden%3Bmargin%3A0%20.2rem%3Boverflow-y%3Aauto%3Bscrollbar-color%3Avar%28--md-default-fg-color--lighter%29%20%230000%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B.md-sidebar__scrollwrap%7Bscrollbar-gutter%3Astable%3Bscrollbar-width%3Athin%7D%7D.md-sidebar__scrollwrap%3A%3A-webkit-scrollbar%7Bheight%3A.2rem%3Bwidth%3A.2rem%7D.md-sidebar__scrollwrap%3Afocus-within%2C.md-sidebar__scrollwrap%3Ahover%7Bscrollbar-color%3Avar%28--md-accent-fg-color%29%20%230000%7D.md-sidebar__scrollwrap%3Afocus-within%3A%3A-webkit-scrollbar-thumb%2C.md-sidebar__scrollwrap%3Ahover%3A%3A-webkit-scrollbar-thumb%7Bbackground-color%3Avar%28--md-default-fg-color--lighter%29%7D.md-sidebar__scrollwrap%3Afocus-within%3A%3A-webkit-scrollbar-thumb%3Ahover%2C.md-sidebar__scrollwrap%3Ahover%3A%3A-webkit-scrollbar-thumb%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color%29%7D%40supports%20selector%28%3A%3A-webkit-scrollbar%29%7B.md-sidebar__scrollwrap%7Bscrollbar-gutter%3Aauto%7D%5Bdir%3Dltr%5D%20.md-sidebar__inner%7Bpadding-right%3Acalc%28100%25%20-%2011.5rem%29%7D%5Bdir%3Drtl%5D%20.md-sidebar__inner%7Bpadding-left%3Acalc%28100%25%20-%2011.5rem%29%7D%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7B.md-overlay%7Bbackground-color%3A%230000008a%3Bheight%3A0%3Bopacity%3A0%3Bposition%3Afixed%3Btop%3A0%3Btransition%3Awidth%200ms%20.25s%2Cheight%200ms%20.25s%2Copacity%20.25s%3Bwidth%3A0%3Bz-index%3A5%7D%5Bdata-md-toggle%3Ddrawer%5D%3Achecked~.md-overlay%7Bheight%3A100%25%3Bopacity%3A1%3Btransition%3Awidth%200ms%2Cheight%200ms%2Copacity%20.25s%3Bwidth%3A100%25%7D%7D%40keyframes%20facts%7B0%25%7Bheight%3A0%7Dto%7Bheight%3A.65rem%7D%7D%40keyframes%20fact%7B0%25%7Bopacity%3A0%3Btransform%3AtranslateY%28100%25%29%7D50%25%7Bopacity%3A0%7Dto%7Bopacity%3A1%3Btransform%3AtranslateY%280%29%7D%7D%3Aroot%7B--md-source-forks-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20d%3D%22M5%205.372v.878c0%20.414.336.75.75.75h4.5a.75.75%200%200%200%20.75-.75v-.878a2.25%202.25%200%201%201%201.5%200v.878a2.25%202.25%200%200%201-2.25%202.25h-1.5v2.128a2.251%202.251%200%201%201-1.5%200V8.5h-1.5A2.25%202.25%200%200%201%203.5%206.25v-.878a2.25%202.25%200%201%201%201.5%200M5%203.25a.75.75%200%201%200-1.5%200%20.75.75%200%200%200%201.5%200m6.75.75a.75.75%200%201%200%200-1.5.75.75%200%200%200%200%201.5m-3%208.75a.75.75%200%201%200-1.5%200%20.75.75%200%200%200%201.5%200%22/%3E%3C/svg%3E%27%29%3B--md-source-repositories-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20d%3D%22M2%202.5A2.5%202.5%200%200%201%204.5%200h8.75a.75.75%200%200%201%20.75.75v12.5a.75.75%200%200%201-.75.75h-2.5a.75.75%200%200%201%200-1.5h1.75v-2h-8a1%201%200%200%200-.714%201.7.75.75%200%201%201-1.072%201.05A2.5%202.5%200%200%201%202%2011.5Zm10.5-1h-8a1%201%200%200%200-1%201v6.708A2.5%202.5%200%200%201%204.5%209h8ZM5%2012.25a.25.25%200%200%201%20.25-.25h3.5a.25.25%200%200%201%20.25.25v3.25a.25.25%200%200%201-.4.2l-1.45-1.087a.25.25%200%200%200-.3%200L5.4%2015.7a.25.25%200%200%201-.4-.2Z%22/%3E%3C/svg%3E%27%29%3B--md-source-stars-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20d%3D%22M8%20.25a.75.75%200%200%201%20.673.418l1.882%203.815%204.21.612a.75.75%200%200%201%20.416%201.279l-3.046%202.97.719%204.192a.751.751%200%200%201-1.088.791L8%2012.347l-3.766%201.98a.75.75%200%200%201-1.088-.79l.72-4.194L.818%206.374a.75.75%200%200%201%20.416-1.28l4.21-.611L7.327.668A.75.75%200%200%201%208%20.25m0%202.445L6.615%205.5a.75.75%200%200%201-.564.41l-3.097.45%202.24%202.184a.75.75%200%200%201%20.216.664l-.528%203.084%202.769-1.456a.75.75%200%200%201%20.698%200l2.77%201.456-.53-3.084a.75.75%200%200%201%20.216-.664l2.24-2.183-3.096-.45a.75.75%200%200%201-.564-.41z%22/%3E%3C/svg%3E%27%29%3B--md-source-version-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20d%3D%22M1%207.775V2.75C1%201.784%201.784%201%202.75%201h5.025c.464%200%20.91.184%201.238.513l6.25%206.25a1.75%201.75%200%200%201%200%202.474l-5.026%205.026a1.75%201.75%200%200%201-2.474%200l-6.25-6.25A1.75%201.75%200%200%201%201%207.775m1.5%200c0%20.066.026.13.073.177l6.25%206.25a.25.25%200%200%200%20.354%200l5.025-5.025a.25.25%200%200%200%200-.354l-6.25-6.25a.25.25%200%200%200-.177-.073H2.75a.25.25%200%200%200-.25.25ZM6%205a1%201%200%201%201%200%202%201%201%200%200%201%200-2%22/%3E%3C/svg%3E%27%29%7D.md-source%7Bbackface-visibility%3Ahidden%3Bdisplay%3Ablock%3Bfont-size%3A.65rem%3Bline-height%3A1.2%3Boutline-color%3Avar%28--md-accent-fg-color%29%3Btransition%3Aopacity%20.25s%3Bwhite-space%3Anowrap%7D.md-source%3Ahover%7Bopacity%3A.7%7D.md-source__icon%7Bdisplay%3Ainline-block%3Bheight%3A2.4rem%3Bvertical-align%3Amiddle%3Bwidth%3A2rem%7D%5Bdir%3Dltr%5D%20.md-source__icon%20svg%7Bmargin-left%3A.6rem%7D%5Bdir%3Drtl%5D%20.md-source__icon%20svg%7Bmargin-right%3A.6rem%7D.md-source__icon%20svg%7Bmargin-top%3A.6rem%7D%5Bdir%3Dltr%5D%20.md-source__icon%2B.md-source__repository%7Bpadding-left%3A2rem%7D%5Bdir%3Drtl%5D%20.md-source__icon%2B.md-source__repository%7Bpadding-right%3A2rem%7D%5Bdir%3Dltr%5D%20.md-source__icon%2B.md-source__repository%7Bmargin-left%3A-2rem%7D%5Bdir%3Drtl%5D%20.md-source__icon%2B.md-source__repository%7Bmargin-right%3A-2rem%7D%5Bdir%3Dltr%5D%20.md-source__repository%7Bmargin-left%3A.6rem%7D%5Bdir%3Drtl%5D%20.md-source__repository%7Bmargin-right%3A.6rem%7D.md-source__repository%7Bdisplay%3Ainline-block%3Bmax-width%3Acalc%28100%25%20-%201.2rem%29%3Boverflow%3Ahidden%3Btext-overflow%3Aellipsis%3Bvertical-align%3Amiddle%7D.md-source__facts%7Bdisplay%3Aflex%3Bfont-size%3A.55rem%3Bgap%3A.4rem%3Blist-style-type%3Anone%3Bmargin%3A.1rem%200%200%3Bopacity%3A.75%3Boverflow%3Ahidden%3Bpadding%3A0%3Bwidth%3A100%25%7D.md-source__repository--active%20.md-source__facts%7Banimation%3Afacts%20.25s%20ease-in%7D.md-source__fact%7Boverflow%3Ahidden%3Btext-overflow%3Aellipsis%7D.md-source__repository--active%20.md-source__fact%7Banimation%3Afact%20.4s%20ease-out%7D%5Bdir%3Dltr%5D%20.md-source__fact%3Abefore%7Bmargin-right%3A.1rem%7D%5Bdir%3Drtl%5D%20.md-source__fact%3Abefore%7Bmargin-left%3A.1rem%7D.md-source__fact%3Abefore%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ainline-block%3Bheight%3A.6rem%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bvertical-align%3Atext-top%3Bwidth%3A.6rem%7D.md-source__fact%3Anth-child%281n%2B2%29%7Bflex-shrink%3A0%7D.md-source__fact--version%3Abefore%7B-webkit-mask-image%3Avar%28--md-source-version-icon%29%3Bmask-image%3Avar%28--md-source-version-icon%29%7D.md-source__fact--stars%3Abefore%7B-webkit-mask-image%3Avar%28--md-source-stars-icon%29%3Bmask-image%3Avar%28--md-source-stars-icon%29%7D.md-source__fact--forks%3Abefore%7B-webkit-mask-image%3Avar%28--md-source-forks-icon%29%3Bmask-image%3Avar%28--md-source-forks-icon%29%7D.md-source__fact--repositories%3Abefore%7B-webkit-mask-image%3Avar%28--md-source-repositories-icon%29%3Bmask-image%3Avar%28--md-source-repositories-icon%29%7D.md-source-file%7Bmargin%3A1em%200%7D%5Bdir%3Dltr%5D%20.md-source-file__fact%7Bmargin-right%3A.6rem%7D%5Bdir%3Drtl%5D%20.md-source-file__fact%7Bmargin-left%3A.6rem%7D.md-source-file__fact%7Balign-items%3Acenter%3Bcolor%3Avar%28--md-default-fg-color--light%29%3Bdisplay%3Ainline-flex%3Bfont-size%3A.68rem%3Bgap%3A.3rem%7D.md-source-file__fact%20.md-icon%7Bflex-shrink%3A0%3Bmargin-bottom%3A.05rem%7D%5Bdir%3Dltr%5D%20.md-source-file__fact%20.md-author%7Bfloat%3Aleft%7D%5Bdir%3Drtl%5D%20.md-source-file__fact%20.md-author%7Bfloat%3Aright%7D.md-source-file__fact%20.md-author%7Bmargin-right%3A.2rem%7D.md-source-file__fact%20svg%7Bwidth%3A.9rem%7D%3Aroot%7B--md-status%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M11%209h2V7h-2m1%2013c-4.41%200-8-3.59-8-8s3.59-8%208-8%208%203.59%208%208-3.59%208-8%208m0-18A10%2010%200%200%200%202%2012a10%2010%200%200%200%2010%2010%2010%2010%200%200%200%2010-10A10%2010%200%200%200%2012%202m-1%2015h2v-6h-2z%22/%3E%3C/svg%3E%27%29%3B--md-status--new%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22m23%2012-2.44-2.78.34-3.68-3.61-.82-1.89-3.18L12%203%208.6%201.54%206.71%204.72l-3.61.81.34%203.68L1%2012l2.44%202.78-.34%203.69%203.61.82%201.89%203.18L12%2021l3.4%201.46%201.89-3.18%203.61-.82-.34-3.68zm-10%205h-2v-2h2zm0-4h-2V7h2z%22/%3E%3C/svg%3E%27%29%3B--md-status--deprecated%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M9%203v1H4v2h1v13a2%202%200%200%200%202%202h10a2%202%200%200%200%202-2V6h1V4h-5V3zm0%205h2v9H9zm4%200h2v9h-2z%22/%3E%3C/svg%3E%27%29%3B--md-status--encrypted%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M12%201%203%205v6c0%205.55%203.84%2010.74%209%2012%205.16-1.26%209-6.45%209-12V5zm0%206c1.4%200%202.8%201.1%202.8%202.5V11c.6%200%201.2.6%201.2%201.3v3.5c0%20.6-.6%201.2-1.3%201.2H9.2c-.6%200-1.2-.6-1.2-1.3v-3.5c0-.6.6-1.2%201.2-1.2V9.5C9.2%208.1%2010.6%207%2012%207m0%201.2c-.8%200-1.5.5-1.5%201.3V11h3V9.5c0-.8-.7-1.3-1.5-1.3%22/%3E%3C/svg%3E%27%29%7D.md-status%3Aafter%7Bbackground-color%3Avar%28--md-default-fg-color--light%29%3Bcontent%3A%22%22%3Bdisplay%3Ainline-block%3Bheight%3A1.125em%3B-webkit-mask-image%3Avar%28--md-status%29%3Bmask-image%3Avar%28--md-status%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bvertical-align%3Atext-bottom%3Bwidth%3A1.125em%7D.md-status%3Ahover%3Aafter%7Bbackground-color%3Acurrentcolor%7D.md-status--new%3Aafter%7B-webkit-mask-image%3Avar%28--md-status--new%29%3Bmask-image%3Avar%28--md-status--new%29%7D.md-status--deprecated%3Aafter%7B-webkit-mask-image%3Avar%28--md-status--deprecated%29%3Bmask-image%3Avar%28--md-status--deprecated%29%7D.md-status--encrypted%3Aafter%7B-webkit-mask-image%3Avar%28--md-status--encrypted%29%3Bmask-image%3Avar%28--md-status--encrypted%29%7D.md-tabs%7Bbackground-color%3Avar%28--md-primary-fg-color%29%3Bcolor%3Avar%28--md-primary-bg-color%29%3Bdisplay%3Ablock%3Bline-height%3A1.3%3Boverflow%3Aauto%3Bwidth%3A100%25%3Bz-index%3A3%7D%40media%20print%7B.md-tabs%7Bdisplay%3Anone%7D%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7B.md-tabs%7Bdisplay%3Anone%7D%7D.md-tabs%5Bhidden%5D%7Bpointer-events%3Anone%7D%5Bdir%3Dltr%5D%20.md-tabs__list%7Bmargin-left%3A.2rem%7D%5Bdir%3Drtl%5D%20.md-tabs__list%7Bmargin-right%3A.2rem%7D.md-tabs__list%7Bcontain%3Acontent%3Bdisplay%3Aflex%3Blist-style%3Anone%3Bmargin%3A0%3Boverflow%3Aauto%3Bpadding%3A0%3Bscrollbar-width%3Anone%3Bwhite-space%3Anowrap%7D.md-tabs__list%3A%3A-webkit-scrollbar%7Bdisplay%3Anone%7D.md-tabs__item%7Bheight%3A2.4rem%3Bpadding-left%3A.6rem%3Bpadding-right%3A.6rem%7D.md-tabs__item--active%20.md-tabs__link%7Bcolor%3Ainherit%3Bopacity%3A1%7D.md-tabs__link%7Bbackface-visibility%3Ahidden%3Bdisplay%3Aflex%3Bfont-size%3A.7rem%3Bmargin-top%3A.8rem%3Bopacity%3A.7%3Boutline-color%3Avar%28--md-accent-fg-color%29%3Boutline-offset%3A.2rem%3Btransition%3Atransform%20.4s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%2Copacity%20.25s%7D.md-tabs__link%3Afocus%2C.md-tabs__link%3Ahover%7Bcolor%3Ainherit%3Bopacity%3A1%7D%5Bdir%3Dltr%5D%20.md-tabs__link%20svg%7Bmargin-right%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-tabs__link%20svg%7Bmargin-left%3A.4rem%7D.md-tabs__link%20svg%7Bfill%3Acurrentcolor%3Bheight%3A1.3em%7D.md-tabs__item%3Anth-child%282%29%20.md-tabs__link%7Btransition-delay%3A20ms%7D.md-tabs__item%3Anth-child%283%29%20.md-tabs__link%7Btransition-delay%3A40ms%7D.md-tabs__item%3Anth-child%284%29%20.md-tabs__link%7Btransition-delay%3A60ms%7D.md-tabs__item%3Anth-child%285%29%20.md-tabs__link%7Btransition-delay%3A80ms%7D.md-tabs__item%3Anth-child%286%29%20.md-tabs__link%7Btransition-delay%3A.1s%7D.md-tabs__item%3Anth-child%287%29%20.md-tabs__link%7Btransition-delay%3A.12s%7D.md-tabs__item%3Anth-child%288%29%20.md-tabs__link%7Btransition-delay%3A.14s%7D.md-tabs__item%3Anth-child%289%29%20.md-tabs__link%7Btransition-delay%3A.16s%7D.md-tabs__item%3Anth-child%2810%29%20.md-tabs__link%7Btransition-delay%3A.18s%7D.md-tabs__item%3Anth-child%2811%29%20.md-tabs__link%7Btransition-delay%3A.2s%7D.md-tabs__item%3Anth-child%2812%29%20.md-tabs__link%7Btransition-delay%3A.22s%7D.md-tabs__item%3Anth-child%2813%29%20.md-tabs__link%7Btransition-delay%3A.24s%7D.md-tabs__item%3Anth-child%2814%29%20.md-tabs__link%7Btransition-delay%3A.26s%7D.md-tabs__item%3Anth-child%2815%29%20.md-tabs__link%7Btransition-delay%3A.28s%7D.md-tabs__item%3Anth-child%2816%29%20.md-tabs__link%7Btransition-delay%3A.3s%7D.md-tabs%5Bhidden%5D%20.md-tabs__link%7Bopacity%3A0%3Btransform%3AtranslateY%2850%25%29%3Btransition%3Atransform%200ms%20.1s%2Copacity%20.1s%7D%3Aroot%7B--md-tag-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22m5.41%2021%20.71-4h-4l.35-2h4l1.06-6h-4l.35-2h4l.71-4h2l-.71%204h6l.71-4h2l-.71%204h4l-.35%202h-4l-1.06%206h4l-.35%202h-4l-.71%204h-2l.71-4h-6l-.71%204zM9.53%209l-1.06%206h6l1.06-6z%22/%3E%3C/svg%3E%27%29%7D.md-typeset%20.md-tags%3Anot%28%5Bhidden%5D%29%7Bdisplay%3Ainline-flex%3Bflex-wrap%3Awrap%3Bgap%3A.5em%3Bmargin-bottom%3A.75em%3Bmargin-top%3A-.125em%7D.md-typeset%20.md-tag%7Balign-items%3Acenter%3Bbackground%3Avar%28--md-default-fg-color--lightest%29%3Bborder-radius%3A2.4rem%3Bdisplay%3Ainline-flex%3Bfont-size%3A.64rem%3Bfont-size%3Amin%28.8em%2C.64rem%29%3Bfont-weight%3A700%3Bgap%3A.5em%3Bletter-spacing%3Anormal%3Bline-height%3A1.6%3Bpadding%3A.3125em%20.78125em%7D.md-typeset%20.md-tag%5Bhref%5D%7B-webkit-tap-highlight-color%3Atransparent%3Bcolor%3Ainherit%3Boutline%3Anone%3Btransition%3Acolor%20125ms%2Cbackground-color%20125ms%7D.md-typeset%20.md-tag%5Bhref%5D%3Afocus%2C.md-typeset%20.md-tag%5Bhref%5D%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color%29%3Bcolor%3Avar%28--md-accent-bg-color%29%7D%5Bid%5D%3E.md-typeset%20.md-tag%7Bvertical-align%3Atext-top%7D.md-typeset%20.md-tag-shadow%7Bopacity%3A.5%7D.md-typeset%20.md-tag-icon%3Abefore%7Bbackground-color%3Avar%28--md-default-fg-color--lighter%29%3Bcontent%3A%22%22%3Bdisplay%3Ainline-block%3Bheight%3A1.2em%3B-webkit-mask-image%3Avar%28--md-tag-icon%29%3Bmask-image%3Avar%28--md-tag-icon%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Btransition%3Abackground-color%20125ms%3Bvertical-align%3Atext-bottom%3Bwidth%3A1.2em%7D.md-typeset%20.md-tag-icon%5Bhref%5D%3Afocus%3Abefore%2C.md-typeset%20.md-tag-icon%5Bhref%5D%3Ahover%3Abefore%7Bbackground-color%3Avar%28--md-accent-bg-color%29%7D%40keyframes%20pulse%7B0%25%7Btransform%3Ascale%28.95%29%7D75%25%7Btransform%3Ascale%281%29%7Dto%7Btransform%3Ascale%28.95%29%7D%7D%3Aroot%7B--md-annotation-bg-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M12%202A10%2010%200%200%200%202%2012a10%2010%200%200%200%2010%2010%2010%2010%200%200%200%2010-10A10%2010%200%200%200%2012%202%22/%3E%3C/svg%3E%27%29%3B--md-annotation-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M17%2013h-4v4h-2v-4H7v-2h4V7h2v4h4m-5-9A10%2010%200%200%200%202%2012a10%2010%200%200%200%2010%2010%2010%2010%200%200%200%2010-10A10%2010%200%200%200%2012%202%22/%3E%3C/svg%3E%27%29%7D.md-tooltip%7Bbackface-visibility%3Ahidden%3Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder-radius%3A.1rem%3Bbox-shadow%3Avar%28--md-shadow-z2%29%3Bcolor%3Avar%28--md-default-fg-color%29%3Bfont-family%3Avar%28--md-text-font-family%29%3Bleft%3Aclamp%28var%28--md-tooltip-0%2C0rem%29%20%2B%20.8rem%2Cvar%28--md-tooltip-x%29%2C100vw%20%2B%20var%28--md-tooltip-0%2C0rem%29%20%2B%20.8rem%20-%20var%28--md-tooltip-width%29%20-%202%20%2A%20.8rem%29%3Bmax-width%3Acalc%28100vw%20-%201.6rem%29%3Bopacity%3A0%3Bposition%3Aabsolute%3Btop%3Avar%28--md-tooltip-y%29%3Btransform%3AtranslateY%28-.4rem%29%3Btransition%3Atransform%200ms%20.25s%2Copacity%20.25s%2Cz-index%20.25s%3Bwidth%3Avar%28--md-tooltip-width%29%3Bz-index%3A0%7D.md-tooltip--active%7Bopacity%3A1%3Btransform%3AtranslateY%280%29%3Btransition%3Atransform%20.25s%20cubic-bezier%28.1%2C.7%2C.1%2C1%29%2Copacity%20.25s%2Cz-index%200ms%3Bz-index%3A2%7D.md-tooltip--inline%7Bfont-weight%3A700%3B-webkit-user-select%3Anone%3Buser-select%3Anone%3Bwidth%3Aauto%7D.md-tooltip--inline%3Anot%28.md-tooltip--active%29%7Btransform%3AtranslateY%28.2rem%29%20scale%28.9%29%7D.md-tooltip--inline%20.md-tooltip__inner%7Bfont-size%3A.5rem%3Bpadding%3A.2rem%20.4rem%7D%5Bhidden%5D%2B.md-tooltip--inline%7Bdisplay%3Anone%7D.focus-visible%3E.md-tooltip%2C.md-tooltip%3Atarget%7Boutline%3Avar%28--md-accent-fg-color%29%20auto%7D.md-tooltip__inner%7Bfont-size%3A.64rem%3Bpadding%3A.8rem%7D.md-tooltip__inner.md-typeset%3E%3Afirst-child%7Bmargin-top%3A0%7D.md-tooltip__inner.md-typeset%3E%3Alast-child%7Bmargin-bottom%3A0%7D.md-annotation%7Bfont-style%3Anormal%3Bfont-weight%3A400%3Boutline%3Anone%3Btext-align%3Ainitial%3Bvertical-align%3Atext-bottom%3Bwhite-space%3Anormal%7D%5Bdir%3Drtl%5D%20.md-annotation%7Bdirection%3Artl%7Dcode%20.md-annotation%7Bfont-family%3Avar%28--md-code-font-family%29%3Bfont-size%3Ainherit%7D.md-annotation%3Anot%28%5Bhidden%5D%29%7Bdisplay%3Ainline-block%3Bline-height%3A1.25%7D.md-annotation__index%7Bborder-radius%3A.01px%3Bcursor%3Apointer%3Bdisplay%3Ainline-block%3Bmargin-left%3A.4ch%3Bmargin-right%3A.4ch%3Boutline%3Anone%3Boverflow%3Ahidden%3Bposition%3Arelative%3B-webkit-user-select%3Anone%3Buser-select%3Anone%3Bvertical-align%3Atext-top%3Bz-index%3A0%7D.md-annotation%20.md-annotation__index%7Btransition%3Az-index%20.25s%7D%40media%20screen%7B.md-annotation__index%7Bwidth%3A2.2ch%7D%5Bdata-md-visible%5D%3E.md-annotation__index%7Banimation%3Apulse%202s%20infinite%7D.md-annotation__index%3Abefore%7Bbackground%3Avar%28--md-default-bg-color%29%3B-webkit-mask-image%3Avar%28--md-annotation-bg-icon%29%3Bmask-image%3Avar%28--md-annotation-bg-icon%29%7D.md-annotation__index%3Aafter%2C.md-annotation__index%3Abefore%7Bcontent%3A%22%22%3Bheight%3A2.2ch%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bposition%3Aabsolute%3Btop%3A-.1ch%3Bwidth%3A2.2ch%3Bz-index%3A-1%7D.md-annotation__index%3Aafter%7Bbackground-color%3Avar%28--md-default-fg-color--lighter%29%3B-webkit-mask-image%3Avar%28--md-annotation-icon%29%3Bmask-image%3Avar%28--md-annotation-icon%29%3Btransform%3Ascale%281.0001%29%3Btransition%3Abackground-color%20.25s%2Ctransform%20.25s%7D.md-tooltip--active%2B.md-annotation__index%3Aafter%7Btransform%3Arotate%2845deg%29%7D.md-tooltip--active%2B.md-annotation__index%3Aafter%2C%3Ahover%3E.md-annotation__index%3Aafter%7Bbackground-color%3Avar%28--md-accent-fg-color%29%7D%7D.md-tooltip--active%2B.md-annotation__index%7Banimation-play-state%3Apaused%3Btransition-duration%3A0ms%3Bz-index%3A2%7D.md-annotation__index%20%5Bdata-md-annotation-id%5D%7Bdisplay%3Ainline-block%7D%40media%20print%7B.md-annotation__index%20%5Bdata-md-annotation-id%5D%7Bbackground%3Avar%28--md-default-fg-color--lighter%29%3Bborder-radius%3A2ch%3Bcolor%3Avar%28--md-default-bg-color%29%3Bfont-weight%3A700%3Bpadding%3A0%20.6ch%3Bwhite-space%3Anowrap%7D.md-annotation__index%20%5Bdata-md-annotation-id%5D%3Aafter%7Bcontent%3Aattr%28data-md-annotation-id%29%7D%7D.md-typeset%20.md-annotation-list%7Bcounter-reset%3Aannotation%3Blist-style%3Anone%21important%7D.md-typeset%20.md-annotation-list%20li%7Bposition%3Arelative%7D%5Bdir%3Dltr%5D%20.md-typeset%20.md-annotation-list%20li%3Abefore%7Bleft%3A-2.125em%7D%5Bdir%3Drtl%5D%20.md-typeset%20.md-annotation-list%20li%3Abefore%7Bright%3A-2.125em%7D.md-typeset%20.md-annotation-list%20li%3Abefore%7Bbackground%3Avar%28--md-default-fg-color--lighter%29%3Bborder-radius%3A2ch%3Bcolor%3Avar%28--md-default-bg-color%29%3Bcontent%3Acounter%28annotation%29%3Bcounter-increment%3Aannotation%3Bfont-size%3A.8875em%3Bfont-weight%3A700%3Bheight%3A2ch%3Bline-height%3A1.25%3Bmin-width%3A2ch%3Bpadding%3A0%20.6ch%3Bposition%3Aabsolute%3Btext-align%3Acenter%3Btop%3A.25em%7D%3Aroot%7B--md-tooltip-width%3A20rem%3B--md-tooltip-tail%3A0.3rem%7D.md-tooltip2%7Bbackface-visibility%3Ahidden%3Bcolor%3Avar%28--md-default-fg-color%29%3Bfont-family%3Avar%28--md-text-font-family%29%3Bopacity%3A0%3Bpointer-events%3Anone%3Bposition%3Aabsolute%3Btop%3Acalc%28var%28--md-tooltip-host-y%29%20%2B%20var%28--md-tooltip-y%29%29%3Btransform%3AtranslateY%28-.4rem%29%3Btransform-origin%3Acalc%28var%28--md-tooltip-host-x%29%20%2B%20var%28--md-tooltip-x%29%29%200%3Btransition%3Atransform%200ms%20.25s%2Copacity%20.25s%2Cz-index%20.25s%3Bwidth%3A100%25%3Bz-index%3A0%7D.md-tooltip2%3Abefore%7Bborder-left%3Avar%28--md-tooltip-tail%29%20solid%20%230000%3Bborder-right%3Avar%28--md-tooltip-tail%29%20solid%20%230000%3Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bleft%3Aclamp%281.5%20%2A%20.8rem%2Cvar%28--md-tooltip-host-x%29%20%2B%20var%28--md-tooltip-x%29%20-%20var%28--md-tooltip-tail%29%2C100vw%20-%202%20%2A%20var%28--md-tooltip-tail%29%20-%201.5%20%2A%20.8rem%29%3Bposition%3Aabsolute%3Bz-index%3A1%7D.md-tooltip2--top%3Abefore%7Bborder-top%3Avar%28--md-tooltip-tail%29%20solid%20var%28--md-default-bg-color%29%3Bbottom%3Acalc%28var%28--md-tooltip-tail%29%2A-1%20%2B%20.025rem%29%3Bfilter%3Adrop-shadow%280%201px%200%20hsla%280%2C0%25%2C0%25%2C.05%29%29%7D.md-tooltip2--bottom%3Abefore%7Bborder-bottom%3Avar%28--md-tooltip-tail%29%20solid%20var%28--md-default-bg-color%29%3Bfilter%3Adrop-shadow%280%20-1px%200%20hsla%280%2C0%25%2C0%25%2C.05%29%29%3Btop%3Acalc%28var%28--md-tooltip-tail%29%2A-1%20%2B%20.025rem%29%7D.md-tooltip2--active%7Bopacity%3A1%3Btransform%3AtranslateY%280%29%3Btransition%3Atransform%20.4s%20cubic-bezier%280%2C1%2C.5%2C1%29%2Copacity%20.25s%2Cz-index%200ms%3Bz-index%3A2%7D.md-tooltip2__inner%7Bscrollbar-gutter%3Astable%3Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder-radius%3A.1rem%3Bbox-shadow%3Avar%28--md-shadow-z2%29%3Bleft%3Aclamp%28.8rem%2Cvar%28--md-tooltip-host-x%29%20-%20.8rem%2C100vw%20-%20var%28--md-tooltip-width%29%20-%20.8rem%29%3Bmax-height%3A40vh%3Bmax-width%3Acalc%28100vw%20-%201.6rem%29%3Bposition%3Arelative%3Bscrollbar-width%3Athin%7D.md-tooltip2__inner%3A%3A-webkit-scrollbar%7Bheight%3A.2rem%3Bwidth%3A.2rem%7D.md-tooltip2__inner%3A%3A-webkit-scrollbar-thumb%7Bbackground-color%3Avar%28--md-default-fg-color--lighter%29%7D.md-tooltip2__inner%3A%3A-webkit-scrollbar-thumb%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color%29%7D%5Brole%3Ddialog%5D%3E.md-tooltip2__inner%7Bfont-size%3A.64rem%3Boverflow%3Aauto%3Bpadding%3A0%20.8rem%3Bpointer-events%3Aauto%3Bwidth%3Avar%28--md-tooltip-width%29%7D%5Brole%3Ddialog%5D%3E.md-tooltip2__inner%3Aafter%2C%5Brole%3Ddialog%5D%3E.md-tooltip2__inner%3Abefore%7Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A.8rem%3Bposition%3Asticky%3Bwidth%3A100%25%3Bz-index%3A10%7D%5Brole%3Ddialog%5D%3E.md-tooltip2__inner%3Abefore%7Bbackground%3Alinear-gradient%28var%28--md-default-bg-color%29%2C%230000%2075%25%29%3Btop%3A0%7D%5Brole%3Ddialog%5D%3E.md-tooltip2__inner%3Aafter%7Bbackground%3Alinear-gradient%28%230000%2Cvar%28--md-default-bg-color%29%2075%25%29%3Bbottom%3A0%7D%5Brole%3Dtooltip%5D%3E.md-tooltip2__inner%7Bfont-size%3A.5rem%3Bfont-weight%3A700%3Bleft%3Aclamp%28.8rem%2Cvar%28--md-tooltip-host-x%29%20%2B%20var%28--md-tooltip-x%29%20-%20var%28--md-tooltip-width%29/2%2C100vw%20-%20var%28--md-tooltip-width%29%20-%20.8rem%29%3Bmax-width%3Amin%28100vw%20-%202%20%2A%20.8rem%2C400px%29%3Bpadding%3A.2rem%20.4rem%3B-webkit-user-select%3Anone%3Buser-select%3Anone%3Bwidth%3Afit-content%7D.md-tooltip2__inner.md-typeset%3E%3Afirst-child%7Bmargin-top%3A0%7D.md-tooltip2__inner.md-typeset%3E%3Alast-child%7Bmargin-bottom%3A0%7D%5Bdir%3Dltr%5D%20.md-top%7Bmargin-left%3A50%25%7D%5Bdir%3Drtl%5D%20.md-top%7Bmargin-right%3A50%25%7D.md-top%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder-radius%3A1.6rem%3Bbox-shadow%3Avar%28--md-shadow-z2%29%3Bcolor%3Avar%28--md-default-fg-color--light%29%3Bcursor%3Apointer%3Bdisplay%3Ablock%3Bfont-size%3A.7rem%3Boutline%3Anone%3Bpadding%3A.4rem%20.8rem%3Bposition%3Afixed%3Btop%3A3.2rem%3Btransform%3Atranslate%28-50%25%29%3Btransition%3Acolor%20125ms%2Cbackground-color%20125ms%2Ctransform%20125ms%20cubic-bezier%28.4%2C0%2C.2%2C1%29%2Copacity%20125ms%3Bz-index%3A2%7D%40media%20print%7B.md-top%7Bdisplay%3Anone%7D%7D%5Bdir%3Drtl%5D%20.md-top%7Btransform%3Atranslate%2850%25%29%7D.md-top%5Bhidden%5D%7Bopacity%3A0%3Bpointer-events%3Anone%3Btransform%3Atranslate%28-50%25%2C.2rem%29%3Btransition-duration%3A0ms%7D%5Bdir%3Drtl%5D%20.md-top%5Bhidden%5D%7Btransform%3Atranslate%2850%25%2C.2rem%29%7D.md-top%3Afocus%2C.md-top%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color%29%3Bcolor%3Avar%28--md-accent-bg-color%29%7D.md-top%20svg%7Bdisplay%3Ainline-block%3Bvertical-align%3A-.5em%7D%40keyframes%20hoverfix%7B0%25%7Bpointer-events%3Anone%7D%7D%3Aroot%7B--md-version-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%20320%20512%22%3E%3C%21--%21%20Font%20Awesome%20Free%207.1.0%20by%20%40fontawesome%20-%20https%3A//fontawesome.com%20License%20-%20https%3A//fontawesome.com/license/free%20%28Icons%3A%20CC%20BY%204.0%2C%20Fonts%3A%20SIL%20OFL%201.1%2C%20Code%3A%20MIT%20License%29%20Copyright%202025%20Fonticons%2C%20Inc.--%3E%3Cpath%20d%3D%22M140.3%20376.8c12.6%2010.2%2031.1%209.5%2042.8-2.2l128-128c9.2-9.2%2011.9-22.9%206.9-34.9S301.4%20192%20288.5%20192h-256c-12.9%200-24.6%207.8-29.6%2019.8s-2.2%2025.7%207%2034.8l128%20128z%22/%3E%3C/svg%3E%27%29%7D.md-version%7Bflex-shrink%3A0%3Bfont-size%3A.8rem%3Bheight%3A2.4rem%7D%5Bdir%3Dltr%5D%20.md-version__current%7Bmargin-left%3A1.4rem%3Bmargin-right%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-version__current%7Bmargin-left%3A.4rem%3Bmargin-right%3A1.4rem%7D.md-version__current%7Bcolor%3Ainherit%3Bcursor%3Apointer%3Boutline%3Anone%3Bposition%3Arelative%3Btop%3A.05rem%7D%5Bdir%3Dltr%5D%20.md-version__current%3Aafter%7Bmargin-left%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-version__current%3Aafter%7Bmargin-right%3A.4rem%7D.md-version__current%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ainline-block%3Bheight%3A.6rem%3B-webkit-mask-image%3Avar%28--md-version-icon%29%3Bmask-image%3Avar%28--md-version-icon%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bwidth%3A.4rem%7D.md-version__alias%7Bmargin-left%3A.3rem%3Bopacity%3A.7%7D.md-version__list%7Bbackground-color%3Avar%28--md-default-bg-color%29%3Bborder-radius%3A.1rem%3Bbox-shadow%3Avar%28--md-shadow-z2%29%3Bcolor%3Avar%28--md-default-fg-color%29%3Blist-style-type%3Anone%3Bmargin%3A.2rem%20.8rem%3Bmax-height%3A0%3Bopacity%3A0%3Boverflow%3Aauto%3Bpadding%3A0%3Bposition%3Aabsolute%3Bscroll-snap-type%3Ay%20mandatory%3Btop%3A.15rem%3Btransition%3Amax-height%200ms%20.5s%2Copacity%20.25s%20.25s%3Bz-index%3A3%7D.md-version%3Afocus-within%20.md-version__list%2C.md-version%3Ahover%20.md-version__list%7Bmax-height%3A10rem%3Bopacity%3A1%3Btransition%3Amax-height%200ms%2Copacity%20.25s%7D%40media%20%28hover%3Anone%29%2C%28pointer%3Acoarse%29%7B.md-version%3Ahover%20.md-version__list%7Banimation%3Ahoverfix%20.25s%20forwards%7D.md-version%3Afocus-within%20.md-version__list%7Banimation%3Anone%7D%7D.md-version__item%7Bline-height%3A1.8rem%7D%5Bdir%3Dltr%5D%20.md-version__link%7Bpadding-left%3A.6rem%3Bpadding-right%3A1.2rem%7D%5Bdir%3Drtl%5D%20.md-version__link%7Bpadding-left%3A1.2rem%3Bpadding-right%3A.6rem%7D.md-version__link%7Bcursor%3Apointer%3Bdisplay%3Ablock%3Boutline%3Anone%3Bscroll-snap-align%3Astart%3Btransition%3Acolor%20.25s%2Cbackground-color%20.25s%3Bwhite-space%3Anowrap%3Bwidth%3A100%25%7D.md-version__link%3Afocus%2C.md-version__link%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-version__link%3Afocus%7Bbackground-color%3Avar%28--md-default-fg-color--lightest%29%7D%3Aroot%7B--md-admonition-icon--note%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M12%202C6.47%202%202%206.47%202%2012s4.47%2010%2010%2010%2010-4.47%2010-10S17.53%202%2012%202m3.1%205.07c.14%200%20.28.05.4.16l1.27%201.27c.23.22.23.57%200%20.78l-1%201-2.05-2.05%201-1c.1-.11.24-.16.38-.16m-1.97%201.74%202.06%202.06-6.06%206.06H7.07v-2.06z%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--abstract%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M17%209H7V7h10m0%206H7v-2h10m-3%206H7v-2h7M12%203a1%201%200%200%201%201%201%201%201%200%200%201-1%201%201%201%200%200%201-1-1%201%201%200%200%201%201-1m7%200h-4.18C14.4%201.84%2013.3%201%2012%201s-2.4.84-2.82%202H5a2%202%200%200%200-2%202v14a2%202%200%200%200%202%202h14a2%202%200%200%200%202-2V5a2%202%200%200%200-2-2%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--info%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M13%209h-2V7h2m0%2010h-2v-6h2m-1-9A10%2010%200%200%200%202%2012a10%2010%200%200%200%2010%2010%2010%2010%200%200%200%2010-10A10%2010%200%200%200%2012%202%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--tip%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M17.66%2011.2c-.23-.3-.51-.56-.77-.82-.67-.6-1.43-1.03-2.07-1.66C13.33%207.26%2013%204.85%2013.95%203c-.95.23-1.78.75-2.49%201.32-2.59%202.08-3.61%205.75-2.39%208.9.04.1.08.2.08.33%200%20.22-.15.42-.35.5-.23.1-.47.04-.66-.12a.6.6%200%200%201-.14-.17c-1.13-1.43-1.31-3.48-.55-5.12C5.78%2010%204.87%2012.3%205%2014.47c.06.5.12%201%20.29%201.5.14.6.41%201.2.71%201.73%201.08%201.73%202.95%202.97%204.96%203.22%202.14.27%204.43-.12%206.07-1.6%201.83-1.66%202.47-4.32%201.53-6.6l-.13-.26c-.21-.46-.77-1.26-.77-1.26m-3.16%206.3c-.28.24-.74.5-1.1.6-1.12.4-2.24-.16-2.9-.82%201.19-.28%201.9-1.16%202.11-2.05.17-.8-.15-1.46-.28-2.23-.12-.74-.1-1.37.17-2.06.19.38.39.76.63%201.06.77%201%201.98%201.44%202.24%202.8.04.14.06.28.06.43.03.82-.33%201.72-.93%202.27%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--success%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M21%207%209%2019l-5.5-5.5%201.41-1.41L9%2016.17%2019.59%205.59z%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--question%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22m15.07%2011.25-.9.92C13.45%2012.89%2013%2013.5%2013%2015h-2v-.5c0-1.11.45-2.11%201.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41a2%202%200%200%200-2-2%202%202%200%200%200-2%202H8a4%204%200%200%201%204-4%204%204%200%200%201%204%204%203.2%203.2%200%200%201-.93%202.25M13%2019h-2v-2h2M12%202A10%2010%200%200%200%202%2012a10%2010%200%200%200%2010%2010%2010%2010%200%200%200%2010-10c0-5.53-4.5-10-10-10%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--warning%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M13%2014h-2V9h2m0%209h-2v-2h2M1%2021h22L12%202z%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--failure%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M19%206.41%2017.59%205%2012%2010.59%206.41%205%205%206.41%2010.59%2012%205%2017.59%206.41%2019%2012%2013.41%2017.59%2019%2019%2017.59%2013.41%2012z%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--danger%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22m11.5%2020%204.86-9.73H13V4l-5%209.73h3.5zM12%202c2.75%200%205.1%201%207.05%202.95S22%209.25%2022%2012s-1%205.1-2.95%207.05S14.75%2022%2012%2022s-5.1-1-7.05-2.95S2%2014.75%202%2012s1-5.1%202.95-7.05S9.25%202%2012%202%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--bug%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M11%2013h2v1h-2zm10-8v6c0%205.5-3.8%2010.7-9%2012-5.2-1.3-9-6.5-9-12V5l9-4zm-4%205h-2.2c-.2-.6-.6-1.1-1.1-1.5l1.2-1.2-.7-.7L12.8%208H12c-.2%200-.5%200-.7.1L9.9%206.6l-.8.8%201.2%201.2c-.5.3-.9.8-1.1%201.4H7v1h2v1H7v1h2v1H7v1h2.2c.4%201.2%201.5%202%202.8%202s2.4-.8%202.8-2H17v-1h-2v-1h2v-1h-2v-1h2zm-6%202h2v-1h-2z%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--example%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M7%202v2h1v14a4%204%200%200%200%204%204%204%204%200%200%200%204-4V4h1V2zm4%2014c-.6%200-1-.4-1-1s.4-1%201-1%201%20.4%201%201-.4%201-1%201m2-4c-.6%200-1-.4-1-1s.4-1%201-1%201%20.4%201%201-.4%201-1%201m1-5h-4V4h4z%22/%3E%3C/svg%3E%27%29%3B--md-admonition-icon--quote%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M14%2017h3l2-4V7h-6v6h3M6%2017h3l2-4V7H5v6h3z%22/%3E%3C/svg%3E%27%29%7D.md-typeset%20.admonition%2C.md-typeset%20details%7Bbackground-color%3Avar%28--md-admonition-bg-color%29%3Bborder%3A.075rem%20solid%20%23448aff%3Bborder-radius%3A.2rem%3Bbox-shadow%3Avar%28--md-shadow-z1%29%3Bcolor%3Avar%28--md-admonition-fg-color%29%3Bdisplay%3Aflow-root%3Bfont-size%3A.64rem%3Bmargin%3A1.5625em%200%3Bpadding%3A0%20.6rem%3Bpage-break-inside%3Aavoid%3Btransition%3Abox-shadow%20125ms%7D%40media%20print%7B.md-typeset%20.admonition%2C.md-typeset%20details%7Bbox-shadow%3Anone%7D%7D.md-typeset%20.admonition%3Afocus-within%2C.md-typeset%20details%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%23448aff1a%7D.md-typeset%20.admonition%3E%2A%2C.md-typeset%20details%3E%2A%7Bbox-sizing%3Aborder-box%7D.md-typeset%20.admonition%20.admonition%2C.md-typeset%20.admonition%20details%2C.md-typeset%20details%20.admonition%2C.md-typeset%20details%20details%7Bmargin-bottom%3A1em%3Bmargin-top%3A1em%7D.md-typeset%20.admonition%20.md-typeset__scrollwrap%2C.md-typeset%20details%20.md-typeset__scrollwrap%7Bmargin%3A1em%20-.6rem%7D.md-typeset%20.admonition%20.md-typeset__table%2C.md-typeset%20details%20.md-typeset__table%7Bpadding%3A0%20.6rem%7D.md-typeset%20.admonition%3E.tabbed-set%3Aonly-child%2C.md-typeset%20details%3E.tabbed-set%3Aonly-child%7Bmargin-top%3A0%7Dhtml%20.md-typeset%20.admonition%3E%3Alast-child%2Chtml%20.md-typeset%20details%3E%3Alast-child%7Bmargin-bottom%3A.6rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20.admonition-title%2C%5Bdir%3Dltr%5D%20.md-typeset%20summary%7Bpadding-left%3A2rem%3Bpadding-right%3A.6rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.admonition-title%2C%5Bdir%3Drtl%5D%20.md-typeset%20summary%7Bpadding-left%3A.6rem%3Bpadding-right%3A2rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20.admonition-title%2C%5Bdir%3Dltr%5D%20.md-typeset%20summary%7Bborder-left-width%3A.2rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.admonition-title%2C%5Bdir%3Drtl%5D%20.md-typeset%20summary%7Bborder-right-width%3A.2rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20.admonition-title%2C%5Bdir%3Dltr%5D%20.md-typeset%20summary%7Bborder-top-left-radius%3A.1rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20.admonition-title%2C%5Bdir%3Dltr%5D%20.md-typeset%20summary%2C%5Bdir%3Drtl%5D%20.md-typeset%20.admonition-title%2C%5Bdir%3Drtl%5D%20.md-typeset%20summary%7Bborder-top-right-radius%3A.1rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.admonition-title%2C%5Bdir%3Drtl%5D%20.md-typeset%20summary%7Bborder-top-left-radius%3A.1rem%7D.md-typeset%20.admonition-title%2C.md-typeset%20summary%7Bbackground-color%3A%23448aff1a%3Bborder%3Anone%3Bfont-weight%3A700%3Bmargin%3A0%20-.6rem%3Bpadding-bottom%3A.4rem%3Bpadding-top%3A.4rem%3Bposition%3Arelative%7Dhtml%20.md-typeset%20.admonition-title%3Alast-child%2Chtml%20.md-typeset%20summary%3Alast-child%7Bmargin-bottom%3A0%7D%5Bdir%3Dltr%5D%20.md-typeset%20.admonition-title%3Abefore%2C%5Bdir%3Dltr%5D%20.md-typeset%20summary%3Abefore%7Bleft%3A.6rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.admonition-title%3Abefore%2C%5Bdir%3Drtl%5D%20.md-typeset%20summary%3Abefore%7Bright%3A.6rem%7D.md-typeset%20.admonition-title%3Abefore%2C.md-typeset%20summary%3Abefore%7Bbackground-color%3A%23448aff%3Bcontent%3A%22%22%3Bheight%3A1rem%3B-webkit-mask-image%3Avar%28--md-admonition-icon--note%29%3Bmask-image%3Avar%28--md-admonition-icon--note%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bposition%3Aabsolute%3Btop%3A.625em%3Bwidth%3A1rem%7D.md-typeset%20.admonition-title%20code%2C.md-typeset%20summary%20code%7Bbox-shadow%3A0%200%200%20.05rem%20var%28--md-default-fg-color--lightest%29%7D.md-typeset%20.admonition.note%2C.md-typeset%20details.note%7Bborder-color%3A%23448aff%7D.md-typeset%20.admonition.note%3Afocus-within%2C.md-typeset%20details.note%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%23448aff1a%7D.md-typeset%20.note%3E.admonition-title%2C.md-typeset%20.note%3Esummary%7Bbackground-color%3A%23448aff1a%7D.md-typeset%20.note%3E.admonition-title%3Abefore%2C.md-typeset%20.note%3Esummary%3Abefore%7Bbackground-color%3A%23448aff%3B-webkit-mask-image%3Avar%28--md-admonition-icon--note%29%3Bmask-image%3Avar%28--md-admonition-icon--note%29%7D.md-typeset%20.note%3E.admonition-title%3Aafter%2C.md-typeset%20.note%3Esummary%3Aafter%7Bcolor%3A%23448aff%7D.md-typeset%20.admonition.abstract%2C.md-typeset%20details.abstract%7Bborder-color%3A%2300b0ff%7D.md-typeset%20.admonition.abstract%3Afocus-within%2C.md-typeset%20details.abstract%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%2300b0ff1a%7D.md-typeset%20.abstract%3E.admonition-title%2C.md-typeset%20.abstract%3Esummary%7Bbackground-color%3A%2300b0ff1a%7D.md-typeset%20.abstract%3E.admonition-title%3Abefore%2C.md-typeset%20.abstract%3Esummary%3Abefore%7Bbackground-color%3A%2300b0ff%3B-webkit-mask-image%3Avar%28--md-admonition-icon--abstract%29%3Bmask-image%3Avar%28--md-admonition-icon--abstract%29%7D.md-typeset%20.abstract%3E.admonition-title%3Aafter%2C.md-typeset%20.abstract%3Esummary%3Aafter%7Bcolor%3A%2300b0ff%7D.md-typeset%20.admonition.info%2C.md-typeset%20details.info%7Bborder-color%3A%2300b8d4%7D.md-typeset%20.admonition.info%3Afocus-within%2C.md-typeset%20details.info%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%2300b8d41a%7D.md-typeset%20.info%3E.admonition-title%2C.md-typeset%20.info%3Esummary%7Bbackground-color%3A%2300b8d41a%7D.md-typeset%20.info%3E.admonition-title%3Abefore%2C.md-typeset%20.info%3Esummary%3Abefore%7Bbackground-color%3A%2300b8d4%3B-webkit-mask-image%3Avar%28--md-admonition-icon--info%29%3Bmask-image%3Avar%28--md-admonition-icon--info%29%7D.md-typeset%20.info%3E.admonition-title%3Aafter%2C.md-typeset%20.info%3Esummary%3Aafter%7Bcolor%3A%2300b8d4%7D.md-typeset%20.admonition.tip%2C.md-typeset%20details.tip%7Bborder-color%3A%2300bfa5%7D.md-typeset%20.admonition.tip%3Afocus-within%2C.md-typeset%20details.tip%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%2300bfa51a%7D.md-typeset%20.tip%3E.admonition-title%2C.md-typeset%20.tip%3Esummary%7Bbackground-color%3A%2300bfa51a%7D.md-typeset%20.tip%3E.admonition-title%3Abefore%2C.md-typeset%20.tip%3Esummary%3Abefore%7Bbackground-color%3A%2300bfa5%3B-webkit-mask-image%3Avar%28--md-admonition-icon--tip%29%3Bmask-image%3Avar%28--md-admonition-icon--tip%29%7D.md-typeset%20.tip%3E.admonition-title%3Aafter%2C.md-typeset%20.tip%3Esummary%3Aafter%7Bcolor%3A%2300bfa5%7D.md-typeset%20.admonition.success%2C.md-typeset%20details.success%7Bborder-color%3A%2300c853%7D.md-typeset%20.admonition.success%3Afocus-within%2C.md-typeset%20details.success%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%2300c8531a%7D.md-typeset%20.success%3E.admonition-title%2C.md-typeset%20.success%3Esummary%7Bbackground-color%3A%2300c8531a%7D.md-typeset%20.success%3E.admonition-title%3Abefore%2C.md-typeset%20.success%3Esummary%3Abefore%7Bbackground-color%3A%2300c853%3B-webkit-mask-image%3Avar%28--md-admonition-icon--success%29%3Bmask-image%3Avar%28--md-admonition-icon--success%29%7D.md-typeset%20.success%3E.admonition-title%3Aafter%2C.md-typeset%20.success%3Esummary%3Aafter%7Bcolor%3A%2300c853%7D.md-typeset%20.admonition.question%2C.md-typeset%20details.question%7Bborder-color%3A%2364dd17%7D.md-typeset%20.admonition.question%3Afocus-within%2C.md-typeset%20details.question%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%2364dd171a%7D.md-typeset%20.question%3E.admonition-title%2C.md-typeset%20.question%3Esummary%7Bbackground-color%3A%2364dd171a%7D.md-typeset%20.question%3E.admonition-title%3Abefore%2C.md-typeset%20.question%3Esummary%3Abefore%7Bbackground-color%3A%2364dd17%3B-webkit-mask-image%3Avar%28--md-admonition-icon--question%29%3Bmask-image%3Avar%28--md-admonition-icon--question%29%7D.md-typeset%20.question%3E.admonition-title%3Aafter%2C.md-typeset%20.question%3Esummary%3Aafter%7Bcolor%3A%2364dd17%7D.md-typeset%20.admonition.warning%2C.md-typeset%20details.warning%7Bborder-color%3A%23ff9100%7D.md-typeset%20.admonition.warning%3Afocus-within%2C.md-typeset%20details.warning%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%23ff91001a%7D.md-typeset%20.warning%3E.admonition-title%2C.md-typeset%20.warning%3Esummary%7Bbackground-color%3A%23ff91001a%7D.md-typeset%20.warning%3E.admonition-title%3Abefore%2C.md-typeset%20.warning%3Esummary%3Abefore%7Bbackground-color%3A%23ff9100%3B-webkit-mask-image%3Avar%28--md-admonition-icon--warning%29%3Bmask-image%3Avar%28--md-admonition-icon--warning%29%7D.md-typeset%20.warning%3E.admonition-title%3Aafter%2C.md-typeset%20.warning%3Esummary%3Aafter%7Bcolor%3A%23ff9100%7D.md-typeset%20.admonition.failure%2C.md-typeset%20details.failure%7Bborder-color%3A%23ff5252%7D.md-typeset%20.admonition.failure%3Afocus-within%2C.md-typeset%20details.failure%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%23ff52521a%7D.md-typeset%20.failure%3E.admonition-title%2C.md-typeset%20.failure%3Esummary%7Bbackground-color%3A%23ff52521a%7D.md-typeset%20.failure%3E.admonition-title%3Abefore%2C.md-typeset%20.failure%3Esummary%3Abefore%7Bbackground-color%3A%23ff5252%3B-webkit-mask-image%3Avar%28--md-admonition-icon--failure%29%3Bmask-image%3Avar%28--md-admonition-icon--failure%29%7D.md-typeset%20.failure%3E.admonition-title%3Aafter%2C.md-typeset%20.failure%3Esummary%3Aafter%7Bcolor%3A%23ff5252%7D.md-typeset%20.admonition.danger%2C.md-typeset%20details.danger%7Bborder-color%3A%23ff1744%7D.md-typeset%20.admonition.danger%3Afocus-within%2C.md-typeset%20details.danger%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%23ff17441a%7D.md-typeset%20.danger%3E.admonition-title%2C.md-typeset%20.danger%3Esummary%7Bbackground-color%3A%23ff17441a%7D.md-typeset%20.danger%3E.admonition-title%3Abefore%2C.md-typeset%20.danger%3Esummary%3Abefore%7Bbackground-color%3A%23ff1744%3B-webkit-mask-image%3Avar%28--md-admonition-icon--danger%29%3Bmask-image%3Avar%28--md-admonition-icon--danger%29%7D.md-typeset%20.danger%3E.admonition-title%3Aafter%2C.md-typeset%20.danger%3Esummary%3Aafter%7Bcolor%3A%23ff1744%7D.md-typeset%20.admonition.bug%2C.md-typeset%20details.bug%7Bborder-color%3A%23f50057%7D.md-typeset%20.admonition.bug%3Afocus-within%2C.md-typeset%20details.bug%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%23f500571a%7D.md-typeset%20.bug%3E.admonition-title%2C.md-typeset%20.bug%3Esummary%7Bbackground-color%3A%23f500571a%7D.md-typeset%20.bug%3E.admonition-title%3Abefore%2C.md-typeset%20.bug%3Esummary%3Abefore%7Bbackground-color%3A%23f50057%3B-webkit-mask-image%3Avar%28--md-admonition-icon--bug%29%3Bmask-image%3Avar%28--md-admonition-icon--bug%29%7D.md-typeset%20.bug%3E.admonition-title%3Aafter%2C.md-typeset%20.bug%3Esummary%3Aafter%7Bcolor%3A%23f50057%7D.md-typeset%20.admonition.example%2C.md-typeset%20details.example%7Bborder-color%3A%237c4dff%7D.md-typeset%20.admonition.example%3Afocus-within%2C.md-typeset%20details.example%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%237c4dff1a%7D.md-typeset%20.example%3E.admonition-title%2C.md-typeset%20.example%3Esummary%7Bbackground-color%3A%237c4dff1a%7D.md-typeset%20.example%3E.admonition-title%3Abefore%2C.md-typeset%20.example%3Esummary%3Abefore%7Bbackground-color%3A%237c4dff%3B-webkit-mask-image%3Avar%28--md-admonition-icon--example%29%3Bmask-image%3Avar%28--md-admonition-icon--example%29%7D.md-typeset%20.example%3E.admonition-title%3Aafter%2C.md-typeset%20.example%3Esummary%3Aafter%7Bcolor%3A%237c4dff%7D.md-typeset%20.admonition.quote%2C.md-typeset%20details.quote%7Bborder-color%3A%239e9e9e%7D.md-typeset%20.admonition.quote%3Afocus-within%2C.md-typeset%20details.quote%3Afocus-within%7Bbox-shadow%3A0%200%200%20.2rem%20%239e9e9e1a%7D.md-typeset%20.quote%3E.admonition-title%2C.md-typeset%20.quote%3Esummary%7Bbackground-color%3A%239e9e9e1a%7D.md-typeset%20.quote%3E.admonition-title%3Abefore%2C.md-typeset%20.quote%3Esummary%3Abefore%7Bbackground-color%3A%239e9e9e%3B-webkit-mask-image%3Avar%28--md-admonition-icon--quote%29%3Bmask-image%3Avar%28--md-admonition-icon--quote%29%7D.md-typeset%20.quote%3E.admonition-title%3Aafter%2C.md-typeset%20.quote%3Esummary%3Aafter%7Bcolor%3A%239e9e9e%7D%3Aroot%7B--md-footnotes-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M19%207v4H5.83l3.58-3.59L8%206l-6%206%206%206%201.41-1.42L5.83%2013H21V7z%22/%3E%3C/svg%3E%27%29%7D.md-typeset%20.footnote%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bfont-size%3A.64rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20.footnote%3Eol%7Bmargin-left%3A0%7D%5Bdir%3Drtl%5D%20.md-typeset%20.footnote%3Eol%7Bmargin-right%3A0%7D.md-typeset%20.footnote%3Eol%3Eli%7Btransition%3Acolor%20125ms%7D.md-typeset%20.footnote%3Eol%3Eli%3Atarget%7Bcolor%3Avar%28--md-default-fg-color%29%7D.md-typeset%20.footnote%3Eol%3Eli%3Afocus-within%20.footnote-backref%7Bopacity%3A1%3Btransform%3AtranslateX%280%29%3Btransition%3Anone%7D.md-typeset%20.footnote%3Eol%3Eli%3Ahover%20.footnote-backref%2C.md-typeset%20.footnote%3Eol%3Eli%3Atarget%20.footnote-backref%7Bopacity%3A1%3Btransform%3AtranslateX%280%29%7D.md-typeset%20.footnote%3Eol%3Eli%3E%3Afirst-child%7Bmargin-top%3A0%7D.md-typeset%20.footnote-ref%7Bfont-size%3A.75em%3Bfont-weight%3A700%7Dhtml%20.md-typeset%20.footnote-ref%7Boutline-offset%3A.1rem%7D.md-typeset%20%5Bid%5E%3D%22fnref%3A%22%5D%3Atarget%3E.footnote-ref%7Boutline%3Aauto%7D.md-typeset%20.footnote-backref%7Bcolor%3Avar%28--md-typeset-a-color%29%3Bdisplay%3Ainline-block%3Bfont-size%3A0%3Bopacity%3A0%3Btransform%3AtranslateX%28.25rem%29%3Btransition%3Acolor%20.25s%2Ctransform%20.25s%20.25s%2Copacity%20125ms%20.25s%3Bvertical-align%3Atext-bottom%7D%40media%20print%7B.md-typeset%20.footnote-backref%7Bcolor%3Avar%28--md-typeset-a-color%29%3Bopacity%3A1%3Btransform%3AtranslateX%280%29%7D%7D%5Bdir%3Drtl%5D%20.md-typeset%20.footnote-backref%7Btransform%3AtranslateX%28-.25rem%29%7D.md-typeset%20.footnote-backref%3Ahover%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-typeset%20.footnote-backref%3Abefore%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ainline-block%3Bheight%3A.8rem%3B-webkit-mask-image%3Avar%28--md-footnotes-icon%29%3Bmask-image%3Avar%28--md-footnotes-icon%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bwidth%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.footnote-backref%3Abefore%7Btransform%3AscaleX%28-1%29%7D%5Bdir%3Dltr%5D%20.md-typeset%20.headerlink%7Bmargin-left%3A.5rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.headerlink%7Bmargin-right%3A.5rem%7D.md-typeset%20.headerlink%7Bcolor%3Avar%28--md-default-fg-color--lighter%29%3Bdisplay%3Ainline-block%3Bopacity%3A0%3Btransition%3Acolor%20.25s%2Copacity%20125ms%7D%40media%20print%7B.md-typeset%20.headerlink%7Bdisplay%3Anone%7D%7D.md-typeset%20.headerlink%3Afocus%2C.md-typeset%20%3Ahover%3E.headerlink%2C.md-typeset%20%3Atarget%3E.headerlink%7Bopacity%3A1%3Btransition%3Acolor%20.25s%2Copacity%20125ms%7D.md-typeset%20.headerlink%3Afocus%2C.md-typeset%20.headerlink%3Ahover%2C.md-typeset%20%3Atarget%3E.headerlink%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-typeset%20%3Atarget%7B--md-scroll-margin%3A3.6rem%3B--md-scroll-offset%3A0rem%3Bscroll-margin-top%3Acalc%28var%28--md-scroll-margin%29%20-%20var%28--md-scroll-offset%29%29%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B.md-header--lifted~.md-container%20.md-typeset%20%3Atarget%7B--md-scroll-margin%3A6rem%7D%7D.md-typeset%20h1%3Atarget%2C.md-typeset%20h2%3Atarget%2C.md-typeset%20h3%3Atarget%7B--md-scroll-offset%3A0.2rem%7D.md-typeset%20h4%3Atarget%7B--md-scroll-offset%3A0.15rem%7D.md-typeset%20div.arithmatex%7Boverflow%3Aauto%7D%40media%20screen%20and%20%28max-width%3A44.984375em%29%7B.md-typeset%20div.arithmatex%7Bmargin%3A0%20-.8rem%7D.md-typeset%20div.arithmatex%3E%2A%7Bwidth%3Amin-content%7D%7D.md-typeset%20div.arithmatex%3E%2A%7Bmargin-left%3Aauto%21important%3Bmargin-right%3Aauto%21important%3Bpadding%3A0%20.8rem%3Btouch-action%3Aauto%7D.md-typeset%20div.arithmatex%3E%2A%20mjx-container%7Bmargin%3A0%21important%7D.md-typeset%20div.arithmatex%20mjx-assistive-mml%7Bheight%3A0%7D.md-typeset%20.katex-html%20svg%7Bmax-width%3Arevert%7D.md-typeset%20del.critic%7Bbackground-color%3Avar%28--md-typeset-del-color%29%7D.md-typeset%20del.critic%2C.md-typeset%20ins.critic%7B-webkit-box-decoration-break%3Aclone%3Bbox-decoration-break%3Aclone%7D.md-typeset%20ins.critic%7Bbackground-color%3Avar%28--md-typeset-ins-color%29%7D.md-typeset%20.critic.comment%7B-webkit-box-decoration-break%3Aclone%3Bbox-decoration-break%3Aclone%3Bcolor%3Avar%28--md-code-hl-comment-color%29%7D.md-typeset%20.critic.comment%3Abefore%7Bcontent%3A%22/%2A%20%22%7D.md-typeset%20.critic.comment%3Aafter%7Bcontent%3A%22%20%2A/%22%7D.md-typeset%20.critic.block%7Bbox-shadow%3Anone%3Bdisplay%3Ablock%3Bmargin%3A1em%200%3Boverflow%3Aauto%3Bpadding-left%3A.8rem%3Bpadding-right%3A.8rem%7D.md-typeset%20.critic.block%3E%3Afirst-child%7Bmargin-top%3A.5em%7D.md-typeset%20.critic.block%3E%3Alast-child%7Bmargin-bottom%3A.5em%7D%3Aroot%7B--md-details-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M8.59%2016.58%2013.17%2012%208.59%207.41%2010%206l6%206-6%206z%22/%3E%3C/svg%3E%27%29%7D.md-typeset%20details%7Bdisplay%3Aflow-root%3Boverflow%3Avisible%3Bpadding-top%3A0%7D.md-typeset%20details%5Bopen%5D%3Esummary%3Aafter%7Btransform%3Arotate%2890deg%29%7D.md-typeset%20details%3Anot%28%5Bopen%5D%29%7Bbox-shadow%3Anone%3Bpadding-bottom%3A0%7D.md-typeset%20details%3Anot%28%5Bopen%5D%29%3Esummary%7Bborder-radius%3A.1rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20summary%7Bpadding-right%3A1.8rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20summary%7Bpadding-left%3A1.8rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20summary%7Bborder-top-left-radius%3A.1rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20summary%2C%5Bdir%3Drtl%5D%20.md-typeset%20summary%7Bborder-top-right-radius%3A.1rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20summary%7Bborder-top-left-radius%3A.1rem%7D.md-typeset%20summary%7Bcursor%3Apointer%3Bdisplay%3Ablock%3Bmin-height%3A1rem%3Boverflow%3Ahidden%7D.md-typeset%20summary.focus-visible%7Boutline-color%3Avar%28--md-accent-fg-color%29%3Boutline-offset%3A.2rem%7D.md-typeset%20summary%3Anot%28.focus-visible%29%7B-webkit-tap-highlight-color%3Atransparent%3Boutline%3Anone%7D%5Bdir%3Dltr%5D%20.md-typeset%20summary%3Aafter%7Bright%3A.4rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20summary%3Aafter%7Bleft%3A.4rem%7D.md-typeset%20summary%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bheight%3A1rem%3B-webkit-mask-image%3Avar%28--md-details-icon%29%3Bmask-image%3Avar%28--md-details-icon%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bposition%3Aabsolute%3Btop%3A.625em%3Btransform%3Arotate%280deg%29%3Btransition%3Atransform%20.25s%3Bwidth%3A1rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20summary%3Aafter%7Btransform%3Arotate%28180deg%29%7D.md-typeset%20summary%3A%3Amarker%7Bdisplay%3Anone%7D.md-typeset%20summary%3A%3A-webkit-details-marker%7Bdisplay%3Anone%7D.md-typeset%20.emojione%2C.md-typeset%20.gemoji%2C.md-typeset%20.twemoji%7B--md-icon-size%3A1.125em%3Bdisplay%3Ainline-flex%3Bheight%3Avar%28--md-icon-size%29%3Bvertical-align%3Atext-top%7D.md-typeset%20.emojione%20svg%2C.md-typeset%20.gemoji%20svg%2C.md-typeset%20.twemoji%20svg%7Bfill%3Acurrentcolor%3Bmax-height%3A100%25%3Bwidth%3Avar%28--md-icon-size%29%7D.md-typeset%20.lg%2C.md-typeset%20.xl%2C.md-typeset%20.xxl%2C.md-typeset%20.xxxl%7Bvertical-align%3Atext-bottom%7D.md-typeset%20.middle%7Bvertical-align%3Amiddle%7D.md-typeset%20.lg%7B--md-icon-size%3A1.5em%7D.md-typeset%20.xl%7B--md-icon-size%3A2.25em%7D.md-typeset%20.xxl%7B--md-icon-size%3A3em%7D.md-typeset%20.xxxl%7B--md-icon-size%3A4em%7D.highlight%20.o%2C.highlight%20.ow%7Bcolor%3Avar%28--md-code-hl-operator-color%29%7D.highlight%20.p%7Bcolor%3Avar%28--md-code-hl-punctuation-color%29%7D.highlight%20.cpf%2C.highlight%20.l%2C.highlight%20.s%2C.highlight%20.s1%2C.highlight%20.s2%2C.highlight%20.sb%2C.highlight%20.sc%2C.highlight%20.si%2C.highlight%20.ss%7Bcolor%3Avar%28--md-code-hl-string-color%29%7D.highlight%20.cp%2C.highlight%20.se%2C.highlight%20.sh%2C.highlight%20.sr%2C.highlight%20.sx%7Bcolor%3Avar%28--md-code-hl-special-color%29%7D.highlight%20.il%2C.highlight%20.m%2C.highlight%20.mb%2C.highlight%20.mf%2C.highlight%20.mh%2C.highlight%20.mi%2C.highlight%20.mo%7Bcolor%3Avar%28--md-code-hl-number-color%29%7D.highlight%20.k%2C.highlight%20.kd%2C.highlight%20.kn%2C.highlight%20.kp%2C.highlight%20.kr%2C.highlight%20.kt%7Bcolor%3Avar%28--md-code-hl-keyword-color%29%7D.highlight%20.kc%2C.highlight%20.n%7Bcolor%3Avar%28--md-code-hl-name-color%29%7D.highlight%20.bp%2C.highlight%20.nb%2C.highlight%20.no%7Bcolor%3Avar%28--md-code-hl-constant-color%29%7D.highlight%20.nc%2C.highlight%20.ne%2C.highlight%20.nf%2C.highlight%20.nn%7Bcolor%3Avar%28--md-code-hl-function-color%29%7D.highlight%20.nd%2C.highlight%20.ni%2C.highlight%20.nl%2C.highlight%20.nt%7Bcolor%3Avar%28--md-code-hl-keyword-color%29%7D.highlight%20.c%2C.highlight%20.c1%2C.highlight%20.ch%2C.highlight%20.cm%2C.highlight%20.cs%2C.highlight%20.sd%7Bcolor%3Avar%28--md-code-hl-comment-color%29%7D.highlight%20.na%2C.highlight%20.nv%2C.highlight%20.vc%2C.highlight%20.vg%2C.highlight%20.vi%7Bcolor%3Avar%28--md-code-hl-variable-color%29%7D.highlight%20.ge%2C.highlight%20.gh%2C.highlight%20.go%2C.highlight%20.gp%2C.highlight%20.gr%2C.highlight%20.gs%2C.highlight%20.gt%2C.highlight%20.gu%7Bcolor%3Avar%28--md-code-hl-generic-color%29%7D.highlight%20.gd%2C.highlight%20.gi%7Bborder-radius%3A.1rem%3Bmargin%3A0%20-.125em%3Bpadding%3A0%20.125em%7D.highlight%20.gd%7Bbackground-color%3Avar%28--md-typeset-del-color%29%7D.highlight%20.gi%7Bbackground-color%3Avar%28--md-typeset-ins-color%29%7D.highlight%20.hll%7Bbackground-color%3Avar%28--md-code-hl-color--light%29%3Bbox-shadow%3A2px%200%200%200%20var%28--md-code-hl-color%29%20inset%3Bdisplay%3Ablock%3Bmargin%3A0%20-1.1764705882em%3Bpadding%3A0%201.1764705882em%7D.highlight%20span.filename%7Bbackground-color%3Avar%28--md-code-bg-color%29%3Bborder-bottom%3A.05rem%20solid%20var%28--md-default-fg-color--lightest%29%3Bborder-top-left-radius%3A.1rem%3Bborder-top-right-radius%3A.1rem%3Bdisplay%3Aflow-root%3Bfont-size%3A.85em%3Bfont-weight%3A700%3Bmargin-top%3A1em%3Bpadding%3A.6617647059em%201.1764705882em%3Bposition%3Arelative%7D.highlight%20span.filename%2Bpre%7Bmargin-top%3A0%7D.highlight%20span.filename%2Bpre%3Ecode%7Bborder-top-left-radius%3A0%3Bborder-top-right-radius%3A0%7D.highlight%20%5Bdata-linenos%5D%3Abefore%7Bbackground-color%3Avar%28--md-code-bg-color%29%3Bbox-shadow%3A-.05rem%200%20var%28--md-default-fg-color--lightest%29%20inset%3Bcolor%3Avar%28--md-default-fg-color--light%29%3Bcontent%3Aattr%28data-linenos%29%3Bfloat%3Aleft%3Bleft%3A-1.1764705882em%3Bmargin-left%3A-1.1764705882em%3Bmargin-right%3A1.1764705882em%3Bpadding-left%3A1.1764705882em%3Bposition%3Asticky%3B-webkit-user-select%3Anone%3Buser-select%3Anone%3Bz-index%3A3%7D.highlight%20code%20a%5Bid%5D%7Bposition%3Aabsolute%3Bvisibility%3Ahidden%7D.highlight%20code%5Bdata-md-copying%5D%7Bdisplay%3Ainitial%7D.highlight%20code%5Bdata-md-copying%5D%20.hll%7Bdisplay%3Acontents%7D.highlight%20code%5Bdata-md-copying%5D%20.md-annotation%7Bdisplay%3Anone%7D.highlighttable%7Bdisplay%3Aflow-root%7D.highlighttable%20tbody%2C.highlighttable%20td%7Bdisplay%3Ablock%3Bpadding%3A0%7D.highlighttable%20tr%7Bdisplay%3Aflex%7D.highlighttable%20pre%7Bmargin%3A0%7D.highlighttable%20th.filename%7Bflex-grow%3A1%3Bpadding%3A0%3Btext-align%3Aleft%7D.highlighttable%20th.filename%20span.filename%7Bmargin-top%3A0%7D.highlighttable%20.linenos%7Bbackground-color%3Avar%28--md-code-bg-color%29%3Bborder-bottom-left-radius%3A.1rem%3Bborder-top-left-radius%3A.1rem%3Bfont-size%3A.85em%3Bpadding%3A.7720588235em%200%20.7720588235em%201.1764705882em%3B-webkit-user-select%3Anone%3Buser-select%3Anone%7D.highlighttable%20.linenodiv%7Bbox-shadow%3A-.05rem%200%20var%28--md-default-fg-color--lightest%29%20inset%7D.highlighttable%20.linenodiv%20pre%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Btext-align%3Aright%7D.highlighttable%20.linenodiv%20span%5Bclass%5D%7Bpadding-right%3A.5882352941em%7D.highlighttable%20.code%7Bflex%3A1%3Bmin-width%3A0%7D.linenodiv%20a%7Bcolor%3Ainherit%7D.md-typeset%20.highlighttable%7Bdirection%3Altr%3Bmargin%3A1em%200%7D.md-typeset%20.highlighttable%3Etbody%3Etr%3E.code%3Ediv%3Epre%3Ecode%7Bborder-bottom-left-radius%3A0%3Bborder-top-left-radius%3A0%7D.md-typeset%20.highlight%2B.result%7Bborder%3A.05rem%20solid%20var%28--md-code-bg-color%29%3Bborder-bottom-left-radius%3A.1rem%3Bborder-bottom-right-radius%3A.1rem%3Bborder-top-width%3A.1rem%3Bmargin-top%3A-1.125em%3Boverflow%3Avisible%3Bpadding%3A0%201em%7D.md-typeset%20.highlight%2B.result%3Aafter%7Bclear%3Aboth%3Bcontent%3A%22%22%3Bdisplay%3Ablock%7D%40media%20screen%20and%20%28max-width%3A44.984375em%29%7B.md-content__inner%3E.highlight%7Bmargin%3A1em%20-.8rem%7D.md-content__inner%3E.highlight%3E.filename%2C.md-content__inner%3E.highlight%3E.highlighttable%3Etbody%3Etr%3E.code%3Ediv%3Epre%3Ecode%2C.md-content__inner%3E.highlight%3E.highlighttable%3Etbody%3Etr%3E.filename%20span.filename%2C.md-content__inner%3E.highlight%3E.highlighttable%3Etbody%3Etr%3E.linenos%2C.md-content__inner%3E.highlight%3Epre%3Ecode%7Bborder-radius%3A0%7D.md-content__inner%3E.highlight%2B.result%7Bborder-left-width%3A0%3Bborder-radius%3A0%3Bborder-right-width%3A0%3Bmargin-left%3A-.8rem%3Bmargin-right%3A-.8rem%7D%7D.md-typeset%20.keys%20kbd%3Aafter%2C.md-typeset%20.keys%20kbd%3Abefore%7B-moz-osx-font-smoothing%3Ainitial%3B-webkit-font-smoothing%3Ainitial%3Bcolor%3Ainherit%3Bmargin%3A0%3Bposition%3Arelative%7D.md-typeset%20.keys%20span%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Bpadding%3A0%20.2em%7D.md-typeset%20.keys%20.key-alt%3Abefore%2C.md-typeset%20.keys%20.key-left-alt%3Abefore%2C.md-typeset%20.keys%20.key-right-alt%3Abefore%7Bcontent%3A%22%E2%8E%87%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-command%3Abefore%2C.md-typeset%20.keys%20.key-left-command%3Abefore%2C.md-typeset%20.keys%20.key-right-command%3Abefore%7Bcontent%3A%22%E2%8C%98%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-control%3Abefore%2C.md-typeset%20.keys%20.key-left-control%3Abefore%2C.md-typeset%20.keys%20.key-right-control%3Abefore%7Bcontent%3A%22%E2%8C%83%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-left-meta%3Abefore%2C.md-typeset%20.keys%20.key-meta%3Abefore%2C.md-typeset%20.keys%20.key-right-meta%3Abefore%7Bcontent%3A%22%E2%97%86%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-left-option%3Abefore%2C.md-typeset%20.keys%20.key-option%3Abefore%2C.md-typeset%20.keys%20.key-right-option%3Abefore%7Bcontent%3A%22%E2%8C%A5%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-left-shift%3Abefore%2C.md-typeset%20.keys%20.key-right-shift%3Abefore%2C.md-typeset%20.keys%20.key-shift%3Abefore%7Bcontent%3A%22%E2%87%A7%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-left-super%3Abefore%2C.md-typeset%20.keys%20.key-right-super%3Abefore%2C.md-typeset%20.keys%20.key-super%3Abefore%7Bcontent%3A%22%E2%9D%96%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-left-windows%3Abefore%2C.md-typeset%20.keys%20.key-right-windows%3Abefore%2C.md-typeset%20.keys%20.key-windows%3Abefore%7Bcontent%3A%22%E2%8A%9E%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-arrow-down%3Abefore%7Bcontent%3A%22%E2%86%93%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-arrow-left%3Abefore%7Bcontent%3A%22%E2%86%90%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-arrow-right%3Abefore%7Bcontent%3A%22%E2%86%92%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-arrow-up%3Abefore%7Bcontent%3A%22%E2%86%91%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-backspace%3Abefore%7Bcontent%3A%22%E2%8C%AB%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-backtab%3Abefore%7Bcontent%3A%22%E2%87%A4%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-caps-lock%3Abefore%7Bcontent%3A%22%E2%87%AA%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-clear%3Abefore%7Bcontent%3A%22%E2%8C%A7%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-context-menu%3Abefore%7Bcontent%3A%22%E2%98%B0%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-delete%3Abefore%7Bcontent%3A%22%E2%8C%A6%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-eject%3Abefore%7Bcontent%3A%22%E2%8F%8F%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-end%3Abefore%7Bcontent%3A%22%E2%A4%93%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-escape%3Abefore%7Bcontent%3A%22%E2%8E%8B%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-home%3Abefore%7Bcontent%3A%22%E2%A4%92%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-insert%3Abefore%7Bcontent%3A%22%E2%8E%80%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-page-down%3Abefore%7Bcontent%3A%22%E2%87%9F%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-page-up%3Abefore%7Bcontent%3A%22%E2%87%9E%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-print-screen%3Abefore%7Bcontent%3A%22%E2%8E%99%22%3Bpadding-right%3A.4em%7D.md-typeset%20.keys%20.key-tab%3Aafter%7Bcontent%3A%22%E2%87%A5%22%3Bpadding-left%3A.4em%7D.md-typeset%20.keys%20.key-num-enter%3Aafter%7Bcontent%3A%22%E2%8C%A4%22%3Bpadding-left%3A.4em%7D.md-typeset%20.keys%20.key-enter%3Aafter%7Bcontent%3A%22%E2%8F%8E%22%3Bpadding-left%3A.4em%7D%3Aroot%7B--md-tabbed-icon--prev%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M15.41%2016.58%2010.83%2012l4.58-4.59L14%206l-6%206%206%206z%22/%3E%3C/svg%3E%27%29%3B--md-tabbed-icon--next%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M8.59%2016.58%2013.17%2012%208.59%207.41%2010%206l6%206-6%206z%22/%3E%3C/svg%3E%27%29%7D.md-typeset%20.tabbed-set%7Bborder-radius%3A.1rem%3Bdisplay%3Aflex%3Bflex-flow%3Acolumn%20wrap%3Bmargin%3A1em%200%3Bposition%3Arelative%7D.md-typeset%20.tabbed-set%3Einput%7Bheight%3A0%3Bopacity%3A0%3Bposition%3Aabsolute%3Bwidth%3A0%7D.md-typeset%20.tabbed-set%3Einput%3Atarget%7B--md-scroll-offset%3A0.625em%7D.md-typeset%20.tabbed-set%3Einput.focus-visible~.tabbed-labels%3Abefore%7Bbackground-color%3Avar%28--md-accent-fg-color%29%7D.md-typeset%20.tabbed-labels%7B-ms-overflow-style%3Anone%3Bbox-shadow%3A0%20-.05rem%20var%28--md-default-fg-color--lightest%29%20inset%3Bdisplay%3Aflex%3Bmax-width%3A100%25%3Boverflow%3Aauto%3Bscrollbar-width%3Anone%7D%40media%20print%7B.md-typeset%20.tabbed-labels%7Bdisplay%3Acontents%7D%7D%40media%20screen%7B.js%20.md-typeset%20.tabbed-labels%7Bposition%3Arelative%7D.js%20.md-typeset%20.tabbed-labels%3Abefore%7Bbackground%3Avar%28--md-default-fg-color%29%3Bbottom%3A0%3Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A2px%3Bleft%3A0%3Bposition%3Aabsolute%3Btransform%3AtranslateX%28var%28--md-indicator-x%29%29%3Btransition%3Awidth%20225ms%2Cbackground-color%20.25s%2Ctransform%20.25s%3Btransition-timing-function%3Acubic-bezier%28.4%2C0%2C.2%2C1%29%3Bwidth%3Avar%28--md-indicator-width%29%7D%7D.md-typeset%20.tabbed-labels%3A%3A-webkit-scrollbar%7Bdisplay%3Anone%7D.md-typeset%20.tabbed-labels%3Elabel%7Bborder-bottom%3A.1rem%20solid%20%230000%3Bborder-radius%3A.1rem%20.1rem%200%200%3Bcolor%3Avar%28--md-default-fg-color--light%29%3Bcursor%3Apointer%3Bflex-shrink%3A0%3Bfont-size%3A.64rem%3Bfont-weight%3A700%3Bpadding%3A.78125em%201.25em%20.625em%3Bscroll-margin-inline-start%3A1rem%3Btransition%3Abackground-color%20.25s%2Ccolor%20.25s%3Bwhite-space%3Anowrap%3Bwidth%3Aauto%7D%40media%20print%7B.md-typeset%20.tabbed-labels%3Elabel%3Afirst-child%7Border%3A1%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%282%29%7Border%3A2%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%283%29%7Border%3A3%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%284%29%7Border%3A4%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%285%29%7Border%3A5%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%286%29%7Border%3A6%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%287%29%7Border%3A7%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%288%29%7Border%3A8%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%289%29%7Border%3A9%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2810%29%7Border%3A10%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2811%29%7Border%3A11%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2812%29%7Border%3A12%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2813%29%7Border%3A13%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2814%29%7Border%3A14%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2815%29%7Border%3A15%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2816%29%7Border%3A16%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2817%29%7Border%3A17%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2818%29%7Border%3A18%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2819%29%7Border%3A19%7D.md-typeset%20.tabbed-labels%3Elabel%3Anth-child%2820%29%7Border%3A20%7D%7D.md-typeset%20.tabbed-labels%3Elabel%3Ahover%7Bcolor%3Avar%28--md-default-fg-color%29%7D.md-typeset%20.tabbed-labels%3Elabel%3E%5Bhref%5D%3Afirst-child%7Bcolor%3Ainherit%7D.md-typeset%20.tabbed-labels--linked%3Elabel%7Bpadding%3A0%7D.md-typeset%20.tabbed-labels--linked%3Elabel%3Ea%7Bdisplay%3Ablock%3Bpadding%3A.78125em%201.25em%20.625em%7D.md-typeset%20.tabbed-content%7Bwidth%3A100%25%7D%40media%20print%7B.md-typeset%20.tabbed-content%7Bdisplay%3Acontents%7D%7D.md-typeset%20.tabbed-block%7Bdisplay%3Anone%7D%40media%20print%7B.md-typeset%20.tabbed-block%7Bdisplay%3Ablock%7D.md-typeset%20.tabbed-block%3Afirst-child%7Border%3A1%7D.md-typeset%20.tabbed-block%3Anth-child%282%29%7Border%3A2%7D.md-typeset%20.tabbed-block%3Anth-child%283%29%7Border%3A3%7D.md-typeset%20.tabbed-block%3Anth-child%284%29%7Border%3A4%7D.md-typeset%20.tabbed-block%3Anth-child%285%29%7Border%3A5%7D.md-typeset%20.tabbed-block%3Anth-child%286%29%7Border%3A6%7D.md-typeset%20.tabbed-block%3Anth-child%287%29%7Border%3A7%7D.md-typeset%20.tabbed-block%3Anth-child%288%29%7Border%3A8%7D.md-typeset%20.tabbed-block%3Anth-child%289%29%7Border%3A9%7D.md-typeset%20.tabbed-block%3Anth-child%2810%29%7Border%3A10%7D.md-typeset%20.tabbed-block%3Anth-child%2811%29%7Border%3A11%7D.md-typeset%20.tabbed-block%3Anth-child%2812%29%7Border%3A12%7D.md-typeset%20.tabbed-block%3Anth-child%2813%29%7Border%3A13%7D.md-typeset%20.tabbed-block%3Anth-child%2814%29%7Border%3A14%7D.md-typeset%20.tabbed-block%3Anth-child%2815%29%7Border%3A15%7D.md-typeset%20.tabbed-block%3Anth-child%2816%29%7Border%3A16%7D.md-typeset%20.tabbed-block%3Anth-child%2817%29%7Border%3A17%7D.md-typeset%20.tabbed-block%3Anth-child%2818%29%7Border%3A18%7D.md-typeset%20.tabbed-block%3Anth-child%2819%29%7Border%3A19%7D.md-typeset%20.tabbed-block%3Anth-child%2820%29%7Border%3A20%7D%7D.md-typeset%20.tabbed-block%3E.highlight%3Afirst-child%3Epre%2C.md-typeset%20.tabbed-block%3Epre%3Afirst-child%7Bmargin%3A0%7D.md-typeset%20.tabbed-block%3E.highlight%3Afirst-child%3Epre%3Ecode%2C.md-typeset%20.tabbed-block%3Epre%3Afirst-child%3Ecode%7Bborder-top-left-radius%3A0%3Bborder-top-right-radius%3A0%7D.md-typeset%20.tabbed-block%3E.highlight%3Afirst-child%3E.filename%7Bborder-top-left-radius%3A0%3Bborder-top-right-radius%3A0%3Bmargin%3A0%7D.md-typeset%20.tabbed-block%3E.highlight%3Afirst-child%3E.highlighttable%7Bmargin%3A0%7D.md-typeset%20.tabbed-block%3E.highlight%3Afirst-child%3E.highlighttable%3Etbody%3Etr%3E.filename%20span.filename%2C.md-typeset%20.tabbed-block%3E.highlight%3Afirst-child%3E.highlighttable%3Etbody%3Etr%3E.linenos%7Bborder-top-left-radius%3A0%3Bborder-top-right-radius%3A0%3Bmargin%3A0%7D.md-typeset%20.tabbed-block%3E.highlight%3Afirst-child%3E.highlighttable%3Etbody%3Etr%3E.code%3Ediv%3Epre%3Ecode%7Bborder-top-left-radius%3A0%3Bborder-top-right-radius%3A0%7D.md-typeset%20.tabbed-block%3E.highlight%3Afirst-child%2B.result%7Bmargin-top%3A-.125em%7D.md-typeset%20.tabbed-block%3E.tabbed-set%7Bmargin%3A0%7D.md-typeset%20.tabbed-button%7Balign-self%3Acenter%3Bborder-radius%3A100%25%3Bcolor%3Avar%28--md-default-fg-color--light%29%3Bcursor%3Apointer%3Bdisplay%3Ablock%3Bheight%3A.9rem%3Bmargin-top%3A.1rem%3Bpointer-events%3Aauto%3Btransition%3Abackground-color%20.25s%3Bwidth%3A.9rem%7D.md-typeset%20.tabbed-button%3Ahover%7Bbackground-color%3Avar%28--md-accent-fg-color--transparent%29%3Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-typeset%20.tabbed-button%3Aafter%7Bbackground-color%3Acurrentcolor%3Bcontent%3A%22%22%3Bdisplay%3Ablock%3Bheight%3A100%25%3B-webkit-mask-image%3Avar%28--md-tabbed-icon--prev%29%3Bmask-image%3Avar%28--md-tabbed-icon--prev%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Btransition%3Abackground-color%20.25s%2Ctransform%20.25s%3Bwidth%3A100%25%7D.md-typeset%20.tabbed-control%7Bbackground%3Alinear-gradient%28to%20right%2Cvar%28--md-default-bg-color%29%2060%25%2C%230000%29%3Bdisplay%3Aflex%3Bheight%3A1.9rem%3Bjustify-content%3Astart%3Bpointer-events%3Anone%3Bposition%3Aabsolute%3Btransition%3Aopacity%20125ms%3Bwidth%3A1.2rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.tabbed-control%7Btransform%3Arotate%28180deg%29%7D.md-typeset%20.tabbed-control%5Bhidden%5D%7Bopacity%3A0%7D.md-typeset%20.tabbed-control--next%7Bbackground%3Alinear-gradient%28to%20left%2Cvar%28--md-default-bg-color%29%2060%25%2C%230000%29%3Bjustify-content%3Aend%3Bright%3A0%7D.md-typeset%20.tabbed-control--next%20.tabbed-button%3Aafter%7B-webkit-mask-image%3Avar%28--md-tabbed-icon--next%29%3Bmask-image%3Avar%28--md-tabbed-icon--next%29%7D%40media%20screen%20and%20%28max-width%3A44.984375em%29%7B%5Bdir%3Dltr%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels%7Bpadding-left%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels%7Bpadding-right%3A.8rem%7D.md-content__inner%3E.tabbed-set%20.tabbed-labels%7Bmargin%3A0%20-.8rem%3Bmax-width%3A100vw%3Bscroll-padding-inline-start%3A.8rem%7D%5Bdir%3Dltr%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels%3Aafter%7Bpadding-right%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels%3Aafter%7Bpadding-left%3A.8rem%7D.md-content__inner%3E.tabbed-set%20.tabbed-labels%3Aafter%7Bcontent%3A%22%22%7D%5Bdir%3Dltr%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--prev%7Bpadding-left%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--prev%7Bpadding-right%3A.8rem%7D%5Bdir%3Dltr%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--prev%7Bmargin-left%3A-.8rem%7D%5Bdir%3Drtl%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--prev%7Bmargin-right%3A-.8rem%7D.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--prev%7Bwidth%3A2rem%7D%5Bdir%3Dltr%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--next%7Bpadding-right%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--next%7Bpadding-left%3A.8rem%7D%5Bdir%3Dltr%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--next%7Bmargin-right%3A-.8rem%7D%5Bdir%3Drtl%5D%20.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--next%7Bmargin-left%3A-.8rem%7D.md-content__inner%3E.tabbed-set%20.tabbed-labels~.tabbed-control--next%7Bwidth%3A2rem%7D%7D%40media%20screen%7B.md-typeset%20.tabbed-set%3Einput%3Afirst-child%3Achecked~.tabbed-labels%3E%3Afirst-child%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2810%29%3Achecked~.tabbed-labels%3E%3Anth-child%2810%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2811%29%3Achecked~.tabbed-labels%3E%3Anth-child%2811%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2812%29%3Achecked~.tabbed-labels%3E%3Anth-child%2812%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2813%29%3Achecked~.tabbed-labels%3E%3Anth-child%2813%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2814%29%3Achecked~.tabbed-labels%3E%3Anth-child%2814%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2815%29%3Achecked~.tabbed-labels%3E%3Anth-child%2815%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2816%29%3Achecked~.tabbed-labels%3E%3Anth-child%2816%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2817%29%3Achecked~.tabbed-labels%3E%3Anth-child%2817%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2818%29%3Achecked~.tabbed-labels%3E%3Anth-child%2818%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2819%29%3Achecked~.tabbed-labels%3E%3Anth-child%2819%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%282%29%3Achecked~.tabbed-labels%3E%3Anth-child%282%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2820%29%3Achecked~.tabbed-labels%3E%3Anth-child%2820%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%283%29%3Achecked~.tabbed-labels%3E%3Anth-child%283%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%284%29%3Achecked~.tabbed-labels%3E%3Anth-child%284%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%285%29%3Achecked~.tabbed-labels%3E%3Anth-child%285%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%286%29%3Achecked~.tabbed-labels%3E%3Anth-child%286%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%287%29%3Achecked~.tabbed-labels%3E%3Anth-child%287%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%288%29%3Achecked~.tabbed-labels%3E%3Anth-child%288%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%289%29%3Achecked~.tabbed-labels%3E%3Anth-child%289%29%7Bcolor%3Avar%28--md-default-fg-color%29%7D.md-typeset%20.no-js%20.tabbed-set%3Einput%3Afirst-child%3Achecked~.tabbed-labels%3E%3Afirst-child%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2810%29%3Achecked~.tabbed-labels%3E%3Anth-child%2810%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2811%29%3Achecked~.tabbed-labels%3E%3Anth-child%2811%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2812%29%3Achecked~.tabbed-labels%3E%3Anth-child%2812%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2813%29%3Achecked~.tabbed-labels%3E%3Anth-child%2813%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2814%29%3Achecked~.tabbed-labels%3E%3Anth-child%2814%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2815%29%3Achecked~.tabbed-labels%3E%3Anth-child%2815%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2816%29%3Achecked~.tabbed-labels%3E%3Anth-child%2816%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2817%29%3Achecked~.tabbed-labels%3E%3Anth-child%2817%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2818%29%3Achecked~.tabbed-labels%3E%3Anth-child%2818%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2819%29%3Achecked~.tabbed-labels%3E%3Anth-child%2819%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%282%29%3Achecked~.tabbed-labels%3E%3Anth-child%282%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%2820%29%3Achecked~.tabbed-labels%3E%3Anth-child%2820%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%283%29%3Achecked~.tabbed-labels%3E%3Anth-child%283%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%284%29%3Achecked~.tabbed-labels%3E%3Anth-child%284%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%285%29%3Achecked~.tabbed-labels%3E%3Anth-child%285%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%286%29%3Achecked~.tabbed-labels%3E%3Anth-child%286%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%287%29%3Achecked~.tabbed-labels%3E%3Anth-child%287%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%288%29%3Achecked~.tabbed-labels%3E%3Anth-child%288%29%2C.md-typeset%20.no-js%20.tabbed-set%3Einput%3Anth-child%289%29%3Achecked~.tabbed-labels%3E%3Anth-child%289%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Afirst-child%3Achecked~.tabbed-labels%3E%3Afirst-child%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2810%29%3Achecked~.tabbed-labels%3E%3Anth-child%2810%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2811%29%3Achecked~.tabbed-labels%3E%3Anth-child%2811%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2812%29%3Achecked~.tabbed-labels%3E%3Anth-child%2812%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2813%29%3Achecked~.tabbed-labels%3E%3Anth-child%2813%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2814%29%3Achecked~.tabbed-labels%3E%3Anth-child%2814%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2815%29%3Achecked~.tabbed-labels%3E%3Anth-child%2815%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2816%29%3Achecked~.tabbed-labels%3E%3Anth-child%2816%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2817%29%3Achecked~.tabbed-labels%3E%3Anth-child%2817%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2818%29%3Achecked~.tabbed-labels%3E%3Anth-child%2818%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2819%29%3Achecked~.tabbed-labels%3E%3Anth-child%2819%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%282%29%3Achecked~.tabbed-labels%3E%3Anth-child%282%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%2820%29%3Achecked~.tabbed-labels%3E%3Anth-child%2820%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%283%29%3Achecked~.tabbed-labels%3E%3Anth-child%283%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%284%29%3Achecked~.tabbed-labels%3E%3Anth-child%284%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%285%29%3Achecked~.tabbed-labels%3E%3Anth-child%285%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%286%29%3Achecked~.tabbed-labels%3E%3Anth-child%286%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%287%29%3Achecked~.tabbed-labels%3E%3Anth-child%287%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%288%29%3Achecked~.tabbed-labels%3E%3Anth-child%288%29%2C.md-typeset%20%5Brole%3Ddialog%5D%20.tabbed-set%3Einput%3Anth-child%289%29%3Achecked~.tabbed-labels%3E%3Anth-child%289%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Afirst-child%3Achecked~.tabbed-labels%3E%3Afirst-child%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2810%29%3Achecked~.tabbed-labels%3E%3Anth-child%2810%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2811%29%3Achecked~.tabbed-labels%3E%3Anth-child%2811%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2812%29%3Achecked~.tabbed-labels%3E%3Anth-child%2812%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2813%29%3Achecked~.tabbed-labels%3E%3Anth-child%2813%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2814%29%3Achecked~.tabbed-labels%3E%3Anth-child%2814%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2815%29%3Achecked~.tabbed-labels%3E%3Anth-child%2815%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2816%29%3Achecked~.tabbed-labels%3E%3Anth-child%2816%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2817%29%3Achecked~.tabbed-labels%3E%3Anth-child%2817%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2818%29%3Achecked~.tabbed-labels%3E%3Anth-child%2818%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2819%29%3Achecked~.tabbed-labels%3E%3Anth-child%2819%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%282%29%3Achecked~.tabbed-labels%3E%3Anth-child%282%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2820%29%3Achecked~.tabbed-labels%3E%3Anth-child%2820%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%283%29%3Achecked~.tabbed-labels%3E%3Anth-child%283%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%284%29%3Achecked~.tabbed-labels%3E%3Anth-child%284%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%285%29%3Achecked~.tabbed-labels%3E%3Anth-child%285%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%286%29%3Achecked~.tabbed-labels%3E%3Anth-child%286%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%287%29%3Achecked~.tabbed-labels%3E%3Anth-child%287%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%288%29%3Achecked~.tabbed-labels%3E%3Anth-child%288%29%2C.no-js%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%289%29%3Achecked~.tabbed-labels%3E%3Anth-child%289%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Afirst-child%3Achecked~.tabbed-labels%3E%3Afirst-child%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2810%29%3Achecked~.tabbed-labels%3E%3Anth-child%2810%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2811%29%3Achecked~.tabbed-labels%3E%3Anth-child%2811%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2812%29%3Achecked~.tabbed-labels%3E%3Anth-child%2812%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2813%29%3Achecked~.tabbed-labels%3E%3Anth-child%2813%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2814%29%3Achecked~.tabbed-labels%3E%3Anth-child%2814%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2815%29%3Achecked~.tabbed-labels%3E%3Anth-child%2815%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2816%29%3Achecked~.tabbed-labels%3E%3Anth-child%2816%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2817%29%3Achecked~.tabbed-labels%3E%3Anth-child%2817%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2818%29%3Achecked~.tabbed-labels%3E%3Anth-child%2818%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2819%29%3Achecked~.tabbed-labels%3E%3Anth-child%2819%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%282%29%3Achecked~.tabbed-labels%3E%3Anth-child%282%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%2820%29%3Achecked~.tabbed-labels%3E%3Anth-child%2820%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%283%29%3Achecked~.tabbed-labels%3E%3Anth-child%283%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%284%29%3Achecked~.tabbed-labels%3E%3Anth-child%284%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%285%29%3Achecked~.tabbed-labels%3E%3Anth-child%285%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%286%29%3Achecked~.tabbed-labels%3E%3Anth-child%286%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%287%29%3Achecked~.tabbed-labels%3E%3Anth-child%287%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%288%29%3Achecked~.tabbed-labels%3E%3Anth-child%288%29%2C%5Brole%3Ddialog%5D%20.md-typeset%20.tabbed-set%3Einput%3Anth-child%289%29%3Achecked~.tabbed-labels%3E%3Anth-child%289%29%7Bborder-color%3Avar%28--md-default-fg-color%29%7D%7D.md-typeset%20.tabbed-set%3Einput%3Afirst-child.focus-visible~.tabbed-labels%3E%3Afirst-child%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2810%29.focus-visible~.tabbed-labels%3E%3Anth-child%2810%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2811%29.focus-visible~.tabbed-labels%3E%3Anth-child%2811%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2812%29.focus-visible~.tabbed-labels%3E%3Anth-child%2812%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2813%29.focus-visible~.tabbed-labels%3E%3Anth-child%2813%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2814%29.focus-visible~.tabbed-labels%3E%3Anth-child%2814%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2815%29.focus-visible~.tabbed-labels%3E%3Anth-child%2815%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2816%29.focus-visible~.tabbed-labels%3E%3Anth-child%2816%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2817%29.focus-visible~.tabbed-labels%3E%3Anth-child%2817%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2818%29.focus-visible~.tabbed-labels%3E%3Anth-child%2818%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2819%29.focus-visible~.tabbed-labels%3E%3Anth-child%2819%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%282%29.focus-visible~.tabbed-labels%3E%3Anth-child%282%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2820%29.focus-visible~.tabbed-labels%3E%3Anth-child%2820%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%283%29.focus-visible~.tabbed-labels%3E%3Anth-child%283%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%284%29.focus-visible~.tabbed-labels%3E%3Anth-child%284%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%285%29.focus-visible~.tabbed-labels%3E%3Anth-child%285%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%286%29.focus-visible~.tabbed-labels%3E%3Anth-child%286%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%287%29.focus-visible~.tabbed-labels%3E%3Anth-child%287%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%288%29.focus-visible~.tabbed-labels%3E%3Anth-child%288%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%289%29.focus-visible~.tabbed-labels%3E%3Anth-child%289%29%7Bcolor%3Avar%28--md-accent-fg-color%29%7D.md-typeset%20.tabbed-set%3Einput%3Afirst-child%3Achecked~.tabbed-content%3E%3Afirst-child%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2810%29%3Achecked~.tabbed-content%3E%3Anth-child%2810%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2811%29%3Achecked~.tabbed-content%3E%3Anth-child%2811%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2812%29%3Achecked~.tabbed-content%3E%3Anth-child%2812%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2813%29%3Achecked~.tabbed-content%3E%3Anth-child%2813%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2814%29%3Achecked~.tabbed-content%3E%3Anth-child%2814%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2815%29%3Achecked~.tabbed-content%3E%3Anth-child%2815%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2816%29%3Achecked~.tabbed-content%3E%3Anth-child%2816%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2817%29%3Achecked~.tabbed-content%3E%3Anth-child%2817%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2818%29%3Achecked~.tabbed-content%3E%3Anth-child%2818%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2819%29%3Achecked~.tabbed-content%3E%3Anth-child%2819%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%282%29%3Achecked~.tabbed-content%3E%3Anth-child%282%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%2820%29%3Achecked~.tabbed-content%3E%3Anth-child%2820%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%283%29%3Achecked~.tabbed-content%3E%3Anth-child%283%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%284%29%3Achecked~.tabbed-content%3E%3Anth-child%284%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%285%29%3Achecked~.tabbed-content%3E%3Anth-child%285%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%286%29%3Achecked~.tabbed-content%3E%3Anth-child%286%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%287%29%3Achecked~.tabbed-content%3E%3Anth-child%287%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%288%29%3Achecked~.tabbed-content%3E%3Anth-child%288%29%2C.md-typeset%20.tabbed-set%3Einput%3Anth-child%289%29%3Achecked~.tabbed-content%3E%3Anth-child%289%29%7Bdisplay%3Ablock%7D%3Aroot%7B--md-tasklist-icon%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M1%2012C1%205.925%205.925%201%2012%201s11%204.925%2011%2011-4.925%2011-11%2011S1%2018.075%201%2012m16.28-2.72a.75.75%200%200%200-.018-1.042.75.75%200%200%200-1.042-.018l-5.97%205.97-2.47-2.47a.75.75%200%200%200-1.042.018.75.75%200%200%200-.018%201.042l3%203a.75.75%200%200%200%201.06%200Z%22/%3E%3C/svg%3E%27%29%3B--md-tasklist-icon--checked%3Aurl%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M1%2012C1%205.925%205.925%201%2012%201s11%204.925%2011%2011-4.925%2011-11%2011S1%2018.075%201%2012m16.28-2.72a.75.75%200%200%200-.018-1.042.75.75%200%200%200-1.042-.018l-5.97%205.97-2.47-2.47a.75.75%200%200%200-1.042.018.75.75%200%200%200-.018%201.042l3%203a.75.75%200%200%200%201.06%200Z%22/%3E%3C/svg%3E%27%29%7D.md-typeset%20.task-list-item%7Blist-style-type%3Anone%3Bposition%3Arelative%7D%5Bdir%3Dltr%5D%20.md-typeset%20.task-list-item%20%5Btype%3Dcheckbox%5D%7Bleft%3A-2em%7D%5Bdir%3Drtl%5D%20.md-typeset%20.task-list-item%20%5Btype%3Dcheckbox%5D%7Bright%3A-2em%7D.md-typeset%20.task-list-item%20%5Btype%3Dcheckbox%5D%7Bposition%3Aabsolute%3Btop%3A.45em%7D.md-typeset%20.task-list-control%20%5Btype%3Dcheckbox%5D%7Bopacity%3A0%3Bz-index%3A-1%7D%5Bdir%3Dltr%5D%20.md-typeset%20.task-list-indicator%3Abefore%7Bleft%3A-1.5em%7D%5Bdir%3Drtl%5D%20.md-typeset%20.task-list-indicator%3Abefore%7Bright%3A-1.5em%7D.md-typeset%20.task-list-indicator%3Abefore%7Bbackground-color%3Avar%28--md-default-fg-color--lightest%29%3Bcontent%3A%22%22%3Bheight%3A1.25em%3B-webkit-mask-image%3Avar%28--md-tasklist-icon%29%3Bmask-image%3Avar%28--md-tasklist-icon%29%3B-webkit-mask-position%3Acenter%3Bmask-position%3Acenter%3B-webkit-mask-repeat%3Ano-repeat%3Bmask-repeat%3Ano-repeat%3B-webkit-mask-size%3Acontain%3Bmask-size%3Acontain%3Bposition%3Aabsolute%3Btop%3A.15em%3Bwidth%3A1.25em%7D.md-typeset%20%5Btype%3Dcheckbox%5D%3Achecked%2B.task-list-indicator%3Abefore%7Bbackground-color%3A%2300e676%3B-webkit-mask-image%3Avar%28--md-tasklist-icon--checked%29%3Bmask-image%3Avar%28--md-tasklist-icon--checked%29%7D%40media%20print%7B.giscus%2C%5Bid%3D__comments%5D%7Bdisplay%3Anone%7D%7D%3Aroot%3E%2A%7B--md-mermaid-font-family%3Avar%28--md-text-font-family%29%2Csans-serif%3B--md-mermaid-edge-color%3Avar%28--md-code-fg-color%29%3B--md-mermaid-node-bg-color%3Avar%28--md-accent-fg-color--transparent%29%3B--md-mermaid-node-fg-color%3Avar%28--md-accent-fg-color%29%3B--md-mermaid-label-bg-color%3Avar%28--md-default-bg-color%29%3B--md-mermaid-label-fg-color%3Avar%28--md-code-fg-color%29%3B--md-mermaid-sequence-actor-bg-color%3Avar%28--md-mermaid-label-bg-color%29%3B--md-mermaid-sequence-actor-fg-color%3Avar%28--md-mermaid-label-fg-color%29%3B--md-mermaid-sequence-actor-border-color%3Avar%28--md-mermaid-node-fg-color%29%3B--md-mermaid-sequence-actor-line-color%3Avar%28--md-default-fg-color--lighter%29%3B--md-mermaid-sequence-actorman-bg-color%3Avar%28--md-mermaid-label-bg-color%29%3B--md-mermaid-sequence-actorman-line-color%3Avar%28--md-mermaid-node-fg-color%29%3B--md-mermaid-sequence-box-bg-color%3Avar%28--md-mermaid-node-bg-color%29%3B--md-mermaid-sequence-box-fg-color%3Avar%28--md-mermaid-edge-color%29%3B--md-mermaid-sequence-label-bg-color%3Avar%28--md-mermaid-node-bg-color%29%3B--md-mermaid-sequence-label-fg-color%3Avar%28--md-mermaid-node-fg-color%29%3B--md-mermaid-sequence-loop-bg-color%3Avar%28--md-mermaid-node-bg-color%29%3B--md-mermaid-sequence-loop-fg-color%3Avar%28--md-mermaid-edge-color%29%3B--md-mermaid-sequence-loop-border-color%3Avar%28--md-mermaid-node-fg-color%29%3B--md-mermaid-sequence-message-fg-color%3Avar%28--md-mermaid-edge-color%29%3B--md-mermaid-sequence-message-line-color%3Avar%28--md-mermaid-edge-color%29%3B--md-mermaid-sequence-note-bg-color%3Avar%28--md-mermaid-label-bg-color%29%3B--md-mermaid-sequence-note-fg-color%3Avar%28--md-mermaid-edge-color%29%3B--md-mermaid-sequence-note-border-color%3Avar%28--md-mermaid-label-fg-color%29%3B--md-mermaid-sequence-number-bg-color%3Avar%28--md-mermaid-node-fg-color%29%3B--md-mermaid-sequence-number-fg-color%3Avar%28--md-accent-bg-color%29%7D.mermaid%7Bline-height%3Anormal%3Bmargin%3A1em%200%7D.md-typeset%20.grid%7Bgrid-gap%3A.4rem%3Bdisplay%3Agrid%3Bgrid-template-columns%3Arepeat%28auto-fit%2Cminmax%28min%28100%25%2C16rem%29%2C1fr%29%29%3Bmargin%3A1em%200%7D.md-typeset%20.grid.cards%3Eol%2C.md-typeset%20.grid.cards%3Eul%7Bdisplay%3Acontents%7D.md-typeset%20.grid.cards%3Eol%3Eli%2C.md-typeset%20.grid.cards%3Eul%3Eli%2C.md-typeset%20.grid%3E.card%7Bborder%3A.05rem%20solid%20var%28--md-default-fg-color--lightest%29%3Bborder-radius%3A.1rem%3Bdisplay%3Ablock%3Bmargin%3A0%3Bpadding%3A.8rem%3Btransition%3Aborder%20.25s%2Cbox-shadow%20.25s%7D.md-typeset%20.grid.cards%3Eol%3Eli%3Afocus-within%2C.md-typeset%20.grid.cards%3Eol%3Eli%3Ahover%2C.md-typeset%20.grid.cards%3Eul%3Eli%3Afocus-within%2C.md-typeset%20.grid.cards%3Eul%3Eli%3Ahover%2C.md-typeset%20.grid%3E.card%3Afocus-within%2C.md-typeset%20.grid%3E.card%3Ahover%7Bborder-color%3A%230000%3Bbox-shadow%3Avar%28--md-shadow-z2%29%7D.md-typeset%20.grid.cards%3Eol%3Eli%3Ehr%2C.md-typeset%20.grid.cards%3Eul%3Eli%3Ehr%2C.md-typeset%20.grid%3E.card%3Ehr%7Bmargin-bottom%3A1em%3Bmargin-top%3A1em%7D.md-typeset%20.grid.cards%3Eol%3Eli%3E%3Afirst-child%2C.md-typeset%20.grid.cards%3Eul%3Eli%3E%3Afirst-child%2C.md-typeset%20.grid%3E.card%3E%3Afirst-child%7Bmargin-top%3A0%7D.md-typeset%20.grid.cards%3Eol%3Eli%3E%3Alast-child%2C.md-typeset%20.grid.cards%3Eul%3Eli%3E%3Alast-child%2C.md-typeset%20.grid%3E.card%3E%3Alast-child%7Bmargin-bottom%3A0%7D.md-typeset%20.grid%3E%2A%2C.md-typeset%20.grid%3E.admonition%2C.md-typeset%20.grid%3E.highlight%3E%2A%2C.md-typeset%20.grid%3E.highlighttable%2C.md-typeset%20.grid%3E.md-typeset%20details%2C.md-typeset%20.grid%3Edetails%2C.md-typeset%20.grid%3Epre%7Bmargin-bottom%3A0%3Bmargin-top%3A0%7D.md-typeset%20.grid%3E.highlight%3Epre%3Aonly-child%2C.md-typeset%20.grid%3E.highlight%3Epre%3Ecode%2C.md-typeset%20.grid%3E.highlighttable%2C.md-typeset%20.grid%3E.highlighttable%3Etbody%2C.md-typeset%20.grid%3E.highlighttable%3Etbody%3Etr%2C.md-typeset%20.grid%3E.highlighttable%3Etbody%3Etr%3E.code%2C.md-typeset%20.grid%3E.highlighttable%3Etbody%3Etr%3E.code%3E.highlight%2C.md-typeset%20.grid%3E.highlighttable%3Etbody%3Etr%3E.code%3E.highlight%3Epre%2C.md-typeset%20.grid%3E.highlighttable%3Etbody%3Etr%3E.code%3E.highlight%3Epre%3Ecode%7Bheight%3A100%25%7D.md-typeset%20.grid%3E.tabbed-set%7Bmargin-bottom%3A0%3Bmargin-top%3A0%7D%40media%20screen%20and%20%28min-width%3A45em%29%7B%5Bdir%3Dltr%5D%20.md-typeset%20.inline%7Bfloat%3Aleft%7D%5Bdir%3Drtl%5D%20.md-typeset%20.inline%7Bfloat%3Aright%7D%5Bdir%3Dltr%5D%20.md-typeset%20.inline%7Bmargin-right%3A.8rem%7D%5Bdir%3Drtl%5D%20.md-typeset%20.inline%7Bmargin-left%3A.8rem%7D.md-typeset%20.inline%7Bmargin-bottom%3A.8rem%3Bmargin-top%3A0%3Bwidth%3A11.7rem%7D%5Bdir%3Dltr%5D%20.md-typeset%20.inline.end%7Bfloat%3Aright%7D%5Bdir%3Drtl%5D%20.md-typeset%20.inline.end%7Bfloat%3Aleft%7D%5Bdir%3Dltr%5D%20.md-typeset%20.inline.end%7Bmargin-left%3A.8rem%3Bmargin-right%3A0%7D%5Bdir%3Drtl%5D%20.md-typeset%20.inline.end%7Bmargin-left%3A0%3Bmargin-right%3A.8rem%7D%7D" rel="stylesheet"/><!--URL:../assets/stylesheets/main.484c7ddc.min.css-->
<link href="data:text/css,%0A/%2A%20%0AThe%20print-site%20banner%0A%2A/%0A%23print-site-banner%20%7B%0A%20%20%20%20border%3A2px%3B%20%0A%20%20%20%20border-style%3Asolid%3B%20%0A%20%20%20%20border-color%3A%23000000%3B%20%0A%20%20%20%20padding%3A%200em%201em%200em%201em%3B%20%0A%20%20%20%20margin-bottom%3A%202em%3B%0A%7D%0A%23print-site-banner%20h3%20%7B%0A%20%20%20%20margin-top%3A%201rem%3B%0A%7D%0A%0A/%2A%20Enumerate%20figures%20%2A/%0A.print-site-enumerate-figures%20figcaption%3Abefore%20%7B%0A%20%20%20%20counter-increment%3A%20figurecounter%3B%0A%20%20%20%20content%3A%20%22Figure%20%22%20counter%28figurecounter%29%20%22%3A%20%22%3B%0A%7D%0A%0A%0A/%2A%20Print%20URLS%3A%20%0AChange%20a%20%27link%27%20to%20%27link%20%28target%29%27%20%2A/%0Adiv.print-site-add-full-url%20section.print-page%20a%5Bhref%5E%3D%22http%22%5D%3A%3Aafter%7B%0A%20%20%20%20content%3A%20%22%20%28%22%20attr%28href%29%20%22%29%20%22%3B%0A%7D%0A%0A%0A/%2A%20Do%20some%20nice%20animations%20when%20clicking%20on%20a%20ToC%20link%20%2A/%0A%23print-site-page%20h1%3Atarget%2C%20%0A%23print-site-page%20h2%3Atarget%2C%20%0A%23print-site-page%20h3%3Atarget%2C%20%0A%23print-site-page%20h4%3Atarget%2C%20%0A%23print-site-page%20h5%3Atarget%2C%20%0A%23print-site-page%20h6%3Atarget%20%7B%0A%20%20%20%20animation%3A%20highlight%201.5s%20ease%3B%0A%7D%0A%23print-site-page%20.print-page%3Atarget%20h1%20%7B%0A%20%20%20%20animation%3A%20highlight%201.5s%20ease%3B%0A%7D%0A%40keyframes%20highlight%20%7B%0A%20%20%20%20from%20%7B%20color%3A%20orange%3B%20%7D%0A%20%20%20%20to%20%7B%20color%3A%20none%3B%20%7D%0A%7D%0A%0A%0A/%2A%20%0APrint%20site%20table%20of%20contents%20styling%0A%20%2A/%0A/%2A%20Don%27t%20display%20the%20table%20of%20contents%20in%20HTML%20version%20%2A/%0A%23print-page-toc%20%7B%20display%3A%20none%20%7D%0A%0A%0A.print-page-toc-nav%20%7B%0A%20%20%20%20padding-bottom%3A%202em%3B%0A%7D%0A%0A%23print-page-toc%20ul%20%7B%0A%20%20%20%20list-style-position%3A%20inside%3B%0A%20%20%20%20list-style-type%3A%20none%3B%0A%7D%0A%0A%23print-site-page%20ul%20%7B%0A%20%20%20%20margin-left%3A%200em%3B%0A%7D%0A%0A/%2A%20Be%20able%20to%20not%20print%20certain%20elements%20%2A/%0A%23print-site-page%20.print-site-plugin-ignore%20%7B%20display%3A%20none%3B%7D%0A%0A%40media%20print%20%7B%20%20%20%20%0A%0A%20%20%20%20/%2A%20included%20bookmarks%20on%20h1%20and%20h2%0A%20%20%20%20Doesn%27t%20work%2C%20but%20included%20In%20case%20Chrome%20gets%20support%20%0A%20%20%20%20for%20these%20experimental%20CSS%20features%20that%20define%20PDF%20bookmarks%20%2A/%0A%20%20%20%20/%2A%20%23print-site-page%20h1%20%7B%0A%20%20%20%20%20%20%20%20bookmark-level%3A%201%3B%0A%20%20%20%20%20%20%20%20bookmark-label%3A%20content%28%29%3B%20%0A%20%20%20%20%20%20%20%20-ah-bookmark-level%3A%201%3B%0A%20%20%20%20%20%20%20%20-ro-pdf-bookmark-level%3A%201%3B%0A%20%20%20%20%7D%0A%20%20%20%20%23print-site-page%20h2%20%7B%0A%20%20%20%20%20%20%20%20bookmark-level%3A%202%3B%0A%20%20%20%20%20%20%20%20bookmark-label%3A%20content%28%29%3B%20%0A%20%20%20%20%20%20%20%20-ah-bookmark-level%3A%202%3B%0A%20%20%20%20%20%20%20%20-ro-pdf-bookmark-level%3A%202%3B%0A%20%20%20%20%7D%20%2A/%0A%0A%20%20%20%20/%2A%20Be%20able%20to%20not%20print%20certain%20elements%20%2A/%0A%20%20%20%20.print-site-plugin-ignore%20%7B%20display%3A%20none%3B%20%7D%0A%0A%20%20%20%20/%2A%20Remove%20print%20site%20banner%20%2A/%0A%20%20%20%20%23print-site-banner%20%7B%20display%3A%20none%3B%20%7D%0A%0A%20%20%20%20/%2A%20display%20the%20table%20of%20contents%20in%20print%20version%20%2A/%0A%20%20%20%20%23print-page-toc%20%7B%20display%3A%20block%20%7D%0A%0A%20%20%20%20/%2A%20PDF%20page%20breaks%20on%20each%20MkDocs%20page%2C%20except%20the%20first%20one%20%2A/%0A%20%20%20%20%23print-site-page%20section.print-page%20%7B%0A%20%20%20%20%20%20%20%20page-break-before%3A%20always%3B%0A%20%20%20%20%7D%0A%20%20%20%20%23print-site-page%20%3E%20section.print-page%3Afirst-of-type%20%7B%0A%20%20%20%20%20%20%20%20page-break-before%3A%20avoid%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20/%2A%20PDF%20page%20breaks%20-%20separate%20title%20page%20for%20each%20section%20%2A/%0A%20%20%20%20%23print-site-page%20section.print-page.md-section%20%3E%20h1%20%7B%0A%20%20%20%20%20%20%20%20align-content%3A%20center%3B%0A%20%20%20%20%20%20%20%20text-align%3A%20center%3B%0A%20%20%20%20%20%20%20%20vertical-align%3A%20middle%3B%0A%20%20%20%20%20%20%20%20padding%3A%205rem%200rem%3B%0A%20%20%20%20%20%20%20%20font-size%3A%202.5em%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%23print-site-page%20p%2C%20%0A%20%20%20%20%23print-site-page%20pre%2C%20%0A%20%20%20%20%23print-site-page%20blockquote%2C%20%0A%20%20%20%20%23print-site-page%20.tabbed-set%20%7B%0A%20%20%20%20%20%20%20%20page-break-inside%3A%20avoid%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20/%2A%20Avoid%20a%20page%20break%20immediately%20after%20a%20heading%20%2A/%0A%20%20%20%20/%2A%20Credits%20https%3A//stackoverflow.com/a/9238898/5525118%20%2A/%0A%20%20%20%20%23print-site-page%20h1%20%7B%0A%20%20%20%20%20%20%20%20page-break-inside%3A%20avoid%3B%0A%20%20%20%20%7D%0A%20%20%20%20%23print-site-page%20h1%3A%3Aafter%20%7B%0A%20%20%20%20%20%20%20%20content%3A%20%22%22%3B%0A%20%20%20%20%20%20%20%20/%2A%20display%3A%20block%3B%20%2A/%0A%20%20%20%20%20%20%20%20height%3A%20100px%3B%0A%20%20%20%20%20%20%20%20margin-bottom%3A%20-100px%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%23print-site-page%20footer%20%7B%20display%20%3A%20none%3B%20%7D%0A%20%20%20%20%0A%20%20%20%20%23print-site-cover-page%20%7B%0A%20%20%20%20%20%20%20%20display%3A%20block%3B%0A%20%20%20%20%20%20%20%20width%3A100%25%3B%20%0A%20%20%20%20%20%20%20%20text-align%3A%20center%3B%0A%20%20%20%20%7D%0A%20%20%20%20%23print-site-cover-page%20h1%20%7B%0A%20%20%20%20%20%20%20%20font-size%3A%20300%25%3B%0A%20%20%20%20%7D%0A%7D%0A" rel="stylesheet"/><!--URL:../css/print-site.css-->
<link href="data:text/css,/%2A%20print%20styles%20for%20mkdocs%20material%20theme%20%0Ahttps%3A//github.com/squidfunk/mkdocs-material%20%2A/%0A%0A%0A/%2A%20Table%20of%20Contents%20styling%20%2A/%0A%23print-site-page%20ul.toc-section-line-border%20%7B%20%0A%20%20%20%20border-left%3A%205px%20solid%20var%28--md-default-fg-color--lightest%29%3B%0A%7D%0A%0A%0A/%2A%20Box%20shadows%20don%27t%20do%20well%20in%20PDFs%20%2A/%0A%23print-site-page%20table%20%7B%0A%20%20%20%20border%3A%201px%20solid%20hsla%28200%2C%2018%25%2C%2026%25%2C%201%29%3B%20/%2A%20%23EFEFEF%20%2A/%0A%20%20%20%20box-shadow%3A%20none%20%21important%3B%0A%7D%0A%0A%40media%20print%20%7B%0A%20%20%20%20%23print-site-page%20td%20%7B%0A%20%20%20%20%20%20%20%20word-wrap%3A%20break-word%3B%0A%20%20%20%20%7D%0A%0A%7D%0A%0A%40page%20%7B%0A%0A%20%20%20%20size%3A%20A4%20portrait%3B%0A%20%20%20%20margin%3A%204em%201.5em%204em%201.5em%3B%0A%20%20%20%20padding%3A%200em%200em%200em%200em%3B%0A%20%20%20%20counter-increment%3A%20page%3B%0A%0A%20%20%20%20%40bottom-center%20%7B%0A%20%20%20%20%20%20%20%20content%3A%20string%28chapter%29%3B%0A%20%20%20%20%7D%0A%20%20%20%20%40bottom-right%20%7B%0A%20%20%20%20%20%20%20%20content%3A%20%27Page%20%27%20counter%28page%29%3B%0A%20%20%20%20%7D%0A%0A%7D" rel="stylesheet"/><!--URL:../css/print-site-material.css-->
<link href="data:text/css,%0A/%2A%20Avoid%20breaking%20parameter%20names%2C%20etc.%20in%20table%20cells.%20%2A/%0A.doc-contents%20td%20code%20%7B%0A%20%20word-break%3A%20normal%20%21important%3B%0A%7D%0A%0A/%2A%20No%20line%20break%20before%20first%20paragraph%20of%20descriptions.%20%2A/%0A.doc-md-description%2C%0A.doc-md-description%3Ep%3Afirst-child%20%7B%0A%20%20display%3A%20inline%3B%0A%7D%0A%0A/%2A%20No%20text%20transformation%20from%20Material%20for%20MkDocs%20for%20H5%20headings.%20%2A/%0A.md-typeset%20h5%20.doc-object-name%20%7B%0A%20%20text-transform%3A%20none%3B%0A%7D%0A%0A/%2A%20Max%20width%20for%20docstring%20sections%20tables.%20%2A/%0A.doc%20.md-typeset__table%2C%0A.doc%20.md-typeset__table%20table%20%7B%0A%20%20display%3A%20table%20%21important%3B%0A%20%20width%3A%20100%25%3B%0A%7D%0A%0A.doc%20.md-typeset__table%20tr%20%7B%0A%20%20display%3A%20table-row%3B%0A%7D%0A%0A/%2A%20Defaults%20in%20Spacy%20table%20style.%20%2A/%0A.doc-param-default%2C%0A.doc-type_param-default%20%7B%0A%20%20float%3A%20right%3B%0A%7D%0A%0A/%2A%20Parameter%20headings%20must%20be%20inline%2C%20not%20blocks.%20%2A/%0A.doc-heading-parameter%2C%0A.doc-heading-type_parameter%20%7B%0A%20%20display%3A%20inline%3B%0A%7D%0A%0A/%2A%20Default%20font%20size%20for%20parameter%20headings.%20%2A/%0A.md-typeset%20.doc-heading-parameter%20%7B%0A%20%20font-size%3A%20inherit%3B%0A%7D%0A%0A/%2A%20Prefer%20space%20on%20the%20right%2C%20not%20the%20left%20of%20parameter%20permalinks.%20%2A/%0A.doc-heading-parameter%20.headerlink%2C%0A.doc-heading-type_parameter%20.headerlink%20%7B%0A%20%20margin-left%3A%200%20%21important%3B%0A%20%20margin-right%3A%200.2rem%3B%0A%7D%0A%0A/%2A%20Backward-compatibility%3A%20docstring%20section%20titles%20in%20bold.%20%2A/%0A.doc-section-title%20%7B%0A%20%20font-weight%3A%20bold%3B%0A%7D%0A%0A/%2A%20Backlinks%20crumb%20separator.%20%2A/%0A.doc-backlink-crumb%20%7B%0A%20%20display%3A%20inline-flex%3B%0A%20%20gap%3A%20.2rem%3B%0A%20%20white-space%3A%20nowrap%3B%0A%20%20align-items%3A%20center%3B%0A%20%20vertical-align%3A%20middle%3B%0A%7D%0A.doc-backlink-crumb%3Anot%28%3Afirst-child%29%3A%3Abefore%20%7B%0A%20%20background-color%3A%20var%28--md-default-fg-color--lighter%29%3B%0A%20%20content%3A%20%22%22%3B%0A%20%20display%3A%20inline%3B%0A%20%20height%3A%201rem%3B%0A%20%20--md-path-icon%3A%20url%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M8.59%2016.58%2013.17%2012%208.59%207.41%2010%206l6%206-6%206z%22/%3E%3C/svg%3E%27%29%3B%0A%20%20-webkit-mask-image%3A%20var%28--md-path-icon%29%3B%0A%20%20mask-image%3A%20var%28--md-path-icon%29%3B%0A%20%20width%3A%201rem%3B%0A%7D%0A.doc-backlink-crumb.last%20%7B%0A%20%20font-weight%3A%20bold%3B%0A%7D%0A%0A/%2A%20Symbols%20in%20Navigation%20and%20ToC.%20%2A/%0A%3Aroot%2C%20%3Ahost%2C%0A%5Bdata-md-color-scheme%3D%22default%22%5D%20%7B%0A%20%20--doc-symbol-parameter-fg-color%3A%20%23df50af%3B%0A%20%20--doc-symbol-type_parameter-fg-color%3A%20%23df50af%3B%0A%20%20--doc-symbol-attribute-fg-color%3A%20%23953800%3B%0A%20%20--doc-symbol-function-fg-color%3A%20%238250df%3B%0A%20%20--doc-symbol-method-fg-color%3A%20%238250df%3B%0A%20%20--doc-symbol-class-fg-color%3A%20%230550ae%3B%0A%20%20--doc-symbol-type_alias-fg-color%3A%20%230550ae%3B%0A%20%20--doc-symbol-module-fg-color%3A%20%235cad0f%3B%0A%0A%20%20--doc-symbol-parameter-bg-color%3A%20%23df50af1a%3B%0A%20%20--doc-symbol-type_parameter-bg-color%3A%20%23df50af1a%3B%0A%20%20--doc-symbol-attribute-bg-color%3A%20%239538001a%3B%0A%20%20--doc-symbol-function-bg-color%3A%20%238250df1a%3B%0A%20%20--doc-symbol-method-bg-color%3A%20%238250df1a%3B%0A%20%20--doc-symbol-class-bg-color%3A%20%230550ae1a%3B%0A%20%20--doc-symbol-type_alias-bg-color%3A%20%230550ae1a%3B%0A%20%20--doc-symbol-module-bg-color%3A%20%235cad0f1a%3B%0A%7D%0A%0A%5Bdata-md-color-scheme%3D%22slate%22%5D%20%7B%0A%20%20--doc-symbol-parameter-fg-color%3A%20%23ffa8cc%3B%0A%20%20--doc-symbol-type_parameter-fg-color%3A%20%23ffa8cc%3B%0A%20%20--doc-symbol-attribute-fg-color%3A%20%23ffa657%3B%0A%20%20--doc-symbol-function-fg-color%3A%20%23d2a8ff%3B%0A%20%20--doc-symbol-method-fg-color%3A%20%23d2a8ff%3B%0A%20%20--doc-symbol-class-fg-color%3A%20%2379c0ff%3B%0A%20%20--doc-symbol-type_alias-fg-color%3A%20%2379c0ff%3B%0A%20%20--doc-symbol-module-fg-color%3A%20%23baff79%3B%0A%0A%20%20--doc-symbol-parameter-bg-color%3A%20%23ffa8cc1a%3B%0A%20%20--doc-symbol-type_parameter-bg-color%3A%20%23ffa8cc1a%3B%0A%20%20--doc-symbol-attribute-bg-color%3A%20%23ffa6571a%3B%0A%20%20--doc-symbol-function-bg-color%3A%20%23d2a8ff1a%3B%0A%20%20--doc-symbol-method-bg-color%3A%20%23d2a8ff1a%3B%0A%20%20--doc-symbol-class-bg-color%3A%20%2379c0ff1a%3B%0A%20%20--doc-symbol-type_alias-bg-color%3A%20%2379c0ff1a%3B%0A%20%20--doc-symbol-module-bg-color%3A%20%23baff791a%3B%0A%7D%0A%0Acode.doc-symbol%20%7B%0A%20%20border-radius%3A%20.1rem%3B%0A%20%20font-size%3A%20.85em%3B%0A%20%20padding%3A%200%20.3em%3B%0A%20%20font-weight%3A%20bold%3B%0A%7D%0A%0Acode.doc-symbol-parameter%2C%0Aa%20code.doc-symbol-parameter%20%7B%0A%20%20color%3A%20var%28--doc-symbol-parameter-fg-color%29%3B%0A%20%20background-color%3A%20var%28--doc-symbol-parameter-bg-color%29%3B%0A%7D%0A%0Acode.doc-symbol-parameter%3A%3Aafter%20%7B%0A%20%20content%3A%20%22param%22%3B%0A%7D%0A%0Acode.doc-symbol-type_parameter%2C%0Aa%20code.doc-symbol-type_parameter%20%7B%0A%20%20color%3A%20var%28--doc-symbol-type_parameter-fg-color%29%3B%0A%20%20background-color%3A%20var%28--doc-symbol-type_parameter-bg-color%29%3B%0A%7D%0A%0Acode.doc-symbol-type_parameter%3A%3Aafter%20%7B%0A%20%20content%3A%20%22type-param%22%3B%0A%7D%0A%0Acode.doc-symbol-attribute%2C%0Aa%20code.doc-symbol-attribute%20%7B%0A%20%20color%3A%20var%28--doc-symbol-attribute-fg-color%29%3B%0A%20%20background-color%3A%20var%28--doc-symbol-attribute-bg-color%29%3B%0A%7D%0A%0Acode.doc-symbol-attribute%3A%3Aafter%20%7B%0A%20%20content%3A%20%22attr%22%3B%0A%7D%0A%0Acode.doc-symbol-function%2C%0Aa%20code.doc-symbol-function%20%7B%0A%20%20color%3A%20var%28--doc-symbol-function-fg-color%29%3B%0A%20%20background-color%3A%20var%28--doc-symbol-function-bg-color%29%3B%0A%7D%0A%0Acode.doc-symbol-function%3A%3Aafter%20%7B%0A%20%20content%3A%20%22func%22%3B%0A%7D%0A%0Acode.doc-symbol-method%2C%0Aa%20code.doc-symbol-method%20%7B%0A%20%20color%3A%20var%28--doc-symbol-method-fg-color%29%3B%0A%20%20background-color%3A%20var%28--doc-symbol-method-bg-color%29%3B%0A%7D%0A%0Acode.doc-symbol-method%3A%3Aafter%20%7B%0A%20%20content%3A%20%22meth%22%3B%0A%7D%0A%0Acode.doc-symbol-class%2C%0Aa%20code.doc-symbol-class%20%7B%0A%20%20color%3A%20var%28--doc-symbol-class-fg-color%29%3B%0A%20%20background-color%3A%20var%28--doc-symbol-class-bg-color%29%3B%0A%7D%0A%0Acode.doc-symbol-class%3A%3Aafter%20%7B%0A%20%20content%3A%20%22class%22%3B%0A%7D%0A%0A%0Acode.doc-symbol-type_alias%2C%0Aa%20code.doc-symbol-type_alias%20%7B%0A%20%20color%3A%20var%28--doc-symbol-type_alias-fg-color%29%3B%0A%20%20background-color%3A%20var%28--doc-symbol-type_alias-bg-color%29%3B%0A%7D%0A%0Acode.doc-symbol-type_alias%3A%3Aafter%20%7B%0A%20%20content%3A%20%22type%22%3B%0A%7D%0A%0Acode.doc-symbol-module%2C%0Aa%20code.doc-symbol-module%20%7B%0A%20%20color%3A%20var%28--doc-symbol-module-fg-color%29%3B%0A%20%20background-color%3A%20var%28--doc-symbol-module-bg-color%29%3B%0A%7D%0A%0Acode.doc-symbol-module%3A%3Aafter%20%7B%0A%20%20content%3A%20%22mod%22%3B%0A%7D%0A%0A.doc-signature%20.autorefs%20%7B%0A%20%20color%3A%20inherit%3B%0A%20%20border-bottom%3A%201px%20dotted%20currentcolor%3B%0A%7D%0A%0A/%2A%20Source%20code%20blocks%20%28admonitions%29.%20%2A/%0A%3Aroot%20%7B%0A%20%20--md-admonition-icon--mkdocstrings-source%3A%20url%28%27data%3Aimage/svg%2Bxml%3Bcharset%3Dutf-8%2C%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M15.22%204.97a.75.75%200%200%201%201.06%200l6.5%206.5a.75.75%200%200%201%200%201.06l-6.5%206.5a.749.749%200%200%201-1.275-.326.75.75%200%200%201%20.215-.734L21.19%2012l-5.97-5.97a.75.75%200%200%201%200-1.06m-6.44%200a.75.75%200%200%201%200%201.06L2.81%2012l5.97%205.97a.749.749%200%200%201-.326%201.275.75.75%200%200%201-.734-.215l-6.5-6.5a.75.75%200%200%201%200-1.06l6.5-6.5a.75.75%200%200%201%201.06%200%22/%3E%3C/svg%3E%27%29%0A%7D%0A.md-typeset%20.admonition.mkdocstrings-source%2C%0A.md-typeset%20details.mkdocstrings-source%20%7B%0A%20%20border%3A%20none%3B%0A%20%20padding%3A%200%3B%0A%7D%0A.md-typeset%20.admonition.mkdocstrings-source%3Afocus-within%2C%0A.md-typeset%20details.mkdocstrings-source%3Afocus-within%20%7B%0A%20%20box-shadow%3A%20none%3B%0A%7D%0A.md-typeset%20.mkdocstrings-source%20%3E%20.admonition-title%2C%0A.md-typeset%20.mkdocstrings-source%20%3E%20summary%20%7B%0A%20%20background-color%3A%20inherit%3B%0A%7D%0A.md-typeset%20.mkdocstrings-source%20%3E%20.admonition-title%3A%3Abefore%2C%0A.md-typeset%20.mkdocstrings-source%20%3E%20summary%3A%3Abefore%20%7B%0A%20%20background-color%3A%20var%28--md-default-fg-color%29%3B%0A%20%20-webkit-mask-image%3A%20var%28--md-admonition-icon--mkdocstrings-source%29%3B%0A%20%20%20%20%20%20%20%20%20%20mask-image%3A%20var%28--md-admonition-icon--mkdocstrings-source%29%3B%0A%7D%0A" rel="stylesheet"/><!--URL:../assets/_mkdocstrings.css-->
<link href="data:text/css,.md-typeset%20.arithmatex%20%7B%0A%20%20overflow-x%3A%20auto%3B%0A%7D%0A%0A.md-typeset%20.doc-contents%20%7B%0A%20%20overflow-wrap%3A%20anywhere%3B%0A%7D%0A%0A.md-typeset%20h1%20code%2C%0A.md-typeset%20h2%20code%2C%0A.md-typeset%20h3%20code%20%7B%0A%20%20word-break%3A%20break-word%3B%0A%7D%0A" rel="stylesheet"/><!--URL:../stylesheets/extra.css-->
<script>__md_scope=new URL("/docs/meanas/",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {
remove_material_navigation();remove_mkdocs_theme_navigation();generate_toc();
})
</script>
</head>
<body dir="ltr">
<input autocomplete="off" class="md-toggle" data-md-toggle="drawer" id="__drawer" type="checkbox"/>
<input autocomplete="off" class="md-toggle" data-md-toggle="search" id="__search" type="checkbox"/>
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a class="md-skip" href="#index">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav aria-label="Header" class="md-header__inner md-grid">
<a aria-label="meanas" class="md-header__button md-logo" data-md-component="logo" href=".." title="meanas">
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"></path></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"></path></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
meanas
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Print Site
</span>
</div>
</div>
</div>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"></path></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input aria-label="Search" autocapitalize="off" autocomplete="off" autocorrect="off" class="md-search__input" data-md-component="search-query" name="query" placeholder="Search" required="" spellcheck="false" type="text"/>
<label class="md-search__icon md-icon" for="__search">
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"></path></svg>
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"></path></svg>
</label>
<nav aria-label="Search" class="md-search__options">
<button aria-label="Clear" class="md-search__icon md-icon" tabindex="-1" title="Clear" type="reset">
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix="" tabindex="0">
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a class="md-source" data-md-component="source" href="https://mpxd.net/code/jan/meanas" title="Go to repository">
<div class="md-source__icon md-icon">
<svg viewbox="0 0 448 512" xmlns="http://www.w3.org/2000/svg"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"></path></svg>
</div>
<div class="md-source__repository">
meanas
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav aria-label="Navigation" class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a aria-label="meanas" class="md-nav__button md-logo" data-md-component="logo" href=".." title="meanas">
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"></path></svg>
</a>
meanas
</label>
<div class="md-nav__source">
<a class="md-source" data-md-component="source" href="https://mpxd.net/code/jan/meanas" title="Go to repository">
<div class="md-source__icon md-icon">
<svg viewbox="0 0 448 512" xmlns="http://www.w3.org/2000/svg"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"></path></svg>
</div>
<div class="md-source__repository">
meanas
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix="">
<li class="md-nav__item">
<a class="md-nav__link" href="..">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle" id="__nav_2" type="checkbox"/>
<div class="md-nav__link md-nav__container">
<a class="md-nav__link" href="../api/">
<span class="md-ellipsis">
API
</span>
</a>
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav aria-expanded="false" aria-labelledby="__nav_2_label" class="md-nav" data-md-level="1">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
API
</label>
<ul class="md-nav__list" data-md-scrollfix="">
<li class="md-nav__item">
<a class="md-nav__link" href="../api/meanas/">
<span class="md-ellipsis">
meanas
</span>
</a>
</li>
<li class="md-nav__item">
<a class="md-nav__link" href="../api/eigensolvers/">
<span class="md-ellipsis">
eigensolvers
</span>
</a>
</li>
<li class="md-nav__item">
<a class="md-nav__link" href="../api/fdfd/">
<span class="md-ellipsis">
fdfd
</span>
</a>
</li>
<li class="md-nav__item">
<a class="md-nav__link" href="../api/waveguides/">
<span class="md-ellipsis">
waveguides
</span>
</a>
</li>
<li class="md-nav__item">
<a class="md-nav__link" href="../api/fdtd/">
<span class="md-ellipsis">
fdtd
</span>
</a>
</li>
<li class="md-nav__item">
<a class="md-nav__link" href="../api/fdmath/">
<span class="md-ellipsis">
fdmath
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav aria-label="Table of contents" class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix="">
<li class="md-nav__item">
<a class="md-nav__link" href="#index">
<span class="md-ellipsis">
1 Home
</span>
</a>
</li>
<li class="md-nav__item">
<a class="md-nav__link" href="#section-2">
<span class="md-ellipsis">
2 API
</span>
</a>
<nav aria-label="2 API" class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a class="md-nav__link" href="#api">
<span class="md-ellipsis">
2.1 Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a class="md-nav__link" href="#api-meanas">
<span class="md-ellipsis">
2.2 meanas
</span>
</a>
</li>
<li class="md-nav__item">
<a class="md-nav__link" href="#api-eigensolvers">
<span class="md-ellipsis">
2.3 eigensolvers
</span>
</a>
</li>
<li class="md-nav__item">
<a class="md-nav__link" href="#api-fdfd">
<span class="md-ellipsis">
2.4 fdfd
</span>
</a>
</li>
<li class="md-nav__item">
<a class="md-nav__link" href="#api-waveguides">
<span class="md-ellipsis">
2.5 waveguides
</span>
</a>
</li>
<li class="md-nav__item">
<a class="md-nav__link" href="#api-fdtd">
<span class="md-ellipsis">
2.6 fdtd
</span>
</a>
</li>
<li class="md-nav__item">
<a class="md-nav__link" href="#api-fdmath">
<span class="md-ellipsis">
2.7 fdmath
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<div class="print-site-enumerate-headings print-site-enumerate-figures" id="print-site-page">
<section class="print-page">
<div data-toc-depth="3" id="print-page-toc">
<nav class="print-page-toc-nav" role="navigation">
<h1 class="print-page-toc-title">Table of Contents</h1>
</nav>
</div>
</section>
<section class="print-page" heading-number="1" id="index"><h1 id="index-meanas">meanas<a class="headerlink" href="#index-meanas" title="Permanent link"></a></h1>
<p><code>meanas</code> is a Python package for finite-difference electromagnetic simulation.
It combines:</p>
<ul>
<li><code>meanas.fdfd</code> for frequency-domain operators, sources, waveguide modes, and SCPML</li>
<li><code>meanas.fdtd</code> for Yee-grid timestepping, CPML, energy/flux accounting, and phasor extraction</li>
<li><code>meanas.fdmath</code> for the shared discrete operators and derivations underneath both solvers</li>
</ul>
<p>This documentation is built directly from the package docstrings. The API pages
are the source of truth for the mathematical derivations and calling
conventions.</p>
<h2 id="index-recommended-starting-points">Recommended starting points<a class="headerlink" href="#index-recommended-starting-points" title="Permanent link"></a></h2>
<ul>
<li>Use the <a href="#api-fdtd">FDTD API</a> when you need time-domain stepping, CPML, or
phasor extraction.</li>
<li>Use the <a href="#api-fdfd">FDFD API</a> when you need driven frequency-domain solves
or operator algebra.</li>
<li>Use the <a href="#api-waveguides">Waveguide API</a> for mode solving, port sources, and
overlap windows.</li>
<li>Use the <a href="#api-fdmath">fdmath API</a> when you need the lower-level finite-difference
operators or the derivation background shared across the package.</li>
</ul>
<h2 id="index-build-outputs">Build outputs<a class="headerlink" href="#index-build-outputs" title="Permanent link"></a></h2>
<p>The docs build generates two HTML views from the same source:</p>
<ul>
<li>a normal multi-page site</li>
<li>a print-oriented combined page under <code>site/print_page/</code></li>
</ul>
<p>If <code>htmlark</code> is installed, <code>./make_docs.sh</code> also writes a fully inlined
<code>site/standalone.html</code>.</p></section>
<section class="print-page md-section" heading-number="2" id="section-2">
<h1>API<a class="headerlink" href="#section-2" title="Permanent link"></a>
</h1>
<section class="print-page" heading-number="2.1" id="api"><h1 id="api-api-overview">API Overview<a class="headerlink" href="#api-api-overview" title="Permanent link"></a></h1>
<p>The package is documented directly from its docstrings. The most useful entry
points are:</p>
<ul>
<li><a href="#api-meanas">meanas</a>: top-level package overview</li>
<li><a href="#api-eigensolvers">eigensolvers</a>: generic eigenvalue utilities used by the mode solvers</li>
<li><a href="#api-fdfd">fdfd</a>: frequency-domain operators, sources, PML, solvers, and far-field transforms</li>
<li><a href="#api-waveguides">waveguides</a>: straight, cylindrical, and 3D waveguide mode helpers</li>
<li><a href="#api-fdtd">fdtd</a>: timestepping, CPML, energy/flux helpers, and phasor extraction</li>
<li><a href="#api-fdmath">fdmath</a>: shared discrete operators, vectorization helpers, and derivation background</li>
</ul>
<p>The waveguide and FDTD pages are the best places to start if you want the
mathematical derivations rather than just the callable reference.</p></section><section class="print-page" heading-number="2.2" id="api-meanas"><h1 id="api-meanas-meanas_1">meanas<a class="headerlink" href="#api-meanas-meanas_1" title="Permanent link"></a></h1>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-meanas-meanas">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas</span>
<a class="headerlink" href="#api-meanas-meanas" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Electromagnetic simulation tools</p>
<p>See the readme or <code>import meanas; help(meanas)</code> for more info.</p>
<div class="doc doc-children">
</div>
</div>
</div></section><section class="print-page" heading-number="2.3" id="api-eigensolvers"><h1 id="api-eigensolvers-eigensolvers">eigensolvers<a class="headerlink" href="#api-eigensolvers-eigensolvers" title="Permanent link"></a></h1>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-eigensolvers-meanas.eigensolvers">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.eigensolvers</span>
<a class="headerlink" href="#api-eigensolvers-meanas.eigensolvers" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Solvers for eigenvalue / eigenvector problems</p>
<div class="doc doc-children">
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-eigensolvers-meanas.eigensolvers.power_iteration">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">power_iteration</span>
<a class="headerlink" href="#api-eigensolvers-meanas.eigensolvers.power_iteration" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-eigensolvers-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">power_iteration</span><span class="p">(</span>
<a href="#api-eigensolvers-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">operator</span><span class="p">:</span> <span class="n">spmatrix</span><span class="p">,</span>
<a href="#api-eigensolvers-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">guess_vector</span><span class="p">:</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complex128</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-eigensolvers-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">iterations</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">20</span><span class="p">,</span>
<a href="#api-eigensolvers-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span><span class="nb">complex</span><span class="p">,</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">]]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Use power iteration to estimate the dominant eigenvector of a matrix.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>operator</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.spmatrix" title="scipy.sparse.spmatrix">spmatrix</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Matrix to analyze.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>guess_vector</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>] | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Starting point for the eigenvector. Default is a randomly chosen vector.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>iterations</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Number of iterations to perform. Default 20.</p>
</div>
</td>
<td>
<code>20</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#complex">complex</a>, <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]]</code>
</td>
<td>
<div class="doc-md-description">
<p>(Largest-magnitude eigenvalue, Corresponding eigenvector estimate)</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-eigensolvers-meanas.eigensolvers.rayleigh_quotient_iteration">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">rayleigh_quotient_iteration</span>
<a class="headerlink" href="#api-eigensolvers-meanas.eigensolvers.rayleigh_quotient_iteration" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-eigensolvers-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">rayleigh_quotient_iteration</span><span class="p">(</span>
<a href="#api-eigensolvers-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">operator</span><span class="p">:</span> <span class="n">spmatrix</span> <span class="o">|</span> <span class="n">LinearOperator</span><span class="p">,</span>
<a href="#api-eigensolvers-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">guess_vector</span><span class="p">:</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complex128</span><span class="p">],</span>
<a href="#api-eigensolvers-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">iterations</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">40</span><span class="p">,</span>
<a href="#api-eigensolvers-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">tolerance</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">1e-13</span><span class="p">,</span>
<a href="#api-eigensolvers-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">solver</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complex128</span><span class="p">]]</span>
<a href="#api-eigensolvers-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-eigensolvers-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span><span class="nb">complex</span><span class="p">,</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">]]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Use Rayleigh quotient iteration to refine an eigenvector guess.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>operator</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.spmatrix" title="scipy.sparse.spmatrix">spmatrix</a> | <a class="autorefs autorefs-internal" href="#scipy.sparse.linalg.LinearOperator" title="scipy.sparse.linalg.LinearOperator">LinearOperator</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Matrix to analyze.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>guess_vector</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Eigenvector to refine.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>iterations</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Maximum number of iterations to perform. Default 40.</p>
</div>
</td>
<td>
<code>40</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>tolerance</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Stop iteration if <code>(A - I*eigenvalue) @ v &lt; num_vectors * tolerance</code>,
Default 1e-13.</p>
</div>
</td>
<td>
<code>1e-13</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>solver</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[..., <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]] | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Solver function of the form <code>x = solver(A, b)</code>.
By default, use scipy.sparse.spsolve for sparse matrices and
scipy.sparse.bicgstab for general LinearOperator instances.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#complex">complex</a>, <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]]</code>
</td>
<td>
<div class="doc-md-description">
<p>(eigenvalues, eigenvectors)</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-eigensolvers-meanas.eigensolvers.signed_eigensolve">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">signed_eigensolve</span>
<a class="headerlink" href="#api-eigensolvers-meanas.eigensolvers.signed_eigensolve" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-eigensolvers-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">signed_eigensolve</span><span class="p">(</span>
<a href="#api-eigensolvers-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">operator</span><span class="p">:</span> <span class="n">spmatrix</span> <span class="o">|</span> <span class="n">LinearOperator</span><span class="p">,</span>
<a href="#api-eigensolvers-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">how_many</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-eigensolvers-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">negative</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
<a href="#api-eigensolvers-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span>
<a href="#api-eigensolvers-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">],</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">]</span>
<a href="#api-eigensolvers-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Find the largest-magnitude positive-only (or negative-only) eigenvalues and
eigenvectors of the provided matrix.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>operator</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.spmatrix" title="scipy.sparse.spmatrix">spmatrix</a> | <a class="autorefs autorefs-internal" href="#scipy.sparse.linalg.LinearOperator" title="scipy.sparse.linalg.LinearOperator">LinearOperator</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Matrix to analyze.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>how_many</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>How many eigenvalues to find.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>negative</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#bool">bool</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Whether to find negative-only eigenvalues.
Default False (positive only).</p>
</div>
</td>
<td>
<code>False</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>(sorted list of eigenvalues, 2D ndarray of corresponding eigenvectors)</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p><code>eigenvectors[:, k]</code> corresponds to the k-th eigenvalue</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div></section><section class="print-page" heading-number="2.4" id="api-fdfd"><h1 id="api-fdfd-fdfd">fdfd<a class="headerlink" href="#api-fdfd-fdfd" title="Permanent link"></a></h1>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-fdfd-meanas.fdfd">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Tools for finite difference frequency-domain (FDFD) simulations and calculations.</p>
<p>These mostly involve picking a single frequency, then setting up and solving a
matrix equation (Ax=b) or eigenvalue problem.</p>
<p>Submodules:</p>
<ul>
<li><code>operators</code>, <code>functional</code>: General FDFD problem setup.</li>
<li><code>solvers</code>: Solver interface and reference implementation.</li>
<li><code>scpml</code>: Stretched-coordinate perfectly matched layer (SCPML) boundary conditions.</li>
<li><code>waveguide_2d</code>: Operators and mode-solver for waveguides with constant cross-section.</li>
<li><code>waveguide_3d</code>: Functions for transforming <code>waveguide_2d</code> results into 3D,
including mode-source and overlap-window construction.</li>
<li><code>farfield</code>, <code>bloch</code>, <code>eme</code>: specialized helper modules for near/far transforms,
Bloch-periodic problems, and eigenmode expansion.</li>
</ul>
<p>================================================================</p>
<p>From the "Frequency domain" section of <code>meanas.fdmath</code>, we have</p>
<div class="arithmatex">\[
\begin{aligned}
\tilde{E}_{l, \vec{r}} &amp;= \tilde{E}_{\vec{r}} e^{-\imath \omega l \Delta_t} \\
\tilde{H}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} &amp;= \tilde{H}_{\vec{r} + \frac{1}{2}} e^{-\imath \omega (l - \frac{1}{2}) \Delta_t} \\
\tilde{J}_{l, \vec{r}} &amp;= \tilde{J}_{\vec{r}} e^{-\imath \omega (l - \frac{1}{2}) \Delta_t} \\
\tilde{M}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} &amp;= \tilde{M}_{\vec{r} + \frac{1}{2}} e^{-\imath \omega l \Delta_t} \\
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{\vec{r}})
-\Omega^2 \epsilon_{\vec{r}} \cdot \tilde{E}_{\vec{r}} &amp;= -\imath \Omega \tilde{J}_{\vec{r}} e^{\imath \omega \Delta_t / 2} \\
\Omega &amp;= 2 \sin(\omega \Delta_t / 2) / \Delta_t
\end{aligned}
\]</div>
<p>resulting in</p>
<div class="arithmatex">\[
\begin{aligned}
\tilde{\partial}_t &amp;\Rightarrow -\imath \Omega e^{-\imath \omega \Delta_t / 2}\\
\hat{\partial}_t &amp;\Rightarrow -\imath \Omega e^{ \imath \omega \Delta_t / 2}\\
\end{aligned}
\]</div>
<p>Maxwell's equations are then</p>
<div class="arithmatex">\[
\begin{aligned}
\tilde{\nabla} \times \tilde{E}_{\vec{r}} &amp;=
\imath \Omega e^{-\imath \omega \Delta_t / 2} \hat{B}_{\vec{r} + \frac{1}{2}}
- \hat{M}_{\vec{r} + \frac{1}{2}} \\
\hat{\nabla} \times \hat{H}_{\vec{r} + \frac{1}{2}} &amp;=
-\imath \Omega e^{ \imath \omega \Delta_t / 2} \tilde{D}_{\vec{r}}
+ \tilde{J}_{\vec{r}} \\
\tilde{\nabla} \cdot \hat{B}_{\vec{r} + \frac{1}{2}} &amp;= 0 \\
\hat{\nabla} \cdot \tilde{D}_{\vec{r}} &amp;= \rho_{\vec{r}}
\end{aligned}
\]</div>
<p>With <span class="arithmatex">\(\Delta_t \to 0\)</span>, this simplifies to</p>
<div class="arithmatex">\[
\begin{aligned}
\tilde{E}_{l, \vec{r}} &amp;\to \tilde{E}_{\vec{r}} \\
\tilde{H}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} &amp;\to \tilde{H}_{\vec{r} + \frac{1}{2}} \\
\tilde{J}_{l, \vec{r}} &amp;\to \tilde{J}_{\vec{r}} \\
\tilde{M}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} &amp;\to \tilde{M}_{\vec{r} + \frac{1}{2}} \\
\Omega &amp;\to \omega \\
\tilde{\partial}_t &amp;\to -\imath \omega \\
\hat{\partial}_t &amp;\to -\imath \omega \\
\end{aligned}
\]</div>
<p>and then</p>
<div class="arithmatex">\[
\begin{aligned}
\tilde{\nabla} \times \tilde{E}_{\vec{r}} &amp;=
\imath \omega \hat{B}_{\vec{r} + \frac{1}{2}}
- \hat{M}_{\vec{r} + \frac{1}{2}} \\
\hat{\nabla} \times \hat{H}_{\vec{r} + \frac{1}{2}} &amp;=
-\imath \omega \tilde{D}_{\vec{r}}
+ \tilde{J}_{\vec{r}} \\
\end{aligned}
\]</div>
<div class="arithmatex">\[
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{\vec{r}})
-\omega^2 \epsilon_{\vec{r}} \cdot \tilde{E}_{\vec{r}} = -\imath \omega \tilde{J}_{\vec{r}} \\
\]</div>
<div class="doc doc-children">
</div>
</div>
</div><h2 id="core-operator-layers">Core operator layers<a class="headerlink" href="#api-fdfd-core-operator-layers" title="Permanent link"></a></h2>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-fdfd-meanas.fdfd.functional">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd.functional</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.functional" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Functional versions of many FDFD operators. These can be useful for performing
FDFD calculations without needing to construct large matrices in memory.</p>
<p>The functions generated here expect <code>cfdfield_t</code> inputs with shape (3, X, Y, Z),
e.g. E = [E_x, E_y, E_z] where each (complex) component has shape (X, Y, Z)</p>
<div class="doc doc-children">
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.functional.e_full">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e_full</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.functional.e_full" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e_full</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">cfdfield_updater_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Wave operator for use with E-field. See <code>operators.e_full</code> for details.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency of the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Dielectric constant</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Magnetic permeability (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title=" cfdfield_updater_t
module-attribute
(meanas.fdmath.cfdfield_updater_t)">cfdfield_updater_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Function <code>f</code> implementing the wave operator</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title=" cfdfield_updater_t
module-attribute
(meanas.fdmath.cfdfield_updater_t)">cfdfield_updater_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p><code>f(E)</code> -&gt; <code>-i * omega * J</code></p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.functional.eh_full">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">eh_full</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.functional.eh_full" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">eh_full</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Callable</span><span class="p">[</span>
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="p">[</span><span class="n">cfdfield</span><span class="p">,</span> <span class="n">cfdfield</span><span class="p">],</span> <span class="nb">tuple</span><span class="p">[</span><span class="n">cfdfield_t</span><span class="p">,</span> <span class="n">cfdfield_t</span><span class="p">]</span>
<a href="#api-fdfd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Wave operator for full (both E and H) field representation.
See <code>operators.eh_full</code>.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency of the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Dielectric constant</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Magnetic permeability (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a>, <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a>], <a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a>]]</code>
</td>
<td>
<div class="doc-md-description">
<p>Function <code>f</code> implementing the wave operator</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a>, <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a>], <a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a>]]</code>
</td>
<td>
<div class="doc-md-description">
<p><code>f(E, H)</code> -&gt; <code>(J, -M)</code></p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.functional.e2h">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e2h</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.functional.e2h" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e2h</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">cfdfield_updater_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Utility operator for converting the <code>E</code> field into the <code>H</code> field.
For use with <code>e_full</code> -- assumes that there is no magnetic current <code>M</code>.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency of the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Magnetic permeability (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title=" cfdfield_updater_t
module-attribute
(meanas.fdmath.cfdfield_updater_t)">cfdfield_updater_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Function <code>f</code> for converting <code>E</code> to <code>H</code>,</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title=" cfdfield_updater_t
module-attribute
(meanas.fdmath.cfdfield_updater_t)">cfdfield_updater_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p><code>f(E)</code> -&gt; <code>H</code></p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.functional.m2j">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">m2j</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.functional.m2j" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">m2j</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">cfdfield_updater_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Utility operator for converting magnetic current <code>M</code> distribution
into equivalent electric current distribution <code>J</code>.
For use with e.g. <code>e_full</code>.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency of the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Magnetic permeability (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title=" cfdfield_updater_t
module-attribute
(meanas.fdmath.cfdfield_updater_t)">cfdfield_updater_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Function <code>f</code> for converting <code>M</code> to <code>J</code>,</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title=" cfdfield_updater_t
module-attribute
(meanas.fdmath.cfdfield_updater_t)">cfdfield_updater_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p><code>f(M)</code> -&gt; <code>J</code></p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.functional.e_tfsf_source">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e_tfsf_source</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.functional.e_tfsf_source" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e_tfsf_source</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">TF_region</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">cfdfield_updater_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Operator that turns an E-field distribution into a total-field/scattered-field
(TFSF) source.</p>
<p>If <code>A</code> is the full wave operator from <code>e_full(...)</code> and <code>Q</code> is the diagonal
mask selecting the total-field region, then the TFSF source is the commutator</p>
<div class="arithmatex">\[
\frac{A Q - Q A}{-i \omega} E.
\]</div>
<p>This vanishes in the interior of the total-field and scattered-field regions
and is supported only at their shared boundary, where the mask discontinuity
makes <code>A</code> and <code>Q</code> fail to commute. The returned current is therefore the
distributed source needed to inject the desired total field without also
forcing the scattered-field region.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>TF_region</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>mask which is set to 1 in the total-field region, and 0 elsewhere
(i.e. in the scattered-field region).
Should have the same shape as the simulation grid, e.g. <code>epsilon[0].shape</code>.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency of the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Dielectric constant distribution</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Magnetic permeability (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title=" cfdfield_updater_t
module-attribute
(meanas.fdmath.cfdfield_updater_t)">cfdfield_updater_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Function <code>f</code> which takes an E field and returns a current distribution,</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title=" cfdfield_updater_t
module-attribute
(meanas.fdmath.cfdfield_updater_t)">cfdfield_updater_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p><code>f(E)</code> -&gt; <code>J</code></p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.functional.poynting_e_cross_h">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">poynting_e_cross_h</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.functional.poynting_e_cross_h" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">poynting_e_cross_h</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Callable</span><span class="p">[[</span><span class="n">cfdfield</span><span class="p">,</span> <span class="n">cfdfield</span><span class="p">],</span> <span class="n">cfdfield_t</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Generates a function that takes the single-frequency <code>E</code> and <code>H</code> fields
and calculates the cross product <code>E</code> x <code>H</code> = <span class="arithmatex">\(E \times H\)</span> as required
for the Poynting vector, <span class="arithmatex">\(S = E \times H\)</span>.</p>
<p>On the Yee grid, the electric and magnetic components are not stored at the
same locations. This helper therefore applies the same one-cell electric-field
shifts used by the sparse <code>operators.poynting_e_cross(...)</code> construction so
that the discrete cross product matches the face-centered energy flux used in
<code>meanas.fdtd.energy.poynting(...)</code>.</p>
<details class="note" open="">
<summary>Note</summary>
<p>This function also shifts the input <code>E</code> field by one cell as required
for computing the Poynting cross product (see <code>meanas.fdfd</code> module docs).</p>
</details>
<details class="note" open="">
<summary>Note</summary>
<p>If <code>E</code> and <code>H</code> are peak amplitudes as assumed elsewhere in this code,
the time-average of the poynting vector is <code>&lt;S&gt; = Re(S)/2 = Re(E x H*) / 2</code>.
The factor of <code>1/2</code> can be omitted if root-mean-square quantities are used
instead.</p>
</details>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a>, <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a>], <a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Function <code>f</code> that returns the staggered-grid cross product <code>E \times H</code>.</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a>, <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a>], <a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>For time-average power, call it as <code>f(E, H.conj())</code> and take <code>Re(...) / 2</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd.operators</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Sparse matrix operators for use with electromagnetic wave equations.</p>
<p>These functions return sparse-matrix (<code>scipy.sparse.sparray</code>) representations of
a variety of operators, intended for use with E and H fields vectorized using the
<code>meanas.fdmath.vectorization.vec()</code> and <code>meanas.fdmath.vectorization.unvec()</code> functions.</p>
<p>E- and H-field values are defined on a Yee cell; <code>epsilon</code> values should be calculated for
cells centered at each E component (<code>mu</code> at each H component).</p>
<p>Many of these functions require a <code>dxes</code> parameter, of type <code>dx_lists_t</code>; see
the <code>meanas.fdmath.types</code> submodule for details.</p>
<p>The following operators are included:</p>
<ul>
<li>E-only wave operator</li>
<li>H-only wave operator</li>
<li>EH wave operator</li>
<li>Curl for use with E, H fields</li>
<li>E to H conversion</li>
<li>M to J conversion</li>
<li>Poynting cross products</li>
<li>Circular shifts</li>
<li>Discrete derivatives</li>
<li>Averaging operators</li>
<li>Cross product matrices</li>
</ul>
<div class="doc doc-children">
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.e_full">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e_full</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.e_full" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e_full</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="n">vcfdfield</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">pec</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">pmc</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Wave operator
$$ \nabla \times (\frac{1}{\mu} \nabla \times) - \Omega^2 \epsilon $$</p>
<div class="highlight"><pre><span></span><code>del x (1/mu * del x) - omega**2 * epsilon
</code></pre></div>
<p>for use with the E-field, with wave equation
$$ (\nabla \times (\frac{1}{\mu} \nabla \times) - \Omega^2 \epsilon) E = -\imath \omega J $$</p>
<div class="highlight"><pre><span></span><code>(del x (1/mu * del x) - omega**2 * epsilon) E = -i * omega * J
</code></pre></div>
<p>To make this matrix symmetric, use the preconditioners from <code>e_full_preconditioners()</code>.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency of the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield" title=" vcfdfield (meanas.fdmath.vcfdfield)">vcfdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability (default 1 everywhere).</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>pec</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized mask specifying PEC cells. Any cells where <code>pec != 0</code> are interpreted
as containing a perfect electrical conductor (PEC).
The PEC is applied per-field-component (i.e. <code>pec.size == epsilon.size</code>)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>pmc</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized mask specifying PMC cells. Any cells where <code>pmc != 0</code> are interpreted
as containing a perfect magnetic conductor (PMC).
The PMC is applied per-field-component (i.e. <code>pmc.size == epsilon.size</code>)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix containing the wave operator.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.e_full_preconditioners">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e_full_preconditioners</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.e_full_preconditioners" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e_full_preconditioners</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span><span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span><span class="p">,</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Left and right preconditioners <code>(Pl, Pr)</code> for symmetrizing the <code>e_full</code> wave operator.</p>
<p>The preconditioned matrix <code>A_symm = (Pl @ A @ Pr)</code> is complex-symmetric
(non-Hermitian unless there is no loss or PMLs).</p>
<p>The preconditioner matrices are diagonal and complex, with <code>Pr = 1 / Pl</code></p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a>, <a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Preconditioner matrices <code>(Pl, Pr)</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.h_full">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">h_full</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.h_full" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">h_full</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdfield</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">pec</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">pmc</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Wave operator
$$ \nabla \times (\frac{1}{\epsilon} \nabla \times) - \omega^2 \mu $$</p>
<div class="highlight"><pre><span></span><code>del x (1/epsilon * del x) - omega**2 * mu
</code></pre></div>
<p>for use with the H-field, with wave equation
$$ (\nabla \times (\frac{1}{\epsilon} \nabla \times) - \omega^2 \mu) E = \imath \omega M $$</p>
<div class="highlight"><pre><span></span><code>(del x (1/epsilon * del x) - omega**2 * mu) E = i * omega * M
</code></pre></div>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency of the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>pec</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized mask specifying PEC cells. Any cells where <code>pec != 0</code> are interpreted
as containing a perfect electrical conductor (PEC).
The PEC is applied per-field-component (i.e. <code>pec.size == epsilon.size</code>)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>pmc</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized mask specifying PMC cells. Any cells where <code>pmc != 0</code> are interpreted
as containing a perfect magnetic conductor (PMC).
The PMC is applied per-field-component (i.e. <code>pmc.size == epsilon.size</code>)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix containing the wave operator.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.eh_full">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">eh_full</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.eh_full" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">eh_full</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdfield</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">pec</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">pmc</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Wave operator for <code>[E, H]</code> field representation. This operator implements Maxwell's
equations without cancelling out either E or H. The operator is
$$ \begin{bmatrix}
-\imath \omega \epsilon &amp; \nabla \times \
\nabla \times &amp; \imath \omega \mu
\end{bmatrix} $$</p>
<div class="highlight"><pre><span></span><code>[[-i * omega * epsilon, del x ],
[del x, i * omega * mu]]
</code></pre></div>
<p>for use with a field vector of the form <code>cat(vec(E), vec(H))</code>:
$$ \begin{bmatrix}
-\imath \omega \epsilon &amp; \nabla \times \
\nabla \times &amp; \imath \omega \mu
\end{bmatrix}
\begin{bmatrix} E \
H
\end{bmatrix}
= \begin{bmatrix} J \
-M
\end{bmatrix} $$</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency of the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>pec</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized mask specifying PEC cells. Any cells where <code>pec != 0</code> are interpreted
as containing a perfect electrical conductor (PEC).
The PEC is applied per-field-component (i.e. <code>pec.size == epsilon.size</code>)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>pmc</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized mask specifying PMC cells. Any cells where <code>pmc != 0</code> are interpreted
as containing a perfect magnetic conductor (PMC).
The PMC is applied per-field-component (i.e. <code>pmc.size == epsilon.size</code>)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix containing the wave operator.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.e2h">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e2h</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.e2h" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e2h</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">pmc</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Utility operator for converting the E field into the H field.
For use with <code>e_full()</code> -- assumes that there is no magnetic current M.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency of the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>pmc</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized mask specifying PMC cells. Any cells where <code>pmc != 0</code> are interpreted
as containing a perfect magnetic conductor (PMC).
The PMC is applied per-field-component (i.e. <code>pmc.size == epsilon.size</code>)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix for converting E to H.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.m2j">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">m2j</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.m2j" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">m2j</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Operator for converting a magnetic current M into an electric current J.
For use with eg. <code>e_full()</code>.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency of the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix for converting M to J.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.poynting_e_cross">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">poynting_e_cross</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.poynting_e_cross" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">poynting_e_cross</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e</span><span class="p">:</span> <span class="n">vcfdfield</span><span class="p">,</span> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Operator for computing the staggered-grid <code>(E \times)</code> part of the Poynting vector.</p>
<p>On the Yee grid the E and H components live on different edges, so the
electric field must be shifted by one cell in the appropriate direction
before forming the discrete cross product. This sparse operator encodes that
shifted cross product directly and is the matrix equivalent of
<code>functional.poynting_e_cross_h(...)</code>.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>e</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield" title=" vcfdfield (meanas.fdmath.vcfdfield)">vcfdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized E-field for the ExH cross product</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix containing the <code>(E \times)</code> part of the staggered Poynting</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>cross product.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.poynting_h_cross">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">poynting_h_cross</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.poynting_h_cross" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">poynting_h_cross</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">h</span><span class="p">:</span> <span class="n">vcfdfield</span><span class="p">,</span> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Operator for computing the staggered-grid <code>(H \times)</code> part of the Poynting vector.</p>
<p>Together with <code>poynting_e_cross(...)</code>, this provides the matrix form of the
Yee-grid cross product used in the flux helpers. The two are related by the
usual antisymmetry of the cross product,</p>
<div class="arithmatex">\[
H \times E = -(E \times H),
\]</div>
<p>once the same staggered field placement is used on both sides.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>h</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield" title=" vcfdfield (meanas.fdmath.vcfdfield)">vcfdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized H-field for the HxE cross product</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix containing the <code>(H \times)</code> part of the staggered Poynting</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>cross product.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.e_tfsf_source">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e_tfsf_source</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.e_tfsf_source" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e_tfsf_source</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">TF_region</span><span class="p">:</span> <span class="n">vfdfield</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdfield</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Operator that turns a desired E-field distribution into a
total-field/scattered-field (TFSF) source.</p>
<p>Let <code>A</code> be the full wave operator from <code>e_full(...)</code>, and let
<code>Q = \mathrm{diag}(TF_region)</code> be the projector onto the total-field region.
Then the TFSF current operator is the commutator</p>
<div class="arithmatex">\[
\frac{A Q - Q A}{-i \omega}.
\]</div>
<p>Inside regions where <code>Q</code> is locally constant, <code>A</code> and <code>Q</code> commute and the
source vanishes. Only cells at the TF/SF boundary contribute nonzero current,
which is exactly the desired distributed source for injecting the chosen
field into the total-field region without directly forcing the
scattered-field region.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>TF_region</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Mask, which is set to 1 inside the total-field region and 0 in the
scattered-field region</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency of the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability (default 1 everywhere).</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix that turns an E-field into a current (J) distribution.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.operators.e_boundary_source">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e_boundary_source</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.operators.e_boundary_source" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e_boundary_source</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">mask</span><span class="p">:</span> <span class="n">vfdfield</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdfield</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">periodic_mask_edges</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Operator that turns an E-field distrubtion into a current (J) distribution
along the edges (external and internal) of the provided mask. This is just an
<code>e_tfsf_source()</code> with an additional masking step.</p>
<p>Equivalently, this helper first constructs the TFSF commutator source for the
full mask and then zeroes out all cells except the mask boundary. The
boundary is defined as the set of cells whose mask value changes under a
one-cell shift in any Cartesian direction. With <code>periodic_mask_edges=False</code>
the shifts mirror at the domain boundary; with <code>True</code> they wrap periodically.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>mask</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The current distribution is generated at the edges of the mask,
i.e. any points where shifting the mask by one cell in any direction
would change its value.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency of the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability (default 1 everywhere).</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix that turns an E-field into a current (J) distribution.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-fdfd-meanas.fdfd.solvers">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd.solvers</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.solvers" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Solvers and solver interface for FDFD problems.</p>
<div class="doc doc-children">
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.solvers.generic">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">generic</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.solvers.generic" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">generic</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">J</span><span class="p">:</span> <span class="n">vcfdfield</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdfield</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="o">*</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">pec</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">pmc</span><span class="p">:</span> <span class="n">vfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="n">adjoint</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">matrix_solver</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="n">ArrayLike</span><span class="p">]</span> <span class="o">=</span> <span class="n">_scipy_qmr</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> <span class="n">matrix_solver_opts</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> <span class="n">E_guess</span><span class="p">:</span> <span class="n">vcfdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">vcfdfield_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Conjugate gradient FDFD solver using CSR sparse matrices.</p>
<p>All ndarray arguments should be 1D arrays, as returned by <code>meanas.fdmath.vectorization.vec()</code>.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Complex frequency to solve at.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p><code>[[dx_e, dy_e, dz_e], [dx_h, dy_h, dz_h]]</code> (complex cell sizes) as
discussed in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>J</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield" title=" vcfdfield (meanas.fdmath.vcfdfield)">vcfdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Electric current distribution (at E-field locations)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Dielectric constant distribution (at E-field locations)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Magnetic permeability distribution (at H-field locations)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>pec</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Perfect electric conductor distribution
(at E-field locations; non-zero value indicates PEC is present)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>pmc</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title=" vfdfield (meanas.fdmath.vfdfield)">vfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Perfect magnetic conductor distribution
(at H-field locations; non-zero value indicates PMC is present)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>adjoint</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#bool">bool</a></code>
</td>
<td>
<div class="doc-md-description">
<p>If true, solves the adjoint problem.</p>
</div>
</td>
<td>
<code>False</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>matrix_solver</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[..., <a class="autorefs autorefs-internal" href="#numpy.typing.ArrayLike" title="numpy.typing.ArrayLike">ArrayLike</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Called as <code>matrix_solver(A, b, **matrix_solver_opts) -&gt; x</code>,
where <code>A</code>: <code>scipy.sparse.csr_array</code>;
<code>b</code>: <code>ArrayLike</code>;
<code>x</code>: <code>ArrayLike</code>;
Default is a wrapped version of <code>scipy.sparse.linalg.qmr()</code>
which doesn't return convergence info and logs the residual
every 100 iterations.</p>
</div>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdfd.solvers._scipy_qmr" title="meanas.fdfd.solvers._scipy_qmr">_scipy_qmr</a></code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>matrix_solver_opts</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>] | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Passed as kwargs to <code>matrix_solver(...)</code></p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>E_guess</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield" title=" vcfdfield (meanas.fdmath.vcfdfield)">vcfdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Guess at the solution E-field. <code>matrix_solver</code> must accept an
<code>x0</code> argument with the same purpose.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdfield_t" title="meanas.fdmath.vcfdfield_t">vcfdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>E-field which solves the system.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-fdfd-meanas.fdfd.scpml">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd.scpml</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.scpml" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Functions for creating stretched coordinate perfectly matched layer (PML) absorbers.</p>
<div class="doc doc-children">
<div class="doc doc-object doc-attribute">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.scpml.s_function_t">
<code class="doc-symbol doc-symbol-heading doc-symbol-attribute"></code> <span class="doc doc-object-name doc-attribute-name">s_function_t</span>
<span class="doc doc-labels">
<small class="doc doc-label doc-label-module-attribute"><code>module-attribute</code></small>
</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.scpml.s_function_t" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="n">s_function_t</span> <span class="o">=</span> <span class="n">Callable</span><span class="p">[</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">float64</span><span class="p">]],</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">float64</span><span class="p">]</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Typedef for s-functions, see <code>prepare_s_function()</code></p>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.scpml.prepare_s_function">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">prepare_s_function</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.scpml.prepare_s_function" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">prepare_s_function</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">ln_R</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="o">-</span><span class="mi">16</span><span class="p">,</span> <span class="n">m</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">4</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">s_function_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Create an s_function to pass to the SCPML functions. This is used when you would like to
customize the PML parameters.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>ln_R</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Natural logarithm of the desired reflectance</p>
</div>
</td>
<td>
<code>-16</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>m</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Polynomial order for the PML (imaginary part increases as distance ** m)</p>
</div>
</td>
<td>
<code>4</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.s_function_t" title=" s_function_t
module-attribute
(meanas.fdfd.scpml.s_function_t)">s_function_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>An s_function, which takes an ndarray (distances) and returns an ndarray (complex part</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.s_function_t" title=" s_function_t
module-attribute
(meanas.fdfd.scpml.s_function_t)">s_function_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>of the cell width; needs to be divided by <code>sqrt(epilon_effective) * real(omega))</code></p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.s_function_t" title=" s_function_t
module-attribute
(meanas.fdfd.scpml.s_function_t)">s_function_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>before use.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.scpml.uniform_grid_scpml">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">uniform_grid_scpml</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.scpml.uniform_grid_scpml" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">uniform_grid_scpml</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">thicknesses</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span>
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon_effective</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">s_function</span><span class="p">:</span> <span class="n">s_function_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="nb">list</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">float64</span><span class="p">]]]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Create dx arrays for a uniform grid with a cell width of 1 and a pml.</p>
<p>If you want something more fine-grained, check out <code>stretch_with_scpml(...)</code>.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>shape</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Shape of the grid, including the PMLs (which are 2*thicknesses thick)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>thicknesses</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p><code>[th_x, th_y, th_z]</code>
Thickness of the PML in each direction.
Both polarities are added.
Each th_ of pml is applied twice, once on each edge of the grid along the given axis.
<code>th_*</code> may be zero, in which case no pml is added.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency for the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon_effective</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Effective epsilon of the PML. Match this to the material
at the edge of your grid.
Default 1.</p>
</div>
</td>
<td>
<code>1.0</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>s_function</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.s_function_t" title=" s_function_t
module-attribute
(meanas.fdfd.scpml.s_function_t)">s_function_t</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>created by <code>prepare_s_function(...)</code>, allowing customization of pml parameters.
Default uses <code>prepare_s_function()</code> with no parameters.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.float64" title="numpy.float64">float64</a>]]]</code>
</td>
<td>
<div class="doc-md-description">
<p>Complex cell widths (dx_lists_mut) as discussed in <code>meanas.fdmath.types</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.scpml.stretch_with_scpml">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">stretch_with_scpml</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.scpml.stretch_with_scpml" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">stretch_with_scpml</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dxes</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">list</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">float64</span><span class="p">]]],</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">polarity</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">epsilon_effective</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">thickness</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">10</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">s_function</span><span class="p">:</span> <span class="n">s_function_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="nb">list</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">float64</span><span class="p">]]]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Stretch dxes to contain a stretched-coordinate PML (SCPML) in one direction along one axis.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.float64" title="numpy.float64">float64</a>]]]</code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>axis</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>axis to stretch (0=x, 1=y, 2=z)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>polarity</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>direction to stretch (-1 for -ve, +1 for +ve)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency for the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon_effective</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Effective epsilon of the PML. Match this to the material at the
edge of your grid. Default 1.</p>
</div>
</td>
<td>
<code>1.0</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>thickness</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>number of cells to use for pml (default 10)</p>
</div>
</td>
<td>
<code>10</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>s_function</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdfd-meanas.fdfd.scpml.s_function_t" title=" s_function_t
module-attribute
(meanas.fdfd.scpml.s_function_t)">s_function_t</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Created by <code>prepare_s_function(...)</code>, allowing customization
of pml parameters. Default uses <code>prepare_s_function()</code> with no parameters.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.float64" title="numpy.float64">float64</a>]]]</code>
</td>
<td>
<div class="doc-md-description">
<p>Complex cell widths (dx_lists_mut) as discussed in <code>meanas.fdmath.types</code>.</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.float64" title="numpy.float64">float64</a>]]]</code>
</td>
<td>
<div class="doc-md-description">
<p>Multiple calls to this function may be necessary if multiple absorpbing boundaries are needed.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-fdfd-meanas.fdfd.farfield">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd.farfield</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.farfield" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Functions for performing near-to-farfield transformation (and the reverse).</p>
<div class="doc doc-children">
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.farfield.near_to_farfield">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">near_to_farfield</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.farfield.near_to_farfield" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">near_to_farfield</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">E_near</span><span class="p">:</span> <span class="n">cfdfield_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">H_near</span><span class="p">:</span> <span class="n">cfdfield_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dx</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dy</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">padded_size</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">|</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Compute the farfield, i.e. the distribution of the fields after propagation
through several wavelengths of uniform medium.</p>
<p>The input fields should be complex phasors.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>E_near</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>List of 2 ndarrays containing the 2D phasor field slices for the transverse
E fields (e.g. [Ex, Ey] for calculating the farfield toward the z-direction).</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>H_near</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>List of 2 ndarrays containing the 2D phasor field slices for the transverse
H fields (e.g. [Hx, hy] for calculating the farfield towrad the z-direction).</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dx</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Cell size along x-dimension, in units of wavelength.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dy</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Cell size along y-dimension, in units of wavelength.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>padded_size</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a>] | <a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Shape of the output. A single integer <code>n</code> will be expanded to <code>(n, n)</code>.
Powers of 2 are most efficient for FFT computation.
Default is the smallest power of 2 larger than the input, for each axis.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Dict with keys</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>E_far</code>: Normalized E-field farfield; multiply by
(i k exp(-i k r) / (4 pi r)) to get the actual field value.</li>
</ul>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>H_far</code>: Normalized H-field farfield; multiply by
(i k exp(-i k r) / (4 pi r)) to get the actual field value.</li>
</ul>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>kx</code>, <code>ky</code>: Wavevector values corresponding to the x- and y- axes in E_far and H_far,
normalized to wavelength (dimensionless).</li>
</ul>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>dkx</code>, <code>dky</code>: step size for kx and ky, normalized to wavelength.</li>
</ul>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>theta</code>: arctan2(ky, kx) corresponding to each (kx, ky).
This is the angle in the x-y plane, counterclockwise from above, starting from +x.</li>
</ul>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>phi</code>: arccos(kz / k) corresponding to each (kx, ky).
This is the angle away from +z.</li>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdfd-meanas.fdfd.farfield.far_to_nearfield">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">far_to_nearfield</span>
<a class="headerlink" href="#api-fdfd-meanas.fdfd.farfield.far_to_nearfield" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdfd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">far_to_nearfield</span><span class="p">(</span>
<a href="#api-fdfd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">E_far</span><span class="p">:</span> <span class="n">cfdfield_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">H_far</span><span class="p">:</span> <span class="n">cfdfield_t</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dkx</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dky</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">padded_size</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">|</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdfd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Compute the farfield, i.e. the distribution of the fields after propagation
through several wavelengths of uniform medium.</p>
<p>The input fields should be complex phasors.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>E_far</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>List of 2 ndarrays containing the 2D phasor field slices for the transverse
E fields (e.g. [Ex, Ey] for calculating the nearfield toward the z-direction).
Fields should be normalized so that
E_far = E_far_actual / (i k exp(-i k r) / (4 pi r))</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>H_far</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>List of 2 ndarrays containing the 2D phasor field slices for the transverse
H fields (e.g. [Hx, hy] for calculating the nearfield toward the z-direction).
Fields should be normalized so that
H_far = H_far_actual / (i k exp(-i k r) / (4 pi r))</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dkx</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>kx discretization, in units of wavelength.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dky</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>ky discretization, in units of wavelength.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>padded_size</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a>] | <a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Shape of the output. A single integer <code>n</code> will be expanded to <code>(n, n)</code>.
Powers of 2 are most efficient for FFT computation.
Default is the smallest power of 2 larger than the input, for each axis.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Dict with keys</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>E</code>: E-field nearfield</li>
</ul>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>H</code>: H-field nearfield</li>
</ul>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>dx</code>, <code>dy</code>: spatial discretization, normalized to wavelength (dimensionless)</li>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div></section><section class="print-page" heading-number="2.5" id="api-waveguides"><h1 id="api-waveguides-waveguides">waveguides<a class="headerlink" href="#api-waveguides-waveguides" title="Permanent link"></a></h1>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd.waveguide_2d</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Operators and helper functions for waveguides with unchanging cross-section.</p>
<p>The propagation direction is chosen to be along the z axis, and all fields
are given an implicit z-dependence of the form <code>exp(-1 * wavenumber * z)</code>.</p>
<p>As the z-dependence is known, all the functions in this file assume a 2D grid
(i.e. <code>dxes = [[[dx_e[0], dx_e[1], ...], [dy_e[0], ...]], [[dx_h[0], ...], [dy_h[0], ...]]]</code>).</p>
<p>===============</p>
<p>Consider Maxwell's equations in continuous space, in the frequency domain. Assuming
a structure with some (x, y) cross-section extending uniformly into the z dimension,
with a diagonal <span class="arithmatex">\(\epsilon\)</span> tensor, we have</p>
<div class="arithmatex">\[
\begin{aligned}
\nabla \times \vec{E}(x, y, z) &amp;= -\imath \omega \mu \vec{H} \\
\nabla \times \vec{H}(x, y, z) &amp;= \imath \omega \epsilon \vec{E} \\
\vec{E}(x,y,z) &amp;= (\vec{E}_t(x, y) + E_z(x, y)\vec{z}) e^{-\imath \beta z} \\
\vec{H}(x,y,z) &amp;= (\vec{H}_t(x, y) + H_z(x, y)\vec{z}) e^{-\imath \beta z} \\
\end{aligned}
\]</div>
<p>Expanding the first two equations into vector components, we get</p>
<div class="arithmatex">\[
\begin{aligned}
-\imath \omega \mu_{xx} H_x &amp;= \partial_y E_z - \partial_z E_y \\
-\imath \omega \mu_{yy} H_y &amp;= \partial_z E_x - \partial_x E_z \\
-\imath \omega \mu_{zz} H_z &amp;= \partial_x E_y - \partial_y E_x \\
\imath \omega \epsilon_{xx} E_x &amp;= \partial_y H_z - \partial_z H_y \\
\imath \omega \epsilon_{yy} E_y &amp;= \partial_z H_x - \partial_x H_z \\
\imath \omega \epsilon_{zz} E_z &amp;= \partial_x H_y - \partial_y H_x \\
\end{aligned}
\]</div>
<p>Substituting in our expressions for <span class="arithmatex">\(\vec{E}\)</span>, <span class="arithmatex">\(\vec{H}\)</span> and discretizing:</p>
<div class="arithmatex">\[
\begin{aligned}
-\imath \omega \mu_{xx} H_x &amp;= \tilde{\partial}_y E_z + \imath \beta E_y \\
-\imath \omega \mu_{yy} H_y &amp;= -\imath \beta E_x - \tilde{\partial}_x E_z \\
-\imath \omega \mu_{zz} H_z &amp;= \tilde{\partial}_x E_y - \tilde{\partial}_y E_x \\
\imath \omega \epsilon_{xx} E_x &amp;= \hat{\partial}_y H_z + \imath \beta H_y \\
\imath \omega \epsilon_{yy} E_y &amp;= -\imath \beta H_x - \hat{\partial}_x H_z \\
\imath \omega \epsilon_{zz} E_z &amp;= \hat{\partial}_x H_y - \hat{\partial}_y H_x \\
\end{aligned}
\]</div>
<p>Rewrite the last three equations as</p>
<div class="arithmatex">\[
\begin{aligned}
\imath \beta H_y &amp;= \imath \omega \epsilon_{xx} E_x - \hat{\partial}_y H_z \\
\imath \beta H_x &amp;= -\imath \omega \epsilon_{yy} E_y - \hat{\partial}_x H_z \\
\imath \omega E_z &amp;= \frac{1}{\epsilon_{zz}} \hat{\partial}_x H_y - \frac{1}{\epsilon_{zz}} \hat{\partial}_y H_x \\
\end{aligned}
\]</div>
<p>Now apply <span class="arithmatex">\(\imath \beta \tilde{\partial}_x\)</span> to the last equation,
then substitute in for <span class="arithmatex">\(\imath \beta H_x\)</span> and <span class="arithmatex">\(\imath \beta H_y\)</span>:</p>
<div class="arithmatex">\[
\begin{aligned}
\imath \beta \tilde{\partial}_x \imath \omega E_z &amp;= \imath \beta \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_x H_y
- \imath \beta \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_y H_x \\
&amp;= \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_x ( \imath \omega \epsilon_{xx} E_x - \hat{\partial}_y H_z)
- \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_y (-\imath \omega \epsilon_{yy} E_y - \hat{\partial}_x H_z) \\
&amp;= \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_x ( \imath \omega \epsilon_{xx} E_x)
- \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_y (-\imath \omega \epsilon_{yy} E_y) \\
\imath \beta \tilde{\partial}_x E_z &amp;= \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
+ \tilde{\partial}_x \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y) \\
\end{aligned}
\]</div>
<p>With a similar approach (but using <span class="arithmatex">\(\imath \beta \tilde{\partial}_y\)</span> instead), we can get</p>
<div class="arithmatex">\[
\begin{aligned}
\imath \beta \tilde{\partial}_y E_z &amp;= \tilde{\partial}_y \frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
+ \tilde{\partial}_y \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y) \\
\end{aligned}
\]</div>
<p>We can combine this equation for <span class="arithmatex">\(\imath \beta \tilde{\partial}_y E_z\)</span> with
the unused <span class="arithmatex">\(\imath \omega \mu_{xx} H_x\)</span> and <span class="arithmatex">\(\imath \omega \mu_{yy} H_y\)</span> equations to get</p>
<div class="arithmatex">\[
\begin{aligned}
-\imath \omega \mu_{xx} \imath \beta H_x &amp;= -\beta^2 E_y + \imath \beta \tilde{\partial}_y E_z \\
-\imath \omega \mu_{xx} \imath \beta H_x &amp;= -\beta^2 E_y + \tilde{\partial}_y (
\frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
+ \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y)
)\\
\end{aligned}
\]</div>
<p>and</p>
<div class="arithmatex">\[
\begin{aligned}
-\imath \omega \mu_{yy} \imath \beta H_y &amp;= \beta^2 E_x - \imath \beta \tilde{\partial}_x E_z \\
-\imath \omega \mu_{yy} \imath \beta H_y &amp;= \beta^2 E_x - \tilde{\partial}_x (
\frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
+ \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y)
)\\
\end{aligned}
\]</div>
<p>However, based on our rewritten equation for <span class="arithmatex">\(\imath \beta H_x\)</span> and the so-far unused
equation for <span class="arithmatex">\(\imath \omega \mu_{zz} H_z\)</span> we can also write</p>
<div class="arithmatex">\[
\begin{aligned}
-\imath \omega \mu_{xx} (\imath \beta H_x) &amp;= -\imath \omega \mu_{xx} (-\imath \omega \epsilon_{yy} E_y - \hat{\partial}_x H_z) \\
&amp;= -\omega^2 \mu_{xx} \epsilon_{yy} E_y + \imath \omega \mu_{xx} \hat{\partial}_x (
\frac{1}{-\imath \omega \mu_{zz}} (\tilde{\partial}_x E_y - \tilde{\partial}_y E_x)) \\
&amp;= -\omega^2 \mu_{xx} \epsilon_{yy} E_y
-\mu_{xx} \hat{\partial}_x \frac{1}{\mu_{zz}} (\tilde{\partial}_x E_y - \tilde{\partial}_y E_x) \\
\end{aligned}
\]</div>
<p>and, similarly,</p>
<div class="arithmatex">\[
\begin{aligned}
-\imath \omega \mu_{yy} (\imath \beta H_y) &amp;= \omega^2 \mu_{yy} \epsilon_{xx} E_x
+\mu_{yy} \hat{\partial}_y \frac{1}{\mu_{zz}} (\tilde{\partial}_x E_y - \tilde{\partial}_y E_x) \\
\end{aligned}
\]</div>
<p>By combining both pairs of expressions, we get</p>
<div class="arithmatex">\[
\begin{aligned}
\beta^2 E_x - \tilde{\partial}_x (
\frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
+ \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y)
) &amp;= \omega^2 \mu_{yy} \epsilon_{xx} E_x
+\mu_{yy} \hat{\partial}_y \frac{1}{\mu_{zz}} (\tilde{\partial}_x E_y - \tilde{\partial}_y E_x) \\
-\beta^2 E_y + \tilde{\partial}_y (
\frac{1}{\epsilon_{zz}} \hat{\partial}_x (\epsilon_{xx} E_x)
+ \frac{1}{\epsilon_{zz}} \hat{\partial}_y (\epsilon_{yy} E_y)
) &amp;= -\omega^2 \mu_{xx} \epsilon_{yy} E_y
-\mu_{xx} \hat{\partial}_x \frac{1}{\mu_{zz}} (\tilde{\partial}_x E_y - \tilde{\partial}_y E_x) \\
\end{aligned}
\]</div>
<p>Using these, we can construct the eigenvalue problem</p>
<div class="arithmatex">\[
\beta^2 \begin{bmatrix} E_x \\
E_y \end{bmatrix} =
(\omega^2 \begin{bmatrix} \mu_{yy} \epsilon_{xx} &amp; 0 \\
0 &amp; \mu_{xx} \epsilon_{yy} \end{bmatrix} +
\begin{bmatrix} -\mu_{yy} \hat{\partial}_y \\
\mu_{xx} \hat{\partial}_x \end{bmatrix} \mu_{zz}^{-1}
\begin{bmatrix} -\tilde{\partial}_y &amp; \tilde{\partial}_x \end{bmatrix} +
\begin{bmatrix} \tilde{\partial}_x \\
\tilde{\partial}_y \end{bmatrix} \epsilon_{zz}^{-1}
\begin{bmatrix} \hat{\partial}_x \epsilon_{xx} &amp; \hat{\partial}_y \epsilon_{yy} \end{bmatrix})
\begin{bmatrix} E_x \\
E_y \end{bmatrix}
\]</div>
<p>In the literature, <span class="arithmatex">\(\beta\)</span> is usually used to denote the lossless/real part of the propagation constant,
but in <code>meanas</code> it is allowed to be complex.</p>
<p>An equivalent eigenvalue problem can be formed using the <span class="arithmatex">\(H_x\)</span> and <span class="arithmatex">\(H_y\)</span> fields, if those are more convenient.</p>
<p>Note that <span class="arithmatex">\(E_z\)</span> was never discretized, so <span class="arithmatex">\(\beta\)</span> will need adjustment to account for numerical dispersion
if the result is introduced into a space with a discretized z-axis.</p>
<div class="doc doc-children">
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.operator_e">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">operator_e</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.operator_e" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">operator_e</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Waveguide operator of the form</p>
<div class="highlight"><pre><span></span><code>omega**2 * mu * epsilon +
mu * [[-Dy], [Dx]] / mu * [-Dy, Dx] +
[[Dx], [Dy]] / epsilon * [Dx, Dy] * epsilon
</code></pre></div>
<p>for use with a field vector of the form <code>cat([E_x, E_y])</code>.</p>
<p>More precisely, the operator is</p>
<div class="arithmatex">\[
\omega^2 \begin{bmatrix} \mu_{yy} \epsilon_{xx} &amp; 0 \\
0 &amp; \mu_{xx} \epsilon_{yy} \end{bmatrix} +
\begin{bmatrix} -\mu_{yy} \hat{\partial}_y \\
\mu_{xx} \hat{\partial}_x \end{bmatrix} \mu_{zz}^{-1}
\begin{bmatrix} -\tilde{\partial}_y &amp; \tilde{\partial}_x \end{bmatrix} +
\begin{bmatrix} \tilde{\partial}_x \\
\tilde{\partial}_y \end{bmatrix} \epsilon_{zz}^{-1}
\begin{bmatrix} \hat{\partial}_x \epsilon_{xx} &amp; \hat{\partial}_y \epsilon_{yy} \end{bmatrix}
\]</div>
<p><span class="arithmatex">\(\tilde{\partial}_x\)</span> and <span class="arithmatex">\(\hat{\partial}_x\)</span> are the forward and backward derivatives along x,
and each <span class="arithmatex">\(\epsilon_{xx}\)</span>, <span class="arithmatex">\(\mu_{yy}\)</span>, etc. is a diagonal matrix containing the vectorized material
property distribution.</p>
<p>This operator can be used to form an eigenvalue problem of the form
<code>operator_e(...) @ [E_x, E_y] = wavenumber**2 * [E_x, E_y]</code></p>
<p>which can then be solved for the eigenmodes of the system (an <code>exp(-i * wavenumber * z)</code>
z-dependence is assumed for the fields).</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The angular frequency of the system.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant grid</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix representation of the operator.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.operator_h">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">operator_h</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.operator_h" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">operator_h</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Waveguide operator of the form</p>
<div class="highlight"><pre><span></span><code>omega**2 * epsilon * mu +
epsilon * [[-Dy], [Dx]] / epsilon * [-Dy, Dx] +
[[Dx], [Dy]] / mu * [Dx, Dy] * mu
</code></pre></div>
<p>for use with a field vector of the form <code>cat([H_x, H_y])</code>.</p>
<p>More precisely, the operator is</p>
<div class="arithmatex">\[
\omega^2 \begin{bmatrix} \epsilon_{yy} \mu_{xx} &amp; 0 \\
0 &amp; \epsilon_{xx} \mu_{yy} \end{bmatrix} +
\begin{bmatrix} -\epsilon_{yy} \tilde{\partial}_y \\
\epsilon_{xx} \tilde{\partial}_x \end{bmatrix} \epsilon_{zz}^{-1}
\begin{bmatrix} -\hat{\partial}_y &amp; \hat{\partial}_x \end{bmatrix} +
\begin{bmatrix} \hat{\partial}_x \\
\hat{\partial}_y \end{bmatrix} \mu_{zz}^{-1}
\begin{bmatrix} \tilde{\partial}_x \mu_{xx} &amp; \tilde{\partial}_y \mu_{yy} \end{bmatrix}
\]</div>
<p><span class="arithmatex">\(\tilde{\partial}_x\)</span> and <span class="arithmatex">\(\hat{\partial}_x\)</span> are the forward and backward derivatives along x,
and each <span class="arithmatex">\(\epsilon_{xx}\)</span>, <span class="arithmatex">\(\mu_{yy}\)</span>, etc. is a diagonal matrix containing the vectorized material
property distribution.</p>
<p>This operator can be used to form an eigenvalue problem of the form
<code>operator_h(...) @ [H_x, H_y] = wavenumber**2 * [H_x, H_y]</code></p>
<p>which can then be solved for the eigenmodes of the system (an <code>exp(-i * wavenumber * z)</code>
z-dependence is assumed for the fields).</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The angular frequency of the system.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant grid</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix representation of the operator.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.normalized_fields_e">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">normalized_fields_e</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.normalized_fields_e" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">normalized_fields_e</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e_xy</span><span class="p">:</span> <span class="n">vcfdfield2</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">prop_phase</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span><span class="n">vcfdslice_t</span><span class="p">,</span> <span class="n">vcfdslice_t</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Given a vector <code>e_xy</code> containing the vectorized E_x and E_y fields,
returns normalized, vectorized E and H fields for the system.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>e_xy</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield2" title=" vcfdfield2 (meanas.fdmath.vcfdfield2)">vcfdfield2</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vector containing E_x and E_y fields</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code>.
It should satisfy <code>operator_e() @ e_xy == wavenumber**2 * e_xy</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The angular frequency of the system</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant grid</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>prop_phase</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Phase shift <code>(dz * corrected_wavenumber)</code> over 1 cell in propagation direction.
Default 0 (continuous propagation direction, i.e. dz-&gt;0).</p>
</div>
</td>
<td>
<code>0</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdslice_t" title="meanas.fdmath.vcfdslice_t">vcfdslice_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p><code>(e, h)</code>, where each field is vectorized, normalized,</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdslice_t" title="meanas.fdmath.vcfdslice_t">vcfdslice_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>and contains all three vector components.</p>
</div>
</td>
</tr>
</tbody>
</table>
<details class="notes" open="">
<summary>Notes</summary>
<p><code>e_xy</code> is only the transverse electric eigenvector. This helper first
reconstructs the full three-component <code>E</code> and <code>H</code> fields with <code>exy2e(...)</code>
and <code>exy2h(...)</code>, then normalizes them to unit forward power using
<code>_normalized_fields(...)</code>.</p>
<p>The normalization target is</p>
<div class="arithmatex">\[
\Re\left[\mathrm{inner\_product}(e, h, \mathrm{conj\_h}=True)\right] = 1,
\]</div>
<p>so the returned fields represent a unit-power forward mode under the
discrete Yee-grid Poynting inner product.</p>
</details>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.normalized_fields_h">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">normalized_fields_h</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.normalized_fields_h" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">normalized_fields_h</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">h_xy</span><span class="p">:</span> <span class="n">vcfdfield2</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">prop_phase</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span><span class="n">vcfdslice_t</span><span class="p">,</span> <span class="n">vcfdslice_t</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Given a vector <code>h_xy</code> containing the vectorized H_x and H_y fields,
returns normalized, vectorized E and H fields for the system.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>h_xy</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield2" title=" vcfdfield2 (meanas.fdmath.vcfdfield2)">vcfdfield2</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vector containing H_x and H_y fields</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code>.
It should satisfy <code>operator_h() @ h_xy == wavenumber**2 * h_xy</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The angular frequency of the system</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant grid</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>prop_phase</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Phase shift <code>(dz * corrected_wavenumber)</code> over 1 cell in propagation direction.
Default 0 (continuous propagation direction, i.e. dz-&gt;0).</p>
</div>
</td>
<td>
<code>0</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdslice_t" title="meanas.fdmath.vcfdslice_t">vcfdslice_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p><code>(e, h)</code>, where each field is vectorized, normalized,</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdslice_t" title="meanas.fdmath.vcfdslice_t">vcfdslice_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>and contains all three vector components.</p>
</div>
</td>
</tr>
</tbody>
</table>
<details class="notes" open="">
<summary>Notes</summary>
<p>This is the <code>H_x/H_y</code> analogue of <code>normalized_fields_e(...)</code>. The final
normalized mode should describe the same physical solution, but because
the overall complex phase and sign are chosen heuristically,
<code>normalized_fields_e(...)</code> and <code>normalized_fields_h(...)</code> need not return
identical representatives for nearly symmetric modes.</p>
</details>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.exy2h">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">exy2h</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.exy2h" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">exy2h</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Operator which transforms the vector <code>e_xy</code> containing the vectorized E_x and E_y fields,
into a vectorized H containing all three H components</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code>.
It should satisfy <code>operator_e() @ e_xy == wavenumber**2 * e_xy</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The angular frequency of the system</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant grid</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix representing the operator.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.hxy2e">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">hxy2e</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.hxy2e" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">hxy2e</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Operator which transforms the vector <code>h_xy</code> containing the vectorized H_x and H_y fields,
into a vectorized E containing all three E components</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code>.
It should satisfy <code>operator_h() @ h_xy == wavenumber**2 * h_xy</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The angular frequency of the system</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant grid</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix representing the operator.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.hxy2h">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">hxy2h</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.hxy2h" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">hxy2h</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Operator which transforms the vector <code>h_xy</code> containing the vectorized H_x and H_y fields,
into a vectorized H containing all three H components</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code>.
It should satisfy <code>operator_h() @ h_xy == wavenumber**2 * h_xy</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix representing the operator.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.exy2e">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">exy2e</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.exy2e" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">exy2e</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Operator which transforms the vector <code>e_xy</code> containing the vectorized E_x and E_y fields,
into a vectorized E containing all three E components</p>
<p>From the operator derivation (see module docs), we have</p>
<div class="arithmatex">\[
\imath \omega \epsilon_{zz} E_z = \hat{\partial}_x H_y - \hat{\partial}_y H_x \\
\]</div>
<p>as well as the intermediate equations</p>
<div class="arithmatex">\[
\begin{aligned}
\imath \beta H_y &amp;= \imath \omega \epsilon_{xx} E_x - \hat{\partial}_y H_z \\
\imath \beta H_x &amp;= -\imath \omega \epsilon_{yy} E_y - \hat{\partial}_x H_z \\
\end{aligned}
\]</div>
<p>Combining these, we get</p>
<div class="arithmatex">\[
\begin{aligned}
E_z &amp;= \frac{1}{- \omega \beta \epsilon_{zz}} ((
\hat{\partial}_y \hat{\partial}_x H_z
-\hat{\partial}_x \hat{\partial}_y H_z)
+ \imath \omega (\hat{\partial}_x \epsilon_{xx} E_x + \hat{\partial}_y \epsilon{yy} E_y))
&amp;= \frac{1}{\imath \beta \epsilon_{zz}} (\hat{\partial}_x \epsilon_{xx} E_x + \hat{\partial}_y \epsilon{yy} E_y)
\end{aligned}
\]</div>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code>
It should satisfy <code>operator_e() @ e_xy == wavenumber**2 * e_xy</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant grid</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix representing the operator.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.e2h">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e2h</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.e2h" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e2h</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Returns an operator which, when applied to a vectorized E eigenfield, produces
the vectorized H eigenfield slice.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The angular frequency of the system</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix representation of the operator.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.h2e">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">h2e</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.h2e" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">h2e</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Returns an operator which, when applied to a vectorized H eigenfield, produces
the vectorized E eigenfield slice.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The angular frequency of the system</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant grid</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix representation of the operator.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.curl_e">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">curl_e</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.curl_e" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">curl_e</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Discretized curl operator for use with the waveguide E field slice.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix representation of the operator.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.curl_h">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">curl_h</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.curl_h" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">curl_h</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Discretized curl operator for use with the waveguide H field slice.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix representation of the operator.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.h_err">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">h_err</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.h_err" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">h_err</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">h</span><span class="p">:</span> <span class="n">vcfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">float</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Calculates the relative error in the H field</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>h</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdslice" title=" vcfdslice (meanas.fdmath.vcfdslice)">vcfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized H field</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The angular frequency of the system</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant grid</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Relative error <code>norm(A_h @ h) / norm(h)</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.e_err">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e_err</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.e_err" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e_err</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e</span><span class="p">:</span> <span class="n">vcfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">float</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Calculates the relative error in the E field</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>e</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdslice" title=" vcfdslice (meanas.fdmath.vcfdslice)">vcfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized E field</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber assuming fields have z-dependence of <code>exp(-i * wavenumber * z)</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The angular frequency of the system</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant grid</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Relative error <code>norm(A_e @ e) / norm(e)</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.sensitivity">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">sensitivity</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.sensitivity" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">sensitivity</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e_norm</span><span class="p">:</span> <span class="n">vcfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">h_norm</span><span class="p">:</span> <span class="n">vcfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">vcfdslice_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Given a waveguide structure (<code>dxes</code>, <code>epsilon</code>, <code>mu</code>) and mode fields
(<code>e_norm</code>, <code>h_norm</code>, <code>wavenumber</code>, <code>omega</code>), calculates the sensitivity of the wavenumber
<span class="arithmatex">\(\beta\)</span> to changes in the dielectric structure <span class="arithmatex">\(\epsilon\)</span>.</p>
<p>The output is a vector of the same size as <code>vec(epsilon)</code>, with each element specifying the
sensitivity of <code>wavenumber</code> to changes in the corresponding element in <code>vec(epsilon)</code>, i.e.</p>
<div class="arithmatex">\[sens_{i} = \frac{\partial\beta}{\partial\epsilon_i}\]</div>
<p>An adjoint approach is used to calculate the sensitivity; the derivation is provided here:</p>
<p>Starting with the eigenvalue equation</p>
<div class="arithmatex">\[\beta^2 E_{xy} = A_E E_{xy}\]</div>
<p>where <span class="arithmatex">\(A_E\)</span> is the waveguide operator from <code>operator_e()</code>, and <span class="arithmatex">\(E_{xy} = \begin{bmatrix} E_x \\
E_y \end{bmatrix}\)</span>,
we can differentiate with respect to one of the <span class="arithmatex">\(\epsilon\)</span> elements (i.e. at one Yee grid point), <span class="arithmatex">\(\epsilon_i\)</span>:</p>
<div class="arithmatex">\[
(2 \beta) \partial_{\epsilon_i}(\beta) E_{xy} + \beta^2 \partial_{\epsilon_i} E_{xy}
= \partial_{\epsilon_i}(A_E) E_{xy} + A_E \partial_{\epsilon_i} E_{xy}
\]</div>
<p>We then multiply by <span class="arithmatex">\(H_{yx}^\star = \begin{bmatrix}H_y^\star \\ -H_x^\star \end{bmatrix}\)</span> from the left:</p>
<div class="arithmatex">\[
(2 \beta) \partial_{\epsilon_i}(\beta) H_{yx}^\star E_{xy} + \beta^2 H_{yx}^\star \partial_{\epsilon_i} E_{xy}
= H_{yx}^\star \partial_{\epsilon_i}(A_E) E_{xy} + H_{yx}^\star A_E \partial_{\epsilon_i} E_{xy}
\]</div>
<p>However, <span class="arithmatex">\(H_{yx}^\star\)</span> is actually a left-eigenvector of <span class="arithmatex">\(A_E\)</span>. This can be verified by inspecting
the form of <code>operator_h</code> (<span class="arithmatex">\(A_H\)</span>) and comparing its conjugate transpose to <code>operator_e</code> (<span class="arithmatex">\(A_E\)</span>). Also, note
<span class="arithmatex">\(H_{yx}^\star \cdot E_{xy} = H^\star \times E\)</span> recalls the mode orthogonality relation. See doi:10.5194/ars-9-85-201
for a similar approach. Therefore,</p>
<div class="arithmatex">\[
H_{yx}^\star A_E \partial_{\epsilon_i} E_{xy} = \beta^2 H_{yx}^\star \partial_{\epsilon_i} E_{xy}
\]</div>
<p>and we can simplify to</p>
<div class="arithmatex">\[
\partial_{\epsilon_i}(\beta)
= \frac{1}{2 \beta} \frac{H_{yx}^\star \partial_{\epsilon_i}(A_E) E_{xy} }{H_{yx}^\star E_{xy}}
\]</div>
<p>This expression can be quickly calculated for all <span class="arithmatex">\(i\)</span> by writing out the various terms of
<span class="arithmatex">\(\partial_{\epsilon_i} A_E\)</span> and recognizing that the vector-matrix-vector products (i.e. scalars)
<span class="arithmatex">\(sens_i = \vec{v}_{left} \partial_{\epsilon_i} (\epsilon_{xyz}) \vec{v}_{right}\)</span>, indexed by <span class="arithmatex">\(i\)</span>, can be expressed as
elementwise multiplications <span class="arithmatex">\(\vec{sens} = \vec{v}_{left} \star \vec{v}_{right}\)</span></p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>e_norm</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdslice" title=" vcfdslice (meanas.fdmath.vcfdslice)">vcfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Normalized, vectorized E_xyz field for the mode. E.g. as returned by <code>normalized_fields_e</code>.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>h_norm</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdslice" title=" vcfdslice (meanas.fdmath.vcfdslice)">vcfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Normalized, vectorized H_xyz field for the mode. E.g. as returned by <code>normalized_fields_e</code>.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Propagation constant for the mode. The z-axis is assumed to be continuous (i.e. without numerical dispersion).</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The angular frequency of the system.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant grid</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdslice_t" title="meanas.fdmath.vcfdslice_t">vcfdslice_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix representation of the operator.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.solve_modes">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">solve_modes</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.solve_modes" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">solve_modes</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">mode_numbers</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">mode_margin</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span>
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">],</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">]</span>
<a href="#api-waveguides-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Given a 2D region, attempts to solve for the eigenmode with the specified mode numbers.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>mode_numbers</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>List of 0-indexed mode numbers to solve for</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency of the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Dielectric constant</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Magnetic permeability (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mode_margin</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The eigensolver will actually solve for <code>(max(mode_number) + mode_margin)</code>
modes, but only return the target mode. Increasing this value can improve the solver's
ability to find the correct mode. Default 2.</p>
</div>
</td>
<td>
<code>2</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Name</th> <th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td><code>e_xys</code></td> <td>
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>NDArray of vfdfield_t specifying fields. First dimension is mode number.</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td><code>wavenumbers</code></td> <td>
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>list of wavenumbers</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.solve_mode">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">solve_mode</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.solve_mode" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">solve_mode</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">mode_number</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="n">Any</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">:</span> <span class="n">Any</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span><span class="n">vcfdfield2_t</span><span class="p">,</span> <span class="nb">complex</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Wrapper around <code>solve_modes()</code> that solves for a single mode.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>mode_number</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>0-indexed mode number to solve for</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>*args</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a></code>
</td>
<td>
<div class="doc-md-description">
<p>passed to <code>solve_modes()</code></p>
</div>
</td>
<td>
<code>()</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>**kwargs</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a></code>
</td>
<td>
<div class="doc-md-description">
<p>passed to <code>solve_modes()</code></p>
</div>
</td>
<td>
<code>{}</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdfield2_t" title="meanas.fdmath.vcfdfield2_t">vcfdfield2_t</a>, <a class="autorefs autorefs-internal" href="#complex">complex</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>(e_xy, wavenumber)</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_2d.inner_product">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">inner_product</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_2d.inner_product" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">inner_product</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e1</span><span class="p">:</span> <span class="n">vcfdfield2</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">h2</span><span class="p">:</span> <span class="n">vcfdfield2</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">prop_phase</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">conj_h</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">trapezoid</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">complex</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Compute the discrete waveguide overlap / Poynting inner product.</p>
<p>This is the 2D transverse integral corresponding to the time-averaged
longitudinal Poynting flux,</p>
<div class="arithmatex">\[
\frac{1}{2}\int (E_x H_y - E_y H_x) \, dx \, dy
\]</div>
<p>with the Yee-grid staggering and optional propagation-phase adjustment used
by the waveguide helpers in this module.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>e1</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield2" title=" vcfdfield2 (meanas.fdmath.vcfdfield2)">vcfdfield2</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized electric field, typically from <code>exy2e(...)</code> or
<code>normalized_fields_e(...)</code>.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>h2</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield2" title=" vcfdfield2 (meanas.fdmath.vcfdfield2)">vcfdfield2</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic field, typically from <code>hxy2h(...)</code>,
<code>exy2h(...)</code>, or one of the normalization helpers.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Two-dimensional Yee-grid spacing lists <code>[dx_e, dx_h]</code>.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>prop_phase</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Phase advance over one propagation cell. This is used to
shift the H field into the same longitudinal reference plane as the
E field.</p>
</div>
</td>
<td>
<code>0</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>conj_h</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#bool">bool</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Whether to conjugate <code>h2</code> before forming the overlap. Use
<code>True</code> for the usual time-averaged power normalization.</p>
</div>
</td>
<td>
<code>False</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>trapezoid</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#bool">bool</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Whether to use trapezoidal quadrature instead of the default
rectangular Yee-cell sum.</p>
</div>
</td>
<td>
<code>False</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Complex overlap / longitudinal power integral.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_3d">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd.waveguide_3d</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_3d" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Tools for working with waveguide modes in 3D domains.</p>
<p>This module relies heavily on <code>waveguide_2d</code> and mostly just transforms
its parameters into 2D equivalents and expands the results back into 3D.</p>
<p>The intended workflow is:</p>
<ol>
<li>Select a single-cell slice normal to the propagation axis.</li>
<li>Solve the corresponding 2D mode problem with <code>solve_mode(...)</code>.</li>
<li>Turn that mode into a one-sided source with <code>compute_source(...)</code>.</li>
<li>Build an overlap window with <code>compute_overlap_e(...)</code> for port readout.</li>
</ol>
<p><code>polarity</code> is part of the public convention throughout this module:</p>
<ul>
<li><code>+1</code> means forward propagation toward increasing index along <code>axis</code></li>
<li><code>-1</code> means backward propagation toward decreasing index along <code>axis</code></li>
</ul>
<p>That same convention controls which side of the selected slice is used for the
overlap window and how the expanded field is phased.</p>
<div class="doc doc-children">
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_3d.solve_mode">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">solve_mode</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_3d.solve_mode" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">solve_mode</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">mode_number</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">polarity</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">slices</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">slice</span><span class="p">],</span>
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">complex</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">]]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Given a 3D grid, selects a slice from the grid and attempts to
solve for an eigenmode propagating through that slice.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>mode_number</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Number of the mode, 0-indexed</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency of the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>axis</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Propagation axis (0=x, 1=y, 2=z)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>polarity</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Propagation direction (+1 for +ve, -1 for -ve)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>slices</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice">slice</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p><code>epsilon[tuple(slices)]</code> is used to select the portion of the grid to use
as the waveguide cross-section. <code>slices[axis]</code> must select exactly one item.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Dielectric constant</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Magnetic permeability (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#complex">complex</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
</td>
<td>
<div class="doc-md-description">
<p>Dictionary containing:</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#complex">complex</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>E</code>: full-grid electric field for the solved mode</li>
</ul>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#complex">complex</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>H</code>: full-grid magnetic field for the solved mode</li>
</ul>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#complex">complex</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>wavenumber</code>: propagation constant corrected for the discretized
propagation axis</li>
</ul>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#complex">complex</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>wavenumber_2d</code>: propagation constant of the reduced 2D eigenproblem</li>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
<details class="notes" open="">
<summary>Notes</summary>
<p>The returned fields are normalized through the <code>waveguide_2d</code>
normalization convention before being expanded back to 3D.</p>
</details>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_3d.compute_source">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">compute_source</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_3d.compute_source" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">compute_source</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">E</span><span class="p">:</span> <span class="n">cfdfield</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">polarity</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">slices</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">slice</span><span class="p">],</span>
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">cfdfield_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Given an eigenmode obtained by <code>solve_mode</code>, returns the current source distribution
necessary to position a unidirectional source at the slice location.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>E</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>E-field of the mode</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber of the mode</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency of the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>axis</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Propagation axis (0=x, 1=y, 2=z)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>polarity</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Propagation direction (+1 for +ve, -1 for -ve)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>slices</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice">slice</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p><code>epsilon[tuple(slices)]</code> is used to select the portion of the grid to use
as the waveguide cross-section. <code>slices[axis]</code> should select only one item.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Magnetic permeability (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p><code>J</code> distribution for a one-sided electric-current source.</p>
</div>
</td>
</tr>
</tbody>
</table>
<details class="notes" open="">
<summary>Notes</summary>
<p>The source is built from the expanded mode field and a boundary-source
operator. The resulting current is intended to be injected with the
same sign convention used elsewhere in the package:</p>
<p><code>E -= dt * J / epsilon</code></p>
</details>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_3d.compute_overlap_e">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">compute_overlap_e</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_3d.compute_overlap_e" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">compute_overlap_e</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">E</span><span class="p">:</span> <span class="n">cfdfield_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">polarity</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">slices</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">slice</span><span class="p">],</span>
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">cfdfield_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Build an overlap field for projecting another 3D electric field onto a mode.</p>
<p>The returned field is intended for the discrete overlap expression</p>
<div class="arithmatex">\[
\sum \mathrm{overlap\_e} \; E_\mathrm{other}^*
\]</div>
<p>where the sum is over the full Yee-grid field storage.</p>
<p>The construction uses a two-cell window immediately upstream of the selected
slice:</p>
<ul>
<li>for <code>polarity=+1</code>, the two cells just before <code>slices[axis].start</code></li>
<li>for <code>polarity=-1</code>, the two cells just after <code>slices[axis].stop</code></li>
</ul>
<p>The window is clipped to the simulation domain if necessary. A clipped but
non-empty window raises <code>RuntimeWarning</code>; an empty window raises
<code>ValueError</code>.</p>
<p>The derivation below assumes reflection symmetry and the standard waveguide
overlap relation involving</p>
<div class="arithmatex">\[
\int ((E \times H_\mathrm{mode}) + (E_\mathrm{mode} \times H)) \cdot dn.
\]</div>
<p>E x H_mode + E_mode x H
-&gt; Ex Hmy - EyHmx + Emx Hy - Emy Hx (Z-prop)
Ex we/B Emx + Ex i/B dy Hmz - Ey (-we/B Emy) - Ey i/B dx Hmz
we/B (Ex Emx + Ey Emy) + i/B (Ex dy Hmz - Ey dx Hmz)
we/B (Ex Emx + Ey Emy) + i/B (Ex dy (dx Emy - dy Emx) - Ey dx (dx Emy - dy Emx))
we/B (Ex Emx + Ey Emy) + i/B (Ex dy dx Emy - Ex dy dy Emx - Ey dx dx Emy - Ey dx dy Emx)</p>
<p>Ex j/wu (-jB Emx - dx Emz) - Ey j/wu (dy Emz + jB Emy)
B/wu (Ex Emx + Ey Emy) - j/wu (Ex dx Emz + Ey dy Emz)</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>E</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>E-field of the mode</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber of the mode</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>axis</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Propagation axis (0=x, 1=y, 2=z)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>polarity</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Propagation direction (+1 for +ve, -1 for -ve)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>slices</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice">slice</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p><code>epsilon[tuple(slices)]</code> is used to select the portion of the grid to use
as the waveguide cross-section. slices[axis] should select only one item.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p><code>overlap_e</code> normalized so that <code>numpy.sum(overlap_e * E.conj()) == 1</code></p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>over the retained overlap window.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_3d.expand_e">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">expand_e</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_3d.expand_e" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">expand_e</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">E</span><span class="p">:</span> <span class="n">cfdfield</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">polarity</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">slices</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">slice</span><span class="p">],</span>
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">cfdfield_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Given an eigenmode obtained by <code>solve_mode</code>, expands the E-field from the 2D
slice where the mode was calculated to the entire domain (along the propagation
axis). This assumes the epsilon cross-section remains constant throughout the
entire domain; it is up to the caller to truncate the expansion to any regions
where it is valid.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>E</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.cfdfield" title=" cfdfield (meanas.fdmath.cfdfield)">cfdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>E-field of the mode</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber of the mode</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>axis</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Propagation axis (0=x, 1=y, 2=z)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>polarity</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Propagation direction (+1 for +ve, -1 for -ve)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>slices</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice">slice</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p><code>epsilon[tuple(slices)]</code> is used to select the portion of the grid to use
as the waveguide cross-section. slices[axis] should select only one item.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.cfdfield_t" title="meanas.fdmath.cfdfield_t">cfdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p><code>E</code>, with the original field expanded along the specified <code>axis</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
<details class="notes" open="">
<summary>Notes</summary>
<p>This helper assumes that the waveguide cross-section remains constant
along the propagation axis and applies the phase factor</p>
<div class="arithmatex">\[
e^{-i \, \mathrm{polarity} \, wavenumber \, \Delta z}
\]</div>
<p>to each copied slice.</p>
</details>
</div>
</div>
</div>
</div>
</div>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdfd.waveguide_cyl</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Operators and helper functions for cylindrical waveguides with unchanging cross-section.</p>
<p>Waveguide operator is derived according to 10.1364/OL.33.001848.</p>
<p>As in <code>waveguide_2d</code>, the propagation dependence is separated from the
transverse solve. Here the propagation coordinate is the bend angle <code>\theta</code>,
and the fields are assumed to have the form</p>
<div class="arithmatex">\[
\vec{E}(r, y, \theta), \vec{H}(r, y, \theta) \propto e^{-\imath m \theta},
\]</div>
<p>where <code>m</code> is the angular wavenumber returned by <code>solve_mode(s)</code>. It is often
convenient to introduce the corresponding linear wavenumber</p>
<div class="arithmatex">\[
\beta = \frac{m}{r_{\min}},
\]</div>
<p>so that the cylindrical problem resembles the straight-waveguide problem with
additional metric factors.</p>
<p>Those metric factors live on the staggered radial Yee grids. If the left edge of
the computational window is at <code>r = r_{\min}</code>, define the electric-grid and
magnetic-grid radial sample locations by</p>
<div class="arithmatex">\[
\begin{aligned}
r_a(n) &amp;= r_{\min} + \sum_{j \le n} \Delta r_{e, j}, \\
r_b\!\left(n + \tfrac{1}{2}\right) &amp;= r_{\min} + \tfrac{1}{2}\Delta r_{e, n}
+ \sum_{j &lt; n} \Delta r_{h, j},
\end{aligned}
\]</div>
<p>and from them the diagonal metric matrices</p>
<div class="arithmatex">\[
\begin{aligned}
T_a &amp;= \operatorname{diag}(r_a / r_{\min}), \\
T_b &amp;= \operatorname{diag}(r_b / r_{\min}).
\end{aligned}
\]</div>
<p>With the same forward/backward derivative notation used in <code>waveguide_2d</code>, the
coordinate-transformed discrete curl equations used here are</p>
<div class="arithmatex">\[
\begin{aligned}
-\imath \omega \mu_{rr} H_r &amp;= \tilde{\partial}_y E_z + \imath \beta T_a^{-1} E_y, \\
-\imath \omega \mu_{yy} H_y &amp;= -\imath \beta T_b^{-1} E_r
- T_b^{-1} \tilde{\partial}_r (T_a E_z), \\
-\imath \omega \mu_{zz} H_z &amp;= \tilde{\partial}_r E_y - \tilde{\partial}_y E_r, \\
\imath \beta H_y &amp;= -\imath \omega T_b \epsilon_{rr} E_r - T_b \hat{\partial}_y H_z, \\
\imath \beta H_r &amp;= \imath \omega T_a \epsilon_{yy} E_y
- T_b T_a^{-1} \hat{\partial}_r (T_b H_z), \\
\imath \omega E_z &amp;= T_a \epsilon_{zz}^{-1}
\left(\hat{\partial}_r H_y - \hat{\partial}_y H_r\right).
\end{aligned}
\]</div>
<p>The first three equations are the cylindrical analogue of the straight-guide
relations for <code>H_r</code>, <code>H_y</code>, and <code>H_z</code>. The next two are the metric-weighted
versions of the straight-guide identities for <code>\imath \beta H_y</code> and
<code>\imath \beta H_r</code>, and the last equation plays the same role as the
longitudinal <code>E_z</code> reconstruction in <code>waveguide_2d</code>.</p>
<p>Following the same elimination steps as in <code>waveguide_2d</code>, apply
<code>\imath \beta \tilde{\partial}_r</code> and <code>\imath \beta \tilde{\partial}_y</code> to the
equation for <code>E_z</code>, substitute for <code>\imath \beta H_r</code> and <code>\imath \beta H_y</code>,
and then eliminate <code>H_z</code> with</p>
<div class="arithmatex">\[
H_z = \frac{1}{-\imath \omega \mu_{zz}}
\left(\tilde{\partial}_r E_y - \tilde{\partial}_y E_r\right).
\]</div>
<p>This yields the transverse electric eigenproblem implemented by
<code>cylindrical_operator(...)</code>:</p>
<div class="arithmatex">\[
\beta^2
\begin{bmatrix} E_r \\ E_y \end{bmatrix}
=
\left(
\omega^2
\begin{bmatrix}
T_b^2 \mu_{yy} \epsilon_{xx} &amp; 0 \\
0 &amp; T_a^2 \mu_{xx} \epsilon_{yy}
\end{bmatrix}
+
\begin{bmatrix}
-T_b \mu_{yy} \hat{\partial}_y \\
T_a \mu_{xx} \hat{\partial}_x
\end{bmatrix}
T_b \mu_{zz}^{-1}
\begin{bmatrix}
-\tilde{\partial}_y &amp; \tilde{\partial}_x
\end{bmatrix}
+
\begin{bmatrix}
\tilde{\partial}_x \\
\tilde{\partial}_y
\end{bmatrix}
T_a \epsilon_{zz}^{-1}
\begin{bmatrix}
\hat{\partial}_x T_b \epsilon_{xx} &amp;
\hat{\partial}_y T_a \epsilon_{yy}
\end{bmatrix}
\right)
\begin{bmatrix} E_r \\ E_y \end{bmatrix}.
\]</div>
<p>Since <code>\beta = m / r_{\min}</code>, the solver implemented in this file returns the
angular wavenumber <code>m</code>, while the operator itself is most naturally written in
terms of the linear quantity <code>\beta</code>. The helpers below reconstruct the full
field components from the solved transverse eigenvector and then normalize the
mode to unit forward power with the same discrete longitudinal Poynting inner
product used by <code>waveguide_2d</code>.</p>
<p>As in the straight-waveguide case, all functions here assume a 2D grid:</p>
<p><code>dxes = [[[dr_e_0, dr_e_1, ...], [dy_e_0, ...]], [[dr_h_0, ...], [dy_h_0, ...]]]</code>.</p>
<div class="doc doc-children">
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.cylindrical_operator">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">cylindrical_operator</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.cylindrical_operator" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">cylindrical_operator</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">rmin</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Cylindrical coordinate waveguide operator of the form</p>
<div class="arithmatex">\[
(\omega^2 \begin{bmatrix} T_b T_b \mu_{yy} \epsilon_{xx} &amp; 0 \\
0 &amp; T_a T_a \mu_{xx} \epsilon_{yy} \end{bmatrix} +
\begin{bmatrix} -T_b \mu_{yy} \hat{\partial}_y \\
T_a \mu_{xx} \hat{\partial}_x \end{bmatrix} T_b \mu_{zz}^{-1}
\begin{bmatrix} -\tilde{\partial}_y &amp; \tilde{\partial}_x \end{bmatrix} +
\begin{bmatrix} \tilde{\partial}_x \\
\tilde{\partial}_y \end{bmatrix} T_a \epsilon_{zz}^{-1}
\begin{bmatrix} \hat{\partial}_x T_b \epsilon_{xx} &amp; \hat{\partial}_y T_a \epsilon_{yy} \end{bmatrix})
\begin{bmatrix} E_r \\
E_y \end{bmatrix}
\]</div>
<p>for use with a field vector of the form <code>[E_r, E_y]</code>.</p>
<p>This operator can be used to form an eigenvalue problem of the form
A @ [E_r, E_y] = beta**2 * [E_r, E_y]</p>
<p>which can then be solved for the eigenmodes of the system
(an <code>exp(-i * angular_wavenumber * theta)</code> theta-dependence is assumed for
the fields, with <code>beta = angular_wavenumber / rmin</code>).</p>
<p>(NOTE: See module docs and 10.1364/OL.33.001848)</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The angular frequency of the system</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant grid</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>rmin</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Radius at the left edge of the simulation domain (at minimum 'x')</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix representation of the operator</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.solve_modes">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">solve_modes</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.solve_modes" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">solve_modes</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">mode_numbers</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">rmin</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">mode_margin</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span>
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">],</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">]</span>
<a href="#api-waveguides-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Given a 2d (r, y) slice of epsilon, attempts to solve for the eigenmode
of the bent waveguide with the specified mode number.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>mode_number</code>
</td>
<td>
</td>
<td>
<div class="doc-md-description">
<p>Number of the mode, 0-indexed</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Angular frequency of the simulation</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters [dx_e, dx_h] as described in meanas.fdmath.types.
The first coordinate is assumed to be r, the second is y.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Dielectric constant</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>rmin</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Radius of curvature for the simulation. This should be the minimum value of
r within the simulation domain.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Name</th> <th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td><code>e_xys</code></td> <td>
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>NDArray of vfdfield_t specifying fields. First dimension is mode number.</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td><code>angular_wavenumbers</code></td> <td>
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>list of wavenumbers in 1/rad units.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.solve_mode">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">solve_mode</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.solve_mode" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">solve_mode</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">mode_number</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="n">Any</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">:</span> <span class="n">Any</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span><span class="n">vcfdslice</span><span class="p">,</span> <span class="nb">complex</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Wrapper around <code>solve_modes()</code> that solves for a single mode.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>mode_number</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>0-indexed mode number to solve for</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>*args</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a></code>
</td>
<td>
<div class="doc-md-description">
<p>passed to <code>solve_modes()</code></p>
</div>
</td>
<td>
<code>()</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>**kwargs</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a></code>
</td>
<td>
<div class="doc-md-description">
<p>passed to <code>solve_modes()</code></p>
</div>
</td>
<td>
<code>{}</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdslice" title=" vcfdslice (meanas.fdmath.vcfdslice)">vcfdslice</a>, <a class="autorefs autorefs-internal" href="#complex">complex</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>(e_xy, angular_wavenumber)</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.linear_wavenumbers">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">linear_wavenumbers</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.linear_wavenumbers" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">linear_wavenumbers</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e_xys</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">vcfdfield2_t</span><span class="p">],</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">angular_wavenumbers</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">rmin</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complex128</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Calculate linear wavenumbers (1/distance) based on angular wavenumbers (1/rad)
and the mode's energy distribution.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>e_xys</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdfield2_t" title="meanas.fdmath.vcfdfield2_t">vcfdfield2_t</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized mode fields with shape (num_modes, 2 * x *y)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>angular_wavenumbers</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#numpy.typing.ArrayLike" title="numpy.typing.ArrayLike">ArrayLike</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumbers assuming fields have theta-dependence of
<code>exp(-i * angular_wavenumber * theta)</code>. They should satisfy
<code>operator_e() @ e_xy == (angular_wavenumber / rmin) ** 2 * e_xy</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant grid with shape (3, x, y)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>rmin</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Radius at the left edge of the simulation domain (at minimum 'x')</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.complex128" title="numpy.complex128">complex128</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>NDArray containing the calculated linear (1/distance) wavenumbers</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.exy2h">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">exy2h</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.exy2h" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">exy2h</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">angular_wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">rmin</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Operator which transforms the vector <code>e_xy</code> containing the vectorized E_r and E_y fields,
into a vectorized H containing all three H components</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>angular_wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber assuming fields have theta-dependence of
<code>exp(-i * angular_wavenumber * theta)</code>. It should satisfy
<code>operator_e() @ e_xy == (angular_wavenumber / rmin) ** 2 * e_xy</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The angular frequency of the system</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>rmin</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Radius at the left edge of the simulation domain (at minimum 'x')</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant grid</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix representing the operator.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.exy2e">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">exy2e</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.exy2e" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">exy2e</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">angular_wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">rmin</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Operator which transforms the vector <code>e_xy</code> containing the vectorized E_r and E_y fields,
into a vectorized E containing all three E components</p>
<p>Unlike the straight waveguide case, the H_z components do not cancel and must be calculated
from E_r and E_y in order to then calculate E_z.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>angular_wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber assuming fields have theta-dependence of
<code>exp(-i * angular_wavenumber * theta)</code>. It should satisfy
<code>operator_e() @ e_xy == (angular_wavenumber / rmin) ** 2 * e_xy</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The angular frequency of the system</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>rmin</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Radius at the left edge of the simulation domain (at minimum 'x')</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant grid</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix representing the operator.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.e2h">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">e2h</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.e2h" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">e2h</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">angular_wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">rmin</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Returns an operator which, when applied to a vectorized E eigenfield, produces
the vectorized H eigenfield.</p>
<p>This operator is created directly from the initial coordinate-transformed equations:
$$
\begin{aligned}
-\imath \omega \mu_{rr} H_r &amp;= \tilde{\partial}<em yy="yy">y E_z + \imath \beta T_a^{-1} E_y, \
-\imath \omega \mu</em> E_r
- T_b^{-1} \tilde{\partial}} H_y &amp;= -\imath \beta T_b^{-1<em zz="zz">r (T_a E_z), \
-\imath \omega \mu</em>_y E_r,
\end{aligned}
$$} H_z &amp;= \tilde{\partial}_r E_y - \tilde{\partial</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>angular_wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber assuming fields have theta-dependence of
<code>exp(-i * angular_wavenumber * theta)</code>. It should satisfy
<code>operator_e() @ e_xy == (angular_wavenumber / rmin) ** 2 * e_xy</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The angular frequency of the system</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>rmin</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Radius at the left edge of the simulation domain (at minimum 'x')</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix representation of the operator.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.dxes2T">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">dxes2T</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.dxes2T" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">dxes2T</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span> <span class="n">rmin</span><span class="p">:</span> <span class="nb">float</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">float64</span><span class="p">],</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">float64</span><span class="p">]]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Construct the cylindrical metric matrices <span class="arithmatex">\(T_a\)</span> and <span class="arithmatex">\(T_b\)</span>.</p>
<p><code>T_a</code> is sampled on the E-grid radial locations, while <code>T_b</code> is sampled on
the staggered H-grid radial locations. These are the diagonal matrices that
convert the straight-waveguide algebra into its cylindrical counterpart.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>rmin</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Radius at the left edge of the simulation domain (at minimum 'x')</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.float64" title="numpy.float64">float64</a>], <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.float64" title="numpy.float64">float64</a>]]</code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse diagonal matrices <code>(T_a, T_b)</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-waveguides-meanas.fdfd.waveguide_cyl.normalized_fields_e">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">normalized_fields_e</span>
<a class="headerlink" href="#api-waveguides-meanas.fdfd.waveguide_cyl.normalized_fields_e" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-waveguides-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">normalized_fields_e</span><span class="p">(</span>
<a href="#api-waveguides-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e_xy</span><span class="p">:</span> <span class="n">vcfdfield2</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">angular_wavenumber</span><span class="p">:</span> <span class="nb">complex</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">omega</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists2_t</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">rmin</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">vfdslice</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">vfdslice</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">prop_phase</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
<a href="#api-waveguides-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span><span class="n">vcfdslice_t</span><span class="p">,</span> <span class="n">vcfdslice_t</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Given a vector <code>e_xy</code> containing the vectorized E_r and E_y fields,
returns normalized, vectorized E and H fields for the system.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>e_xy</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vcfdfield2" title=" vcfdfield2 (meanas.fdmath.vcfdfield2)">vcfdfield2</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vector containing E_r and E_y fields</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>angular_wavenumber</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#complex">complex</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Wavenumber assuming fields have theta-dependence of
<code>exp(-i * angular_wavenumber * theta)</code>. It should satisfy
<code>operator_e() @ e_xy == (angular_wavenumber / rmin) ** 2 * e_xy</code></p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>omega</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>The angular frequency of the system</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title=" dx_lists2_t
module-attribute
(meanas.fdmath.dx_lists2_t)">dx_lists2_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Grid parameters <code>[dx_e, dx_h]</code> as described in <code>meanas.fdmath.types</code> (2D)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>rmin</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Radius at the left edge of the simulation domain (at minimum 'x')</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized dielectric constant grid</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.vfdslice" title=" vfdslice (meanas.fdmath.vfdslice)">vfdslice</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Vectorized magnetic permeability grid (default 1 everywhere)</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>prop_phase</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Phase shift <code>(dz * corrected_wavenumber)</code> over 1 cell in propagation direction.
Default 0 (continuous propagation direction, i.e. dz-&gt;0).</p>
</div>
</td>
<td>
<code>0</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdslice_t" title="meanas.fdmath.vcfdslice_t">vcfdslice_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p><code>(e, h)</code>, where each field is vectorized, normalized,</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.vcfdslice_t" title="meanas.fdmath.vcfdslice_t">vcfdslice_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>and contains all three vector components.</p>
</div>
</td>
</tr>
</tbody>
</table>
<details class="notes" open="">
<summary>Notes</summary>
<p>The normalization step is delegated to <code>_normalized_fields(...)</code>, which
enforces unit forward power under the discrete inner product</p>
<div class="arithmatex">\[
\frac{1}{2}\int (E_r H_y^* - E_y H_r^*) \, dr \, dy.
\]</div>
<p>The angular wavenumber <code>m</code> is first converted into the full three-component
fields, then the overall complex phase and sign are fixed so the result is
reproducible for symmetric modes.</p>
</details>
</div>
</div>
</div>
</div>
</div></section><section class="print-page" heading-number="2.6" id="api-fdtd"><h1 id="api-fdtd-fdtd">fdtd<a class="headerlink" href="#api-fdtd-fdtd" title="Permanent link"></a></h1>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-fdtd-meanas.fdtd">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdtd</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Utilities for running finite-difference time-domain (FDTD) simulations</p>
<p>See the discussion of <code>Maxwell's Equations</code> in <code>meanas.fdmath</code> for basic
mathematical background.</p>
<h3 id="api-fdtd-meanas.fdtd--timestep">Timestep<a class="headerlink" href="#api-fdtd-meanas.fdtd--timestep" title="Permanent link"></a></h3>
<p>From the discussion of "Plane waves and the Dispersion relation" in <code>meanas.fdmath</code>,
we have</p>
<div class="arithmatex">\[ c^2 \Delta_t^2 = \frac{\Delta_t^2}{\mu \epsilon} &lt; 1/(\frac{1}{\Delta_x^2} + \frac{1}{\Delta_y^2} + \frac{1}{\Delta_z^2}) \]</div>
<p>or, if <span class="arithmatex">\(\Delta_x = \Delta_y = \Delta_z\)</span>, then <span class="arithmatex">\(c \Delta_t &lt; \frac{\Delta_x}{\sqrt{3}}\)</span>.</p>
<p>Based on this, we can set</p>
<div class="highlight"><pre><span></span><code>dt = sqrt(mu.min() * epsilon.min()) / sqrt(1/dx_min**2 + 1/dy_min**2 + 1/dz_min**2)
</code></pre></div>
<p>The <code>dx_min</code>, <code>dy_min</code>, <code>dz_min</code> should be the minimum value across both the base and derived grids.</p>
<h3 id="api-fdtd-meanas.fdtd--poynting-vector-and-energy-conservation">Poynting Vector and Energy Conservation<a class="headerlink" href="#api-fdtd-meanas.fdtd--poynting-vector-and-energy-conservation" title="Permanent link"></a></h3>
<p>Let</p>
<div class="arithmatex">\[ \begin{aligned}
\tilde{S}_{l, l', \vec{r}} &amp;=&amp; &amp;\tilde{E}_{l, \vec{r}} \otimes \hat{H}_{l', \vec{r} + \frac{1}{2}} \\
&amp;=&amp; &amp;\vec{x} (\tilde{E}^y_{l,m+1,n,p} \hat{H}^z_{l',\vec{r} + \frac{1}{2}} - \tilde{E}^z_{l,m+1,n,p} \hat{H}^y_{l', \vec{r} + \frac{1}{2}}) \\
&amp; &amp;+ &amp;\vec{y} (\tilde{E}^z_{l,m,n+1,p} \hat{H}^x_{l',\vec{r} + \frac{1}{2}} - \tilde{E}^x_{l,m,n+1,p} \hat{H}^z_{l', \vec{r} + \frac{1}{2}}) \\
&amp; &amp;+ &amp;\vec{z} (\tilde{E}^x_{l,m,n,p+1} \hat{H}^y_{l',\vec{r} + \frac{1}{2}} - \tilde{E}^y_{l,m,n,p+1} \hat{H}^z_{l', \vec{r} + \frac{1}{2}})
\end{aligned}
\]</div>
<p>where <span class="arithmatex">\(\vec{r} = (m, n, p)\)</span> and <span class="arithmatex">\(\otimes\)</span> is a modified cross product
in which the <span class="arithmatex">\(\tilde{E}\)</span> terms are shifted as indicated.</p>
<p>By taking the divergence and rearranging terms, we can show that</p>
<div class="arithmatex">\[
\begin{aligned}
\hat{\nabla} \cdot \tilde{S}_{l, l', \vec{r}}
&amp;= \hat{\nabla} \cdot (\tilde{E}_{l, \vec{r}} \otimes \hat{H}_{l', \vec{r} + \frac{1}{2}}) \\
&amp;= \hat{H}_{l', \vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l, \vec{r}} -
\tilde{E}_{l, \vec{r}} \cdot \hat{\nabla} \times \hat{H}_{l', \vec{r} + \frac{1}{2}} \\
&amp;= \hat{H}_{l', \vec{r} + \frac{1}{2}} \cdot
(-\tilde{\partial}_t \mu_{\vec{r} + \frac{1}{2}} \hat{H}_{l - \frac{1}{2}, \vec{r} + \frac{1}{2}} -
\hat{M}_{l, \vec{r} + \frac{1}{2}}) -
\tilde{E}_{l, \vec{r}} \cdot (\hat{\partial}_t \tilde{\epsilon}_{\vec{r}} \tilde{E}_{l'+\frac{1}{2}, \vec{r}} +
\tilde{J}_{l', \vec{r}}) \\
&amp;= \hat{H}_{l'} \cdot (-\mu / \Delta_t)(\hat{H}_{l + \frac{1}{2}} - \hat{H}_{l - \frac{1}{2}}) -
\tilde{E}_l \cdot (\epsilon / \Delta_t )(\tilde{E}_{l'+\frac{1}{2}} - \tilde{E}_{l'-\frac{1}{2}})
- \hat{H}_{l'} \cdot \hat{M}_{l} - \tilde{E}_l \cdot \tilde{J}_{l'} \\
\end{aligned}
\]</div>
<p>where in the last line the spatial subscripts have been dropped to emphasize
the time subscripts <span class="arithmatex">\(l, l'\)</span>, i.e.</p>
<div class="arithmatex">\[
\begin{aligned}
\tilde{E}_l &amp;= \tilde{E}_{l, \vec{r}} \\
\hat{H}_l &amp;= \tilde{H}_{l, \vec{r} + \frac{1}{2}} \\
\tilde{\epsilon} &amp;= \tilde{\epsilon}_{\vec{r}} \\
\end{aligned}
\]</div>
<p>etc.
For <span class="arithmatex">\(l' = l + \frac{1}{2}\)</span> we get</p>
<div class="arithmatex">\[
\begin{aligned}
\hat{\nabla} \cdot \tilde{S}_{l, l + \frac{1}{2}}
&amp;= \hat{H}_{l + \frac{1}{2}} \cdot
(-\mu / \Delta_t)(\hat{H}_{l + \frac{1}{2}} - \hat{H}_{l - \frac{1}{2}}) -
\tilde{E}_l \cdot (\epsilon / \Delta_t)(\tilde{E}_{l+1} - \tilde{E}_l)
- \hat{H}_{l'} \cdot \hat{M}_l - \tilde{E}_l \cdot \tilde{J}_{l + \frac{1}{2}} \\
&amp;= (-\mu / \Delta_t)(\hat{H}^2_{l + \frac{1}{2}} - \hat{H}_{l + \frac{1}{2}} \cdot \hat{H}_{l - \frac{1}{2}}) -
(\epsilon / \Delta_t)(\tilde{E}_{l+1} \cdot \tilde{E}_l - \tilde{E}^2_l)
- \hat{H}_{l'} \cdot \hat{M}_l - \tilde{E}_l \cdot \tilde{J}_{l + \frac{1}{2}} \\
&amp;= -(\mu \hat{H}^2_{l + \frac{1}{2}}
+\epsilon \tilde{E}_{l+1} \cdot \tilde{E}_l) / \Delta_t \\
+(\mu \hat{H}_{l + \frac{1}{2}} \cdot \hat{H}_{l - \frac{1}{2}}
+\epsilon \tilde{E}^2_l) / \Delta_t \\
- \hat{H}_{l+\frac{1}{2}} \cdot \hat{M}_l \\
- \tilde{E}_l \cdot \tilde{J}_{l+\frac{1}{2}} \\
\end{aligned}
\]</div>
<p>and for <span class="arithmatex">\(l' = l - \frac{1}{2}\)</span>,</p>
<div class="arithmatex">\[
\begin{aligned}
\hat{\nabla} \cdot \tilde{S}_{l, l - \frac{1}{2}}
&amp;= (\mu \hat{H}^2_{l - \frac{1}{2}}
+\epsilon \tilde{E}_{l-1} \cdot \tilde{E}_l) / \Delta_t \\
-(\mu \hat{H}_{l + \frac{1}{2}} \cdot \hat{H}_{l - \frac{1}{2}}
+\epsilon \tilde{E}^2_l) / \Delta_t \\
- \hat{H}_{l-\frac{1}{2}} \cdot \hat{M}_l \\
- \tilde{E}_l \cdot \tilde{J}_{l-\frac{1}{2}} \\
\end{aligned}
\]</div>
<p>These two results form the discrete time-domain analogue to Poynting's theorem.
They hint at the expressions for the energy, which can be calculated at the same
time-index as either the E or H field:</p>
<div class="arithmatex">\[
\begin{aligned}
U_l &amp;= \epsilon \tilde{E}^2_l + \mu \hat{H}_{l + \frac{1}{2}} \cdot \hat{H}_{l - \frac{1}{2}} \\
U_{l + \frac{1}{2}} &amp;= \epsilon \tilde{E}_l \cdot \tilde{E}_{l + 1} + \mu \hat{H}^2_{l + \frac{1}{2}} \\
\end{aligned}
\]</div>
<p>Rewriting the Poynting theorem in terms of the energy expressions,</p>
<div class="arithmatex">\[
\begin{aligned}
(U_{l+\frac{1}{2}} - U_l) / \Delta_t
&amp;= -\hat{\nabla} \cdot \tilde{S}_{l, l + \frac{1}{2}} \\
- \hat{H}_{l+\frac{1}{2}} \cdot \hat{M}_l \\
- \tilde{E}_l \cdot \tilde{J}_{l+\frac{1}{2}} \\
(U_l - U_{l-\frac{1}{2}}) / \Delta_t
&amp;= -\hat{\nabla} \cdot \tilde{S}_{l, l - \frac{1}{2}} \\
- \hat{H}_{l-\frac{1}{2}} \cdot \hat{M}_l \\
- \tilde{E}_l \cdot \tilde{J}_{l-\frac{1}{2}} \\
\end{aligned}
\]</div>
<p>This result is exact and should practically hold to within numerical precision. No time-
or spatial-averaging is necessary.</p>
<p>Note that each value of <span class="arithmatex">\(J\)</span> contributes to the energy twice (i.e. once per field update)
despite only causing the value of <span class="arithmatex">\(E\)</span> to change once (same for <span class="arithmatex">\(M\)</span> and <span class="arithmatex">\(H\)</span>).</p>
<h3 id="api-fdtd-meanas.fdtd--sources">Sources<a class="headerlink" href="#api-fdtd-meanas.fdtd--sources" title="Permanent link"></a></h3>
<p>It is often useful to excite the simulation with an arbitrary broadband pulse and then
extract the frequency-domain response by performing an on-the-fly Fourier transform
of the time-domain fields.</p>
<p><code>accumulate_phasor</code> in <code>meanas.fdtd.phasor</code> performs the phase accumulation for one
or more target frequencies, while leaving source normalization and simulation-loop
policy to the caller. Convenience wrappers <code>accumulate_phasor_e</code>,
<code>accumulate_phasor_h</code>, and <code>accumulate_phasor_j</code> apply the usual Yee time offsets.
The helpers accumulate</p>
<div class="arithmatex">\[ \Delta_t \sum_l w_l e^{-i \omega t_l} f_l \]</div>
<p>with caller-provided sample times and weights. In this codebase the matching
electric-current convention is typically <code>E -= dt * J / epsilon</code> in FDTD and
<code>-i \omega J</code> on the right-hand side of the FDFD wave equation.</p>
<p>The Ricker wavelet (normalized second derivative of a Gaussian) is commonly used for the pulse
shape. It can be written</p>
<div class="arithmatex">\[ f_r(t) = (1 - \frac{1}{2} (\omega (t - \tau))^2) e^{-(\frac{\omega (t - \tau)}{2})^2} \]</div>
<p>with <span class="arithmatex">\(\tau &gt; \frac{2 * \pi}{\omega}\)</span> as a minimum delay to avoid a discontinuity at
t=0 (assuming the source is off for t&lt;0 this gives <span class="arithmatex">\(\sim 10^{-3}\)</span> error at t=0).</p>
<h3 id="api-fdtd-meanas.fdtd--boundary-conditions">Boundary conditions<a class="headerlink" href="#api-fdtd-meanas.fdtd--boundary-conditions" title="Permanent link"></a></h3>
<p><code>meanas.fdtd</code> exposes two boundary-related building blocks:</p>
<ul>
<li><code>conducting_boundary(...)</code> for simple perfect-electric-conductor style field
clamping at one face of the domain.</li>
<li><code>cpml_params(...)</code> and <code>updates_with_cpml(...)</code> for convolutional perfectly
matched layers (CPMLs) attached to one or more faces of the Yee grid.</li>
</ul>
<p><code>updates_with_cpml(...)</code> accepts a three-by-two table of CPML parameter blocks:</p>
<div class="highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>cpml_params[axis][polarity_index]
</code></pre></div>
<p>where <code>axis</code> is <code>0</code>, <code>1</code>, or <code>2</code> and <code>polarity_index</code> corresponds to <code>(-1, +1)</code>.
Passing <code>None</code> for one entry disables CPML on that face while leaving the other
directions unchanged. This is how mixed boundary setups such as "absorbing in x,
periodic in y/z" are expressed.</p>
<p>When comparing an FDTD run against an FDFD solve, use the same stretched
coordinate system in both places:</p>
<ol>
<li>Build the FDTD update with the desired CPML parameters.</li>
<li>Stretch the FDFD <code>dxes</code> with the matching SCPML transform.</li>
<li>Compare the extracted phasor against the FDFD field or residual on those
stretched <code>dxes</code>.</li>
</ol>
<p>The electric-current sign convention used throughout the examples and tests is</p>
<div class="arithmatex">\[
E \leftarrow E - \Delta_t J / \epsilon
\]</div>
<p>which matches the FDFD right-hand side</p>
<div class="arithmatex">\[
-i \omega J.
\]</div>
<div class="doc doc-children">
</div>
</div>
</div><h2 id="core-update-and-analysis-helpers">Core update and analysis helpers<a class="headerlink" href="#api-fdtd-core-update-and-analysis-helpers" title="Permanent link"></a></h2>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-fdtd-meanas.fdtd.base">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdtd.base</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.base" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Basic FDTD field updates</p>
<div class="doc doc-children">
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.base.maxwell_e">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">maxwell_e</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.base.maxwell_e" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">maxwell_e</span><span class="p">(</span>
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">fdfield_updater_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Build a function which performs a portion the time-domain E-field update,</p>
<div class="highlight"><pre><span></span><code>E += curl_back(H[t]) / epsilon
</code></pre></div>
<p>The full update should be</p>
<div class="highlight"><pre><span></span><code>E += (curl_back(H[t]) + J) / epsilon
</code></pre></div>
<p>which requires an additional step of <code>E += J / epsilon</code> which is not performed
by the generated function.</p>
<p>See <code>meanas.fdmath</code> for descriptions of</p>
<ul>
<li>This update step: "Maxwell's equations" section</li>
<li><code>dxes</code>: "Datastructure: dx_lists_t" section</li>
<li><code>epsilon</code>: "Permittivity and Permeability" section</li>
</ul>
<p>Also see the "Timestep" section of <code>meanas.fdtd</code> for a discussion of
the <code>dt</code> parameter.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>dt</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Timestep. See <code>meanas.fdtd</code> for details.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Grid description; see <code>meanas.fdmath</code>.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title=" fdfield_updater_t
module-attribute
(meanas.fdmath.fdfield_updater_t)">fdfield_updater_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Function <code>f(E_old, H_old, epsilon) -&gt; E_new</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.base.maxwell_h">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">maxwell_h</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.base.maxwell_h" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">maxwell_h</span><span class="p">(</span>
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">fdfield_updater_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Build a function which performs part of the time-domain H-field update,</p>
<div class="highlight"><pre><span></span><code>H -= curl_forward(E[t]) / mu
</code></pre></div>
<p>The full update should be</p>
<div class="highlight"><pre><span></span><code>H -= (curl_forward(E[t]) + M) / mu
</code></pre></div>
<p>which requires an additional step of <code>H -= M / mu</code> which is not performed
by the generated function; this step can be omitted if there is no magnetic
current <code>M</code>.</p>
<p>See <code>meanas.fdmath</code> for descriptions of</p>
<ul>
<li>This update step: "Maxwell's equations" section</li>
<li><code>dxes</code>: "Datastructure: dx_lists_t" section</li>
<li><code>mu</code>: "Permittivity and Permeability" section</li>
</ul>
<p>Also see the "Timestep" section of <code>meanas.fdtd</code> for a discussion of
the <code>dt</code> parameter.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>dt</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Timestep. See <code>meanas.fdtd</code> for details.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Grid description; see <code>meanas.fdmath</code>.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title=" fdfield_updater_t
module-attribute
(meanas.fdmath.fdfield_updater_t)">fdfield_updater_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Function <code>f(E_old, H_old, epsilon) -&gt; E_new</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-fdtd-meanas.fdtd.pml">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdtd.pml</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.pml" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Convolutional perfectly matched layer (CPML) support for FDTD updates.</p>
<p>The helpers in this module construct per-face CPML parameters and then wrap the
standard Yee updates with the additional auxiliary <code>psi</code> fields needed by the
CPML recurrence.</p>
<p>The intended call pattern is:</p>
<ol>
<li>Build a <code>cpml_params[axis][polarity_index]</code> table with <code>cpml_params(...)</code>.</li>
<li>Pass that table into <code>updates_with_cpml(...)</code> together with <code>dt</code>, <code>dxes</code>, and
<code>epsilon</code>.</li>
<li>Advance the returned <code>update_E</code> / <code>update_H</code> closures in the simulation loop.</li>
</ol>
<p>Each face can be enabled or disabled independently by replacing one table entry
with <code>None</code>.</p>
<div class="doc doc-children">
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.pml.cpml_params">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">cpml_params</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.pml.cpml_params" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">cpml_params</span><span class="p">(</span>
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">polarity</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">thickness</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">8</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">ln_R_per_layer</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="o">-</span><span class="mf">1.6</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">epsilon_eff</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">mu_eff</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">m</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">3.5</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="n">ma</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">cfs_alpha</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Construct the parameter block for one CPML face.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>axis</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Which Cartesian axis the CPML is normal to (<code>0</code>, <code>1</code>, or <code>2</code>).</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>polarity</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Which face along that axis (<code>-1</code> for the low-index face,
<code>+1</code> for the high-index face).</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dt</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Timestep used by the Yee update.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>thickness</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Number of Yee cells occupied by the CPML region.</p>
</div>
</td>
<td>
<code>8</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>ln_R_per_layer</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Logarithmic attenuation target per layer.</p>
</div>
</td>
<td>
<code>-1.6</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon_eff</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Effective permittivity used when choosing the CPML scaling.</p>
</div>
</td>
<td>
<code>1</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu_eff</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Effective permeability used when choosing the CPML scaling.</p>
</div>
</td>
<td>
<code>1</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>m</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Polynomial grading exponent for <code>sigma</code> and <code>kappa</code>.</p>
</div>
</td>
<td>
<code>3.5</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>ma</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Polynomial grading exponent for the complex-frequency shift <code>alpha</code>.</p>
</div>
</td>
<td>
<code>1</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>cfs_alpha</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Maximum complex-frequency shift parameter.</p>
</div>
</td>
<td>
<code>0</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Dictionary with:</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>param_e</code>: <code>(p0, p1, p2)</code> arrays for the E update</li>
</ul>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>param_h</code>: <code>(p0, p1, p2)</code> arrays for the H update</li>
</ul>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>region</code>: slice tuple selecting the CPML cells on that face</li>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.pml.updates_with_cpml">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">updates_with_cpml</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.pml.updates_with_cpml" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">updates_with_cpml</span><span class="p">(</span>
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">cpml_params</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">Sequence</span><span class="p">[</span><span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="kc">None</span><span class="p">]],</span>
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">*</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dtype</span><span class="p">:</span> <span class="n">DTypeLike</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">float32</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span>
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">Callable</span><span class="p">[[</span><span class="n">fdfield_t</span><span class="p">,</span> <span class="n">fdfield_t</span><span class="p">,</span> <span class="n">fdfield_t</span><span class="p">],</span> <span class="kc">None</span><span class="p">],</span>
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="n">Callable</span><span class="p">[[</span><span class="n">fdfield_t</span><span class="p">,</span> <span class="n">fdfield_t</span><span class="p">,</span> <span class="n">fdfield_t</span><span class="p">],</span> <span class="kc">None</span><span class="p">],</span>
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Build Yee-step update closures augmented with CPML terms.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>cpml_params</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#dict">dict</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t">str</a>, <a class="autorefs autorefs-internal" href="#typing.Any" title="typing.Any">Any</a>] | None]]</code>
</td>
<td>
<div class="doc-md-description">
<p>Three-by-two sequence indexed as <code>[axis][polarity_index]</code>.
Entries are the dictionaries returned by <code>cpml_params(...)</code>; use
<code>None</code> to disable CPML on one face.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dt</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#float">float</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Timestep.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Yee-grid spacing lists <code>[dx_e, dx_h]</code>.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Electric material distribution used by the E update.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dtype</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#numpy.typing.DTypeLike" title="numpy.typing.DTypeLike">DTypeLike</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Storage dtype for the auxiliary CPML state arrays.</p>
</div>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#numpy.float32" title="numpy.float32">float32</a></code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>], None]</code>
</td>
<td>
<div class="doc-md-description">
<p><code>(update_E, update_H)</code> closures with the same call shape as the basic</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>], None]</code>
</td>
<td>
<div class="doc-md-description">
<p>Yee updates:</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>], None], <a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>], None]]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>update_E(e, h, epsilon)</code></li>
</ul>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>], None], <a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>], None]]</code>
</td>
<td>
<div class="doc-md-description">
<ul>
<li><code>update_H(e, h, mu)</code></li>
</ul>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>], None], <a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>, <a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a>], None]]</code>
</td>
<td>
<div class="doc-md-description">
<p>The closures retain the CPML auxiliary state internally.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-fdtd-meanas.fdtd.boundaries">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdtd.boundaries</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.boundaries" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Boundary conditions</p>
<h3 id="api-fdtd-meanas.fdtd.boundaries--todo-conducting-boundary-documentation">TODO conducting boundary documentation<a class="headerlink" href="#api-fdtd-meanas.fdtd.boundaries--todo-conducting-boundary-documentation" title="Permanent link"></a></h3>
<div class="doc doc-children">
</div>
</div>
</div>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdtd.energy</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<div class="doc doc-children">
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy.poynting">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">poynting</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy.poynting" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">poynting</span><span class="p">(</span>
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span> <span class="n">h</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">fdfield_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Calculate the poynting vector <code>S</code> (<span class="arithmatex">\(S\)</span>).</p>
<p>This is the energy transfer rate (amount of energy <code>U</code> per <code>dt</code> transferred
between adjacent cells) in each direction that happens during the half-step
bounded by the two provided fields.</p>
<p>The returned vector field <code>S</code> is the energy flow across +x, +y, and +z
boundaries of the corresponding <code>U</code> cell. For example,</p>
<div class="highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a> mx = numpy.roll(mask, -1, axis=0)
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> my = numpy.roll(mask, -1, axis=1)
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> mz = numpy.roll(mask, -1, axis=2)
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a>
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> u_hstep = fdtd.energy_hstep(e0=es[ii - 1], h1=hs[ii], e2=es[ii], **args)
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> u_estep = fdtd.energy_estep(h0=hs[ii], e1=es[ii], h2=hs[ii + 1], **args)
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> delta_j_B = fdtd.delta_energy_j(j0=js[ii], e1=es[ii], dxes=dxes)
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> du_half_h2e = u_estep - u_hstep - delta_j_B
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a>
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> s_h2e = -fdtd.poynting(e=es[ii], h=hs[ii], dxes=dxes) * dt
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> planes = [s_h2e[0, mask].sum(), -s_h2e[0, mx].sum(),
<a href="#api-fdtd-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> s_h2e[1, mask].sum(), -s_h2e[1, my].sum(),
<a href="#api-fdtd-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> s_h2e[2, mask].sum(), -s_h2e[2, mz].sum()]
<a href="#api-fdtd-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a>
<a href="#api-fdtd-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a> assert_close(sum(planes), du_half_h2e[mask])
</code></pre></div>
<p>(see <code>meanas.tests.test_fdtd.test_poynting_planes</code>)</p>
<p>The full relationship is
$$
\begin{aligned}
(U_{l+\frac{1}{2}} - U_l) / \Delta_t
&amp;= -\hat{\nabla} \cdot \tilde{S}<em l_frac_1="l+\frac{1">{l, l + \frac{1}{2}} \
- \hat{H}</em>}{2}} \cdot \hat{M<em l_frac_1="l+\frac{1">l \
- \tilde{E}_l \cdot \tilde{J}</em> \
(U_l - U_{l-\frac{1}{2}}) / \Delta_t
&amp;= -\hat{\nabla} \cdot \tilde{S}}{2}<em l-_frac_1="l-\frac{1">{l, l - \frac{1}{2}} \
- \hat{H}</em>}{2}} \cdot \hat{M<em l-_frac_1="l-\frac{1">l \
- \tilde{E}_l \cdot \tilde{J}</em> \
\end{aligned}
$$}{2}</p>
<p>These equalities are exact and should practically hold to within numerical precision.
No time- or spatial-averaging is necessary. (See <code>meanas.fdtd</code> docs for derivation.)</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>e</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>E-field</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>h</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>H-field (one half-timestep before or after <code>e</code>)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Grid description; see <code>meanas.fdmath</code>.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Name</th> <th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td><code>s</code></td> <td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vector field. Components indicate the energy transfer rate from the
corresponding energy cell into its +x, +y, and +z neighbors during
the half-step from the time of the earlier input field until the
time of later input field.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy.poynting_divergence">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">poynting_divergence</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy.poynting_divergence" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">poynting_divergence</span><span class="p">(</span>
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">s</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="o">*</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">e</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">h</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">fdfield_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Calculate the divergence of the poynting vector.</p>
<p>This is the net energy flow for each cell, i.e. the change in energy <code>U</code>
per <code>dt</code> caused by transfer of energy to nearby cells (rather than
absorption/emission by currents <code>J</code> or <code>M</code>).</p>
<p>See <code>poynting</code> and <code>meanas.fdtd</code> for more details.
Args:
s: Poynting vector, as calculated with <code>poynting</code>. Optional; caller
can provide <code>e</code> and <code>h</code> instead.
e: E-field (optional; need either <code>s</code> or both <code>e</code> and <code>h</code>)
h: H-field (optional; need either <code>s</code> or both <code>e</code> and <code>h</code>)
dxes: Grid description; see <code>meanas.fdmath</code>.</p>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Name</th> <th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td><code>ds</code></td> <td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Divergence of the poynting vector.
Entries indicate the net energy flow out of the corresponding
energy cell.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy.energy_hstep">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">energy_hstep</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy.energy_hstep" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">energy_hstep</span><span class="p">(</span>
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">e0</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">h1</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">e2</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">fdfield_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Calculate energy <code>U</code> at the time of the provided H-field <code>h1</code>.</p>
<p>TODO: Figure out what this means spatially.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>e0</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>E-field one half-timestep before the energy.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>h1</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>H-field (at the same timestep as the energy).</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>e2</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>E-field one half-timestep after the energy.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Dielectric constant distribution.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Magnetic permeability distribution.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Grid description; see <code>meanas.fdmath</code>.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Energy, at the time of the H-field <code>h1</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy.energy_estep">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">energy_estep</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy.energy_estep" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">energy_estep</span><span class="p">(</span>
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">h0</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">e1</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">h2</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">fdfield_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Calculate energy <code>U</code> at the time of the provided E-field <code>e1</code>.</p>
<p>TODO: Figure out what this means spatially.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>h0</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>H-field one half-timestep before the energy.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>e1</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>E-field (at the same timestep as the energy).</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>h2</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>H-field one half-timestep after the energy.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Dielectric constant distribution.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Magnetic permeability distribution.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Grid description; see <code>meanas.fdmath</code>.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Energy, at the time of the E-field <code>e1</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy.delta_energy_h2e">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">delta_energy_h2e</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy.delta_energy_h2e" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">delta_energy_h2e</span><span class="p">(</span>
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">e0</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">h1</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">e2</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">h3</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">fdfield_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Change in energy during the half-step from <code>h1</code> to <code>e2</code>.</p>
<p>This is just from (e2 * e2 + h3 * h1) - (h1 * h1 + e0 * e2)</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>e0</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>E-field one half-timestep before the start of the energy delta.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>h1</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>H-field at the start of the energy delta.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>e2</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>E-field at the end of the energy delta (one half-timestep after <code>h1</code>).</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>h3</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>H-field one half-timestep after the end of the energy delta.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Dielectric constant distribution.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Magnetic permeability distribution.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Grid description; see <code>meanas.fdmath</code>.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Change in energy from the time of <code>h1</code> to the time of <code>e2</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy.delta_energy_e2h">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">delta_energy_e2h</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy.delta_energy_e2h" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">delta_energy_e2h</span><span class="p">(</span>
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">h0</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">e1</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">h2</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">e3</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">fdfield_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Change in energy during the half-step from <code>e1</code> to <code>h2</code>.</p>
<p>This is just from (h2 * h2 + e3 * e1) - (e1 * e1 + h0 * h2)</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>h0</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>E-field one half-timestep before the start of the energy delta.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>e1</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>H-field at the start of the energy delta.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>h2</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>E-field at the end of the energy delta (one half-timestep after <code>e1</code>).</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>e3</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>H-field one half-timestep after the end of the energy delta.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Dielectric constant distribution.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Magnetic permeability distribution.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Grid description; see <code>meanas.fdmath</code>.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Change in energy from the time of <code>e1</code> to the time of <code>h2</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy.delta_energy_j">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">delta_energy_j</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy.delta_energy_j" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">delta_energy_j</span><span class="p">(</span>
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">j0</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span> <span class="n">e1</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span>
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">fdfield_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Calculate the electric-current work term <span class="arithmatex">\(J \cdot E\)</span> on the Yee grid.</p>
<p>This is the source contribution that appears beside the flux divergence in
the discrete Poynting identities documented in <code>meanas.fdtd</code>.</p>
<p>Note that each value of <code>J</code> contributes twice in a full Yee cycle (once per
half-step energy balance) even though it directly changes <code>E</code> only once.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>j0</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Electric-current density sampled at the same half-step as the
current work term.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>e1</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Electric field sampled at the matching integer timestep.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Grid description; defaults to unit spacing.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Per-cell source-work contribution with the scalar field shape.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.energy.dxmul">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">dxmul</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.energy.dxmul" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">dxmul</span><span class="p">(</span>
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">ee</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">hh</span><span class="p">:</span> <span class="n">fdfield</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="n">epsilon</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="nb">float</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">mu</span><span class="p">:</span> <span class="n">fdfield</span> <span class="o">|</span> <span class="nb">float</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="n">dxes</span><span class="p">:</span> <span class="n">dx_lists_t</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">fdfield_t</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Multiply E- and H-like field products by material weights and cell volumes.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>ee</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Three-component electric-field product, such as <code>e0 * e2</code>.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>hh</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Three-component magnetic-field product, such as <code>h1 * h1</code>.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>epsilon</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | <a class="autorefs autorefs-internal" href="#float">float</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Electric material weight; defaults to <code>1</code>.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>mu</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield" title=" fdfield (meanas.fdmath.fdfield)">fdfield</a> | <a class="autorefs autorefs-internal" href="#float">float</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Magnetic material weight; defaults to <code>1</code>.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>dxes</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title=" dx_lists_t
module-attribute
(meanas.fdmath.dx_lists_t)">dx_lists_t</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Grid description; defaults to unit spacing.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Scalar field containing the weighted electric plus magnetic contribution</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.fdfield_t" title="meanas.fdmath.fdfield_t">fdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>for each Yee cell.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-fdtd-meanas.fdtd.phasor">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdtd.phasor</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.phasor" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Helpers for extracting single- or multi-frequency phasors from FDTD samples.</p>
<p>These helpers are intentionally low-level: callers own the accumulator arrays and
the sampling policy. The accumulated quantity is</p>
<div class="highlight"><pre><span></span><code>dt * sum(weight * exp(-1j * omega * t_step) * sample_step)
</code></pre></div>
<p>where <code>t_step = (step + offset_steps) * dt</code>.</p>
<p>The usual Yee offsets are:</p>
<ul>
<li><code>accumulate_phasor_e(..., step=l)</code> for <code>E_l</code></li>
<li><code>accumulate_phasor_h(..., step=l)</code> for <code>H_{l + 1/2}</code></li>
<li><code>accumulate_phasor_j(..., step=l)</code> for <code>J_{l + 1/2}</code></li>
</ul>
<p>These helpers do not choose warmup/accumulation windows or pulse-envelope
normalization. They also do not impose a current sign convention. In this
codebase, electric-current injection normally appears as <code>E -= dt * J / epsilon</code>,
which matches the FDFD right-hand side <code>-1j * omega * J</code>.</p>
<div class="doc doc-children">
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.phasor.accumulate_phasor">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">accumulate_phasor</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.phasor.accumulate_phasor" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">accumulate_phasor</span><span class="p">(</span>
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">accumulator</span><span class="p">:</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">],</span>
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">sample</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">step</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="o">*</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">offset_steps</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> <span class="n">weight</span><span class="p">:</span> <span class="n">ArrayLike</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complexfloating</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Add one time-domain sample into a phasor accumulator.</p>
<p>The added quantity is</p>
<div class="highlight"><pre><span></span><code>dt * weight * exp(-1j * omega * t_step) * sample
</code></pre></div>
<p>where <code>t_step = (step + offset_steps) * dt</code>.</p>
<details class="note" open="">
<summary>Note</summary>
<p>This helper already multiplies by <code>dt</code>. If the caller's normalization
factor was derived from a discrete sum that already includes <code>dt</code>, pass
<code>weight / dt</code> here.</p>
</details>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.phasor.accumulate_phasor_e">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">accumulate_phasor_e</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.phasor.accumulate_phasor_e" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">accumulate_phasor_e</span><span class="p">(</span>
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">accumulator</span><span class="p">:</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">],</span>
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">sample</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">step</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="o">*</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">weight</span><span class="p">:</span> <span class="n">ArrayLike</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complexfloating</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Accumulate an E-field sample taken at integer timestep <code>step</code>.</p>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.phasor.accumulate_phasor_h">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">accumulate_phasor_h</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.phasor.accumulate_phasor_h" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">accumulate_phasor_h</span><span class="p">(</span>
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">accumulator</span><span class="p">:</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">],</span>
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">sample</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">step</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="o">*</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">weight</span><span class="p">:</span> <span class="n">ArrayLike</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complexfloating</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Accumulate an H-field sample corresponding to <code>H_{step + 1/2}</code>.</p>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdtd-meanas.fdtd.phasor.accumulate_phasor_j">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">accumulate_phasor_j</span>
<a class="headerlink" href="#api-fdtd-meanas.fdtd.phasor.accumulate_phasor_j" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdtd-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">accumulate_phasor_j</span><span class="p">(</span>
<a href="#api-fdtd-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">accumulator</span><span class="p">:</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">],</span>
<a href="#api-fdtd-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="n">omegas</span><span class="p">:</span> <span class="nb">float</span>
<a href="#api-fdtd-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="nb">complex</span>
<a href="#api-fdtd-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">float</span> <span class="o">|</span> <span class="nb">complex</span><span class="p">]</span>
<a href="#api-fdtd-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">NDArray</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="n">dt</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="n">sample</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="n">step</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="o">*</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">weight</span><span class="p">:</span> <span class="n">ArrayLike</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span>
<a href="#api-fdtd-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">numpy</span><span class="o">.</span><span class="n">complexfloating</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Accumulate a current sample corresponding to <code>J_{step + 1/2}</code>.</p>
</div>
</div>
</div>
</div>
</div></section><section class="print-page" heading-number="2.7" id="api-fdmath"><h1 id="api-fdmath-fdmath">fdmath<a class="headerlink" href="#api-fdmath-fdmath" title="Permanent link"></a></h1>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-fdmath-meanas.fdmath">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdmath</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Basic discrete calculus for finite difference (fd) simulations.</p>
<h3 id="api-fdmath-meanas.fdmath--fields-functions-and-operators">Fields, Functions, and Operators<a class="headerlink" href="#api-fdmath-meanas.fdmath--fields-functions-and-operators" title="Permanent link"></a></h3>
<p>Discrete fields are stored in one of two forms:</p>
<ul>
<li>The <code>fdfield_t</code> form is a multidimensional <code>numpy.NDArray</code><ul>
<li>For a scalar field, this is just <code>U[m, n, p]</code>, where <code>m</code>, <code>n</code>, and <code>p</code> are
discrete indices referring to positions on the x, y, and z axes respectively.</li>
<li>For a vector field, the first index specifies which vector component is accessed:
<code>E[:, m, n, p] = [Ex[m, n, p], Ey[m, n, p], Ez[m, n, p]]</code>.</li>
</ul>
</li>
<li>The <code>vfdfield_t</code> form is simply a vectorzied (i.e. 1D) version of the <code>fdfield_t</code>,
as obtained by <code>meanas.fdmath.vectorization.vec</code> (effectively just <code>numpy.ravel</code>)</li>
</ul>
<details class="operators-which-act-on-fields-also-come-in-two-forms" open="">
<summary>Operators which act on fields also come in two forms</summary>
<ul>
<li>Python functions, created by the functions in <code>meanas.fdmath.functional</code>.
The generated functions act on fields in the <code>fdfield_t</code> form.</li>
<li>Linear operators, usually 2D sparse matrices using <code>scipy.sparse</code>, created
by <code>meanas.fdmath.operators</code>. These operators act on vectorized fields in the
<code>vfdfield_t</code> form.</li>
</ul>
</details> <p>The operations performed should be equivalent: <code>functional.op(*args)(E)</code> should be
equivalent to <code>unvec(operators.op(*args) @ vec(E), E.shape[1:])</code>.</p>
<p>Generally speaking the <code>field_t</code> form is easier to work with, but can be harder or less
efficient to compose (e.g. it is easy to generate a single matrix by multiplying a
series of other matrices).</p>
<h3 id="api-fdmath-meanas.fdmath--discrete-calculus">Discrete calculus<a class="headerlink" href="#api-fdmath-meanas.fdmath--discrete-calculus" title="Permanent link"></a></h3>
<p>This documentation and approach is roughly based on W.C. Chew's excellent
"Electromagnetic Theory on a Lattice" (doi:10.1063/1.355770),
which covers a superset of this material with similar notation and more detail.</p>
<h4 id="api-fdmath-meanas.fdmath--scalar-derivatives-and-cell-shifts">Scalar derivatives and cell shifts<a class="headerlink" href="#api-fdmath-meanas.fdmath--scalar-derivatives-and-cell-shifts" title="Permanent link"></a></h4>
<p>Define the discrete forward derivative as
$$ [\tilde{\partial}<em _="+" _frac_1="\frac{1" m="m">x f]</em> - f_m) $$
where }{2}} = \frac{1}{\Delta_{x, m}} (f_{m + 1<span class="arithmatex">\(f\)</span> is a function defined at discrete locations on the x-axis (labeled using <span class="arithmatex">\(m\)</span>).
The value at <span class="arithmatex">\(m\)</span> occupies a length <span class="arithmatex">\(\Delta_{x, m}\)</span> along the x-axis. Note that <span class="arithmatex">\(m\)</span>
is an index along the x-axis, <em>not</em> necessarily an x-coordinate, since each length
<span class="arithmatex">\(\Delta_{x, m}, \Delta_{x, m+1}, ...\)</span> is independently chosen.</p>
<p>If we treat <code>f</code> as a 1D array of values, with the <code>i</code>-th value <code>f[i]</code> taking up a length <code>dx[i]</code>
along the x-axis, the forward derivative is</p>
<div class="highlight"><pre><span></span><code>deriv_forward(f)[i] = (f[i + 1] - f[i]) / dx[i]
</code></pre></div>
<p>Likewise, discrete reverse derivative is
$$ [\hat{\partial}<em -="-" _frac_1="\frac{1" m="m">x f ]</em>) $$
or}{2}} = \frac{1}{\Delta_{x, m}} (f_{m} - f_{m - 1</p>
<div class="highlight"><pre><span></span><code>deriv_back(f)[i] = (f[i] - f[i - 1]) / dx[i]
</code></pre></div>
<p>The derivatives' values are shifted by a half-cell relative to the original function, and
will have different cell widths if all the <code>dx[i]</code> ( <span class="arithmatex">\(\Delta_{x, m}\)</span> ) are not
identical:</p>
<div class="highlight"><pre><span></span><code>[figure: derivatives and cell sizes]
dx0 dx1 dx2 dx3 cell sizes for function
----- ----- ----------- -----
______________________________
| | | |
f0 | f1 | f2 | f3 | function
_____|_____|___________|_____|
| | | |
| Df0 | Df1 | Df2 | Df3 forward derivative (periodic boundary)
__|_____|________|________|___
dx'3] dx'0 dx'1 dx'2 [dx'3 cell sizes for forward derivative
-- ----- -------- -------- ---
dx'0] dx'1 dx'2 dx'3 [dx'0 cell sizes for reverse derivative
______________________________
| | | |
| df1 | df2 | df3 | df0 reverse derivative (periodic boundary)
__|_____|________|________|___
Periodic boundaries are used here and elsewhere unless otherwise noted.
</code></pre></div>
<p>In the above figure,
<code>f0 =</code> <span class="arithmatex">\(f_0\)</span>, <code>f1 =</code> <span class="arithmatex">\(f_1\)</span>
<code>Df0 =</code> <span class="arithmatex">\([\tilde{\partial}f]_{0 + \frac{1}{2}}\)</span>
<code>Df1 =</code> <span class="arithmatex">\([\tilde{\partial}f]_{1 + \frac{1}{2}}\)</span>
<code>df0 =</code> <span class="arithmatex">\([\hat{\partial}f]_{0 - \frac{1}{2}}\)</span>
etc.</p>
<p>The fractional subscript <span class="arithmatex">\(m + \frac{1}{2}\)</span> is used to indicate values defined
at shifted locations relative to the original <span class="arithmatex">\(m\)</span>, with corresponding lengths
$$ \Delta_{x, m + \frac{1}{2}} = \frac{1}{2} * (\Delta_{x, m} + \Delta_{x, m + 1}) $$</p>
<p>Just as <span class="arithmatex">\(m\)</span> is not itself an x-coordinate, neither is <span class="arithmatex">\(m + \frac{1}{2}\)</span>;
carefully note the positions of the various cells in the above figure vs their labels.
If the positions labeled with <span class="arithmatex">\(m\)</span> are considered the "base" or "original" grid,
the positions labeled with <span class="arithmatex">\(m + \frac{1}{2}\)</span> are said to lie on a "dual" or
"derived" grid.</p>
<p>For the remainder of the <code>Discrete calculus</code> section, all figures will show
constant-length cells in order to focus on the vector derivatives themselves.
See the <code>Grid description</code> section below for additional information on this topic
and generalization to three dimensions.</p>
<h4 id="api-fdmath-meanas.fdmath--gradients-and-fore-vectors">Gradients and fore-vectors<a class="headerlink" href="#api-fdmath-meanas.fdmath--gradients-and-fore-vectors" title="Permanent link"></a></h4>
<p>Expanding to three dimensions, we can define two gradients
$$ [\tilde{\nabla} f]<em _="+" _frac_1="\frac{1" m="m">{m,n,p} = \vec{x} [\tilde{\partial}_x f]</em> +
\vec{y} [\tilde{\partial}}{2},n,p<em _="+" _frac_1="\frac{1" m_n="m,n">y f]</em> +
\vec{z} [\tilde{\partial}}{2},p<em _="+" _frac_1="\frac{1" m_n_p="m,n,p">z f]</em> $$
$$ [\hat{\nabla} f]}{2}<em _="+" _frac_1="\frac{1" m="m">{m,n,p} = \vec{x} [\hat{\partial}_x f]</em> +
\vec{y} [\hat{\partial}}{2},n,p<em _="+" _frac_1="\frac{1" m_n="m,n">y f]</em> +
\vec{z} [\hat{\partial}}{2},p<em _="+" _frac_1="\frac{1" m_n_p="m,n,p">z f]</em> $$}{2}</p>
<p>or</p>
<div class="highlight"><pre><span></span><code>[code: gradients]
grad_forward(f)[i,j,k] = [Dx_forward(f)[i, j, k],
Dy_forward(f)[i, j, k],
Dz_forward(f)[i, j, k]]
= [(f[i + 1, j, k] - f[i, j, k]) / dx[i],
(f[i, j + 1, k] - f[i, j, k]) / dy[i],
(f[i, j, k + 1] - f[i, j, k]) / dz[i]]
grad_back(f)[i,j,k] = [Dx_back(f)[i, j, k],
Dy_back(f)[i, j, k],
Dz_back(f)[i, j, k]]
= [(f[i, j, k] - f[i - 1, j, k]) / dx[i],
(f[i, j, k] - f[i, j - 1, k]) / dy[i],
(f[i, j, k] - f[i, j, k - 1]) / dz[i]]
</code></pre></div>
<p>The three derivatives in the gradient cause shifts in different
directions, so the x/y/z components of the resulting "vector" are defined
at different points: the x-component is shifted in the x-direction,
y in y, and z in z.</p>
<p>We call the resulting object a "fore-vector" or "back-vector", depending
on the direction of the shift. We write it as
$$ \tilde{g}<em _="+" _frac_1="\frac{1" m="m">{m,n,p} = \vec{x} g^x</em> +
\vec{y} g^y_{m,n + \frac{1}{2},p} +
\vec{z} g^z_{m,n,p + \frac{1}{2}} $$
$$ \hat{g}}{2},n,p<em -="-" _frac_1="\frac{1" m="m">{m,n,p} = \vec{x} g^x</em> +
\vec{y} g^y_{m,n - \frac{1}{2},p} +
\vec{z} g^z_{m,n,p - \frac{1}{2}} $$}{2},n,p</p>
<div class="highlight"><pre><span></span><code>[figure: gradient / fore-vector]
(m, n+1, p+1) ______________ (m+1, n+1, p+1)
/: /|
/ : / |
/ : / |
(m, n, p+1)/_____________/ | The forward derivatives are defined
| : | | at the Dx, Dy, Dz points,
| :.........|...| but the forward-gradient fore-vector
z y Dz / | / is the set of all three
|/_x | Dy | / and is said to be "located" at (m,n,p)
|/ |/
(m, n, p)|_____Dx______| (m+1, n, p)
</code></pre></div>
<h4 id="api-fdmath-meanas.fdmath--divergences">Divergences<a class="headerlink" href="#api-fdmath-meanas.fdmath--divergences" title="Permanent link"></a></h4>
<p>There are also two divergences,</p>
<p>$$ d_{n,m,p} = [\tilde{\nabla} \cdot \hat{g}]<em m_n_p="m,n,p">{n,m,p}
= [\tilde{\partial}_x g^x]</em> +
[\tilde{\partial}<em m_n_p="m,n,p">y g^y]</em> +
[\tilde{\partial}<em m_n_p="m,n,p">z g^z]</em> $$</p>
<p>$$ d_{n,m,p} = [\hat{\nabla} \cdot \tilde{g}]<em m_n_p="m,n,p">{n,m,p}
= [\hat{\partial}_x g^x]</em> +
[\hat{\partial}<em m_n_p="m,n,p">y g^y]</em> +
[\hat{\partial}<em m_n_p="m,n,p">z g^z]</em> $$</p>
<p>or</p>
<div class="highlight"><pre><span></span><code>[code: divergences]
div_forward(g)[i,j,k] = Dx_forward(gx)[i, j, k] +
Dy_forward(gy)[i, j, k] +
Dz_forward(gz)[i, j, k]
= (gx[i + 1, j, k] - gx[i, j, k]) / dx[i] +
(gy[i, j + 1, k] - gy[i, j, k]) / dy[i] +
(gz[i, j, k + 1] - gz[i, j, k]) / dz[i]
div_back(g)[i,j,k] = Dx_back(gx)[i, j, k] +
Dy_back(gy)[i, j, k] +
Dz_back(gz)[i, j, k]
= (gx[i, j, k] - gx[i - 1, j, k]) / dx[i] +
(gy[i, j, k] - gy[i, j - 1, k]) / dy[i] +
(gz[i, j, k] - gz[i, j, k - 1]) / dz[i]
</code></pre></div>
<p>where <code>g = [gx, gy, gz]</code> is a fore- or back-vector field.</p>
<p>Since we applied the forward divergence to the back-vector (and vice-versa), the resulting scalar value
is defined at the back-vector's (fore-vector's) location <span class="arithmatex">\((m,n,p)\)</span> and not at the locations of its components
<span class="arithmatex">\((m \pm \frac{1}{2},n,p)\)</span> etc.</p>
<div class="highlight"><pre><span></span><code>[figure: divergence]
^^
(m-1/2, n+1/2, p+1/2) _____||_______ (m+1/2, n+1/2, p+1/2)
/: || ,, /|
/ : || // / | The divergence at (m, n, p) (the center
/ : // / | of this cube) of a fore-vector field
(m-1/2, n-1/2, p+1/2)/_____________/ | is the sum of the outward-pointing
| : | | fore-vector components, which are
z y &lt;==|== :.........|.====&gt; located at the face centers.
|/_x | / | /
| / // | / Note that in a nonuniform grid, each
|/ // || |/ dimension is normalized by the cell width.
(m-1/2, n-1/2, p-1/2)|____//_______| (m+1/2, n-1/2, p-1/2)
'' ||
VV
</code></pre></div>
<h4 id="api-fdmath-meanas.fdmath--curls">Curls<a class="headerlink" href="#api-fdmath-meanas.fdmath--curls" title="Permanent link"></a></h4>
<p>The two curls are then</p>
<p>$$ \begin{aligned}
\hat{h}<em _="+" _frac_1="\frac{1" m="m">{m + \frac{1}{2}, n + \frac{1}{2}, p + \frac{1}{2}} &amp;= \
[\tilde{\nabla} \times \tilde{g}]</em> &amp;=
\vec{x} (\tilde{\partial}}{2}, n + \frac{1}{2}, p + \frac{1}{2}<em _="+" _frac_1="\frac{1" m_n_p="m,n,p">y g^z</em>}{2}} - \tilde{\partial<em _="+" _frac_1="\frac{1" m_n="m,n">z g^y</em>) \
&amp;+ \vec{y} (\tilde{\partial}}{2},p<em _="+" _frac_1="\frac{1" m="m">z g^x</em>}{2},n,p} - \tilde{\partial<em _="+" _frac_1="\frac{1" m_n_p="m,n,p">x g^z</em>) \
&amp;+ \vec{z} (\tilde{\partial}}{2}<em _="+" _frac_1="\frac{1" m_n="m,n">x g^y</em>}{2},p} - \tilde{\partial<em _="+" _frac_1="\frac{1" m="m">y g^z</em>)
\end{aligned} $$}{2},n,p</p>
<p>and</p>
<p>$$ \tilde{h}<em -="-" _frac_1="\frac{1" m="m">{m - \frac{1}{2}, n - \frac{1}{2}, p - \frac{1}{2}} =
[\hat{\nabla} \times \hat{g}]</em> $$}{2}, n - \frac{1}{2}, p - \frac{1}{2}</p>
<p>where <span class="arithmatex">\(\hat{g}\)</span> and <span class="arithmatex">\(\tilde{g}\)</span> are located at <span class="arithmatex">\((m,n,p)\)</span>
with components at <span class="arithmatex">\((m \pm \frac{1}{2},n,p)\)</span> etc.,
while <span class="arithmatex">\(\hat{h}\)</span> and <span class="arithmatex">\(\tilde{h}\)</span> are located at <span class="arithmatex">\((m \pm \frac{1}{2}, n \pm \frac{1}{2}, p \pm \frac{1}{2})\)</span>
with components at <span class="arithmatex">\((m, n \pm \frac{1}{2}, p \pm \frac{1}{2})\)</span> etc.</p>
<div class="highlight"><pre><span></span><code>[code: curls]
curl_forward(g)[i,j,k] = [Dy_forward(gz)[i, j, k] - Dz_forward(gy)[i, j, k],
Dz_forward(gx)[i, j, k] - Dx_forward(gz)[i, j, k],
Dx_forward(gy)[i, j, k] - Dy_forward(gx)[i, j, k]]
curl_back(g)[i,j,k] = [Dy_back(gz)[i, j, k] - Dz_back(gy)[i, j, k],
Dz_back(gx)[i, j, k] - Dx_back(gz)[i, j, k],
Dx_back(gy)[i, j, k] - Dy_back(gx)[i, j, k]]
</code></pre></div>
<p>For example, consider the forward curl, at (m, n, p), of a back-vector field <code>g</code>, defined
on a grid containing (m + 1/2, n + 1/2, p + 1/2).
The curl will be a fore-vector, so its z-component will be defined at (m, n, p + 1/2).
Take the nearest x- and y-components of <code>g</code> in the xy plane where the curl's z-component
is located; these are</p>
<div class="highlight"><pre><span></span><code>[curl components]
(m, n + 1/2, p + 1/2) : x-component of back-vector at (m + 1/2, n + 1/2, p + 1/2)
(m + 1, n + 1/2, p + 1/2) : x-component of back-vector at (m + 3/2, n + 1/2, p + 1/2)
(m + 1/2, n , p + 1/2) : y-component of back-vector at (m + 1/2, n + 1/2, p + 1/2)
(m + 1/2, n + 1 , p + 1/2) : y-component of back-vector at (m + 1/2, n + 3/2, p + 1/2)
</code></pre></div>
<p>These four xy-components can be used to form a loop around the curl's z-component; its magnitude and sign
is set by their loop-oriented sum (i.e. two have their signs flipped to complete the loop).</p>
<div class="highlight"><pre><span></span><code>[figure: z-component of curl]
: |
z y : ^^ |
|/_x :....||.&lt;.....| (m+1, n+1, p+1/2)
/ || /
| v || | ^
|/ |/
(m, n, p+1/2) |_____&gt;______| (m+1, n, p+1/2)
</code></pre></div>
<h3 id="api-fdmath-meanas.fdmath--maxwells-equations">Maxwell's Equations<a class="headerlink" href="#api-fdmath-meanas.fdmath--maxwells-equations" title="Permanent link"></a></h3>
<p>If we discretize both space (m,n,p) and time (l), Maxwell's equations become</p>
<p>$$ \begin{aligned}
\tilde{\nabla} \times \tilde{E}<em l-_frac_1="l-\frac{1">{l,\vec{r}} &amp;= -\tilde{\partial}_t \hat{B}</em>
- \hat{M}}{2}, \vec{r} + \frac{1}{2}<em l-_frac_1="l-\frac{1">{l, \vec{r} + \frac{1}{2}} \
\hat{\nabla} \times \hat{H}</em>}{2},\vec{r} + \frac{1}{2}} &amp;= \hat{\partial<em _vec_r="\vec{r" l_="l,">t \tilde{D}</em>
+ \tilde{J}}<em l-_frac_1="l-\frac{1">{l-\frac{1}{2},\vec{r}} \
\tilde{\nabla} \cdot \hat{B}</em> &amp;= 0 \
\hat{\nabla} \cdot \tilde{D}}{2}, \vec{r} + \frac{1}{2}<em l_vec_r="l,\vec{r">{l,\vec{r}} &amp;= \rho</em>
\end{aligned} $$}</p>
<p>with</p>
<p>$$ \begin{aligned}
\hat{B}<em _vec_r="\vec{r">{\vec{r}} &amp;= \mu</em>} + \frac{1}{2}} \cdot \hat{H<em _vec_r="\vec{r">{\vec{r} + \frac{1}{2}} \
\tilde{D}</em>
\end{aligned} $$}} &amp;= \epsilon_{\vec{r}} \cdot \tilde{E}_{\vec{r}</p>
<p>where the spatial subscripts are abbreviated as <span class="arithmatex">\(\vec{r} = (m, n, p)\)</span> and
<span class="arithmatex">\(\vec{r} + \frac{1}{2} = (m + \frac{1}{2}, n + \frac{1}{2}, p + \frac{1}{2})\)</span>,
<span class="arithmatex">\(\tilde{E}\)</span> and <span class="arithmatex">\(\hat{H}\)</span> are the electric and magnetic fields,
<span class="arithmatex">\(\tilde{J}\)</span> and <span class="arithmatex">\(\hat{M}\)</span> are the electric and magnetic current distributions,
and <span class="arithmatex">\(\epsilon\)</span> and <span class="arithmatex">\(\mu\)</span> are the dielectric permittivity and magnetic permeability.</p>
<p>The above is Yee's algorithm, written in a form analogous to Maxwell's equations.
The time derivatives can be expanded to form the update equations:</p>
<div class="highlight"><pre><span></span><code>[code: Maxwell's equations updates]
H[i, j, k] -= dt * (curl_forward(E)[i, j, k] + M[t, i, j, k]) / mu[i, j, k]
E[i, j, k] += dt * (curl_back( H)[i, j, k] + J[t, i, j, k]) / epsilon[i, j, k]
</code></pre></div>
<p>Note that the E-field fore-vector and H-field back-vector are offset by a half-cell, resulting
in distinct locations for all six E- and H-field components:</p>
<div class="highlight"><pre><span></span><code>[figure: Field components]
(m - 1/2,=&gt; ____________Hx__________[H] &lt;= r + 1/2 = (m + 1/2,
n + 1/2, /: /: /| n + 1/2,
z y p + 1/2) / : / : / | p + 1/2)
|/_x / : / : / |
/ : Ez__________Hy | Locations of the E- and
/ : : : /| | H-field components for the
(m - 1/2, / : : Ey...../.|..Hz [E] fore-vector at r = (m,n,p)
n - 1/2, =&gt;/________________________/ | /| (the large cube's center)
p + 1/2) | : : / | | / | and [H] back-vector at r + 1/2
| : :/ | |/ | (the top right corner)
| : [E].......|.Ex |
| :.................|......| &lt;= (m + 1/2, n + 1/2, p + 1/2)
| / | /
| / | /
| / | / This is the Yee discretization
| / | / scheme ("Yee cell").
r - 1/2 = | / | /
(m - 1/2, |/ |/
n - 1/2,=&gt; |________________________| &lt;= (m + 1/2, n - 1/2, p - 1/2)
p - 1/2)
</code></pre></div>
<p>Each component forms its own grid, offset from the others:</p>
<div class="highlight"><pre><span></span><code>[figure: E-fields for adjacent cells]
H1__________Hx0_________H0
z y /: /|
|/_x / : / | This figure shows H back-vector locations
/ : / | H0, H1, etc. and their associated components
Hy1 : Hy0 | H0 = (Hx0, Hy0, Hz0) etc.
/ : / |
/ Hz1 / Hz0
H2___________Hx3_________H3 | The equivalent drawing for E would have
| : | | fore-vectors located at the cube's
| : | | center (and the centers of adjacent cubes),
| : | | with components on the cube's faces.
| H5..........Hx4...|......H4
| / | /
Hz2 / Hz2 /
| / | /
| Hy6 | Hy4
| / | /
|/ |/
H6__________Hx7__________H7
</code></pre></div>
<p>The divergence equations can be derived by taking the divergence of the curl equations
and combining them with charge continuity,
$$ \hat{\nabla} \cdot \tilde{J} + \hat{\partial}_t \rho = 0 $$
implying that the discrete Maxwell's equations do not produce spurious charges.</p>
<h4 id="api-fdmath-meanas.fdmath--wave-equation">Wave equation<a class="headerlink" href="#api-fdmath-meanas.fdmath--wave-equation" title="Permanent link"></a></h4>
<p>Taking the backward curl of the <span class="arithmatex">\(\tilde{\nabla} \times \tilde{E}\)</span> equation and
replacing the resulting <span class="arithmatex">\(\hat{\nabla} \times \hat{H}\)</span> term using its respective equation,
and setting <span class="arithmatex">\(\hat{M}\)</span> to zero, we can form the discrete wave equation:</p>
<div class="arithmatex">\[
\begin{aligned}
\tilde{\nabla} \times \tilde{E}_{l,\vec{r}} &amp;=
-\tilde{\partial}_t \hat{B}_{l-\frac{1}{2}, \vec{r} + \frac{1}{2}}
- \hat{M}_{l-1, \vec{r} + \frac{1}{2}} \\
\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}} &amp;=
-\tilde{\partial}_t \hat{H}_{l-\frac{1}{2}, \vec{r} + \frac{1}{2}} \\
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}}) &amp;=
\hat{\nabla} \times (-\tilde{\partial}_t \hat{H}_{l-\frac{1}{2}, \vec{r} + \frac{1}{2}}) \\
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}}) &amp;=
-\tilde{\partial}_t \hat{\nabla} \times \hat{H}_{l-\frac{1}{2}, \vec{r} + \frac{1}{2}} \\
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}}) &amp;=
-\tilde{\partial}_t \hat{\partial}_t \epsilon_{\vec{r}} \tilde{E}_{l, \vec{r}} + \hat{\partial}_t \tilde{J}_{l-\frac{1}{2},\vec{r}} \\
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{l,\vec{r}})
+ \tilde{\partial}_t \hat{\partial}_t \epsilon_{\vec{r}} \cdot \tilde{E}_{l, \vec{r}}
&amp;= \tilde{\partial}_t \tilde{J}_{l - \frac{1}{2}, \vec{r}}
\end{aligned}
\]</div>
<h4 id="api-fdmath-meanas.fdmath--frequency-domain">Frequency domain<a class="headerlink" href="#api-fdmath-meanas.fdmath--frequency-domain" title="Permanent link"></a></h4>
<p>We can substitute in a time-harmonic fields</p>
<div class="arithmatex">\[
\begin{aligned}
\tilde{E}_{l, \vec{r}} &amp;= \tilde{E}_{\vec{r}} e^{-\imath \omega l \Delta_t} \\
\tilde{J}_{l, \vec{r}} &amp;= \tilde{J}_{\vec{r}} e^{-\imath \omega (l - \frac{1}{2}) \Delta_t}
\end{aligned}
\]</div>
<p>resulting in</p>
<div class="arithmatex">\[
\begin{aligned}
\tilde{\partial}_t &amp;\Rightarrow (e^{ \imath \omega \Delta_t} - 1) / \Delta_t = \frac{-2 \imath}{\Delta_t} \sin(\omega \Delta_t / 2) e^{-\imath \omega \Delta_t / 2} = -\imath \Omega e^{-\imath \omega \Delta_t / 2}\\
\hat{\partial}_t &amp;\Rightarrow (1 - e^{-\imath \omega \Delta_t}) / \Delta_t = \frac{-2 \imath}{\Delta_t} \sin(\omega \Delta_t / 2) e^{ \imath \omega \Delta_t / 2} = -\imath \Omega e^{ \imath \omega \Delta_t / 2}\\
\Omega &amp;= 2 \sin(\omega \Delta_t / 2) / \Delta_t
\end{aligned}
\]</div>
<p>This gives the frequency-domain wave equation,</p>
<div class="arithmatex">\[
\hat{\nabla} \times (\mu^{-1}_{\vec{r} + \frac{1}{2}} \cdot \tilde{\nabla} \times \tilde{E}_{\vec{r}})
-\Omega^2 \epsilon_{\vec{r}} \cdot \tilde{E}_{\vec{r}} = -\imath \Omega \tilde{J}_{\vec{r}} e^{\imath \omega \Delta_t / 2} \\
\]</div>
<h4 id="api-fdmath-meanas.fdmath--plane-waves-and-dispersion-relation">Plane waves and Dispersion relation<a class="headerlink" href="#api-fdmath-meanas.fdmath--plane-waves-and-dispersion-relation" title="Permanent link"></a></h4>
<p>With uniform material distribution and no sources</p>
<div class="arithmatex">\[
\begin{aligned}
\mu_{\vec{r} + \frac{1}{2}} &amp;= \mu \\
\epsilon_{\vec{r}} &amp;= \epsilon \\
\tilde{J}_{\vec{r}} &amp;= 0 \\
\end{aligned}
\]</div>
<p>the frequency domain wave equation simplifies to</p>
<div class="arithmatex">\[ \hat{\nabla} \times \tilde{\nabla} \times \tilde{E}_{\vec{r}} - \Omega^2 \epsilon \mu \tilde{E}_{\vec{r}} = 0 \]</div>
<p>Since <span class="arithmatex">\(\hat{\nabla} \cdot \tilde{E}_{\vec{r}} = 0\)</span>, we can simplify</p>
<div class="arithmatex">\[
\begin{aligned}
\hat{\nabla} \times \tilde{\nabla} \times \tilde{E}_{\vec{r}}
&amp;= \tilde{\nabla}(\hat{\nabla} \cdot \tilde{E}_{\vec{r}}) - \hat{\nabla} \cdot \tilde{\nabla} \tilde{E}_{\vec{r}} \\
&amp;= - \hat{\nabla} \cdot \tilde{\nabla} \tilde{E}_{\vec{r}} \\
&amp;= - \tilde{\nabla}^2 \tilde{E}_{\vec{r}}
\end{aligned}
\]</div>
<p>and we get</p>
<div class="arithmatex">\[ \tilde{\nabla}^2 \tilde{E}_{\vec{r}} + \Omega^2 \epsilon \mu \tilde{E}_{\vec{r}} = 0 \]</div>
<p>We can convert this to three scalar-wave equations of the form</p>
<div class="arithmatex">\[ (\tilde{\nabla}^2 + K^2) \phi_{\vec{r}} = 0 \]</div>
<p>with <span class="arithmatex">\(K^2 = \Omega^2 \mu \epsilon\)</span>. Now we let</p>
<div class="arithmatex">\[ \phi_{\vec{r}} = A e^{\imath (k_x m \Delta_x + k_y n \Delta_y + k_z p \Delta_z)} \]</div>
<p>resulting in</p>
<div class="arithmatex">\[
\begin{aligned}
\tilde{\partial}_x &amp;\Rightarrow (e^{ \imath k_x \Delta_x} - 1) / \Delta_t = \frac{-2 \imath}{\Delta_x} \sin(k_x \Delta_x / 2) e^{ \imath k_x \Delta_x / 2} = \imath K_x e^{ \imath k_x \Delta_x / 2}\\
\hat{\partial}_x &amp;\Rightarrow (1 - e^{-\imath k_x \Delta_x}) / \Delta_t = \frac{-2 \imath}{\Delta_x} \sin(k_x \Delta_x / 2) e^{-\imath k_x \Delta_x / 2} = \imath K_x e^{-\imath k_x \Delta_x / 2}\\
K_x &amp;= 2 \sin(k_x \Delta_x / 2) / \Delta_x \\
\end{aligned}
\]</div>
<p>with similar expressions for the y and z dimnsions (and <span class="arithmatex">\(K_y, K_z\)</span>).</p>
<p>This implies</p>
<div class="arithmatex">\[
\tilde{\nabla}^2 = -(K_x^2 + K_y^2 + K_z^2) \phi_{\vec{r}} \\
K_x^2 + K_y^2 + K_z^2 = \Omega^2 \mu \epsilon = \Omega^2 / c^2
\]</div>
<p>where <span class="arithmatex">\(c = \sqrt{\mu \epsilon}\)</span>.</p>
<p>Assuming real <span class="arithmatex">\((k_x, k_y, k_z), \omega\)</span> will be real only if</p>
<div class="arithmatex">\[ c^2 \Delta_t^2 = \frac{\Delta_t^2}{\mu \epsilon} &lt; 1/(\frac{1}{\Delta_x^2} + \frac{1}{\Delta_y^2} + \frac{1}{\Delta_z^2}) \]</div>
<p>If <span class="arithmatex">\(\Delta_x = \Delta_y = \Delta_z\)</span>, this simplifies to <span class="arithmatex">\(c \Delta_t &lt; \Delta_x / \sqrt{3}\)</span>.
This last form can be interpreted as enforcing causality; the distance that light
travels in one timestep (i.e., <span class="arithmatex">\(c \Delta_t\)</span>) must be less than the diagonal
of the smallest cell ( <span class="arithmatex">\(\Delta_x / \sqrt{3}\)</span> when on a uniform cubic grid).</p>
<h3 id="api-fdmath-meanas.fdmath--grid-description">Grid description<a class="headerlink" href="#api-fdmath-meanas.fdmath--grid-description" title="Permanent link"></a></h3>
<p>As described in the section on scalar discrete derivatives above, cell widths
(<code>dx[i]</code>, <code>dy[j]</code>, <code>dz[k]</code>) along each axis can be arbitrary and independently
defined. Moreover, all field components are actually defined at "derived" or "dual"
positions, in-between the "base" grid points on one or more axes.</p>
<p>To get a better sense of how this works, let's start by drawing a grid with uniform
<code>dy</code> and <code>dz</code> and nonuniform <code>dx</code>. We will only draw one cell in the y and z dimensions
to make the illustration simpler; we need at least two cells in the x dimension to
demonstrate how nonuniform <code>dx</code> affects the various components.</p>
<p>Place the E fore-vectors at integer indices <span class="arithmatex">\(r = (m, n, p)\)</span> and the H back-vectors
at fractional indices <span class="arithmatex">\(r + \frac{1}{2} = (m + \frac{1}{2}, n + \frac{1}{2},
p + \frac{1}{2})\)</span>. Remember that these are indices and not coordinates; they can
correspond to arbitrary (monotonically increasing) coordinates depending on the cell widths.</p>
<p>Draw lines to denote the planes on which the H components and back-vectors are defined.
For simplicity, don't draw the equivalent planes for the E components and fore-vectors,
except as necessary to show their locations -- it's easiest to just connect them to their
associated H-equivalents.</p>
<p>The result looks something like this:</p>
<div class="highlight"><pre><span></span><code>[figure: Component centers]
p=
[H]__________Hx___________[H]_____Hx______[H] __ +1/2
z y /: /: /: /: /| | |
|/_x / : / : / : / : / | | |
/ : / : / : / : / | | |
Hy : Ez...........Hy : Ez......Hy | | |
/: : : : /: : : : /| | | |
/ : Hz : Ey....../.:..Hz : Ey./.|..Hz __ 0 | dz[0]
/ : /: : / / : /: : / / | /| | |
/_________________________/_______________/ | / | | |
| :/ : :/ | :/ : :/ | |/ | | |
| Ex : [E].......|..Ex : [E]..|..Ex | | |
| : | : | | | |
| [H]..........Hx....|......[H].....H|x.....[H] __ --------- (n=+1/2, p=-1/2)
| / | / | / / /
Hz / Hz / Hz / / /
| / | / | / / /
| Hy | Hy | Hy __ 0 / dy[0]
| / | / | / / /
| / | / | / / /
|/ |/ |/ / /
[H]__________Hx___________[H]_____Hx______[H] __ -1/2 /
=n
|------------|------------|-------|-------|
-1/2 0 +1/2 +1 +3/2 = m
------------------------- ----------------
dx[0] dx[1]
Part of a nonuniform "base grid", with labels specifying
positions of the various field components. [E] fore-vectors
are at the cell centers, and [H] back-vectors are at the
vertices. H components along the near (-y) top (+z) edge
have been omitted to make the insides of the cubes easier
to visualize.
</code></pre></div>
<p>The above figure shows where all the components are located; however, it is also useful to show
what volumes those components correspond to. Consider the Ex component at <code>m = +1/2</code>: it is
shifted in the x-direction by a half-cell from the E fore-vector at <code>m = 0</code> (labeled <code>[E]</code>
in the figure). It corresponds to a volume between <code>m = 0</code> and <code>m = +1</code> (the other
dimensions are not shifted, i.e. they are still bounded by <code>n, p = +-1/2</code>). (See figure
below). Since <code>m</code> is an index and not an x-coordinate, the Ex component is not necessarily
at the center of the volume it represents, and the x-length of its volume is the derived
quantity <code>dx'[0] = (dx[0] + dx[1]) / 2</code> rather than the base <code>dx</code>.
(See also <code>Scalar derivatives and cell shifts</code>).</p>
<div class="highlight"><pre><span></span><code>[figure: Ex volumes]
p=
&lt;_________________________________________&gt; __ +1/2
z y &lt;&lt; /: / /: &gt;&gt; | |
|/_x &lt; &lt; / : / / : &gt; &gt; | |
&lt; &lt; / : / / : &gt; &gt; | |
&lt; &lt; / : / / : &gt; &gt; | |
&lt;: &lt; / : : / : &gt;: &gt; | |
&lt; : &lt; / : : / : &gt; : &gt; __ 0 | dz[0]
&lt; : &lt; / : : / :&gt; : &gt; | |
&lt;____________/____________________/_______&gt; : &gt; | |
&lt; : &lt; | : : | &gt; : &gt; | |
&lt; Ex &lt; | : Ex | &gt; Ex &gt; | |
&lt; : &lt; | : : | &gt; : &gt; | |
&lt; : &lt;....|.......:........:...|.......&gt;...:...&gt; __ --------- (n=+1/2, p=-1/2)
&lt; : &lt; | / : /| /&gt; : &gt; / /
&lt; : &lt; | / : / | / &gt; : &gt; / /
&lt; :&lt; | / :/ | / &gt; :&gt; / /
&lt; &lt; | / : | / &gt; &gt; _ 0 / dy[0]
&lt; &lt; | / | / &gt; &gt; / /
&lt; &lt; | / | / &gt; &gt; / /
&lt;&lt; |/ |/ &gt;&gt; / /
&lt;____________|____________________|_______&gt; __ -1/2 /
=n
|------------|------------|-------|-------|
-1/2 0 +1/2 +1 +3/2 = m
~------------ -------------------- -------~
dx'[-1] dx'[0] dx'[1]
The Ex values are positioned on the x-faces of the base
grid. They represent the Ex field in volumes shifted by
a half-cell in the x-dimension, as shown here. Only the
center cell (with width dx'[0]) is fully shown; the
other two are truncated (shown using &gt;&lt; markers).
Note that the Ex positions are the in the same positions
as the previous figure; only the cell boundaries have moved.
Also note that the points at which Ex is defined are not
necessarily centered in the volumes they represent; non-
uniform cell sizes result in off-center volumes like the
center cell here.
</code></pre></div>
<p>The next figure shows the volumes corresponding to the Hy components, which
are shifted in two dimensions (x and z) compared to the base grid.</p>
<div class="highlight"><pre><span></span><code>[figure: Hy volumes]
p=
z y mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm __ +1/2 s
|/_x &lt;&lt; m: m: &gt;&gt; | |
&lt; &lt; m : m : &gt; &gt; | | dz'[1]
&lt; &lt; m : m : &gt; &gt; | |
Hy........... m........Hy...........m......Hy &gt; | |
&lt; &lt; m : m : &gt; &gt; | |
&lt; ______ m_____:_______________m_____:_&gt;______ __ 0
&lt; &lt; m /: m / &gt; &gt; | |
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm &gt; | |
&lt; &lt; | / : | / &gt; &gt; | | dz'[0]
&lt; &lt; | / : | / &gt; &gt; | |
&lt; &lt; | / : | / &gt; &gt; | |
&lt; wwwww|w/wwwwwwwwwwwwwwwwwww|w/wwwww&gt;wwwwwwww __ s
&lt; &lt; |/ w |/ w&gt; &gt; / /
_____________|_____________________|________ &gt; / /
&lt; &lt; | w | w &gt; &gt; / /
&lt; Hy........|...w........Hy.......|...w...&gt;..Hy _ 0 / dy[0]
&lt; &lt; | w | w &gt; &gt; / /
&lt;&lt; | w | w &gt; &gt; / /
&lt; |w |w &gt;&gt; / /
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww __ -1/2 /
|------------|------------|--------|-------|
-1/2 0 +1/2 +1 +3/2 = m
~------------ --------------------- -------~
dx'[-1] dx'[0] dx'[1]
The Hy values are positioned on the y-edges of the base
grid. Again here, the 'Hy' labels represent the same points
as in the basic grid figure above; the edges have shifted
by a half-cell along the x- and z-axes.
The grid lines _|:/ are edges of the area represented by
each Hy value, and the lines drawn using &lt;m&gt;.w represent
edges where a cell's faces extend beyond the drawn area
(i.e. where the drawing is truncated in the x- or z-
directions).
</code></pre></div>
<h4 id="api-fdmath-meanas.fdmath--datastructure-dx_lists_t">Datastructure: dx_lists_t<a class="headerlink" href="#api-fdmath-meanas.fdmath--datastructure-dx_lists_t" title="Permanent link"></a></h4>
<p>In this documentation, the E fore-vectors are placed on the base grid. An
equivalent formulation could place the H back-vectors on the base grid instead.
However, in the case of a non-uniform grid, the operation to get from the "base"
cell widths to "derived" ones is not its own inverse.</p>
<p>The base grid's cell sizes could be fully described by a list of three 1D arrays,
specifying the cell widths along all three axes:</p>
<div class="highlight"><pre><span></span><code>[dx, dy, dz] = [[dx[0], dx[1], ...], [dy[0], ...], [dz[0], ...]]
</code></pre></div>
<p>Note that this is a list-of-arrays rather than a 2D array, as the simulation domain
may have a different number of cells along each axis.</p>
<p>Knowing the base grid's cell widths and the boundary conditions (periodic unless
otherwise noted) is enough information to calculate the cell widths <code>dx'</code>, <code>dy'</code>,
and <code>dz'</code> for the derived grids.</p>
<p>However, since most operations are trivially generalized to allow either E or H
to be defined on the base grid, they are written to take the a full set of base
and derived cell widths, distinguished by which field they apply to rather than
their "base" or "derived" status. This removes the need for each function to
generate the derived widths, and makes the "base" vs "derived" distinction
unnecessary in the code.</p>
<p>The resulting data structure containing all the cell widths takes the form of a
list-of-lists-of-arrays. The first list-of-arrays provides the cell widths for
the E-field fore-vectors, while the second list-of-arrays does the same for the
H-field back-vectors:</p>
<div class="highlight"><pre><span></span><code> [[[dx_e[0], dx_e[1], ...], [dy_e[0], ...], [dz_e[0], ...]],
[[dx_h[0], dx_h[1], ...], [dy_h[0], ...], [dz_h[0], ...]]]
</code></pre></div>
<p>where <code>dx_e[0]</code> is the x-width of the <code>m=0</code> cells, as used when calculating dE/dx,
and <code>dy_h[0]</code> is the y-width of the <code>n=0</code> cells, as used when calculating dH/dy, etc.</p>
<h3 id="api-fdmath-meanas.fdmath--permittivity-and-permeability">Permittivity and Permeability<a class="headerlink" href="#api-fdmath-meanas.fdmath--permittivity-and-permeability" title="Permanent link"></a></h3>
<p>Since each vector component of E and H is defined in a different location and represents
a different volume, the value of the spatially-discrete <code>epsilon</code> and <code>mu</code> can also be
different for all three field components, even when representing a simple planar interface
between two isotropic materials.</p>
<p>As a result, <code>epsilon</code> and <code>mu</code> are taken to have the same dimensions as the field, and
composed of the three diagonal tensor components:</p>
<div class="highlight"><pre><span></span><code>[equations: epsilon_and_mu]
epsilon = [epsilon_xx, epsilon_yy, epsilon_zz]
mu = [mu_xx, mu_yy, mu_zz]
</code></pre></div>
<p>or</p>
<div class="arithmatex">\[
\epsilon = \begin{bmatrix} \epsilon_{xx} &amp; 0 &amp; 0 \\
0 &amp; \epsilon_{yy} &amp; 0 \\
0 &amp; 0 &amp; \epsilon_{zz} \end{bmatrix}
$$
$$
\mu = \begin{bmatrix} \mu_{xx} &amp; 0 &amp; 0 \\
0 &amp; \mu_{yy} &amp; 0 \\
0 &amp; 0 &amp; \mu_{zz} \end{bmatrix}
\]</div>
<p>where the off-diagonal terms (e.g. <code>epsilon_xy</code>) are assumed to be zero.</p>
<p>High-accuracy volumetric integration of shapes on multiple grids can be performed
by the <a href="https://mpxd.net/code/jan/gridlock">gridlock</a> module.</p>
<p>The values of the vacuum permittivity and permability effectively become scaling
factors that appear in several locations (e.g. between the E and H fields). In
order to limit floating-point inaccuracy and simplify calculations, they are often
set to 1 and relative permittivities and permeabilities are used in their places;
the true values can be multiplied back in after the simulation is complete if non-
normalized results are needed.</p>
<div class="doc doc-children">
</div>
</div>
</div><h2 id="functional-and-sparse-operators">Functional and sparse operators<a class="headerlink" href="#api-fdmath-functional-and-sparse-operators" title="Permanent link"></a></h2>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-fdmath-meanas.fdmath.functional">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdmath.functional</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.functional" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Math functions for finite difference simulations</p>
<p>Basic discrete calculus etc.</p>
<div class="doc doc-children">
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.functional.deriv_forward">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">deriv_forward</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.functional.deriv_forward" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">deriv_forward</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dx_e</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]]</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdmath-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span>
<a href="#api-fdmath-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">fdfield_updater_t</span><span class="p">,</span> <span class="n">fdfield_updater_t</span><span class="p">,</span> <span class="n">fdfield_updater_t</span>
<a href="#api-fdmath-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Utility operators for taking discretized derivatives (backward variant).</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>dx_e</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.floating" title="numpy.floating">floating</a> | <a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]] | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Lists of cell sizes for all axes
<code>[[dx_0, dx_1, ...], [dy_0, dy_1, ...], ...]</code>.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title=" fdfield_updater_t
module-attribute
(meanas.fdmath.types.fdfield_updater_t)">fdfield_updater_t</a>, <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title=" fdfield_updater_t
module-attribute
(meanas.fdmath.types.fdfield_updater_t)">fdfield_updater_t</a>, <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title=" fdfield_updater_t
module-attribute
(meanas.fdmath.types.fdfield_updater_t)">fdfield_updater_t</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>List of functions for taking forward derivatives along each axis.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.functional.deriv_back">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">deriv_back</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.functional.deriv_back" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">deriv_back</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dx_h</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]]</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdmath-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span>
<a href="#api-fdmath-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="n">fdfield_updater_t</span><span class="p">,</span> <span class="n">fdfield_updater_t</span><span class="p">,</span> <span class="n">fdfield_updater_t</span>
<a href="#api-fdmath-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Utility operators for taking discretized derivatives (forward variant).</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>dx_h</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.floating" title="numpy.floating">floating</a> | <a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]] | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Lists of cell sizes for all axes
<code>[[dx_0, dx_1, ...], [dy_0, dy_1, ...], ...]</code>.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#tuple">tuple</a>[<a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title=" fdfield_updater_t
module-attribute
(meanas.fdmath.types.fdfield_updater_t)">fdfield_updater_t</a>, <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title=" fdfield_updater_t
module-attribute
(meanas.fdmath.types.fdfield_updater_t)">fdfield_updater_t</a>, <a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title=" fdfield_updater_t
module-attribute
(meanas.fdmath.types.fdfield_updater_t)">fdfield_updater_t</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>List of functions for taking forward derivatives along each axis.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.functional.curl_forward">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">curl_forward</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.functional.curl_forward" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">curl_forward</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dx_e</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]]</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdmath-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Callable</span><span class="p">[[</span><span class="n">TT</span><span class="p">],</span> <span class="n">TT</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Curl operator for use with the E field.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>dx_e</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.floating" title="numpy.floating">floating</a> | <a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]] | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Lists of cell sizes for all axes
<code>[[dx_0, dx_1, ...], [dy_0, dy_1, ...], ...]</code>.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.functional.TT" title="meanas.fdmath.functional.TT">TT</a>], <a class="autorefs autorefs-internal" href="#meanas.fdmath.functional.TT" title="meanas.fdmath.functional.TT">TT</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Function <code>f</code> for taking the discrete forward curl of a field,</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.functional.TT" title="meanas.fdmath.functional.TT">TT</a>], <a class="autorefs autorefs-internal" href="#meanas.fdmath.functional.TT" title="meanas.fdmath.functional.TT">TT</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p><code>f(E)</code> -&gt; curlE <span class="arithmatex">\(= \nabla_f \times E\)</span></p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.functional.curl_back">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">curl_back</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.functional.curl_back" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">curl_back</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dx_h</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]]</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdmath-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Callable</span><span class="p">[[</span><span class="n">TT</span><span class="p">],</span> <span class="n">TT</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Create a function which takes the backward curl of a field.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>dx_h</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.floating" title="numpy.floating">floating</a> | <a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]] | None</code>
</td>
<td>
<div class="doc-md-description">
<p>Lists of cell sizes for all axes
<code>[[dx_0, dx_1, ...], [dy_0, dy_1, ...], ...]</code>.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.functional.TT" title="meanas.fdmath.functional.TT">TT</a>], <a class="autorefs autorefs-internal" href="#meanas.fdmath.functional.TT" title="meanas.fdmath.functional.TT">TT</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Function <code>f</code> for taking the discrete backward curl of a field,</p>
</div>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Callable" title="collections.abc.Callable">Callable</a>[[<a class="autorefs autorefs-internal" href="#meanas.fdmath.functional.TT" title="meanas.fdmath.functional.TT">TT</a>], <a class="autorefs autorefs-internal" href="#meanas.fdmath.functional.TT" title="meanas.fdmath.functional.TT">TT</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p><code>f(H)</code> -&gt; curlH <span class="arithmatex">\(= \nabla_b \times H\)</span></p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdmath.operators</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Matrix operators for finite difference simulations</p>
<p>Basic discrete calculus etc.</p>
<div class="doc doc-children">
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.shift_circ">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">shift_circ</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.shift_circ" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">shift_circ</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">shift_distance</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">1</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Utility operator for performing a circular shift along a specified axis by a
specified number of elements.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>axis</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Axis to shift along. x=0, y=1, z=2</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>shape</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Shape of the grid being shifted</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>shift_distance</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Number of cells to shift by. May be negative. Default 1.</p>
</div>
</td>
<td>
<code>1</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix for performing the circular shift.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.shift_with_mirror">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">shift_with_mirror</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.shift_with_mirror" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">shift_with_mirror</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">shift_distance</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">1</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Utility operator for performing an n-element shift along a specified axis, with mirror
boundary conditions applied to the cells beyond the receding edge.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>axis</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Axis to shift along. x=0, y=1, z=2</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>shape</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Shape of the grid being shifted</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>shift_distance</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Number of cells to shift by. May be negative. Default 1.</p>
</div>
</td>
<td>
<code>1</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix for performing the shift-with-mirror.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.deriv_forward">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">deriv_forward</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.deriv_forward" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">deriv_forward</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dx_e</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]],</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Utility operators for taking discretized derivatives (forward variant).</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>dx_e</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.floating" title="numpy.floating">floating</a> | <a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
</td>
<td>
<div class="doc-md-description">
<p>Lists of cell sizes for all axes
<code>[[dx_0, dx_1, ...], [dy_0, dy_1, ...], ...]</code>.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>List of operators for taking forward derivatives along each axis.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.deriv_back">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">deriv_back</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.deriv_back" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">deriv_back</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dx_h</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]],</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Utility operators for taking discretized derivatives (backward variant).</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>dx_h</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.floating" title="numpy.floating">floating</a> | <a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
</td>
<td>
<div class="doc-md-description">
<p>Lists of cell sizes for all axes
<code>[[dx_0, dx_1, ...], [dy_0, dy_1, ...], ...]</code>.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut">list</a>[<a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>List of operators for taking forward derivatives along each axis.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.cross">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">cross</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.cross" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">cross</span><span class="p">(</span><span class="n">B</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">sparray</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Cross product operator</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>B</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>List <code>[Bx, By, Bz]</code> of sparse matrices corresponding to the x, y, z
portions of the operator on the left side of the cross product.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix corresponding to (B x), where x is the cross product.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.vec_cross">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">vec_cross</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.vec_cross" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec_cross</span><span class="p">(</span><span class="n">b</span><span class="p">:</span> <span class="n">vfdfield_t</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Vector cross product operator</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>b</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vfdfield_t" title="meanas.fdmath.types.vfdfield_t">vfdfield_t</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Vector on the left side of the cross product.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p>Returns:</p>
<div class="highlight"><pre><span></span><code>Sparse matrix corresponding to (b x), where x is the cross product.
</code></pre></div>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.avg_forward">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">avg_forward</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.avg_forward" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">avg_forward</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Forward average operator <code>(x4 = (x4 + x5) / 2)</code></p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>axis</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Axis to average along (x=0, y=1, z=2)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>shape</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Shape of the grid to average</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix for forward average operation.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.avg_back">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">avg_back</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.avg_back" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">avg_back</span><span class="p">(</span><span class="n">axis</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Backward average operator <code>(x4 = (x4 + x3) / 2)</code></p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>axis</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Axis to average along (x=0, y=1, z=2)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>shape</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Shape of the grid to average</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix for backward average operation.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.curl_forward">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">curl_forward</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.curl_forward" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">curl_forward</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dx_e</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]],</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Curl operator for use with the E field.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>dx_e</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.floating" title="numpy.floating">floating</a> | <a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
</td>
<td>
<div class="doc-md-description">
<p>Lists of cell sizes for all axes
<code>[[dx_0, dx_1, ...], [dy_0, dy_1, ...], ...]</code>.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix for taking the discretized curl of the E-field</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.operators.curl_back">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">curl_back</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.operators.curl_back" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">curl_back</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">dx_h</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]],</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">sparse</span><span class="o">.</span><span class="n">sparray</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Curl operator for use with the H field.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>dx_h</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a>[<a class="autorefs autorefs-internal" href="#numpy.floating" title="numpy.floating">floating</a> | <a class="autorefs autorefs-internal" href="#numpy.complexfloating" title="numpy.complexfloating">complexfloating</a>]]</code>
</td>
<td>
<div class="doc-md-description">
<p>Lists of cell sizes for all axes
<code>[[dx_0, dx_1, ...], [dy_0, dy_1, ...], ...]</code>.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#scipy.sparse.sparray" title="scipy.sparse.sparray">sparray</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Sparse matrix for taking the discretized curl of the H-field</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-fdmath-meanas.fdmath.vectorization">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdmath.vectorization</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.vectorization" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Functions for moving between a vector field (list of 3 ndarrays, <code>[f_x, f_y, f_z]</code>)
and a 1D array representation of that field <code>[f_x0, f_x1, f_x2,... f_y0,... f_z0,...]</code>.
Vectorized versions of the field use row-major (ie., C-style) ordering.</p>
<div class="doc doc-children">
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.vectorization.vec">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">vec</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.vectorization.vec" title="Permanent link"></a></h3>
<div class="doc-overloads">
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span><span class="n">f</span><span class="p">:</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span>
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span><span class="n">f</span><span class="p">:</span> <span class="n">fdfield_t</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">vfdfield_t</span>
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span><span class="n">f</span><span class="p">:</span> <span class="n">cfdfield_t</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">vcfdfield_t</span>
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span><span class="n">f</span><span class="p">:</span> <span class="n">fdfield2_t</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">vfdfield2_t</span>
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span><span class="n">f</span><span class="p">:</span> <span class="n">cfdfield2_t</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">vcfdfield2_t</span>
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span><span class="n">f</span><span class="p">:</span> <span class="n">fdslice_t</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">vfdslice_t</span>
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span><span class="n">f</span><span class="p">:</span> <span class="n">cfdslice_t</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">vcfdslice_t</span>
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span><span class="n">f</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">NDArray</span>
</code></pre></div> </div>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">vec</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">f</span><span class="p">:</span> <span class="n">fdfield_t</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="o">|</span> <span class="n">cfdfield_t</span>
<a href="#api-fdmath-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="n">fdfield2_t</span>
<a href="#api-fdmath-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">cfdfield2_t</span>
<a href="#api-fdmath-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">fdslice_t</span>
<a href="#api-fdmath-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="o">|</span> <span class="n">cfdslice_t</span>
<a href="#api-fdmath-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="o">|</span> <span class="n">ArrayLike</span>
<a href="#api-fdmath-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="o">|</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdmath-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">vfdfield_t</span>
<a href="#api-fdmath-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> <span class="o">|</span> <span class="n">vcfdfield_t</span>
<a href="#api-fdmath-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> <span class="o">|</span> <span class="n">vfdfield2_t</span>
<a href="#api-fdmath-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a> <span class="o">|</span> <span class="n">vcfdfield2_t</span>
<a href="#api-fdmath-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a> <span class="o">|</span> <span class="n">vfdslice_t</span>
<a href="#api-fdmath-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a> <span class="o">|</span> <span class="n">vcfdslice_t</span>
<a href="#api-fdmath-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a> <span class="o">|</span> <span class="n">NDArray</span>
<a href="#api-fdmath-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a> <span class="o">|</span> <span class="kc">None</span>
<a href="#api-fdmath-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a><span class="p">)</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Create a 1D ndarray from a vector field which spans a 1-3D region.</p>
<p>Returns <code>None</code> if called with <code>f=None</code>.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>f</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.types.fdfield_t" title="meanas.fdmath.types.fdfield_t">fdfield_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.cfdfield_t" title="meanas.fdmath.types.cfdfield_t">cfdfield_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.fdfield2_t" title="meanas.fdmath.types.fdfield2_t">fdfield2_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.cfdfield2_t" title="meanas.fdmath.types.cfdfield2_t">cfdfield2_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.fdslice_t" title="meanas.fdmath.types.fdslice_t">fdslice_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.cfdslice_t" title="meanas.fdmath.types.cfdslice_t">cfdslice_t</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.ArrayLike" title="numpy.typing.ArrayLike">ArrayLike</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>A vector field, e.g. <code>[f_x, f_y, f_z]</code> where each <code>f_</code> component is a 1- to
3-D ndarray (<code>f_*</code> should all be the same size). Doesn't fail with <code>f=None</code>.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vfdfield_t" title="meanas.fdmath.types.vfdfield_t">vfdfield_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vcfdfield_t" title="meanas.fdmath.types.vcfdfield_t">vcfdfield_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vfdfield2_t" title="meanas.fdmath.types.vfdfield2_t">vfdfield2_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vcfdfield2_t" title="meanas.fdmath.types.vcfdfield2_t">vcfdfield2_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vfdslice_t" title="meanas.fdmath.types.vfdslice_t">vfdslice_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vcfdslice_t" title="meanas.fdmath.types.vcfdslice_t">vcfdslice_t</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>1D ndarray containing the linearized field (or <code>None</code>)</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="doc doc-object doc-function">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.vectorization.unvec">
<code class="doc-symbol doc-symbol-heading doc-symbol-function"></code> <span class="doc doc-object-name doc-function-name">unvec</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.vectorization.unvec" title="Permanent link"></a></h3>
<div class="doc-overloads">
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span>
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="n">vfdfield_t</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">fdfield_t</span>
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="n">vcfdfield_t</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">cfdfield_t</span>
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="n">vfdfield2_t</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">fdfield2_t</span>
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="n">vcfdfield2_t</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">cfdfield2_t</span>
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="n">vfdslice_t</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">fdslice_t</span>
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="n">vcfdslice_t</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">cfdslice_t</span>
</code></pre></div><div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="n">ArrayLike</span><span class="p">,</span> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">NDArray</span>
</code></pre></div> </div>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">unvec</span><span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">v</span><span class="p">:</span> <span class="n">vfdfield_t</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> <span class="o">|</span> <span class="n">vcfdfield_t</span>
<a href="#api-fdmath-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="o">|</span> <span class="n">vfdfield2_t</span>
<a href="#api-fdmath-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> <span class="o">|</span> <span class="n">vcfdfield2_t</span>
<a href="#api-fdmath-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="o">|</span> <span class="n">vfdslice_t</span>
<a href="#api-fdmath-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> <span class="o">|</span> <span class="n">vcfdslice_t</span>
<a href="#api-fdmath-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="o">|</span> <span class="n">ArrayLike</span>
<a href="#api-fdmath-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="o">|</span> <span class="kc">None</span><span class="p">,</span>
<a href="#api-fdmath-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="n">shape</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span>
<a href="#api-fdmath-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="n">nvdim</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span><span class="p">,</span>
<a href="#api-fdmath-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="p">(</span>
<a href="#api-fdmath-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> <span class="n">fdfield_t</span>
<a href="#api-fdmath-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a> <span class="o">|</span> <span class="n">cfdfield_t</span>
<a href="#api-fdmath-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a> <span class="o">|</span> <span class="n">fdfield2_t</span>
<a href="#api-fdmath-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a> <span class="o">|</span> <span class="n">cfdfield2_t</span>
<a href="#api-fdmath-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a> <span class="o">|</span> <span class="n">fdslice_t</span>
<a href="#api-fdmath-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a> <span class="o">|</span> <span class="n">cfdslice_t</span>
<a href="#api-fdmath-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a> <span class="o">|</span> <span class="n">NDArray</span>
<a href="#api-fdmath-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a> <span class="o">|</span> <span class="kc">None</span>
<a href="#api-fdmath-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a><span class="p">)</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Perform the inverse of vec(): take a 1D ndarray and output an <code>nvdim</code>-component field
of form e.g. <code>[f_x, f_y, f_z]</code> (<code>nvdim=3</code>) where each of <code>f_*</code> is a len(shape)-dimensional
ndarray.</p>
<p>Returns <code>None</code> if called with <code>v=None</code>.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code>v</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vfdfield_t" title="meanas.fdmath.types.vfdfield_t">vfdfield_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vcfdfield_t" title="meanas.fdmath.types.vcfdfield_t">vcfdfield_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vfdfield2_t" title="meanas.fdmath.types.vfdfield2_t">vfdfield2_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vcfdfield2_t" title="meanas.fdmath.types.vcfdfield2_t">vcfdfield2_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vfdslice_t" title="meanas.fdmath.types.vfdslice_t">vfdslice_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.vcfdslice_t" title="meanas.fdmath.types.vcfdslice_t">vcfdslice_t</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.ArrayLike" title="numpy.typing.ArrayLike">ArrayLike</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p>1D ndarray representing a vector field of shape shape (or None)</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>shape</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#collections.abc.Sequence" title="collections.abc.Sequence">Sequence</a>[<a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a>]</code>
</td>
<td>
<div class="doc-md-description">
<p>shape of the vector field</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td>
<code>nvdim</code>
</td>
<td>
<code><a class="autorefs autorefs-internal" href="#index-recommended-starting-points">int</a></code>
</td>
<td>
<div class="doc-md-description">
<p>Number of components in each vector</p>
</div>
</td>
<td>
<code>3</code>
</td>
</tr>
</tbody>
</table>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><a class="autorefs autorefs-internal" href="#meanas.fdmath.types.fdfield_t" title="meanas.fdmath.types.fdfield_t">fdfield_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.cfdfield_t" title="meanas.fdmath.types.cfdfield_t">cfdfield_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.fdfield2_t" title="meanas.fdmath.types.fdfield2_t">fdfield2_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.cfdfield2_t" title="meanas.fdmath.types.cfdfield2_t">cfdfield2_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.fdslice_t" title="meanas.fdmath.types.fdslice_t">fdslice_t</a> | <a class="autorefs autorefs-internal" href="#meanas.fdmath.types.cfdslice_t" title="meanas.fdmath.types.cfdslice_t">cfdslice_t</a> | <a class="autorefs autorefs-internal" href="#numpy.typing.NDArray" title="numpy.typing.NDArray">NDArray</a> | None</code>
</td>
<td>
<div class="doc-md-description">
<p><code>[f_x, f_y, f_z]</code> where each <code>f_</code> is a <code>len(shape)</code> dimensional ndarray (or <code>None</code>)</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="doc doc-object doc-module">
<h2 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">meanas.fdmath.types</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types" title="Permanent link"></a></h2>
<div class="doc doc-contents first">
<p>Types shared across multiple submodules</p>
<div class="doc doc-children">
<div class="doc doc-object doc-attribute">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.dx_lists_t">
<code class="doc-symbol doc-symbol-heading doc-symbol-attribute"></code> <span class="doc doc-object-name doc-attribute-name">dx_lists_t</span>
<span class="doc doc-labels">
<small class="doc doc-label doc-label-module-attribute"><code>module-attribute</code></small>
</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.dx_lists_t" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="n">dx_lists_t</span> <span class="o">=</span> <span class="n">Sequence</span><span class="p">[</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]]</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>'dxes' datastructure which contains grid cell width information in the following format:</p>
<div class="highlight"><pre><span></span><code>[[[dx_e[0], dx_e[1], ...], [dy_e[0], ...], [dz_e[0], ...]],
[[dx_h[0], dx_h[1], ...], [dy_h[0], ...], [dz_h[0], ...]]]
</code></pre></div>
<p>where <code>dx_e[0]</code> is the x-width of the <code>x=0</code> cells, as used when calculating dE/dx,
and <code>dy_h[0]</code> is the y-width of the <code>y=0</code> cells, as used when calculating dH/dy, etc.</p>
</div>
</div>
<div class="doc doc-object doc-attribute">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.dx_lists2_t">
<code class="doc-symbol doc-symbol-heading doc-symbol-attribute"></code> <span class="doc doc-object-name doc-attribute-name">dx_lists2_t</span>
<span class="doc doc-labels">
<small class="doc doc-label doc-label-module-attribute"><code>module-attribute</code></small>
</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.dx_lists2_t" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="n">dx_lists2_t</span> <span class="o">=</span> <span class="n">Sequence</span><span class="p">[</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">Sequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]]</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>2D 'dxes' datastructure which contains grid cell width information in the following format:</p>
<div class="highlight"><pre><span></span><code>[[[dx_e[0], dx_e[1], ...], [dy_e[0], ...]],
[[dx_h[0], dx_h[1], ...], [dy_h[0], ...]]]
</code></pre></div>
<p>where <code>dx_e[0]</code> is the x-width of the <code>x=0</code> cells, as used when calculating dE/dx,
and <code>dy_h[0]</code> is the y-width of the <code>y=0</code> cells, as used when calculating dH/dy, etc.</p>
</div>
</div>
<div class="doc doc-object doc-attribute">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.dx_lists_mut">
<code class="doc-symbol doc-symbol-heading doc-symbol-attribute"></code> <span class="doc doc-object-name doc-attribute-name">dx_lists_mut</span>
<span class="doc doc-labels">
<small class="doc doc-label doc-label-module-attribute"><code>module-attribute</code></small>
</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.dx_lists_mut" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="n">dx_lists_mut</span> <span class="o">=</span> <span class="n">MutableSequence</span><span class="p">[</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">MutableSequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]]</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Mutable version of <code>dx_lists_t</code></p>
</div>
</div>
<div class="doc doc-object doc-attribute">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.dx_lists2_mut">
<code class="doc-symbol doc-symbol-heading doc-symbol-attribute"></code> <span class="doc doc-object-name doc-attribute-name">dx_lists2_mut</span>
<span class="doc doc-labels">
<small class="doc doc-label doc-label-module-attribute"><code>module-attribute</code></small>
</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.dx_lists2_mut" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="n">dx_lists2_mut</span> <span class="o">=</span> <span class="n">MutableSequence</span><span class="p">[</span>
<a href="#api-fdmath-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> <span class="n">MutableSequence</span><span class="p">[</span><span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span> <span class="o">|</span> <span class="n">complexfloating</span><span class="p">]]</span>
<a href="#api-fdmath-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Mutable version of <code>dx_lists2_t</code></p>
</div>
</div>
<div class="doc doc-object doc-attribute">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.fdfield_updater_t">
<code class="doc-symbol doc-symbol-heading doc-symbol-attribute"></code> <span class="doc doc-object-name doc-attribute-name">fdfield_updater_t</span>
<span class="doc doc-labels">
<small class="doc doc-label doc-label-module-attribute"><code>module-attribute</code></small>
</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.fdfield_updater_t" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="n">fdfield_updater_t</span> <span class="o">=</span> <span class="n">Callable</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="n">fdfield_t</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Convenience type for functions which take and return an fdfield_t</p>
</div>
</div>
<div class="doc doc-object doc-attribute">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.cfdfield_updater_t">
<code class="doc-symbol doc-symbol-heading doc-symbol-attribute"></code> <span class="doc doc-object-name doc-attribute-name">cfdfield_updater_t</span>
<span class="doc doc-labels">
<small class="doc doc-label doc-label-module-attribute"><code>module-attribute</code></small>
</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.cfdfield_updater_t" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="n">cfdfield_updater_t</span> <span class="o">=</span> <span class="n">Callable</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="n">cfdfield_t</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Convenience type for functions which take and return an cfdfield_t</p>
</div>
</div>
<div class="doc doc-object doc-type_alias">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.fdfield">
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">fdfield</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.fdfield" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">fdfield</span> <span class="o">=</span> <span class="n">fdfield_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Vector field with shape (3, X, Y, Z) (e.g. <code>[E_x, E_y, E_z]</code>)</p>
</div>
</div>
<div class="doc doc-object doc-type_alias">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.vfdfield">
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">vfdfield</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.vfdfield" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">vfdfield</span> <span class="o">=</span> <span class="n">vfdfield_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Linearized vector field (single vector of length 3<em>X</em>Y*Z)</p>
</div>
</div>
<div class="doc doc-object doc-type_alias">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.cfdfield">
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">cfdfield</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.cfdfield" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">cfdfield</span> <span class="o">=</span> <span class="n">cfdfield_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Complex vector field with shape (3, X, Y, Z) (e.g. <code>[E_x, E_y, E_z]</code>)</p>
</div>
</div>
<div class="doc doc-object doc-type_alias">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.vcfdfield">
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">vcfdfield</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.vcfdfield" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">vcfdfield</span> <span class="o">=</span> <span class="n">vcfdfield_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Linearized complex vector field (single vector of length 3<em>X</em>Y*Z)</p>
</div>
</div>
<div class="doc doc-object doc-type_alias">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.fdslice">
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">fdslice</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.fdslice" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">fdslice</span> <span class="o">=</span> <span class="n">fdslice_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Vector field slice with shape (3, X, Y) (e.g. <code>[E_x, E_y, E_z]</code> at a single Z position)</p>
</div>
</div>
<div class="doc doc-object doc-type_alias">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.vfdslice">
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">vfdslice</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.vfdslice" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">vfdslice</span> <span class="o">=</span> <span class="n">vfdslice_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Linearized vector field slice (single vector of length 3<em>X</em>Y)</p>
</div>
</div>
<div class="doc doc-object doc-type_alias">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.cfdslice">
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">cfdslice</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.cfdslice" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">cfdslice</span> <span class="o">=</span> <span class="n">cfdslice_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Complex vector field slice with shape (3, X, Y) (e.g. <code>[E_x, E_y, E_z]</code> at a single Z position)</p>
</div>
</div>
<div class="doc doc-object doc-type_alias">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.vcfdslice">
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">vcfdslice</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.vcfdslice" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">vcfdslice</span> <span class="o">=</span> <span class="n">vcfdslice_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>Linearized complex vector field slice (single vector of length 3<em>X</em>Y)</p>
</div>
</div>
<div class="doc doc-object doc-type_alias">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.fdfield2">
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">fdfield2</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.fdfield2" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">fdfield2</span> <span class="o">=</span> <span class="n">fdfield2_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>2D Vector field with shape (2, X, Y) (e.g. <code>[E_x, E_y]</code>)</p>
</div>
</div>
<div class="doc doc-object doc-type_alias">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.vfdfield2">
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">vfdfield2</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.vfdfield2" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">vfdfield2</span> <span class="o">=</span> <span class="n">vfdfield2_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">floating</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>2D Linearized vector field (single vector of length 2<em>X</em>Y)</p>
</div>
</div>
<div class="doc doc-object doc-type_alias">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.cfdfield2">
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">cfdfield2</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.cfdfield2" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">cfdfield2</span> <span class="o">=</span> <span class="n">cfdfield2_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>2D Complex vector field with shape (2, X, Y) (e.g. <code>[E_x, E_y]</code>)</p>
</div>
</div>
<div class="doc doc-object doc-type_alias">
<h3 class="doc doc-heading" id="api-fdmath-meanas.fdmath.types.vcfdfield2">
<code class="doc-symbol doc-symbol-heading doc-symbol-type_alias"></code> <span class="doc doc-object-name doc-type_alias-name">vcfdfield2</span>
<a class="headerlink" href="#api-fdmath-meanas.fdmath.types.vcfdfield2" title="Permanent link"></a></h3>
<div class="doc-signature highlight"><pre><span></span><code><a href="#api-fdmath-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nc">vcfdfield2</span> <span class="o">=</span> <span class="n">vcfdfield2_t</span> <span class="o">|</span> <span class="n">NDArray</span><span class="p">[</span><span class="n">complexfloating</span><span class="p">]</span>
</code></pre></div>
<div class="doc doc-contents">
<p>2D Linearized complex vector field (single vector of length 2<em>X</em>Y)</p>
</div>
</div>
</div>
</div>
</div></section></section></div><style>.print-site-enumerate-headings #index > h1:before { content: '1 ' }
.print-site-enumerate-headings #index h2:before { content: '1.' counter(counter-index-2) ' ' }
.print-site-enumerate-headings #index h2 { counter-reset: counter-index-3 ; counter-increment: counter-index-2 }
.print-site-enumerate-headings #index h3:before { content: '1.' counter(counter-index-2) '.' counter(counter-index-3) ' ' }
.print-site-enumerate-headings #index h3 { counter-increment: counter-index-3 }
.print-site-enumerate-headings #section-2 > h1:before { content: '2 ' }
.print-site-enumerate-headings #api > h1:before { content: '2.1 ' }
.print-site-enumerate-headings #api h2:before { content: '2.1.' counter(counter-api-2) ' ' }
.print-site-enumerate-headings #api h2 { counter-increment: counter-api-2 }
.print-site-enumerate-headings #api-meanas > h1:before { content: '2.2 ' }
.print-site-enumerate-headings #api-meanas h2:before { content: '2.2.' counter(counter-api-meanas-2) ' ' }
.print-site-enumerate-headings #api-meanas h2 { counter-increment: counter-api-meanas-2 }
.print-site-enumerate-headings #api-eigensolvers > h1:before { content: '2.3 ' }
.print-site-enumerate-headings #api-eigensolvers h2:before { content: '2.3.' counter(counter-api-eigensolvers-2) ' ' }
.print-site-enumerate-headings #api-eigensolvers h2 { counter-increment: counter-api-eigensolvers-2 }
.print-site-enumerate-headings #api-fdfd > h1:before { content: '2.4 ' }
.print-site-enumerate-headings #api-fdfd h2:before { content: '2.4.' counter(counter-api-fdfd-2) ' ' }
.print-site-enumerate-headings #api-fdfd h2 { counter-increment: counter-api-fdfd-2 }
.print-site-enumerate-headings #api-waveguides > h1:before { content: '2.5 ' }
.print-site-enumerate-headings #api-waveguides h2:before { content: '2.5.' counter(counter-api-waveguides-2) ' ' }
.print-site-enumerate-headings #api-waveguides h2 { counter-increment: counter-api-waveguides-2 }
.print-site-enumerate-headings #api-fdtd > h1:before { content: '2.6 ' }
.print-site-enumerate-headings #api-fdtd h2:before { content: '2.6.' counter(counter-api-fdtd-2) ' ' }
.print-site-enumerate-headings #api-fdtd h2 { counter-increment: counter-api-fdtd-2 }
.print-site-enumerate-headings #api-fdmath > h1:before { content: '2.7 ' }
.print-site-enumerate-headings #api-fdmath h2:before { content: '2.7.' counter(counter-api-fdmath-2) ' ' }
.print-site-enumerate-headings #api-fdmath h2 { counter-increment: counter-api-fdmath-2 }
</style>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button class="md-top md-icon" data-md-component="top" hidden="" type="button">
<svg viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"></path></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" rel="noopener" target="_blank">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"annotate": null, "base": "/docs/meanas/", "features": ["navigation.indexes", "navigation.sections", "navigation.top", "content.code.copy", "toc.follow"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="data:text/javascript;base64,InVzZSBzdHJpY3QiOygoKT0+e3ZhciBaaT1PYmplY3QuY3JlYXRlO3ZhciBfcj1PYmplY3QuZGVmaW5lUHJvcGVydHk7dmFyIGVhPU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7dmFyIHRhPU9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzLEJ0PU9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMscmE9T2JqZWN0LmdldFByb3RvdHlwZU9mLEFyPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksYm89T2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTt2YXIgaG89KGUsdCxyKT0+dCBpbiBlP19yKGUsdCx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6cn0pOmVbdF09cixQPShlLHQpPT57Zm9yKHZhciByIGluIHR8fCh0PXt9KSlBci5jYWxsKHQscikmJmhvKGUscix0W3JdKTtpZihCdClmb3IodmFyIHIgb2YgQnQodCkpYm8uY2FsbCh0LHIpJiZobyhlLHIsdFtyXSk7cmV0dXJuIGV9O3ZhciB2bz0oZSx0KT0+e3ZhciByPXt9O2Zvcih2YXIgbyBpbiBlKUFyLmNhbGwoZSxvKSYmdC5pbmRleE9mKG8pPDAmJihyW29dPWVbb10pO2lmKGUhPW51bGwmJkJ0KWZvcih2YXIgbyBvZiBCdChlKSl0LmluZGV4T2Yobyk8MCYmYm8uY2FsbChlLG8pJiYocltvXT1lW29dKTtyZXR1cm4gcn07dmFyIENyPShlLHQpPT4oKT0+KHR8fGUoKHQ9e2V4cG9ydHM6e319KS5leHBvcnRzLHQpLHQuZXhwb3J0cyk7dmFyIG9hPShlLHQscixvKT0+e2lmKHQmJnR5cGVvZiB0PT0ib2JqZWN0Inx8dHlwZW9mIHQ9PSJmdW5jdGlvbiIpZm9yKGxldCBuIG9mIHRhKHQpKSFBci5jYWxsKGUsbikmJm4hPT1yJiZfcihlLG4se2dldDooKT0+dFtuXSxlbnVtZXJhYmxlOiEobz1lYSh0LG4pKXx8by5lbnVtZXJhYmxlfSk7cmV0dXJuIGV9O3ZhciAkdD0oZSx0LHIpPT4ocj1lIT1udWxsP1ppKHJhKGUpKTp7fSxvYSh0fHwhZXx8IWUuX19lc01vZHVsZT9fcihyLCJkZWZhdWx0Iix7dmFsdWU6ZSxlbnVtZXJhYmxlOiEwfSk6cixlKSk7dmFyIGdvPShlLHQscik9Pm5ldyBQcm9taXNlKChvLG4pPT57dmFyIGk9Yz0+e3RyeXthKHIubmV4dChjKSl9Y2F0Y2gocCl7bihwKX19LHM9Yz0+e3RyeXthKHIudGhyb3coYykpfWNhdGNoKHApe24ocCl9fSxhPWM9PmMuZG9uZT9vKGMudmFsdWUpOlByb21pc2UucmVzb2x2ZShjLnZhbHVlKS50aGVuKGkscyk7YSgocj1yLmFwcGx5KGUsdCkpLm5leHQoKSl9KTt2YXIgeG89Q3IoKGtyLHlvKT0+eyhmdW5jdGlvbihlLHQpe3R5cGVvZiBrcj09Im9iamVjdCImJnR5cGVvZiB5byE9InVuZGVmaW5lZCI/dCgpOnR5cGVvZiBkZWZpbmU9PSJmdW5jdGlvbiImJmRlZmluZS5hbWQ/ZGVmaW5lKHQpOnQoKX0pKGtyLChmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBlKHIpe3ZhciBvPSEwLG49ITEsaT1udWxsLHM9e3RleHQ6ITAsc2VhcmNoOiEwLHVybDohMCx0ZWw6ITAsZW1haWw6ITAscGFzc3dvcmQ6ITAsbnVtYmVyOiEwLGRhdGU6ITAsbW9udGg6ITAsd2VlazohMCx0aW1lOiEwLGRhdGV0aW1lOiEwLCJkYXRldGltZS1sb2NhbCI6ITB9O2Z1bmN0aW9uIGEoayl7cmV0dXJuISEoayYmayE9PWRvY3VtZW50JiZrLm5vZGVOYW1lIT09IkhUTUwiJiZrLm5vZGVOYW1lIT09IkJPRFkiJiYiY2xhc3NMaXN0ImluIGsmJiJjb250YWlucyJpbiBrLmNsYXNzTGlzdCl9ZnVuY3Rpb24gYyhrKXt2YXIgdXQ9ay50eXBlLGplPWsudGFnTmFtZTtyZXR1cm4hIShqZT09PSJJTlBVVCImJnNbdXRdJiYhay5yZWFkT25seXx8amU9PT0iVEVYVEFSRUEiJiYhay5yZWFkT25seXx8ay5pc0NvbnRlbnRFZGl0YWJsZSl9ZnVuY3Rpb24gcChrKXtrLmNsYXNzTGlzdC5jb250YWlucygiZm9jdXMtdmlzaWJsZSIpfHwoay5jbGFzc0xpc3QuYWRkKCJmb2N1cy12aXNpYmxlIiksay5zZXRBdHRyaWJ1dGUoImRhdGEtZm9jdXMtdmlzaWJsZS1hZGRlZCIsIiIpKX1mdW5jdGlvbiBsKGspe2suaGFzQXR0cmlidXRlKCJkYXRhLWZvY3VzLXZpc2libGUtYWRkZWQiKSYmKGsuY2xhc3NMaXN0LnJlbW92ZSgiZm9jdXMtdmlzaWJsZSIpLGsucmVtb3ZlQXR0cmlidXRlKCJkYXRhLWZvY3VzLXZpc2libGUtYWRkZWQiKSl9ZnVuY3Rpb24gZihrKXtrLm1ldGFLZXl8fGsuYWx0S2V5fHxrLmN0cmxLZXl8fChhKHIuYWN0aXZlRWxlbWVudCkmJnAoci5hY3RpdmVFbGVtZW50KSxvPSEwKX1mdW5jdGlvbiB1KGspe289ITF9ZnVuY3Rpb24gZChrKXthKGsudGFyZ2V0KSYmKG98fGMoay50YXJnZXQpKSYmcChrLnRhcmdldCl9ZnVuY3Rpb24gdihrKXthKGsudGFyZ2V0KSYmKGsudGFyZ2V0LmNsYXNzTGlzdC5jb250YWlucygiZm9jdXMtdmlzaWJsZSIpfHxrLnRhcmdldC5oYXNBdHRyaWJ1dGUoImRhdGEtZm9jdXMtdmlzaWJsZS1hZGRlZCIpKSYmKG49ITAsd2luZG93LmNsZWFyVGltZW91dChpKSxpPXdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7bj0hMX0sMTAwKSxsKGsudGFyZ2V0KSl9ZnVuY3Rpb24gUyhrKXtkb2N1bWVudC52aXNpYmlsaXR5U3RhdGU9PT0iaGlkZGVuIiYmKG4mJihvPSEwKSxYKCkpfWZ1bmN0aW9uIFgoKXtkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJtb3VzZW1vdmUiLGVlKSxkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJtb3VzZWRvd24iLGVlKSxkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJtb3VzZXVwIixlZSksZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigicG9pbnRlcm1vdmUiLGVlKSxkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJwb2ludGVyZG93biIsZWUpLGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoInBvaW50ZXJ1cCIsZWUpLGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoInRvdWNobW92ZSIsZWUpLGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoInRvdWNoc3RhcnQiLGVlKSxkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJ0b3VjaGVuZCIsZWUpfWZ1bmN0aW9uIHJlKCl7ZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigibW91c2Vtb3ZlIixlZSksZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigibW91c2Vkb3duIixlZSksZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigibW91c2V1cCIsZWUpLGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoInBvaW50ZXJtb3ZlIixlZSksZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigicG9pbnRlcmRvd24iLGVlKSxkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCJwb2ludGVydXAiLGVlKSxkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCJ0b3VjaG1vdmUiLGVlKSxkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCJ0b3VjaHN0YXJ0IixlZSksZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigidG91Y2hlbmQiLGVlKX1mdW5jdGlvbiBlZShrKXtrLnRhcmdldC5ub2RlTmFtZSYmay50YXJnZXQubm9kZU5hbWUudG9Mb3dlckNhc2UoKT09PSJodG1sInx8KG89ITEscmUoKSl9ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigia2V5ZG93biIsZiwhMCksZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigibW91c2Vkb3duIix1LCEwKSxkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJwb2ludGVyZG93biIsdSwhMCksZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigidG91Y2hzdGFydCIsdSwhMCksZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigidmlzaWJpbGl0eWNoYW5nZSIsUywhMCksWCgpLHIuYWRkRXZlbnRMaXN0ZW5lcigiZm9jdXMiLGQsITApLHIuYWRkRXZlbnRMaXN0ZW5lcigiYmx1ciIsdiwhMCksci5ub2RlVHlwZT09PU5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERSYmci5ob3N0P3IuaG9zdC5zZXRBdHRyaWJ1dGUoImRhdGEtanMtZm9jdXMtdmlzaWJsZSIsIiIpOnIubm9kZVR5cGU9PT1Ob2RlLkRPQ1VNRU5UX05PREUmJihkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgianMtZm9jdXMtdmlzaWJsZSIpLGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zZXRBdHRyaWJ1dGUoImRhdGEtanMtZm9jdXMtdmlzaWJsZSIsIiIpKX1pZih0eXBlb2Ygd2luZG93IT0idW5kZWZpbmVkIiYmdHlwZW9mIGRvY3VtZW50IT0idW5kZWZpbmVkIil7d2luZG93LmFwcGx5Rm9jdXNWaXNpYmxlUG9seWZpbGw9ZTt2YXIgdDt0cnl7dD1uZXcgQ3VzdG9tRXZlbnQoImZvY3VzLXZpc2libGUtcG9seWZpbGwtcmVhZHkiKX1jYXRjaChyKXt0PWRvY3VtZW50LmNyZWF0ZUV2ZW50KCJDdXN0b21FdmVudCIpLHQuaW5pdEN1c3RvbUV2ZW50KCJmb2N1cy12aXNpYmxlLXBvbHlmaWxsLXJlYWR5IiwhMSwhMSx7fSl9d2luZG93LmRpc3BhdGNoRXZlbnQodCl9dHlwZW9mIGRvY3VtZW50IT0idW5kZWZpbmVkIiYmZShkb2N1bWVudCl9KSl9KTt2YXIgcm89Q3IoKGp5LFJuKT0+eyJ1c2Ugc3RyaWN0IjsvKiEKICogZXNjYXBlLWh0bWwKICogQ29weXJpZ2h0KGMpIDIwMTItMjAxMyBUSiBIb2xvd2F5Y2h1awogKiBDb3B5cmlnaHQoYykgMjAxNSBBbmRyZWFzIEx1YmJlCiAqIENvcHlyaWdodChjKSAyMDE1IFRpYW5jaGVuZyAiVGltb3RoeSIgR3UKICogTUlUIExpY2Vuc2VkCiAqL3ZhciBxYT0vWyInJjw+XS87Um4uZXhwb3J0cz1LYTtmdW5jdGlvbiBLYShlKXt2YXIgdD0iIitlLHI9cWEuZXhlYyh0KTtpZighcilyZXR1cm4gdDt2YXIgbyxuPSIiLGk9MCxzPTA7Zm9yKGk9ci5pbmRleDtpPHQubGVuZ3RoO2krKyl7c3dpdGNoKHQuY2hhckNvZGVBdChpKSl7Y2FzZSAzNDpvPSImcXVvdDsiO2JyZWFrO2Nhc2UgMzg6bz0iJmFtcDsiO2JyZWFrO2Nhc2UgMzk6bz0iJiMzOTsiO2JyZWFrO2Nhc2UgNjA6bz0iJmx0OyI7YnJlYWs7Y2FzZSA2MjpvPSImZ3Q7IjticmVhaztkZWZhdWx0OmNvbnRpbnVlfXMhPT1pJiYobis9dC5zdWJzdHJpbmcocyxpKSkscz1pKzEsbis9b31yZXR1cm4gcyE9PWk/bit0LnN1YnN0cmluZyhzLGkpOm59fSk7dmFyIGFvPUNyKChOdCxpbyk9PnsvKiEKICogY2xpcGJvYXJkLmpzIHYyLjAuMTEKICogaHR0cHM6Ly9jbGlwYm9hcmRqcy5jb20vCiAqCiAqIExpY2Vuc2VkIE1JVCDCqSBaZW5vIFJvY2hhCiAqLyhmdW5jdGlvbih0LHIpe3R5cGVvZiBOdD09Im9iamVjdCImJnR5cGVvZiBpbz09Im9iamVjdCI/aW8uZXhwb3J0cz1yKCk6dHlwZW9mIGRlZmluZT09ImZ1bmN0aW9uIiYmZGVmaW5lLmFtZD9kZWZpbmUoW10scik6dHlwZW9mIE50PT0ib2JqZWN0Ij9OdC5DbGlwYm9hcmRKUz1yKCk6dC5DbGlwYm9hcmRKUz1yKCl9KShOdCxmdW5jdGlvbigpe3JldHVybihmdW5jdGlvbigpe3ZhciBlPXs2ODY6KGZ1bmN0aW9uKG8sbixpKXsidXNlIHN0cmljdCI7aS5kKG4se2RlZmF1bHQ6ZnVuY3Rpb24oKXtyZXR1cm4gWGl9fSk7dmFyIHM9aSgyNzkpLGE9aS5uKHMpLGM9aSgzNzApLHA9aS5uKGMpLGw9aSg4MTcpLGY9aS5uKGwpO2Z1bmN0aW9uIHUocSl7dHJ5e3JldHVybiBkb2N1bWVudC5leGVjQ29tbWFuZChxKX1jYXRjaChDKXtyZXR1cm4hMX19dmFyIGQ9ZnVuY3Rpb24oQyl7dmFyIF89ZigpKEMpO3JldHVybiB1KCJjdXQiKSxffSx2PWQ7ZnVuY3Rpb24gUyhxKXt2YXIgQz1kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZ2V0QXR0cmlidXRlKCJkaXIiKT09PSJydGwiLF89ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGV4dGFyZWEiKTtfLnN0eWxlLmZvbnRTaXplPSIxMnB0IixfLnN0eWxlLmJvcmRlcj0iMCIsXy5zdHlsZS5wYWRkaW5nPSIwIixfLnN0eWxlLm1hcmdpbj0iMCIsXy5zdHlsZS5wb3NpdGlvbj0iYWJzb2x1dGUiLF8uc3R5bGVbQz8icmlnaHQiOiJsZWZ0Il09Ii05OTk5cHgiO3ZhciBEPXdpbmRvdy5wYWdlWU9mZnNldHx8ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcDtyZXR1cm4gXy5zdHlsZS50b3A9IiIuY29uY2F0KEQsInB4IiksXy5zZXRBdHRyaWJ1dGUoInJlYWRvbmx5IiwiIiksXy52YWx1ZT1xLF99dmFyIFg9ZnVuY3Rpb24oQyxfKXt2YXIgRD1TKEMpO18uY29udGFpbmVyLmFwcGVuZENoaWxkKEQpO3ZhciBOPWYoKShEKTtyZXR1cm4gdSgiY29weSIpLEQucmVtb3ZlKCksTn0scmU9ZnVuY3Rpb24oQyl7dmFyIF89YXJndW1lbnRzLmxlbmd0aD4xJiZhcmd1bWVudHNbMV0hPT12b2lkIDA/YXJndW1lbnRzWzFdOntjb250YWluZXI6ZG9jdW1lbnQuYm9keX0sRD0iIjtyZXR1cm4gdHlwZW9mIEM9PSJzdHJpbmciP0Q9WChDLF8pOkMgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50JiYhWyJ0ZXh0Iiwic2VhcmNoIiwidXJsIiwidGVsIiwicGFzc3dvcmQiXS5pbmNsdWRlcyhDPT1udWxsP3ZvaWQgMDpDLnR5cGUpP0Q9WChDLnZhbHVlLF8pOihEPWYoKShDKSx1KCJjb3B5IikpLER9LGVlPXJlO2Z1bmN0aW9uIGsocSl7IkBiYWJlbC9oZWxwZXJzIC0gdHlwZW9mIjtyZXR1cm4gdHlwZW9mIFN5bWJvbD09ImZ1bmN0aW9uIiYmdHlwZW9mIFN5bWJvbC5pdGVyYXRvcj09InN5bWJvbCI/az1mdW5jdGlvbihfKXtyZXR1cm4gdHlwZW9mIF99Oms9ZnVuY3Rpb24oXyl7cmV0dXJuIF8mJnR5cGVvZiBTeW1ib2w9PSJmdW5jdGlvbiImJl8uY29uc3RydWN0b3I9PT1TeW1ib2wmJl8hPT1TeW1ib2wucHJvdG90eXBlPyJzeW1ib2wiOnR5cGVvZiBffSxrKHEpfXZhciB1dD1mdW5jdGlvbigpe3ZhciBDPWFyZ3VtZW50cy5sZW5ndGg+MCYmYXJndW1lbnRzWzBdIT09dm9pZCAwP2FyZ3VtZW50c1swXTp7fSxfPUMuYWN0aW9uLEQ9Xz09PXZvaWQgMD8iY29weSI6XyxOPUMuY29udGFpbmVyLEc9Qy50YXJnZXQsV2U9Qy50ZXh0O2lmKEQhPT0iY29weSImJkQhPT0iY3V0Iil0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgImFjdGlvbiIgdmFsdWUsIHVzZSBlaXRoZXIgImNvcHkiIG9yICJjdXQiJyk7aWYoRyE9PXZvaWQgMClpZihHJiZrKEcpPT09Im9iamVjdCImJkcubm9kZVR5cGU9PT0xKXtpZihEPT09ImNvcHkiJiZHLmhhc0F0dHJpYnV0ZSgiZGlzYWJsZWQiKSl0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgInRhcmdldCIgYXR0cmlidXRlLiBQbGVhc2UgdXNlICJyZWFkb25seSIgaW5zdGVhZCBvZiAiZGlzYWJsZWQiIGF0dHJpYnV0ZScpO2lmKEQ9PT0iY3V0IiYmKEcuaGFzQXR0cmlidXRlKCJyZWFkb25seSIpfHxHLmhhc0F0dHJpYnV0ZSgiZGlzYWJsZWQiKSkpdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkICJ0YXJnZXQiIGF0dHJpYnV0ZS4gWW91IGNhbid0IGN1dCB0ZXh0IGZyb20gZWxlbWVudHMgd2l0aCAicmVhZG9ubHkiIG9yICJkaXNhYmxlZCIgYXR0cmlidXRlc2ApfWVsc2UgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkICJ0YXJnZXQiIHZhbHVlLCB1c2UgYSB2YWxpZCBFbGVtZW50Jyk7aWYoV2UpcmV0dXJuIGVlKFdlLHtjb250YWluZXI6Tn0pO2lmKEcpcmV0dXJuIEQ9PT0iY3V0Ij92KEcpOmVlKEcse2NvbnRhaW5lcjpOfSl9LGplPXV0O2Z1bmN0aW9uIFIocSl7IkBiYWJlbC9oZWxwZXJzIC0gdHlwZW9mIjtyZXR1cm4gdHlwZW9mIFN5bWJvbD09ImZ1bmN0aW9uIiYmdHlwZW9mIFN5bWJvbC5pdGVyYXRvcj09InN5bWJvbCI/Uj1mdW5jdGlvbihfKXtyZXR1cm4gdHlwZW9mIF99OlI9ZnVuY3Rpb24oXyl7cmV0dXJuIF8mJnR5cGVvZiBTeW1ib2w9PSJmdW5jdGlvbiImJl8uY29uc3RydWN0b3I9PT1TeW1ib2wmJl8hPT1TeW1ib2wucHJvdG90eXBlPyJzeW1ib2wiOnR5cGVvZiBffSxSKHEpfWZ1bmN0aW9uIHNlKHEsQyl7aWYoIShxIGluc3RhbmNlb2YgQykpdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uIil9ZnVuY3Rpb24gY2UocSxDKXtmb3IodmFyIF89MDtfPEMubGVuZ3RoO18rKyl7dmFyIEQ9Q1tfXTtELmVudW1lcmFibGU9RC5lbnVtZXJhYmxlfHwhMSxELmNvbmZpZ3VyYWJsZT0hMCwidmFsdWUiaW4gRCYmKEQud3JpdGFibGU9ITApLE9iamVjdC5kZWZpbmVQcm9wZXJ0eShxLEQua2V5LEQpfX1mdW5jdGlvbiBoZShxLEMsXyl7cmV0dXJuIEMmJmNlKHEucHJvdG90eXBlLEMpLF8mJmNlKHEsXykscX1mdW5jdGlvbiBTZShxLEMpe2lmKHR5cGVvZiBDIT0iZnVuY3Rpb24iJiZDIT09bnVsbCl0aHJvdyBuZXcgVHlwZUVycm9yKCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiIpO3EucHJvdG90eXBlPU9iamVjdC5jcmVhdGUoQyYmQy5wcm90b3R5cGUse2NvbnN0cnVjdG9yOnt2YWx1ZTpxLHdyaXRhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMH19KSxDJiZVZShxLEMpfWZ1bmN0aW9uIFVlKHEsQyl7cmV0dXJuIFVlPU9iamVjdC5zZXRQcm90b3R5cGVPZnx8ZnVuY3Rpb24oRCxOKXtyZXR1cm4gRC5fX3Byb3RvX189TixEfSxVZShxLEMpfWZ1bmN0aW9uIFFpKHEpe3ZhciBDPUdpKCk7cmV0dXJuIGZ1bmN0aW9uKCl7dmFyIEQ9UXQocSksTjtpZihDKXt2YXIgRz1RdCh0aGlzKS5jb25zdHJ1Y3RvcjtOPVJlZmxlY3QuY29uc3RydWN0KEQsYXJndW1lbnRzLEcpfWVsc2UgTj1ELmFwcGx5KHRoaXMsYXJndW1lbnRzKTtyZXR1cm4gWWkodGhpcyxOKX19ZnVuY3Rpb24gWWkocSxDKXtyZXR1cm4gQyYmKFIoQyk9PT0ib2JqZWN0Inx8dHlwZW9mIEM9PSJmdW5jdGlvbiIpP0M6QmkocSl9ZnVuY3Rpb24gQmkocSl7aWYocT09PXZvaWQgMCl0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZCIpO3JldHVybiBxfWZ1bmN0aW9uIEdpKCl7aWYodHlwZW9mIFJlZmxlY3Q9PSJ1bmRlZmluZWQifHwhUmVmbGVjdC5jb25zdHJ1Y3R8fFJlZmxlY3QuY29uc3RydWN0LnNoYW0pcmV0dXJuITE7aWYodHlwZW9mIFByb3h5PT0iZnVuY3Rpb24iKXJldHVybiEwO3RyeXtyZXR1cm4gRGF0ZS5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChEYXRlLFtdLGZ1bmN0aW9uKCl7fSkpLCEwfWNhdGNoKHEpe3JldHVybiExfX1mdW5jdGlvbiBRdChxKXtyZXR1cm4gUXQ9T2JqZWN0LnNldFByb3RvdHlwZU9mP09iamVjdC5nZXRQcm90b3R5cGVPZjpmdW5jdGlvbihfKXtyZXR1cm4gXy5fX3Byb3RvX198fE9iamVjdC5nZXRQcm90b3R5cGVPZihfKX0sUXQocSl9ZnVuY3Rpb24gTXIocSxDKXt2YXIgXz0iZGF0YS1jbGlwYm9hcmQtIi5jb25jYXQocSk7aWYoQy5oYXNBdHRyaWJ1dGUoXykpcmV0dXJuIEMuZ2V0QXR0cmlidXRlKF8pfXZhciBKaT0oZnVuY3Rpb24ocSl7U2UoXyxxKTt2YXIgQz1RaShfKTtmdW5jdGlvbiBfKEQsTil7dmFyIEc7cmV0dXJuIHNlKHRoaXMsXyksRz1DLmNhbGwodGhpcyksRy5yZXNvbHZlT3B0aW9ucyhOKSxHLmxpc3RlbkNsaWNrKEQpLEd9cmV0dXJuIGhlKF8sW3trZXk6InJlc29sdmVPcHRpb25zIix2YWx1ZTpmdW5jdGlvbigpe3ZhciBOPWFyZ3VtZW50cy5sZW5ndGg+MCYmYXJndW1lbnRzWzBdIT09dm9pZCAwP2FyZ3VtZW50c1swXTp7fTt0aGlzLmFjdGlvbj10eXBlb2YgTi5hY3Rpb249PSJmdW5jdGlvbiI/Ti5hY3Rpb246dGhpcy5kZWZhdWx0QWN0aW9uLHRoaXMudGFyZ2V0PXR5cGVvZiBOLnRhcmdldD09ImZ1bmN0aW9uIj9OLnRhcmdldDp0aGlzLmRlZmF1bHRUYXJnZXQsdGhpcy50ZXh0PXR5cGVvZiBOLnRleHQ9PSJmdW5jdGlvbiI/Ti50ZXh0OnRoaXMuZGVmYXVsdFRleHQsdGhpcy5jb250YWluZXI9UihOLmNvbnRhaW5lcik9PT0ib2JqZWN0Ij9OLmNvbnRhaW5lcjpkb2N1bWVudC5ib2R5fX0se2tleToibGlzdGVuQ2xpY2siLHZhbHVlOmZ1bmN0aW9uKE4pe3ZhciBHPXRoaXM7dGhpcy5saXN0ZW5lcj1wKCkoTiwiY2xpY2siLGZ1bmN0aW9uKFdlKXtyZXR1cm4gRy5vbkNsaWNrKFdlKX0pfX0se2tleToib25DbGljayIsdmFsdWU6ZnVuY3Rpb24oTil7dmFyIEc9Ti5kZWxlZ2F0ZVRhcmdldHx8Ti5jdXJyZW50VGFyZ2V0LFdlPXRoaXMuYWN0aW9uKEcpfHwiY29weSIsWXQ9amUoe2FjdGlvbjpXZSxjb250YWluZXI6dGhpcy5jb250YWluZXIsdGFyZ2V0OnRoaXMudGFyZ2V0KEcpLHRleHQ6dGhpcy50ZXh0KEcpfSk7dGhpcy5lbWl0KFl0PyJzdWNjZXNzIjoiZXJyb3IiLHthY3Rpb246V2UsdGV4dDpZdCx0cmlnZ2VyOkcsY2xlYXJTZWxlY3Rpb246ZnVuY3Rpb24oKXtHJiZHLmZvY3VzKCksd2luZG93LmdldFNlbGVjdGlvbigpLnJlbW92ZUFsbFJhbmdlcygpfX0pfX0se2tleToiZGVmYXVsdEFjdGlvbiIsdmFsdWU6ZnVuY3Rpb24oTil7cmV0dXJuIE1yKCJhY3Rpb24iLE4pfX0se2tleToiZGVmYXVsdFRhcmdldCIsdmFsdWU6ZnVuY3Rpb24oTil7dmFyIEc9TXIoInRhcmdldCIsTik7aWYoRylyZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihHKX19LHtrZXk6ImRlZmF1bHRUZXh0Iix2YWx1ZTpmdW5jdGlvbihOKXtyZXR1cm4gTXIoInRleHQiLE4pfX0se2tleToiZGVzdHJveSIsdmFsdWU6ZnVuY3Rpb24oKXt0aGlzLmxpc3RlbmVyLmRlc3Ryb3koKX19XSxbe2tleToiY29weSIsdmFsdWU6ZnVuY3Rpb24oTil7dmFyIEc9YXJndW1lbnRzLmxlbmd0aD4xJiZhcmd1bWVudHNbMV0hPT12b2lkIDA/YXJndW1lbnRzWzFdOntjb250YWluZXI6ZG9jdW1lbnQuYm9keX07cmV0dXJuIGVlKE4sRyl9fSx7a2V5OiJjdXQiLHZhbHVlOmZ1bmN0aW9uKE4pe3JldHVybiB2KE4pfX0se2tleToiaXNTdXBwb3J0ZWQiLHZhbHVlOmZ1bmN0aW9uKCl7dmFyIE49YXJndW1lbnRzLmxlbmd0aD4wJiZhcmd1bWVudHNbMF0hPT12b2lkIDA/YXJndW1lbnRzWzBdOlsiY29weSIsImN1dCJdLEc9dHlwZW9mIE49PSJzdHJpbmciP1tOXTpOLFdlPSEhZG9jdW1lbnQucXVlcnlDb21tYW5kU3VwcG9ydGVkO3JldHVybiBHLmZvckVhY2goZnVuY3Rpb24oWXQpe1dlPVdlJiYhIWRvY3VtZW50LnF1ZXJ5Q29tbWFuZFN1cHBvcnRlZChZdCl9KSxXZX19XSksX30pKGEoKSksWGk9Sml9KSw4Mjg6KGZ1bmN0aW9uKG8pe3ZhciBuPTk7aWYodHlwZW9mIEVsZW1lbnQhPSJ1bmRlZmluZWQiJiYhRWxlbWVudC5wcm90b3R5cGUubWF0Y2hlcyl7dmFyIGk9RWxlbWVudC5wcm90b3R5cGU7aS5tYXRjaGVzPWkubWF0Y2hlc1NlbGVjdG9yfHxpLm1vek1hdGNoZXNTZWxlY3Rvcnx8aS5tc01hdGNoZXNTZWxlY3Rvcnx8aS5vTWF0Y2hlc1NlbGVjdG9yfHxpLndlYmtpdE1hdGNoZXNTZWxlY3Rvcn1mdW5jdGlvbiBzKGEsYyl7Zm9yKDthJiZhLm5vZGVUeXBlIT09bjspe2lmKHR5cGVvZiBhLm1hdGNoZXM9PSJmdW5jdGlvbiImJmEubWF0Y2hlcyhjKSlyZXR1cm4gYTthPWEucGFyZW50Tm9kZX19by5leHBvcnRzPXN9KSw0Mzg6KGZ1bmN0aW9uKG8sbixpKXt2YXIgcz1pKDgyOCk7ZnVuY3Rpb24gYShsLGYsdSxkLHYpe3ZhciBTPXAuYXBwbHkodGhpcyxhcmd1bWVudHMpO3JldHVybiBsLmFkZEV2ZW50TGlzdGVuZXIodSxTLHYpLHtkZXN0cm95OmZ1bmN0aW9uKCl7bC5yZW1vdmVFdmVudExpc3RlbmVyKHUsUyx2KX19fWZ1bmN0aW9uIGMobCxmLHUsZCx2KXtyZXR1cm4gdHlwZW9mIGwuYWRkRXZlbnRMaXN0ZW5lcj09ImZ1bmN0aW9uIj9hLmFwcGx5KG51bGwsYXJndW1lbnRzKTp0eXBlb2YgdT09ImZ1bmN0aW9uIj9hLmJpbmQobnVsbCxkb2N1bWVudCkuYXBwbHkobnVsbCxhcmd1bWVudHMpOih0eXBlb2YgbD09InN0cmluZyImJihsPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwobCkpLEFycmF5LnByb3RvdHlwZS5tYXAuY2FsbChsLGZ1bmN0aW9uKFMpe3JldHVybiBhKFMsZix1LGQsdil9KSl9ZnVuY3Rpb24gcChsLGYsdSxkKXtyZXR1cm4gZnVuY3Rpb24odil7di5kZWxlZ2F0ZVRhcmdldD1zKHYudGFyZ2V0LGYpLHYuZGVsZWdhdGVUYXJnZXQmJmQuY2FsbChsLHYpfX1vLmV4cG9ydHM9Y30pLDg3OTooZnVuY3Rpb24obyxuKXtuLm5vZGU9ZnVuY3Rpb24oaSl7cmV0dXJuIGkhPT12b2lkIDAmJmkgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCYmaS5ub2RlVHlwZT09PTF9LG4ubm9kZUxpc3Q9ZnVuY3Rpb24oaSl7dmFyIHM9T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGkpO3JldHVybiBpIT09dm9pZCAwJiYocz09PSJbb2JqZWN0IE5vZGVMaXN0XSJ8fHM9PT0iW29iamVjdCBIVE1MQ29sbGVjdGlvbl0iKSYmImxlbmd0aCJpbiBpJiYoaS5sZW5ndGg9PT0wfHxuLm5vZGUoaVswXSkpfSxuLnN0cmluZz1mdW5jdGlvbihpKXtyZXR1cm4gdHlwZW9mIGk9PSJzdHJpbmcifHxpIGluc3RhbmNlb2YgU3RyaW5nfSxuLmZuPWZ1bmN0aW9uKGkpe3ZhciBzPU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpKTtyZXR1cm4gcz09PSJbb2JqZWN0IEZ1bmN0aW9uXSJ9fSksMzcwOihmdW5jdGlvbihvLG4saSl7dmFyIHM9aSg4NzkpLGE9aSg0MzgpO2Z1bmN0aW9uIGModSxkLHYpe2lmKCF1JiYhZCYmIXYpdGhyb3cgbmV3IEVycm9yKCJNaXNzaW5nIHJlcXVpcmVkIGFyZ3VtZW50cyIpO2lmKCFzLnN0cmluZyhkKSl0aHJvdyBuZXcgVHlwZUVycm9yKCJTZWNvbmQgYXJndW1lbnQgbXVzdCBiZSBhIFN0cmluZyIpO2lmKCFzLmZuKHYpKXRocm93IG5ldyBUeXBlRXJyb3IoIlRoaXJkIGFyZ3VtZW50IG11c3QgYmUgYSBGdW5jdGlvbiIpO2lmKHMubm9kZSh1KSlyZXR1cm4gcCh1LGQsdik7aWYocy5ub2RlTGlzdCh1KSlyZXR1cm4gbCh1LGQsdik7aWYocy5zdHJpbmcodSkpcmV0dXJuIGYodSxkLHYpO3Rocm93IG5ldyBUeXBlRXJyb3IoIkZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBTdHJpbmcsIEhUTUxFbGVtZW50LCBIVE1MQ29sbGVjdGlvbiwgb3IgTm9kZUxpc3QiKX1mdW5jdGlvbiBwKHUsZCx2KXtyZXR1cm4gdS5hZGRFdmVudExpc3RlbmVyKGQsdikse2Rlc3Ryb3k6ZnVuY3Rpb24oKXt1LnJlbW92ZUV2ZW50TGlzdGVuZXIoZCx2KX19fWZ1bmN0aW9uIGwodSxkLHYpe3JldHVybiBBcnJheS5wcm90b3R5cGUuZm9yRWFjaC5jYWxsKHUsZnVuY3Rpb24oUyl7Uy5hZGRFdmVudExpc3RlbmVyKGQsdil9KSx7ZGVzdHJveTpmdW5jdGlvbigpe0FycmF5LnByb3RvdHlwZS5mb3JFYWNoLmNhbGwodSxmdW5jdGlvbihTKXtTLnJlbW92ZUV2ZW50TGlzdGVuZXIoZCx2KX0pfX19ZnVuY3Rpb24gZih1LGQsdil7cmV0dXJuIGEoZG9jdW1lbnQuYm9keSx1LGQsdil9by5leHBvcnRzPWN9KSw4MTc6KGZ1bmN0aW9uKG8pe2Z1bmN0aW9uIG4oaSl7dmFyIHM7aWYoaS5ub2RlTmFtZT09PSJTRUxFQ1QiKWkuZm9jdXMoKSxzPWkudmFsdWU7ZWxzZSBpZihpLm5vZGVOYW1lPT09IklOUFVUInx8aS5ub2RlTmFtZT09PSJURVhUQVJFQSIpe3ZhciBhPWkuaGFzQXR0cmlidXRlKCJyZWFkb25seSIpO2F8fGkuc2V0QXR0cmlidXRlKCJyZWFkb25seSIsIiIpLGkuc2VsZWN0KCksaS5zZXRTZWxlY3Rpb25SYW5nZSgwLGkudmFsdWUubGVuZ3RoKSxhfHxpLnJlbW92ZUF0dHJpYnV0ZSgicmVhZG9ubHkiKSxzPWkudmFsdWV9ZWxzZXtpLmhhc0F0dHJpYnV0ZSgiY29udGVudGVkaXRhYmxlIikmJmkuZm9jdXMoKTt2YXIgYz13aW5kb3cuZ2V0U2VsZWN0aW9uKCkscD1kb2N1bWVudC5jcmVhdGVSYW5nZSgpO3Auc2VsZWN0Tm9kZUNvbnRlbnRzKGkpLGMucmVtb3ZlQWxsUmFuZ2VzKCksYy5hZGRSYW5nZShwKSxzPWMudG9TdHJpbmcoKX1yZXR1cm4gc31vLmV4cG9ydHM9bn0pLDI3OTooZnVuY3Rpb24obyl7ZnVuY3Rpb24gbigpe31uLnByb3RvdHlwZT17b246ZnVuY3Rpb24oaSxzLGEpe3ZhciBjPXRoaXMuZXx8KHRoaXMuZT17fSk7cmV0dXJuKGNbaV18fChjW2ldPVtdKSkucHVzaCh7Zm46cyxjdHg6YX0pLHRoaXN9LG9uY2U6ZnVuY3Rpb24oaSxzLGEpe3ZhciBjPXRoaXM7ZnVuY3Rpb24gcCgpe2Mub2ZmKGkscCkscy5hcHBseShhLGFyZ3VtZW50cyl9cmV0dXJuIHAuXz1zLHRoaXMub24oaSxwLGEpfSxlbWl0OmZ1bmN0aW9uKGkpe3ZhciBzPVtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLDEpLGE9KCh0aGlzLmV8fCh0aGlzLmU9e30pKVtpXXx8W10pLnNsaWNlKCksYz0wLHA9YS5sZW5ndGg7Zm9yKGM7YzxwO2MrKylhW2NdLmZuLmFwcGx5KGFbY10uY3R4LHMpO3JldHVybiB0aGlzfSxvZmY6ZnVuY3Rpb24oaSxzKXt2YXIgYT10aGlzLmV8fCh0aGlzLmU9e30pLGM9YVtpXSxwPVtdO2lmKGMmJnMpZm9yKHZhciBsPTAsZj1jLmxlbmd0aDtsPGY7bCsrKWNbbF0uZm4hPT1zJiZjW2xdLmZuLl8hPT1zJiZwLnB1c2goY1tsXSk7cmV0dXJuIHAubGVuZ3RoP2FbaV09cDpkZWxldGUgYVtpXSx0aGlzfX0sby5leHBvcnRzPW4sby5leHBvcnRzLlRpbnlFbWl0dGVyPW59KX0sdD17fTtmdW5jdGlvbiByKG8pe2lmKHRbb10pcmV0dXJuIHRbb10uZXhwb3J0czt2YXIgbj10W29dPXtleHBvcnRzOnt9fTtyZXR1cm4gZVtvXShuLG4uZXhwb3J0cyxyKSxuLmV4cG9ydHN9cmV0dXJuKGZ1bmN0aW9uKCl7ci5uPWZ1bmN0aW9uKG8pe3ZhciBuPW8mJm8uX19lc01vZHVsZT9mdW5jdGlvbigpe3JldHVybiBvLmRlZmF1bHR9OmZ1bmN0aW9uKCl7cmV0dXJuIG99O3JldHVybiByLmQobix7YTpufSksbn19KSgpLChmdW5jdGlvbigpe3IuZD1mdW5jdGlvbihvLG4pe2Zvcih2YXIgaSBpbiBuKXIubyhuLGkpJiYhci5vKG8saSkmJk9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLGkse2VudW1lcmFibGU6ITAsZ2V0Om5baV19KX19KSgpLChmdW5jdGlvbigpe3Iubz1mdW5jdGlvbihvLG4pe3JldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobyxuKX19KSgpLHIoNjg2KX0pKCkuZGVmYXVsdH0pfSk7dmFyIFpNPSR0KHhvKCkpO3ZhciBIcj1mdW5jdGlvbihlLHQpe3JldHVybiBIcj1PYmplY3Quc2V0UHJvdG90eXBlT2Z8fHtfX3Byb3RvX186W119aW5zdGFuY2VvZiBBcnJheSYmZnVuY3Rpb24ocixvKXtyLl9fcHJvdG9fXz1vfXx8ZnVuY3Rpb24ocixvKXtmb3IodmFyIG4gaW4gbylPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobyxuKSYmKHJbbl09b1tuXSl9LEhyKGUsdCl9O2Z1bmN0aW9uIGllKGUsdCl7aWYodHlwZW9mIHQhPSJmdW5jdGlvbiImJnQhPT1udWxsKXRocm93IG5ldyBUeXBlRXJyb3IoIkNsYXNzIGV4dGVuZHMgdmFsdWUgIitTdHJpbmcodCkrIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsIik7SHIoZSx0KTtmdW5jdGlvbiByKCl7dGhpcy5jb25zdHJ1Y3Rvcj1lfWUucHJvdG90eXBlPXQ9PT1udWxsP09iamVjdC5jcmVhdGUodCk6KHIucHJvdG90eXBlPXQucHJvdG90eXBlLG5ldyByKX1mdW5jdGlvbiBFbyhlLHQscixvKXtmdW5jdGlvbiBuKGkpe3JldHVybiBpIGluc3RhbmNlb2Ygcj9pOm5ldyByKGZ1bmN0aW9uKHMpe3MoaSl9KX1yZXR1cm4gbmV3KHJ8fChyPVByb21pc2UpKShmdW5jdGlvbihpLHMpe2Z1bmN0aW9uIGEobCl7dHJ5e3Aoby5uZXh0KGwpKX1jYXRjaChmKXtzKGYpfX1mdW5jdGlvbiBjKGwpe3RyeXtwKG8udGhyb3cobCkpfWNhdGNoKGYpe3MoZil9fWZ1bmN0aW9uIHAobCl7bC5kb25lP2kobC52YWx1ZSk6bihsLnZhbHVlKS50aGVuKGEsYyl9cCgobz1vLmFwcGx5KGUsdHx8W10pKS5uZXh0KCkpfSl9ZnVuY3Rpb24gR3QoZSx0KXt2YXIgcj17bGFiZWw6MCxzZW50OmZ1bmN0aW9uKCl7aWYoaVswXSYxKXRocm93IGlbMV07cmV0dXJuIGlbMV19LHRyeXM6W10sb3BzOltdfSxvLG4saSxzPU9iamVjdC5jcmVhdGUoKHR5cGVvZiBJdGVyYXRvcj09ImZ1bmN0aW9uIj9JdGVyYXRvcjpPYmplY3QpLnByb3RvdHlwZSk7cmV0dXJuIHMubmV4dD1hKDApLHMudGhyb3c9YSgxKSxzLnJldHVybj1hKDIpLHR5cGVvZiBTeW1ib2w9PSJmdW5jdGlvbiImJihzW1N5bWJvbC5pdGVyYXRvcl09ZnVuY3Rpb24oKXtyZXR1cm4gdGhpc30pLHM7ZnVuY3Rpb24gYShwKXtyZXR1cm4gZnVuY3Rpb24obCl7cmV0dXJuIGMoW3AsbF0pfX1mdW5jdGlvbiBjKHApe2lmKG8pdGhyb3cgbmV3IFR5cGVFcnJvcigiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLiIpO2Zvcig7cyYmKHM9MCxwWzBdJiYocj0wKSkscjspdHJ5e2lmKG89MSxuJiYoaT1wWzBdJjI/bi5yZXR1cm46cFswXT9uLnRocm93fHwoKGk9bi5yZXR1cm4pJiZpLmNhbGwobiksMCk6bi5uZXh0KSYmIShpPWkuY2FsbChuLHBbMV0pKS5kb25lKXJldHVybiBpO3N3aXRjaChuPTAsaSYmKHA9W3BbMF0mMixpLnZhbHVlXSkscFswXSl7Y2FzZSAwOmNhc2UgMTppPXA7YnJlYWs7Y2FzZSA0OnJldHVybiByLmxhYmVsKysse3ZhbHVlOnBbMV0sZG9uZTohMX07Y2FzZSA1OnIubGFiZWwrKyxuPXBbMV0scD1bMF07Y29udGludWU7Y2FzZSA3OnA9ci5vcHMucG9wKCksci50cnlzLnBvcCgpO2NvbnRpbnVlO2RlZmF1bHQ6aWYoaT1yLnRyeXMsIShpPWkubGVuZ3RoPjAmJmlbaS5sZW5ndGgtMV0pJiYocFswXT09PTZ8fHBbMF09PT0yKSl7cj0wO2NvbnRpbnVlfWlmKHBbMF09PT0zJiYoIWl8fHBbMV0+aVswXSYmcFsxXTxpWzNdKSl7ci5sYWJlbD1wWzFdO2JyZWFrfWlmKHBbMF09PT02JiZyLmxhYmVsPGlbMV0pe3IubGFiZWw9aVsxXSxpPXA7YnJlYWt9aWYoaSYmci5sYWJlbDxpWzJdKXtyLmxhYmVsPWlbMl0sci5vcHMucHVzaChwKTticmVha31pWzJdJiZyLm9wcy5wb3AoKSxyLnRyeXMucG9wKCk7Y29udGludWV9cD10LmNhbGwoZSxyKX1jYXRjaChsKXtwPVs2LGxdLG49MH1maW5hbGx5e289aT0wfWlmKHBbMF0mNSl0aHJvdyBwWzFdO3JldHVybnt2YWx1ZTpwWzBdP3BbMV06dm9pZCAwLGRvbmU6ITB9fX1mdW5jdGlvbiBPZShlKXt2YXIgdD10eXBlb2YgU3ltYm9sPT0iZnVuY3Rpb24iJiZTeW1ib2wuaXRlcmF0b3Iscj10JiZlW3RdLG89MDtpZihyKXJldHVybiByLmNhbGwoZSk7aWYoZSYmdHlwZW9mIGUubGVuZ3RoPT0ibnVtYmVyIilyZXR1cm57bmV4dDpmdW5jdGlvbigpe3JldHVybiBlJiZvPj1lLmxlbmd0aCYmKGU9dm9pZCAwKSx7dmFsdWU6ZSYmZVtvKytdLGRvbmU6IWV9fX07dGhyb3cgbmV3IFR5cGVFcnJvcih0PyJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLiI6IlN5bWJvbC5pdGVyYXRvciBpcyBub3QgZGVmaW5lZC4iKX1mdW5jdGlvbiBLKGUsdCl7dmFyIHI9dHlwZW9mIFN5bWJvbD09ImZ1bmN0aW9uIiYmZVtTeW1ib2wuaXRlcmF0b3JdO2lmKCFyKXJldHVybiBlO3ZhciBvPXIuY2FsbChlKSxuLGk9W10sczt0cnl7Zm9yKDsodD09PXZvaWQgMHx8dC0tID4wKSYmIShuPW8ubmV4dCgpKS5kb25lOylpLnB1c2gobi52YWx1ZSl9Y2F0Y2goYSl7cz17ZXJyb3I6YX19ZmluYWxseXt0cnl7biYmIW4uZG9uZSYmKHI9by5yZXR1cm4pJiZyLmNhbGwobyl9ZmluYWxseXtpZihzKXRocm93IHMuZXJyb3J9fXJldHVybiBpfWZ1bmN0aW9uIEIoZSx0LHIpe2lmKHJ8fGFyZ3VtZW50cy5sZW5ndGg9PT0yKWZvcih2YXIgbz0wLG49dC5sZW5ndGgsaTtvPG47bysrKShpfHwhKG8gaW4gdCkpJiYoaXx8KGk9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodCwwLG8pKSxpW29dPXRbb10pO3JldHVybiBlLmNvbmNhdChpfHxBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0KSl9ZnVuY3Rpb24gZHQoZSl7cmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBkdD8odGhpcy52PWUsdGhpcyk6bmV3IGR0KGUpfWZ1bmN0aW9uIHdvKGUsdCxyKXtpZighU3ltYm9sLmFzeW5jSXRlcmF0b3IpdGhyb3cgbmV3IFR5cGVFcnJvcigiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuIik7dmFyIG89ci5hcHBseShlLHR8fFtdKSxuLGk9W107cmV0dXJuIG49T2JqZWN0LmNyZWF0ZSgodHlwZW9mIEFzeW5jSXRlcmF0b3I9PSJmdW5jdGlvbiI/QXN5bmNJdGVyYXRvcjpPYmplY3QpLnByb3RvdHlwZSksYSgibmV4dCIpLGEoInRocm93IiksYSgicmV0dXJuIixzKSxuW1N5bWJvbC5hc3luY0l0ZXJhdG9yXT1mdW5jdGlvbigpe3JldHVybiB0aGlzfSxuO2Z1bmN0aW9uIHMoZCl7cmV0dXJuIGZ1bmN0aW9uKHYpe3JldHVybiBQcm9taXNlLnJlc29sdmUodikudGhlbihkLGYpfX1mdW5jdGlvbiBhKGQsdil7b1tkXSYmKG5bZF09ZnVuY3Rpb24oUyl7cmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKFgscmUpe2kucHVzaChbZCxTLFgscmVdKT4xfHxjKGQsUyl9KX0sdiYmKG5bZF09dihuW2RdKSkpfWZ1bmN0aW9uIGMoZCx2KXt0cnl7cChvW2RdKHYpKX1jYXRjaChTKXt1KGlbMF1bM10sUyl9fWZ1bmN0aW9uIHAoZCl7ZC52YWx1ZSBpbnN0YW5jZW9mIGR0P1Byb21pc2UucmVzb2x2ZShkLnZhbHVlLnYpLnRoZW4obCxmKTp1KGlbMF1bMl0sZCl9ZnVuY3Rpb24gbChkKXtjKCJuZXh0IixkKX1mdW5jdGlvbiBmKGQpe2MoInRocm93IixkKX1mdW5jdGlvbiB1KGQsdil7ZCh2KSxpLnNoaWZ0KCksaS5sZW5ndGgmJmMoaVswXVswXSxpWzBdWzFdKX19ZnVuY3Rpb24gVG8oZSl7aWYoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKXRocm93IG5ldyBUeXBlRXJyb3IoIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLiIpO3ZhciB0PWVbU3ltYm9sLmFzeW5jSXRlcmF0b3JdLHI7cmV0dXJuIHQ/dC5jYWxsKGUpOihlPXR5cGVvZiBPZT09ImZ1bmN0aW9uIj9PZShlKTplW1N5bWJvbC5pdGVyYXRvcl0oKSxyPXt9LG8oIm5leHQiKSxvKCJ0aHJvdyIpLG8oInJldHVybiIpLHJbU3ltYm9sLmFzeW5jSXRlcmF0b3JdPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXN9LHIpO2Z1bmN0aW9uIG8oaSl7cltpXT1lW2ldJiZmdW5jdGlvbihzKXtyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24oYSxjKXtzPWVbaV0ocyksbihhLGMscy5kb25lLHMudmFsdWUpfSl9fWZ1bmN0aW9uIG4oaSxzLGEsYyl7UHJvbWlzZS5yZXNvbHZlKGMpLnRoZW4oZnVuY3Rpb24ocCl7aSh7dmFsdWU6cCxkb25lOmF9KX0scyl9fWZ1bmN0aW9uIEkoZSl7cmV0dXJuIHR5cGVvZiBlPT0iZnVuY3Rpb24ifWZ1bmN0aW9uIHl0KGUpe3ZhciB0PWZ1bmN0aW9uKG8pe0Vycm9yLmNhbGwobyksby5zdGFjaz1uZXcgRXJyb3IoKS5zdGFja30scj1lKHQpO3JldHVybiByLnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKEVycm9yLnByb3RvdHlwZSksci5wcm90b3R5cGUuY29uc3RydWN0b3I9cixyfXZhciBKdD15dChmdW5jdGlvbihlKXtyZXR1cm4gZnVuY3Rpb24ocil7ZSh0aGlzKSx0aGlzLm1lc3NhZ2U9cj9yLmxlbmd0aCtgIGVycm9ycyBvY2N1cnJlZCBkdXJpbmcgdW5zdWJzY3JpcHRpb246CmArci5tYXAoZnVuY3Rpb24obyxuKXtyZXR1cm4gbisxKyIpICIrby50b1N0cmluZygpfSkuam9pbihgCiAgYCk6IiIsdGhpcy5uYW1lPSJVbnN1YnNjcmlwdGlvbkVycm9yIix0aGlzLmVycm9ycz1yfX0pO2Z1bmN0aW9uIFplKGUsdCl7aWYoZSl7dmFyIHI9ZS5pbmRleE9mKHQpOzA8PXImJmUuc3BsaWNlKHIsMSl9fXZhciBxZT0oZnVuY3Rpb24oKXtmdW5jdGlvbiBlKHQpe3RoaXMuaW5pdGlhbFRlYXJkb3duPXQsdGhpcy5jbG9zZWQ9ITEsdGhpcy5fcGFyZW50YWdlPW51bGwsdGhpcy5fZmluYWxpemVycz1udWxsfXJldHVybiBlLnByb3RvdHlwZS51bnN1YnNjcmliZT1mdW5jdGlvbigpe3ZhciB0LHIsbyxuLGk7aWYoIXRoaXMuY2xvc2VkKXt0aGlzLmNsb3NlZD0hMDt2YXIgcz10aGlzLl9wYXJlbnRhZ2U7aWYocylpZih0aGlzLl9wYXJlbnRhZ2U9bnVsbCxBcnJheS5pc0FycmF5KHMpKXRyeXtmb3IodmFyIGE9T2UocyksYz1hLm5leHQoKTshYy5kb25lO2M9YS5uZXh0KCkpe3ZhciBwPWMudmFsdWU7cC5yZW1vdmUodGhpcyl9fWNhdGNoKFMpe3Q9e2Vycm9yOlN9fWZpbmFsbHl7dHJ5e2MmJiFjLmRvbmUmJihyPWEucmV0dXJuKSYmci5jYWxsKGEpfWZpbmFsbHl7aWYodCl0aHJvdyB0LmVycm9yfX1lbHNlIHMucmVtb3ZlKHRoaXMpO3ZhciBsPXRoaXMuaW5pdGlhbFRlYXJkb3duO2lmKEkobCkpdHJ5e2woKX1jYXRjaChTKXtpPVMgaW5zdGFuY2VvZiBKdD9TLmVycm9yczpbU119dmFyIGY9dGhpcy5fZmluYWxpemVycztpZihmKXt0aGlzLl9maW5hbGl6ZXJzPW51bGw7dHJ5e2Zvcih2YXIgdT1PZShmKSxkPXUubmV4dCgpOyFkLmRvbmU7ZD11Lm5leHQoKSl7dmFyIHY9ZC52YWx1ZTt0cnl7U28odil9Y2F0Y2goUyl7aT1pIT1udWxsP2k6W10sUyBpbnN0YW5jZW9mIEp0P2k9QihCKFtdLEsoaSkpLEsoUy5lcnJvcnMpKTppLnB1c2goUyl9fX1jYXRjaChTKXtvPXtlcnJvcjpTfX1maW5hbGx5e3RyeXtkJiYhZC5kb25lJiYobj11LnJldHVybikmJm4uY2FsbCh1KX1maW5hbGx5e2lmKG8pdGhyb3cgby5lcnJvcn19fWlmKGkpdGhyb3cgbmV3IEp0KGkpfX0sZS5wcm90b3R5cGUuYWRkPWZ1bmN0aW9uKHQpe3ZhciByO2lmKHQmJnQhPT10aGlzKWlmKHRoaXMuY2xvc2VkKVNvKHQpO2Vsc2V7aWYodCBpbnN0YW5jZW9mIGUpe2lmKHQuY2xvc2VkfHx0Ll9oYXNQYXJlbnQodGhpcykpcmV0dXJuO3QuX2FkZFBhcmVudCh0aGlzKX0odGhpcy5fZmluYWxpemVycz0ocj10aGlzLl9maW5hbGl6ZXJzKSE9PW51bGwmJnIhPT12b2lkIDA/cjpbXSkucHVzaCh0KX19LGUucHJvdG90eXBlLl9oYXNQYXJlbnQ9ZnVuY3Rpb24odCl7dmFyIHI9dGhpcy5fcGFyZW50YWdlO3JldHVybiByPT09dHx8QXJyYXkuaXNBcnJheShyKSYmci5pbmNsdWRlcyh0KX0sZS5wcm90b3R5cGUuX2FkZFBhcmVudD1mdW5jdGlvbih0KXt2YXIgcj10aGlzLl9wYXJlbnRhZ2U7dGhpcy5fcGFyZW50YWdlPUFycmF5LmlzQXJyYXkocik/KHIucHVzaCh0KSxyKTpyP1tyLHRdOnR9LGUucHJvdG90eXBlLl9yZW1vdmVQYXJlbnQ9ZnVuY3Rpb24odCl7dmFyIHI9dGhpcy5fcGFyZW50YWdlO3I9PT10P3RoaXMuX3BhcmVudGFnZT1udWxsOkFycmF5LmlzQXJyYXkocikmJlplKHIsdCl9LGUucHJvdG90eXBlLnJlbW92ZT1mdW5jdGlvbih0KXt2YXIgcj10aGlzLl9maW5hbGl6ZXJzO3ImJlplKHIsdCksdCBpbnN0YW5jZW9mIGUmJnQuX3JlbW92ZVBhcmVudCh0aGlzKX0sZS5FTVBUWT0oZnVuY3Rpb24oKXt2YXIgdD1uZXcgZTtyZXR1cm4gdC5jbG9zZWQ9ITAsdH0pKCksZX0pKCk7dmFyICRyPXFlLkVNUFRZO2Z1bmN0aW9uIFh0KGUpe3JldHVybiBlIGluc3RhbmNlb2YgcWV8fGUmJiJjbG9zZWQiaW4gZSYmSShlLnJlbW92ZSkmJkkoZS5hZGQpJiZJKGUudW5zdWJzY3JpYmUpfWZ1bmN0aW9uIFNvKGUpe0koZSk/ZSgpOmUudW5zdWJzY3JpYmUoKX12YXIgRGU9e29uVW5oYW5kbGVkRXJyb3I6bnVsbCxvblN0b3BwZWROb3RpZmljYXRpb246bnVsbCxQcm9taXNlOnZvaWQgMCx1c2VEZXByZWNhdGVkU3luY2hyb25vdXNFcnJvckhhbmRsaW5nOiExLHVzZURlcHJlY2F0ZWROZXh0Q29udGV4dDohMX07dmFyIHh0PXtzZXRUaW1lb3V0OmZ1bmN0aW9uKGUsdCl7Zm9yKHZhciByPVtdLG89MjtvPGFyZ3VtZW50cy5sZW5ndGg7bysrKXJbby0yXT1hcmd1bWVudHNbb107dmFyIG49eHQuZGVsZWdhdGU7cmV0dXJuIG4hPW51bGwmJm4uc2V0VGltZW91dD9uLnNldFRpbWVvdXQuYXBwbHkobixCKFtlLHRdLEsocikpKTpzZXRUaW1lb3V0LmFwcGx5KHZvaWQgMCxCKFtlLHRdLEsocikpKX0sY2xlYXJUaW1lb3V0OmZ1bmN0aW9uKGUpe3ZhciB0PXh0LmRlbGVnYXRlO3JldHVybigodD09bnVsbD92b2lkIDA6dC5jbGVhclRpbWVvdXQpfHxjbGVhclRpbWVvdXQpKGUpfSxkZWxlZ2F0ZTp2b2lkIDB9O2Z1bmN0aW9uIFp0KGUpe3h0LnNldFRpbWVvdXQoZnVuY3Rpb24oKXt2YXIgdD1EZS5vblVuaGFuZGxlZEVycm9yO2lmKHQpdChlKTtlbHNlIHRocm93IGV9KX1mdW5jdGlvbiBnZSgpe312YXIgT289KGZ1bmN0aW9uKCl7cmV0dXJuIFByKCJDIix2b2lkIDAsdm9pZCAwKX0pKCk7ZnVuY3Rpb24gTG8oZSl7cmV0dXJuIFByKCJFIix2b2lkIDAsZSl9ZnVuY3Rpb24gTW8oZSl7cmV0dXJuIFByKCJOIixlLHZvaWQgMCl9ZnVuY3Rpb24gUHIoZSx0LHIpe3JldHVybntraW5kOmUsdmFsdWU6dCxlcnJvcjpyfX12YXIgaHQ9bnVsbDtmdW5jdGlvbiBFdChlKXtpZihEZS51c2VEZXByZWNhdGVkU3luY2hyb25vdXNFcnJvckhhbmRsaW5nKXt2YXIgdD0haHQ7aWYodCYmKGh0PXtlcnJvclRocm93bjohMSxlcnJvcjpudWxsfSksZSgpLHQpe3ZhciByPWh0LG89ci5lcnJvclRocm93bixuPXIuZXJyb3I7aWYoaHQ9bnVsbCxvKXRocm93IG59fWVsc2UgZSgpfWZ1bmN0aW9uIF9vKGUpe0RlLnVzZURlcHJlY2F0ZWRTeW5jaHJvbm91c0Vycm9ySGFuZGxpbmcmJmh0JiYoaHQuZXJyb3JUaHJvd249ITAsaHQuZXJyb3I9ZSl9dmFyIFB0PShmdW5jdGlvbihlKXtpZSh0LGUpO2Z1bmN0aW9uIHQocil7dmFyIG89ZS5jYWxsKHRoaXMpfHx0aGlzO3JldHVybiBvLmlzU3RvcHBlZD0hMSxyPyhvLmRlc3RpbmF0aW9uPXIsWHQocikmJnIuYWRkKG8pKTpvLmRlc3RpbmF0aW9uPXNhLG99cmV0dXJuIHQuY3JlYXRlPWZ1bmN0aW9uKHIsbyxuKXtyZXR1cm4gbmV3IGJ0KHIsbyxuKX0sdC5wcm90b3R5cGUubmV4dD1mdW5jdGlvbihyKXt0aGlzLmlzU3RvcHBlZD9JcihNbyhyKSx0aGlzKTp0aGlzLl9uZXh0KHIpfSx0LnByb3RvdHlwZS5lcnJvcj1mdW5jdGlvbihyKXt0aGlzLmlzU3RvcHBlZD9JcihMbyhyKSx0aGlzKToodGhpcy5pc1N0b3BwZWQ9ITAsdGhpcy5fZXJyb3IocikpfSx0LnByb3RvdHlwZS5jb21wbGV0ZT1mdW5jdGlvbigpe3RoaXMuaXNTdG9wcGVkP0lyKE9vLHRoaXMpOih0aGlzLmlzU3RvcHBlZD0hMCx0aGlzLl9jb21wbGV0ZSgpKX0sdC5wcm90b3R5cGUudW5zdWJzY3JpYmU9ZnVuY3Rpb24oKXt0aGlzLmNsb3NlZHx8KHRoaXMuaXNTdG9wcGVkPSEwLGUucHJvdG90eXBlLnVuc3Vic2NyaWJlLmNhbGwodGhpcyksdGhpcy5kZXN0aW5hdGlvbj1udWxsKX0sdC5wcm90b3R5cGUuX25leHQ9ZnVuY3Rpb24ocil7dGhpcy5kZXN0aW5hdGlvbi5uZXh0KHIpfSx0LnByb3RvdHlwZS5fZXJyb3I9ZnVuY3Rpb24ocil7dHJ5e3RoaXMuZGVzdGluYXRpb24uZXJyb3Iocil9ZmluYWxseXt0aGlzLnVuc3Vic2NyaWJlKCl9fSx0LnByb3RvdHlwZS5fY29tcGxldGU9ZnVuY3Rpb24oKXt0cnl7dGhpcy5kZXN0aW5hdGlvbi5jb21wbGV0ZSgpfWZpbmFsbHl7dGhpcy51bnN1YnNjcmliZSgpfX0sdH0pKHFlKTt2YXIgbmE9RnVuY3Rpb24ucHJvdG90eXBlLmJpbmQ7ZnVuY3Rpb24gUnIoZSx0KXtyZXR1cm4gbmEuY2FsbChlLHQpfXZhciBpYT0oZnVuY3Rpb24oKXtmdW5jdGlvbiBlKHQpe3RoaXMucGFydGlhbE9ic2VydmVyPXR9cmV0dXJuIGUucHJvdG90eXBlLm5leHQ9ZnVuY3Rpb24odCl7dmFyIHI9dGhpcy5wYXJ0aWFsT2JzZXJ2ZXI7aWYoci5uZXh0KXRyeXtyLm5leHQodCl9Y2F0Y2gobyl7ZXIobyl9fSxlLnByb3RvdHlwZS5lcnJvcj1mdW5jdGlvbih0KXt2YXIgcj10aGlzLnBhcnRpYWxPYnNlcnZlcjtpZihyLmVycm9yKXRyeXtyLmVycm9yKHQpfWNhdGNoKG8pe2VyKG8pfWVsc2UgZXIodCl9LGUucHJvdG90eXBlLmNvbXBsZXRlPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5wYXJ0aWFsT2JzZXJ2ZXI7aWYodC5jb21wbGV0ZSl0cnl7dC5jb21wbGV0ZSgpfWNhdGNoKHIpe2VyKHIpfX0sZX0pKCksYnQ9KGZ1bmN0aW9uKGUpe2llKHQsZSk7ZnVuY3Rpb24gdChyLG8sbil7dmFyIGk9ZS5jYWxsKHRoaXMpfHx0aGlzLHM7aWYoSShyKXx8IXIpcz17bmV4dDpyIT1udWxsP3I6dm9pZCAwLGVycm9yOm8hPW51bGw/bzp2b2lkIDAsY29tcGxldGU6biE9bnVsbD9uOnZvaWQgMH07ZWxzZXt2YXIgYTtpJiZEZS51c2VEZXByZWNhdGVkTmV4dENvbnRleHQ/KGE9T2JqZWN0LmNyZWF0ZShyKSxhLnVuc3Vic2NyaWJlPWZ1bmN0aW9uKCl7cmV0dXJuIGkudW5zdWJzY3JpYmUoKX0scz17bmV4dDpyLm5leHQmJlJyKHIubmV4dCxhKSxlcnJvcjpyLmVycm9yJiZScihyLmVycm9yLGEpLGNvbXBsZXRlOnIuY29tcGxldGUmJlJyKHIuY29tcGxldGUsYSl9KTpzPXJ9cmV0dXJuIGkuZGVzdGluYXRpb249bmV3IGlhKHMpLGl9cmV0dXJuIHR9KShQdCk7ZnVuY3Rpb24gZXIoZSl7RGUudXNlRGVwcmVjYXRlZFN5bmNocm9ub3VzRXJyb3JIYW5kbGluZz9fbyhlKTpadChlKX1mdW5jdGlvbiBhYShlKXt0aHJvdyBlfWZ1bmN0aW9uIElyKGUsdCl7dmFyIHI9RGUub25TdG9wcGVkTm90aWZpY2F0aW9uO3ImJnh0LnNldFRpbWVvdXQoZnVuY3Rpb24oKXtyZXR1cm4gcihlLHQpfSl9dmFyIHNhPXtjbG9zZWQ6ITAsbmV4dDpnZSxlcnJvcjphYSxjb21wbGV0ZTpnZX07dmFyIHd0PShmdW5jdGlvbigpe3JldHVybiB0eXBlb2YgU3ltYm9sPT0iZnVuY3Rpb24iJiZTeW1ib2wub2JzZXJ2YWJsZXx8IkBAb2JzZXJ2YWJsZSJ9KSgpO2Z1bmN0aW9uIGJlKGUpe3JldHVybiBlfWZ1bmN0aW9uIEFvKCl7Zm9yKHZhciBlPVtdLHQ9MDt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKWVbdF09YXJndW1lbnRzW3RdO3JldHVybiBGcihlKX1mdW5jdGlvbiBGcihlKXtyZXR1cm4gZS5sZW5ndGg9PT0wP2JlOmUubGVuZ3RoPT09MT9lWzBdOmZ1bmN0aW9uKHIpe3JldHVybiBlLnJlZHVjZShmdW5jdGlvbihvLG4pe3JldHVybiBuKG8pfSxyKX19dmFyIEY9KGZ1bmN0aW9uKCl7ZnVuY3Rpb24gZSh0KXt0JiYodGhpcy5fc3Vic2NyaWJlPXQpfXJldHVybiBlLnByb3RvdHlwZS5saWZ0PWZ1bmN0aW9uKHQpe3ZhciByPW5ldyBlO3JldHVybiByLnNvdXJjZT10aGlzLHIub3BlcmF0b3I9dCxyfSxlLnByb3RvdHlwZS5zdWJzY3JpYmU9ZnVuY3Rpb24odCxyLG8pe3ZhciBuPXRoaXMsaT1wYSh0KT90Om5ldyBidCh0LHIsbyk7cmV0dXJuIEV0KGZ1bmN0aW9uKCl7dmFyIHM9bixhPXMub3BlcmF0b3IsYz1zLnNvdXJjZTtpLmFkZChhP2EuY2FsbChpLGMpOmM/bi5fc3Vic2NyaWJlKGkpOm4uX3RyeVN1YnNjcmliZShpKSl9KSxpfSxlLnByb3RvdHlwZS5fdHJ5U3Vic2NyaWJlPWZ1bmN0aW9uKHQpe3RyeXtyZXR1cm4gdGhpcy5fc3Vic2NyaWJlKHQpfWNhdGNoKHIpe3QuZXJyb3Iocil9fSxlLnByb3RvdHlwZS5mb3JFYWNoPWZ1bmN0aW9uKHQscil7dmFyIG89dGhpcztyZXR1cm4gcj1DbyhyKSxuZXcgcihmdW5jdGlvbihuLGkpe3ZhciBzPW5ldyBidCh7bmV4dDpmdW5jdGlvbihhKXt0cnl7dChhKX1jYXRjaChjKXtpKGMpLHMudW5zdWJzY3JpYmUoKX19LGVycm9yOmksY29tcGxldGU6bn0pO28uc3Vic2NyaWJlKHMpfSl9LGUucHJvdG90eXBlLl9zdWJzY3JpYmU9ZnVuY3Rpb24odCl7dmFyIHI7cmV0dXJuKHI9dGhpcy5zb3VyY2UpPT09bnVsbHx8cj09PXZvaWQgMD92b2lkIDA6ci5zdWJzY3JpYmUodCl9LGUucHJvdG90eXBlW3d0XT1mdW5jdGlvbigpe3JldHVybiB0aGlzfSxlLnByb3RvdHlwZS5waXBlPWZ1bmN0aW9uKCl7Zm9yKHZhciB0PVtdLHI9MDtyPGFyZ3VtZW50cy5sZW5ndGg7cisrKXRbcl09YXJndW1lbnRzW3JdO3JldHVybiBGcih0KSh0aGlzKX0sZS5wcm90b3R5cGUudG9Qcm9taXNlPWZ1bmN0aW9uKHQpe3ZhciByPXRoaXM7cmV0dXJuIHQ9Q28odCksbmV3IHQoZnVuY3Rpb24obyxuKXt2YXIgaTtyLnN1YnNjcmliZShmdW5jdGlvbihzKXtyZXR1cm4gaT1zfSxmdW5jdGlvbihzKXtyZXR1cm4gbihzKX0sZnVuY3Rpb24oKXtyZXR1cm4gbyhpKX0pfSl9LGUuY3JlYXRlPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgZSh0KX0sZX0pKCk7ZnVuY3Rpb24gQ28oZSl7dmFyIHQ7cmV0dXJuKHQ9ZSE9bnVsbD9lOkRlLlByb21pc2UpIT09bnVsbCYmdCE9PXZvaWQgMD90OlByb21pc2V9ZnVuY3Rpb24gY2EoZSl7cmV0dXJuIGUmJkkoZS5uZXh0KSYmSShlLmVycm9yKSYmSShlLmNvbXBsZXRlKX1mdW5jdGlvbiBwYShlKXtyZXR1cm4gZSYmZSBpbnN0YW5jZW9mIFB0fHxjYShlKSYmWHQoZSl9ZnVuY3Rpb24gbGEoZSl7cmV0dXJuIEkoZT09bnVsbD92b2lkIDA6ZS5saWZ0KX1mdW5jdGlvbiBFKGUpe3JldHVybiBmdW5jdGlvbih0KXtpZihsYSh0KSlyZXR1cm4gdC5saWZ0KGZ1bmN0aW9uKHIpe3RyeXtyZXR1cm4gZShyLHRoaXMpfWNhdGNoKG8pe3RoaXMuZXJyb3Iobyl9fSk7dGhyb3cgbmV3IFR5cGVFcnJvcigiVW5hYmxlIHRvIGxpZnQgdW5rbm93biBPYnNlcnZhYmxlIHR5cGUiKX19ZnVuY3Rpb24gdyhlLHQscixvLG4pe3JldHVybiBuZXcgbWEoZSx0LHIsbyxuKX12YXIgbWE9KGZ1bmN0aW9uKGUpe2llKHQsZSk7ZnVuY3Rpb24gdChyLG8sbixpLHMsYSl7dmFyIGM9ZS5jYWxsKHRoaXMscil8fHRoaXM7cmV0dXJuIGMub25GaW5hbGl6ZT1zLGMuc2hvdWxkVW5zdWJzY3JpYmU9YSxjLl9uZXh0PW8/ZnVuY3Rpb24ocCl7dHJ5e28ocCl9Y2F0Y2gobCl7ci5lcnJvcihsKX19OmUucHJvdG90eXBlLl9uZXh0LGMuX2Vycm9yPWk/ZnVuY3Rpb24ocCl7dHJ5e2kocCl9Y2F0Y2gobCl7ci5lcnJvcihsKX1maW5hbGx5e3RoaXMudW5zdWJzY3JpYmUoKX19OmUucHJvdG90eXBlLl9lcnJvcixjLl9jb21wbGV0ZT1uP2Z1bmN0aW9uKCl7dHJ5e24oKX1jYXRjaChwKXtyLmVycm9yKHApfWZpbmFsbHl7dGhpcy51bnN1YnNjcmliZSgpfX06ZS5wcm90b3R5cGUuX2NvbXBsZXRlLGN9cmV0dXJuIHQucHJvdG90eXBlLnVuc3Vic2NyaWJlPWZ1bmN0aW9uKCl7dmFyIHI7aWYoIXRoaXMuc2hvdWxkVW5zdWJzY3JpYmV8fHRoaXMuc2hvdWxkVW5zdWJzY3JpYmUoKSl7dmFyIG89dGhpcy5jbG9zZWQ7ZS5wcm90b3R5cGUudW5zdWJzY3JpYmUuY2FsbCh0aGlzKSwhbyYmKChyPXRoaXMub25GaW5hbGl6ZSk9PT1udWxsfHxyPT09dm9pZCAwfHxyLmNhbGwodGhpcykpfX0sdH0pKFB0KTt2YXIgVHQ9e3NjaGVkdWxlOmZ1bmN0aW9uKGUpe3ZhciB0PXJlcXVlc3RBbmltYXRpb25GcmFtZSxyPWNhbmNlbEFuaW1hdGlvbkZyYW1lLG89VHQuZGVsZWdhdGU7byYmKHQ9by5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUscj1vLmNhbmNlbEFuaW1hdGlvbkZyYW1lKTt2YXIgbj10KGZ1bmN0aW9uKGkpe3I9dm9pZCAwLGUoaSl9KTtyZXR1cm4gbmV3IHFlKGZ1bmN0aW9uKCl7cmV0dXJuIHI9PW51bGw/dm9pZCAwOnIobil9KX0scmVxdWVzdEFuaW1hdGlvbkZyYW1lOmZ1bmN0aW9uKCl7Zm9yKHZhciBlPVtdLHQ9MDt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKWVbdF09YXJndW1lbnRzW3RdO3ZhciByPVR0LmRlbGVnYXRlO3JldHVybigocj09bnVsbD92b2lkIDA6ci5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUpfHxyZXF1ZXN0QW5pbWF0aW9uRnJhbWUpLmFwcGx5KHZvaWQgMCxCKFtdLEsoZSkpKX0sY2FuY2VsQW5pbWF0aW9uRnJhbWU6ZnVuY3Rpb24oKXtmb3IodmFyIGU9W10sdD0wO3Q8YXJndW1lbnRzLmxlbmd0aDt0KyspZVt0XT1hcmd1bWVudHNbdF07dmFyIHI9VHQuZGVsZWdhdGU7cmV0dXJuKChyPT1udWxsP3ZvaWQgMDpyLmNhbmNlbEFuaW1hdGlvbkZyYW1lKXx8Y2FuY2VsQW5pbWF0aW9uRnJhbWUpLmFwcGx5KHZvaWQgMCxCKFtdLEsoZSkpKX0sZGVsZWdhdGU6dm9pZCAwfTt2YXIga289eXQoZnVuY3Rpb24oZSl7cmV0dXJuIGZ1bmN0aW9uKCl7ZSh0aGlzKSx0aGlzLm5hbWU9Ik9iamVjdFVuc3Vic2NyaWJlZEVycm9yIix0aGlzLm1lc3NhZ2U9Im9iamVjdCB1bnN1YnNjcmliZWQifX0pO3ZhciBUPShmdW5jdGlvbihlKXtpZSh0LGUpO2Z1bmN0aW9uIHQoKXt2YXIgcj1lLmNhbGwodGhpcyl8fHRoaXM7cmV0dXJuIHIuY2xvc2VkPSExLHIuY3VycmVudE9ic2VydmVycz1udWxsLHIub2JzZXJ2ZXJzPVtdLHIuaXNTdG9wcGVkPSExLHIuaGFzRXJyb3I9ITEsci50aHJvd25FcnJvcj1udWxsLHJ9cmV0dXJuIHQucHJvdG90eXBlLmxpZnQ9ZnVuY3Rpb24ocil7dmFyIG89bmV3IEhvKHRoaXMsdGhpcyk7cmV0dXJuIG8ub3BlcmF0b3I9cixvfSx0LnByb3RvdHlwZS5fdGhyb3dJZkNsb3NlZD1mdW5jdGlvbigpe2lmKHRoaXMuY2xvc2VkKXRocm93IG5ldyBrb30sdC5wcm90b3R5cGUubmV4dD1mdW5jdGlvbihyKXt2YXIgbz10aGlzO0V0KGZ1bmN0aW9uKCl7dmFyIG4saTtpZihvLl90aHJvd0lmQ2xvc2VkKCksIW8uaXNTdG9wcGVkKXtvLmN1cnJlbnRPYnNlcnZlcnN8fChvLmN1cnJlbnRPYnNlcnZlcnM9QXJyYXkuZnJvbShvLm9ic2VydmVycykpO3RyeXtmb3IodmFyIHM9T2Uoby5jdXJyZW50T2JzZXJ2ZXJzKSxhPXMubmV4dCgpOyFhLmRvbmU7YT1zLm5leHQoKSl7dmFyIGM9YS52YWx1ZTtjLm5leHQocil9fWNhdGNoKHApe249e2Vycm9yOnB9fWZpbmFsbHl7dHJ5e2EmJiFhLmRvbmUmJihpPXMucmV0dXJuKSYmaS5jYWxsKHMpfWZpbmFsbHl7aWYobil0aHJvdyBuLmVycm9yfX19fSl9LHQucHJvdG90eXBlLmVycm9yPWZ1bmN0aW9uKHIpe3ZhciBvPXRoaXM7RXQoZnVuY3Rpb24oKXtpZihvLl90aHJvd0lmQ2xvc2VkKCksIW8uaXNTdG9wcGVkKXtvLmhhc0Vycm9yPW8uaXNTdG9wcGVkPSEwLG8udGhyb3duRXJyb3I9cjtmb3IodmFyIG49by5vYnNlcnZlcnM7bi5sZW5ndGg7KW4uc2hpZnQoKS5lcnJvcihyKX19KX0sdC5wcm90b3R5cGUuY29tcGxldGU9ZnVuY3Rpb24oKXt2YXIgcj10aGlzO0V0KGZ1bmN0aW9uKCl7aWYoci5fdGhyb3dJZkNsb3NlZCgpLCFyLmlzU3RvcHBlZCl7ci5pc1N0b3BwZWQ9ITA7Zm9yKHZhciBvPXIub2JzZXJ2ZXJzO28ubGVuZ3RoOylvLnNoaWZ0KCkuY29tcGxldGUoKX19KX0sdC5wcm90b3R5cGUudW5zdWJzY3JpYmU9ZnVuY3Rpb24oKXt0aGlzLmlzU3RvcHBlZD10aGlzLmNsb3NlZD0hMCx0aGlzLm9ic2VydmVycz10aGlzLmN1cnJlbnRPYnNlcnZlcnM9bnVsbH0sT2JqZWN0LmRlZmluZVByb3BlcnR5KHQucHJvdG90eXBlLCJvYnNlcnZlZCIse2dldDpmdW5jdGlvbigpe3ZhciByO3JldHVybigocj10aGlzLm9ic2VydmVycyk9PT1udWxsfHxyPT09dm9pZCAwP3ZvaWQgMDpyLmxlbmd0aCk+MH0sZW51bWVyYWJsZTohMSxjb25maWd1cmFibGU6ITB9KSx0LnByb3RvdHlwZS5fdHJ5U3Vic2NyaWJlPWZ1bmN0aW9uKHIpe3JldHVybiB0aGlzLl90aHJvd0lmQ2xvc2VkKCksZS5wcm90b3R5cGUuX3RyeVN1YnNjcmliZS5jYWxsKHRoaXMscil9LHQucHJvdG90eXBlLl9zdWJzY3JpYmU9ZnVuY3Rpb24ocil7cmV0dXJuIHRoaXMuX3Rocm93SWZDbG9zZWQoKSx0aGlzLl9jaGVja0ZpbmFsaXplZFN0YXR1c2VzKHIpLHRoaXMuX2lubmVyU3Vic2NyaWJlKHIpfSx0LnByb3RvdHlwZS5faW5uZXJTdWJzY3JpYmU9ZnVuY3Rpb24ocil7dmFyIG89dGhpcyxuPXRoaXMsaT1uLmhhc0Vycm9yLHM9bi5pc1N0b3BwZWQsYT1uLm9ic2VydmVycztyZXR1cm4gaXx8cz8kcjoodGhpcy5jdXJyZW50T2JzZXJ2ZXJzPW51bGwsYS5wdXNoKHIpLG5ldyBxZShmdW5jdGlvbigpe28uY3VycmVudE9ic2VydmVycz1udWxsLFplKGEscil9KSl9LHQucHJvdG90eXBlLl9jaGVja0ZpbmFsaXplZFN0YXR1c2VzPWZ1bmN0aW9uKHIpe3ZhciBvPXRoaXMsbj1vLmhhc0Vycm9yLGk9by50aHJvd25FcnJvcixzPW8uaXNTdG9wcGVkO24/ci5lcnJvcihpKTpzJiZyLmNvbXBsZXRlKCl9LHQucHJvdG90eXBlLmFzT2JzZXJ2YWJsZT1mdW5jdGlvbigpe3ZhciByPW5ldyBGO3JldHVybiByLnNvdXJjZT10aGlzLHJ9LHQuY3JlYXRlPWZ1bmN0aW9uKHIsbyl7cmV0dXJuIG5ldyBIbyhyLG8pfSx0fSkoRik7dmFyIEhvPShmdW5jdGlvbihlKXtpZSh0LGUpO2Z1bmN0aW9uIHQocixvKXt2YXIgbj1lLmNhbGwodGhpcyl8fHRoaXM7cmV0dXJuIG4uZGVzdGluYXRpb249cixuLnNvdXJjZT1vLG59cmV0dXJuIHQucHJvdG90eXBlLm5leHQ9ZnVuY3Rpb24ocil7dmFyIG8sbjsobj0obz10aGlzLmRlc3RpbmF0aW9uKT09PW51bGx8fG89PT12b2lkIDA/dm9pZCAwOm8ubmV4dCk9PT1udWxsfHxuPT09dm9pZCAwfHxuLmNhbGwobyxyKX0sdC5wcm90b3R5cGUuZXJyb3I9ZnVuY3Rpb24ocil7dmFyIG8sbjsobj0obz10aGlzLmRlc3RpbmF0aW9uKT09PW51bGx8fG89PT12b2lkIDA/dm9pZCAwOm8uZXJyb3IpPT09bnVsbHx8bj09PXZvaWQgMHx8bi5jYWxsKG8scil9LHQucHJvdG90eXBlLmNvbXBsZXRlPWZ1bmN0aW9uKCl7dmFyIHIsbzsobz0ocj10aGlzLmRlc3RpbmF0aW9uKT09PW51bGx8fHI9PT12b2lkIDA/dm9pZCAwOnIuY29tcGxldGUpPT09bnVsbHx8bz09PXZvaWQgMHx8by5jYWxsKHIpfSx0LnByb3RvdHlwZS5fc3Vic2NyaWJlPWZ1bmN0aW9uKHIpe3ZhciBvLG47cmV0dXJuKG49KG89dGhpcy5zb3VyY2UpPT09bnVsbHx8bz09PXZvaWQgMD92b2lkIDA6by5zdWJzY3JpYmUocikpIT09bnVsbCYmbiE9PXZvaWQgMD9uOiRyfSx0fSkoVCk7dmFyIGpyPShmdW5jdGlvbihlKXtpZSh0LGUpO2Z1bmN0aW9uIHQocil7dmFyIG89ZS5jYWxsKHRoaXMpfHx0aGlzO3JldHVybiBvLl92YWx1ZT1yLG99cmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LnByb3RvdHlwZSwidmFsdWUiLHtnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5nZXRWYWx1ZSgpfSxlbnVtZXJhYmxlOiExLGNvbmZpZ3VyYWJsZTohMH0pLHQucHJvdG90eXBlLl9zdWJzY3JpYmU9ZnVuY3Rpb24ocil7dmFyIG89ZS5wcm90b3R5cGUuX3N1YnNjcmliZS5jYWxsKHRoaXMscik7cmV0dXJuIW8uY2xvc2VkJiZyLm5leHQodGhpcy5fdmFsdWUpLG99LHQucHJvdG90eXBlLmdldFZhbHVlPWZ1bmN0aW9uKCl7dmFyIHI9dGhpcyxvPXIuaGFzRXJyb3Isbj1yLnRocm93bkVycm9yLGk9ci5fdmFsdWU7aWYobyl0aHJvdyBuO3JldHVybiB0aGlzLl90aHJvd0lmQ2xvc2VkKCksaX0sdC5wcm90b3R5cGUubmV4dD1mdW5jdGlvbihyKXtlLnByb3RvdHlwZS5uZXh0LmNhbGwodGhpcyx0aGlzLl92YWx1ZT1yKX0sdH0pKFQpO3ZhciBSdD17bm93OmZ1bmN0aW9uKCl7cmV0dXJuKFJ0LmRlbGVnYXRlfHxEYXRlKS5ub3coKX0sZGVsZWdhdGU6dm9pZCAwfTt2YXIgSXQ9KGZ1bmN0aW9uKGUpe2llKHQsZSk7ZnVuY3Rpb24gdChyLG8sbil7cj09PXZvaWQgMCYmKHI9MS8wKSxvPT09dm9pZCAwJiYobz0xLzApLG49PT12b2lkIDAmJihuPVJ0KTt2YXIgaT1lLmNhbGwodGhpcyl8fHRoaXM7cmV0dXJuIGkuX2J1ZmZlclNpemU9cixpLl93aW5kb3dUaW1lPW8saS5fdGltZXN0YW1wUHJvdmlkZXI9bixpLl9idWZmZXI9W10saS5faW5maW5pdGVUaW1lV2luZG93PSEwLGkuX2luZmluaXRlVGltZVdpbmRvdz1vPT09MS8wLGkuX2J1ZmZlclNpemU9TWF0aC5tYXgoMSxyKSxpLl93aW5kb3dUaW1lPU1hdGgubWF4KDEsbyksaX1yZXR1cm4gdC5wcm90b3R5cGUubmV4dD1mdW5jdGlvbihyKXt2YXIgbz10aGlzLG49by5pc1N0b3BwZWQsaT1vLl9idWZmZXIscz1vLl9pbmZpbml0ZVRpbWVXaW5kb3csYT1vLl90aW1lc3RhbXBQcm92aWRlcixjPW8uX3dpbmRvd1RpbWU7bnx8KGkucHVzaChyKSwhcyYmaS5wdXNoKGEubm93KCkrYykpLHRoaXMuX3RyaW1CdWZmZXIoKSxlLnByb3RvdHlwZS5uZXh0LmNhbGwodGhpcyxyKX0sdC5wcm90b3R5cGUuX3N1YnNjcmliZT1mdW5jdGlvbihyKXt0aGlzLl90aHJvd0lmQ2xvc2VkKCksdGhpcy5fdHJpbUJ1ZmZlcigpO2Zvcih2YXIgbz10aGlzLl9pbm5lclN1YnNjcmliZShyKSxuPXRoaXMsaT1uLl9pbmZpbml0ZVRpbWVXaW5kb3cscz1uLl9idWZmZXIsYT1zLnNsaWNlKCksYz0wO2M8YS5sZW5ndGgmJiFyLmNsb3NlZDtjKz1pPzE6MilyLm5leHQoYVtjXSk7cmV0dXJuIHRoaXMuX2NoZWNrRmluYWxpemVkU3RhdHVzZXMociksb30sdC5wcm90b3R5cGUuX3RyaW1CdWZmZXI9ZnVuY3Rpb24oKXt2YXIgcj10aGlzLG89ci5fYnVmZmVyU2l6ZSxuPXIuX3RpbWVzdGFtcFByb3ZpZGVyLGk9ci5fYnVmZmVyLHM9ci5faW5maW5pdGVUaW1lV2luZG93LGE9KHM/MToyKSpvO2lmKG88MS8wJiZhPGkubGVuZ3RoJiZpLnNwbGljZSgwLGkubGVuZ3RoLWEpLCFzKXtmb3IodmFyIGM9bi5ub3coKSxwPTAsbD0xO2w8aS5sZW5ndGgmJmlbbF08PWM7bCs9MilwPWw7cCYmaS5zcGxpY2UoMCxwKzEpfX0sdH0pKFQpO3ZhciAkbz0oZnVuY3Rpb24oZSl7aWUodCxlKTtmdW5jdGlvbiB0KHIsbyl7cmV0dXJuIGUuY2FsbCh0aGlzKXx8dGhpc31yZXR1cm4gdC5wcm90b3R5cGUuc2NoZWR1bGU9ZnVuY3Rpb24ocixvKXtyZXR1cm4gbz09PXZvaWQgMCYmKG89MCksdGhpc30sdH0pKHFlKTt2YXIgRnQ9e3NldEludGVydmFsOmZ1bmN0aW9uKGUsdCl7Zm9yKHZhciByPVtdLG89MjtvPGFyZ3VtZW50cy5sZW5ndGg7bysrKXJbby0yXT1hcmd1bWVudHNbb107dmFyIG49RnQuZGVsZWdhdGU7cmV0dXJuIG4hPW51bGwmJm4uc2V0SW50ZXJ2YWw/bi5zZXRJbnRlcnZhbC5hcHBseShuLEIoW2UsdF0sSyhyKSkpOnNldEludGVydmFsLmFwcGx5KHZvaWQgMCxCKFtlLHRdLEsocikpKX0sY2xlYXJJbnRlcnZhbDpmdW5jdGlvbihlKXt2YXIgdD1GdC5kZWxlZ2F0ZTtyZXR1cm4oKHQ9PW51bGw/dm9pZCAwOnQuY2xlYXJJbnRlcnZhbCl8fGNsZWFySW50ZXJ2YWwpKGUpfSxkZWxlZ2F0ZTp2b2lkIDB9O3ZhciBTdD0oZnVuY3Rpb24oZSl7aWUodCxlKTtmdW5jdGlvbiB0KHIsbyl7dmFyIG49ZS5jYWxsKHRoaXMscixvKXx8dGhpcztyZXR1cm4gbi5zY2hlZHVsZXI9cixuLndvcms9byxuLnBlbmRpbmc9ITEsbn1yZXR1cm4gdC5wcm90b3R5cGUuc2NoZWR1bGU9ZnVuY3Rpb24ocixvKXt2YXIgbjtpZihvPT09dm9pZCAwJiYobz0wKSx0aGlzLmNsb3NlZClyZXR1cm4gdGhpczt0aGlzLnN0YXRlPXI7dmFyIGk9dGhpcy5pZCxzPXRoaXMuc2NoZWR1bGVyO3JldHVybiBpIT1udWxsJiYodGhpcy5pZD10aGlzLnJlY3ljbGVBc3luY0lkKHMsaSxvKSksdGhpcy5wZW5kaW5nPSEwLHRoaXMuZGVsYXk9byx0aGlzLmlkPShuPXRoaXMuaWQpIT09bnVsbCYmbiE9PXZvaWQgMD9uOnRoaXMucmVxdWVzdEFzeW5jSWQocyx0aGlzLmlkLG8pLHRoaXN9LHQucHJvdG90eXBlLnJlcXVlc3RBc3luY0lkPWZ1bmN0aW9uKHIsbyxuKXtyZXR1cm4gbj09PXZvaWQgMCYmKG49MCksRnQuc2V0SW50ZXJ2YWwoci5mbHVzaC5iaW5kKHIsdGhpcyksbil9LHQucHJvdG90eXBlLnJlY3ljbGVBc3luY0lkPWZ1bmN0aW9uKHIsbyxuKXtpZihuPT09dm9pZCAwJiYobj0wKSxuIT1udWxsJiZ0aGlzLmRlbGF5PT09biYmdGhpcy5wZW5kaW5nPT09ITEpcmV0dXJuIG87byE9bnVsbCYmRnQuY2xlYXJJbnRlcnZhbChvKX0sdC5wcm90b3R5cGUuZXhlY3V0ZT1mdW5jdGlvbihyLG8pe2lmKHRoaXMuY2xvc2VkKXJldHVybiBuZXcgRXJyb3IoImV4ZWN1dGluZyBhIGNhbmNlbGxlZCBhY3Rpb24iKTt0aGlzLnBlbmRpbmc9ITE7dmFyIG49dGhpcy5fZXhlY3V0ZShyLG8pO2lmKG4pcmV0dXJuIG47dGhpcy5wZW5kaW5nPT09ITEmJnRoaXMuaWQhPW51bGwmJih0aGlzLmlkPXRoaXMucmVjeWNsZUFzeW5jSWQodGhpcy5zY2hlZHVsZXIsdGhpcy5pZCxudWxsKSl9LHQucHJvdG90eXBlLl9leGVjdXRlPWZ1bmN0aW9uKHIsbyl7dmFyIG49ITEsaTt0cnl7dGhpcy53b3JrKHIpfWNhdGNoKHMpe249ITAsaT1zfHxuZXcgRXJyb3IoIlNjaGVkdWxlZCBhY3Rpb24gdGhyZXcgZmFsc3kgZXJyb3IiKX1pZihuKXJldHVybiB0aGlzLnVuc3Vic2NyaWJlKCksaX0sdC5wcm90b3R5cGUudW5zdWJzY3JpYmU9ZnVuY3Rpb24oKXtpZighdGhpcy5jbG9zZWQpe3ZhciByPXRoaXMsbz1yLmlkLG49ci5zY2hlZHVsZXIsaT1uLmFjdGlvbnM7dGhpcy53b3JrPXRoaXMuc3RhdGU9dGhpcy5zY2hlZHVsZXI9bnVsbCx0aGlzLnBlbmRpbmc9ITEsWmUoaSx0aGlzKSxvIT1udWxsJiYodGhpcy5pZD10aGlzLnJlY3ljbGVBc3luY0lkKG4sbyxudWxsKSksdGhpcy5kZWxheT1udWxsLGUucHJvdG90eXBlLnVuc3Vic2NyaWJlLmNhbGwodGhpcyl9fSx0fSkoJG8pO3ZhciBVcj0oZnVuY3Rpb24oKXtmdW5jdGlvbiBlKHQscil7cj09PXZvaWQgMCYmKHI9ZS5ub3cpLHRoaXMuc2NoZWR1bGVyQWN0aW9uQ3Rvcj10LHRoaXMubm93PXJ9cmV0dXJuIGUucHJvdG90eXBlLnNjaGVkdWxlPWZ1bmN0aW9uKHQscixvKXtyZXR1cm4gcj09PXZvaWQgMCYmKHI9MCksbmV3IHRoaXMuc2NoZWR1bGVyQWN0aW9uQ3Rvcih0aGlzLHQpLnNjaGVkdWxlKG8scil9LGUubm93PVJ0Lm5vdyxlfSkoKTt2YXIgT3Q9KGZ1bmN0aW9uKGUpe2llKHQsZSk7ZnVuY3Rpb24gdChyLG8pe289PT12b2lkIDAmJihvPVVyLm5vdyk7dmFyIG49ZS5jYWxsKHRoaXMscixvKXx8dGhpcztyZXR1cm4gbi5hY3Rpb25zPVtdLG4uX2FjdGl2ZT0hMSxufXJldHVybiB0LnByb3RvdHlwZS5mbHVzaD1mdW5jdGlvbihyKXt2YXIgbz10aGlzLmFjdGlvbnM7aWYodGhpcy5fYWN0aXZlKXtvLnB1c2gocik7cmV0dXJufXZhciBuO3RoaXMuX2FjdGl2ZT0hMDtkbyBpZihuPXIuZXhlY3V0ZShyLnN0YXRlLHIuZGVsYXkpKWJyZWFrO3doaWxlKHI9by5zaGlmdCgpKTtpZih0aGlzLl9hY3RpdmU9ITEsbil7Zm9yKDtyPW8uc2hpZnQoKTspci51bnN1YnNjcmliZSgpO3Rocm93IG59fSx0fSkoVXIpO3ZhciBwZT1uZXcgT3QoU3QpLFdyPXBlO3ZhciBQbz0oZnVuY3Rpb24oZSl7aWUodCxlKTtmdW5jdGlvbiB0KHIsbyl7dmFyIG49ZS5jYWxsKHRoaXMscixvKXx8dGhpcztyZXR1cm4gbi5zY2hlZHVsZXI9cixuLndvcms9byxufXJldHVybiB0LnByb3RvdHlwZS5zY2hlZHVsZT1mdW5jdGlvbihyLG8pe3JldHVybiBvPT09dm9pZCAwJiYobz0wKSxvPjA/ZS5wcm90b3R5cGUuc2NoZWR1bGUuY2FsbCh0aGlzLHIsbyk6KHRoaXMuZGVsYXk9byx0aGlzLnN0YXRlPXIsdGhpcy5zY2hlZHVsZXIuZmx1c2godGhpcyksdGhpcyl9LHQucHJvdG90eXBlLmV4ZWN1dGU9ZnVuY3Rpb24ocixvKXtyZXR1cm4gbz4wfHx0aGlzLmNsb3NlZD9lLnByb3RvdHlwZS5leGVjdXRlLmNhbGwodGhpcyxyLG8pOnRoaXMuX2V4ZWN1dGUocixvKX0sdC5wcm90b3R5cGUucmVxdWVzdEFzeW5jSWQ9ZnVuY3Rpb24ocixvLG4pe3JldHVybiBuPT09dm9pZCAwJiYobj0wKSxuIT1udWxsJiZuPjB8fG49PW51bGwmJnRoaXMuZGVsYXk+MD9lLnByb3RvdHlwZS5yZXF1ZXN0QXN5bmNJZC5jYWxsKHRoaXMscixvLG4pOihyLmZsdXNoKHRoaXMpLDApfSx0fSkoU3QpO3ZhciBSbz0oZnVuY3Rpb24oZSl7aWUodCxlKTtmdW5jdGlvbiB0KCl7cmV0dXJuIGUhPT1udWxsJiZlLmFwcGx5KHRoaXMsYXJndW1lbnRzKXx8dGhpc31yZXR1cm4gdH0pKE90KTt2YXIgRHI9bmV3IFJvKFBvKTt2YXIgSW89KGZ1bmN0aW9uKGUpe2llKHQsZSk7ZnVuY3Rpb24gdChyLG8pe3ZhciBuPWUuY2FsbCh0aGlzLHIsbyl8fHRoaXM7cmV0dXJuIG4uc2NoZWR1bGVyPXIsbi53b3JrPW8sbn1yZXR1cm4gdC5wcm90b3R5cGUucmVxdWVzdEFzeW5jSWQ9ZnVuY3Rpb24ocixvLG4pe3JldHVybiBuPT09dm9pZCAwJiYobj0wKSxuIT09bnVsbCYmbj4wP2UucHJvdG90eXBlLnJlcXVlc3RBc3luY0lkLmNhbGwodGhpcyxyLG8sbik6KHIuYWN0aW9ucy5wdXNoKHRoaXMpLHIuX3NjaGVkdWxlZHx8KHIuX3NjaGVkdWxlZD1UdC5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnVuY3Rpb24oKXtyZXR1cm4gci5mbHVzaCh2b2lkIDApfSkpKX0sdC5wcm90b3R5cGUucmVjeWNsZUFzeW5jSWQ9ZnVuY3Rpb24ocixvLG4pe3ZhciBpO2lmKG49PT12b2lkIDAmJihuPTApLG4hPW51bGw/bj4wOnRoaXMuZGVsYXk+MClyZXR1cm4gZS5wcm90b3R5cGUucmVjeWNsZUFzeW5jSWQuY2FsbCh0aGlzLHIsbyxuKTt2YXIgcz1yLmFjdGlvbnM7byE9bnVsbCYmbz09PXIuX3NjaGVkdWxlZCYmKChpPXNbcy5sZW5ndGgtMV0pPT09bnVsbHx8aT09PXZvaWQgMD92b2lkIDA6aS5pZCkhPT1vJiYoVHQuY2FuY2VsQW5pbWF0aW9uRnJhbWUobyksci5fc2NoZWR1bGVkPXZvaWQgMCl9LHR9KShTdCk7dmFyIEZvPShmdW5jdGlvbihlKXtpZSh0LGUpO2Z1bmN0aW9uIHQoKXtyZXR1cm4gZSE9PW51bGwmJmUuYXBwbHkodGhpcyxhcmd1bWVudHMpfHx0aGlzfXJldHVybiB0LnByb3RvdHlwZS5mbHVzaD1mdW5jdGlvbihyKXt0aGlzLl9hY3RpdmU9ITA7dmFyIG87cj9vPXIuaWQ6KG89dGhpcy5fc2NoZWR1bGVkLHRoaXMuX3NjaGVkdWxlZD12b2lkIDApO3ZhciBuPXRoaXMuYWN0aW9ucyxpO3I9cnx8bi5zaGlmdCgpO2RvIGlmKGk9ci5leGVjdXRlKHIuc3RhdGUsci5kZWxheSkpYnJlYWs7d2hpbGUoKHI9blswXSkmJnIuaWQ9PT1vJiZuLnNoaWZ0KCkpO2lmKHRoaXMuX2FjdGl2ZT0hMSxpKXtmb3IoOyhyPW5bMF0pJiZyLmlkPT09byYmbi5zaGlmdCgpOylyLnVuc3Vic2NyaWJlKCk7dGhyb3cgaX19LHR9KShPdCk7dmFyIHllPW5ldyBGbyhJbyk7dmFyIHk9bmV3IEYoZnVuY3Rpb24oZSl7cmV0dXJuIGUuY29tcGxldGUoKX0pO2Z1bmN0aW9uIHRyKGUpe3JldHVybiBlJiZJKGUuc2NoZWR1bGUpfWZ1bmN0aW9uIFZyKGUpe3JldHVybiBlW2UubGVuZ3RoLTFdfWZ1bmN0aW9uIHB0KGUpe3JldHVybiBJKFZyKGUpKT9lLnBvcCgpOnZvaWQgMH1mdW5jdGlvbiBGZShlKXtyZXR1cm4gdHIoVnIoZSkpP2UucG9wKCk6dm9pZCAwfWZ1bmN0aW9uIHJyKGUsdCl7cmV0dXJuIHR5cGVvZiBWcihlKT09Im51bWJlciI/ZS5wb3AoKTp0fXZhciBMdD0oZnVuY3Rpb24oZSl7cmV0dXJuIGUmJnR5cGVvZiBlLmxlbmd0aD09Im51bWJlciImJnR5cGVvZiBlIT0iZnVuY3Rpb24ifSk7ZnVuY3Rpb24gb3IoZSl7cmV0dXJuIEkoZT09bnVsbD92b2lkIDA6ZS50aGVuKX1mdW5jdGlvbiBucihlKXtyZXR1cm4gSShlW3d0XSl9ZnVuY3Rpb24gaXIoZSl7cmV0dXJuIFN5bWJvbC5hc3luY0l0ZXJhdG9yJiZJKGU9PW51bGw/dm9pZCAwOmVbU3ltYm9sLmFzeW5jSXRlcmF0b3JdKX1mdW5jdGlvbiBhcihlKXtyZXR1cm4gbmV3IFR5cGVFcnJvcigiWW91IHByb3ZpZGVkICIrKGUhPT1udWxsJiZ0eXBlb2YgZT09Im9iamVjdCI/ImFuIGludmFsaWQgb2JqZWN0IjoiJyIrZSsiJyIpKyIgd2hlcmUgYSBzdHJlYW0gd2FzIGV4cGVjdGVkLiBZb3UgY2FuIHByb3ZpZGUgYW4gT2JzZXJ2YWJsZSwgUHJvbWlzZSwgUmVhZGFibGVTdHJlYW0sIEFycmF5LCBBc3luY0l0ZXJhYmxlLCBvciBJdGVyYWJsZS4iKX1mdW5jdGlvbiBmYSgpe3JldHVybiB0eXBlb2YgU3ltYm9sIT0iZnVuY3Rpb24ifHwhU3ltYm9sLml0ZXJhdG9yPyJAQGl0ZXJhdG9yIjpTeW1ib2wuaXRlcmF0b3J9dmFyIHNyPWZhKCk7ZnVuY3Rpb24gY3IoZSl7cmV0dXJuIEkoZT09bnVsbD92b2lkIDA6ZVtzcl0pfWZ1bmN0aW9uIHByKGUpe3JldHVybiB3byh0aGlzLGFyZ3VtZW50cyxmdW5jdGlvbigpe3ZhciByLG8sbixpO3JldHVybiBHdCh0aGlzLGZ1bmN0aW9uKHMpe3N3aXRjaChzLmxhYmVsKXtjYXNlIDA6cj1lLmdldFJlYWRlcigpLHMubGFiZWw9MTtjYXNlIDE6cy50cnlzLnB1c2goWzEsLDksMTBdKSxzLmxhYmVsPTI7Y2FzZSAyOnJldHVybls0LGR0KHIucmVhZCgpKV07Y2FzZSAzOnJldHVybiBvPXMuc2VudCgpLG49by52YWx1ZSxpPW8uZG9uZSxpP1s0LGR0KHZvaWQgMCldOlszLDVdO2Nhc2UgNDpyZXR1cm5bMixzLnNlbnQoKV07Y2FzZSA1OnJldHVybls0LGR0KG4pXTtjYXNlIDY6cmV0dXJuWzQscy5zZW50KCldO2Nhc2UgNzpyZXR1cm4gcy5zZW50KCksWzMsMl07Y2FzZSA4OnJldHVyblszLDEwXTtjYXNlIDk6cmV0dXJuIHIucmVsZWFzZUxvY2soKSxbN107Y2FzZSAxMDpyZXR1cm5bMl19fSl9KX1mdW5jdGlvbiBscihlKXtyZXR1cm4gSShlPT1udWxsP3ZvaWQgMDplLmdldFJlYWRlcil9ZnVuY3Rpb24gVShlKXtpZihlIGluc3RhbmNlb2YgRilyZXR1cm4gZTtpZihlIT1udWxsKXtpZihucihlKSlyZXR1cm4gdWEoZSk7aWYoTHQoZSkpcmV0dXJuIGRhKGUpO2lmKG9yKGUpKXJldHVybiBoYShlKTtpZihpcihlKSlyZXR1cm4gam8oZSk7aWYoY3IoZSkpcmV0dXJuIGJhKGUpO2lmKGxyKGUpKXJldHVybiB2YShlKX10aHJvdyBhcihlKX1mdW5jdGlvbiB1YShlKXtyZXR1cm4gbmV3IEYoZnVuY3Rpb24odCl7dmFyIHI9ZVt3dF0oKTtpZihJKHIuc3Vic2NyaWJlKSlyZXR1cm4gci5zdWJzY3JpYmUodCk7dGhyb3cgbmV3IFR5cGVFcnJvcigiUHJvdmlkZWQgb2JqZWN0IGRvZXMgbm90IGNvcnJlY3RseSBpbXBsZW1lbnQgU3ltYm9sLm9ic2VydmFibGUiKX0pfWZ1bmN0aW9uIGRhKGUpe3JldHVybiBuZXcgRihmdW5jdGlvbih0KXtmb3IodmFyIHI9MDtyPGUubGVuZ3RoJiYhdC5jbG9zZWQ7cisrKXQubmV4dChlW3JdKTt0LmNvbXBsZXRlKCl9KX1mdW5jdGlvbiBoYShlKXtyZXR1cm4gbmV3IEYoZnVuY3Rpb24odCl7ZS50aGVuKGZ1bmN0aW9uKHIpe3QuY2xvc2VkfHwodC5uZXh0KHIpLHQuY29tcGxldGUoKSl9LGZ1bmN0aW9uKHIpe3JldHVybiB0LmVycm9yKHIpfSkudGhlbihudWxsLFp0KX0pfWZ1bmN0aW9uIGJhKGUpe3JldHVybiBuZXcgRihmdW5jdGlvbih0KXt2YXIgcixvO3RyeXtmb3IodmFyIG49T2UoZSksaT1uLm5leHQoKTshaS5kb25lO2k9bi5uZXh0KCkpe3ZhciBzPWkudmFsdWU7aWYodC5uZXh0KHMpLHQuY2xvc2VkKXJldHVybn19Y2F0Y2goYSl7cj17ZXJyb3I6YX19ZmluYWxseXt0cnl7aSYmIWkuZG9uZSYmKG89bi5yZXR1cm4pJiZvLmNhbGwobil9ZmluYWxseXtpZihyKXRocm93IHIuZXJyb3J9fXQuY29tcGxldGUoKX0pfWZ1bmN0aW9uIGpvKGUpe3JldHVybiBuZXcgRihmdW5jdGlvbih0KXtnYShlLHQpLmNhdGNoKGZ1bmN0aW9uKHIpe3JldHVybiB0LmVycm9yKHIpfSl9KX1mdW5jdGlvbiB2YShlKXtyZXR1cm4gam8ocHIoZSkpfWZ1bmN0aW9uIGdhKGUsdCl7dmFyIHIsbyxuLGk7cmV0dXJuIEVvKHRoaXMsdm9pZCAwLHZvaWQgMCxmdW5jdGlvbigpe3ZhciBzLGE7cmV0dXJuIEd0KHRoaXMsZnVuY3Rpb24oYyl7c3dpdGNoKGMubGFiZWwpe2Nhc2UgMDpjLnRyeXMucHVzaChbMCw1LDYsMTFdKSxyPVRvKGUpLGMubGFiZWw9MTtjYXNlIDE6cmV0dXJuWzQsci5uZXh0KCldO2Nhc2UgMjppZihvPWMuc2VudCgpLCEhby5kb25lKXJldHVyblszLDRdO2lmKHM9by52YWx1ZSx0Lm5leHQocyksdC5jbG9zZWQpcmV0dXJuWzJdO2MubGFiZWw9MztjYXNlIDM6cmV0dXJuWzMsMV07Y2FzZSA0OnJldHVyblszLDExXTtjYXNlIDU6cmV0dXJuIGE9Yy5zZW50KCksbj17ZXJyb3I6YX0sWzMsMTFdO2Nhc2UgNjpyZXR1cm4gYy50cnlzLnB1c2goWzYsLDksMTBdKSxvJiYhby5kb25lJiYoaT1yLnJldHVybik/WzQsaS5jYWxsKHIpXTpbMyw4XTtjYXNlIDc6Yy5zZW50KCksYy5sYWJlbD04O2Nhc2UgODpyZXR1cm5bMywxMF07Y2FzZSA5OmlmKG4pdGhyb3cgbi5lcnJvcjtyZXR1cm5bN107Y2FzZSAxMDpyZXR1cm5bN107Y2FzZSAxMTpyZXR1cm4gdC5jb21wbGV0ZSgpLFsyXX19KX0pfWZ1bmN0aW9uIF9lKGUsdCxyLG8sbil7bz09PXZvaWQgMCYmKG89MCksbj09PXZvaWQgMCYmKG49ITEpO3ZhciBpPXQuc2NoZWR1bGUoZnVuY3Rpb24oKXtyKCksbj9lLmFkZCh0aGlzLnNjaGVkdWxlKG51bGwsbykpOnRoaXMudW5zdWJzY3JpYmUoKX0sbyk7aWYoZS5hZGQoaSksIW4pcmV0dXJuIGl9ZnVuY3Rpb24geGUoZSx0KXtyZXR1cm4gdD09PXZvaWQgMCYmKHQ9MCksRShmdW5jdGlvbihyLG8pe3Iuc3Vic2NyaWJlKHcobyxmdW5jdGlvbihuKXtyZXR1cm4gX2UobyxlLGZ1bmN0aW9uKCl7cmV0dXJuIG8ubmV4dChuKX0sdCl9LGZ1bmN0aW9uKCl7cmV0dXJuIF9lKG8sZSxmdW5jdGlvbigpe3JldHVybiBvLmNvbXBsZXRlKCl9LHQpfSxmdW5jdGlvbihuKXtyZXR1cm4gX2UobyxlLGZ1bmN0aW9uKCl7cmV0dXJuIG8uZXJyb3Iobil9LHQpfSkpfSl9ZnVuY3Rpb24gZXQoZSx0KXtyZXR1cm4gdD09PXZvaWQgMCYmKHQ9MCksRShmdW5jdGlvbihyLG8pe28uYWRkKGUuc2NoZWR1bGUoZnVuY3Rpb24oKXtyZXR1cm4gci5zdWJzY3JpYmUobyl9LHQpKX0pfWZ1bmN0aW9uIFVvKGUsdCl7cmV0dXJuIFUoZSkucGlwZShldCh0KSx4ZSh0KSl9ZnVuY3Rpb24gV28oZSx0KXtyZXR1cm4gVShlKS5waXBlKGV0KHQpLHhlKHQpKX1mdW5jdGlvbiBEbyhlLHQpe3JldHVybiBuZXcgRihmdW5jdGlvbihyKXt2YXIgbz0wO3JldHVybiB0LnNjaGVkdWxlKGZ1bmN0aW9uKCl7bz09PWUubGVuZ3RoP3IuY29tcGxldGUoKTooci5uZXh0KGVbbysrXSksci5jbG9zZWR8fHRoaXMuc2NoZWR1bGUoKSl9KX0pfWZ1bmN0aW9uIFZvKGUsdCl7cmV0dXJuIG5ldyBGKGZ1bmN0aW9uKHIpe3ZhciBvO3JldHVybiBfZShyLHQsZnVuY3Rpb24oKXtvPWVbc3JdKCksX2Uocix0LGZ1bmN0aW9uKCl7dmFyIG4saSxzO3RyeXtuPW8ubmV4dCgpLGk9bi52YWx1ZSxzPW4uZG9uZX1jYXRjaChhKXtyLmVycm9yKGEpO3JldHVybn1zP3IuY29tcGxldGUoKTpyLm5leHQoaSl9LDAsITApfSksZnVuY3Rpb24oKXtyZXR1cm4gSShvPT1udWxsP3ZvaWQgMDpvLnJldHVybikmJm8ucmV0dXJuKCl9fSl9ZnVuY3Rpb24gbXIoZSx0KXtpZighZSl0aHJvdyBuZXcgRXJyb3IoIkl0ZXJhYmxlIGNhbm5vdCBiZSBudWxsIik7cmV0dXJuIG5ldyBGKGZ1bmN0aW9uKHIpe19lKHIsdCxmdW5jdGlvbigpe3ZhciBvPWVbU3ltYm9sLmFzeW5jSXRlcmF0b3JdKCk7X2Uocix0LGZ1bmN0aW9uKCl7by5uZXh0KCkudGhlbihmdW5jdGlvbihuKXtuLmRvbmU/ci5jb21wbGV0ZSgpOnIubmV4dChuLnZhbHVlKX0pfSwwLCEwKX0pfSl9ZnVuY3Rpb24gTm8oZSx0KXtyZXR1cm4gbXIocHIoZSksdCl9ZnVuY3Rpb24gem8oZSx0KXtpZihlIT1udWxsKXtpZihucihlKSlyZXR1cm4gVW8oZSx0KTtpZihMdChlKSlyZXR1cm4gRG8oZSx0KTtpZihvcihlKSlyZXR1cm4gV28oZSx0KTtpZihpcihlKSlyZXR1cm4gbXIoZSx0KTtpZihjcihlKSlyZXR1cm4gVm8oZSx0KTtpZihscihlKSlyZXR1cm4gTm8oZSx0KX10aHJvdyBhcihlKX1mdW5jdGlvbiBmZShlLHQpe3JldHVybiB0P3pvKGUsdCk6VShlKX1mdW5jdGlvbiAkKCl7Zm9yKHZhciBlPVtdLHQ9MDt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKWVbdF09YXJndW1lbnRzW3RdO3ZhciByPUZlKGUpO3JldHVybiBmZShlLHIpfWZ1bmN0aW9uIE5yKGUsdCl7dmFyIHI9SShlKT9lOmZ1bmN0aW9uKCl7cmV0dXJuIGV9LG89ZnVuY3Rpb24obil7cmV0dXJuIG4uZXJyb3IocigpKX07cmV0dXJuIG5ldyBGKHQ/ZnVuY3Rpb24obil7cmV0dXJuIHQuc2NoZWR1bGUobywwLG4pfTpvKX12YXIgZnI9eXQoZnVuY3Rpb24oZSl7cmV0dXJuIGZ1bmN0aW9uKCl7ZSh0aGlzKSx0aGlzLm5hbWU9IkVtcHR5RXJyb3IiLHRoaXMubWVzc2FnZT0ibm8gZWxlbWVudHMgaW4gc2VxdWVuY2UifX0pO2Z1bmN0aW9uIHFvKGUpe3JldHVybiBlIGluc3RhbmNlb2YgRGF0ZSYmIWlzTmFOKGUpfWZ1bmN0aW9uIG0oZSx0KXtyZXR1cm4gRShmdW5jdGlvbihyLG8pe3ZhciBuPTA7ci5zdWJzY3JpYmUodyhvLGZ1bmN0aW9uKGkpe28ubmV4dChlLmNhbGwodCxpLG4rKykpfSkpfSl9dmFyIHlhPUFycmF5LmlzQXJyYXk7ZnVuY3Rpb24geGEoZSx0KXtyZXR1cm4geWEodCk/ZS5hcHBseSh2b2lkIDAsQihbXSxLKHQpKSk6ZSh0KX1mdW5jdGlvbiBsdChlKXtyZXR1cm4gbShmdW5jdGlvbih0KXtyZXR1cm4geGEoZSx0KX0pfXZhciBFYT1BcnJheS5pc0FycmF5LHdhPU9iamVjdC5nZXRQcm90b3R5cGVPZixUYT1PYmplY3QucHJvdG90eXBlLFNhPU9iamVjdC5rZXlzO2Z1bmN0aW9uIEtvKGUpe2lmKGUubGVuZ3RoPT09MSl7dmFyIHQ9ZVswXTtpZihFYSh0KSlyZXR1cm57YXJnczp0LGtleXM6bnVsbH07aWYoT2EodCkpe3ZhciByPVNhKHQpO3JldHVybnthcmdzOnIubWFwKGZ1bmN0aW9uKG8pe3JldHVybiB0W29dfSksa2V5czpyfX19cmV0dXJue2FyZ3M6ZSxrZXlzOm51bGx9fWZ1bmN0aW9uIE9hKGUpe3JldHVybiBlJiZ0eXBlb2YgZT09Im9iamVjdCImJndhKGUpPT09VGF9ZnVuY3Rpb24gUW8oZSx0KXtyZXR1cm4gZS5yZWR1Y2UoZnVuY3Rpb24ocixvLG4pe3JldHVybiByW29dPXRbbl0scn0se30pfWZ1bmN0aW9uIHooKXtmb3IodmFyIGU9W10sdD0wO3Q8YXJndW1lbnRzLmxlbmd0aDt0KyspZVt0XT1hcmd1bWVudHNbdF07dmFyIHI9RmUoZSksbz1wdChlKSxuPUtvKGUpLGk9bi5hcmdzLHM9bi5rZXlzO2lmKGkubGVuZ3RoPT09MClyZXR1cm4gZmUoW10scik7dmFyIGE9bmV3IEYoenIoaSxyLHM/ZnVuY3Rpb24oYyl7cmV0dXJuIFFvKHMsYyl9OmJlKSk7cmV0dXJuIG8/YS5waXBlKGx0KG8pKTphfWZ1bmN0aW9uIHpyKGUsdCxyKXtyZXR1cm4gcj09PXZvaWQgMCYmKHI9YmUpLGZ1bmN0aW9uKG8pe1lvKHQsZnVuY3Rpb24oKXtmb3IodmFyIG49ZS5sZW5ndGgsaT1uZXcgQXJyYXkobikscz1uLGE9bixjPWZ1bmN0aW9uKGwpe1lvKHQsZnVuY3Rpb24oKXt2YXIgZj1mZShlW2xdLHQpLHU9ITE7Zi5zdWJzY3JpYmUodyhvLGZ1bmN0aW9uKGQpe2lbbF09ZCx1fHwodT0hMCxhLS0pLGF8fG8ubmV4dChyKGkuc2xpY2UoKSkpfSxmdW5jdGlvbigpey0tc3x8by5jb21wbGV0ZSgpfSkpfSxvKX0scD0wO3A8bjtwKyspYyhwKX0sbyl9fWZ1bmN0aW9uIFlvKGUsdCxyKXtlP19lKHIsZSx0KTp0KCl9ZnVuY3Rpb24gQm8oZSx0LHIsbyxuLGkscyxhKXt2YXIgYz1bXSxwPTAsbD0wLGY9ITEsdT1mdW5jdGlvbigpe2YmJiFjLmxlbmd0aCYmIXAmJnQuY29tcGxldGUoKX0sZD1mdW5jdGlvbihTKXtyZXR1cm4gcDxvP3YoUyk6Yy5wdXNoKFMpfSx2PWZ1bmN0aW9uKFMpe2kmJnQubmV4dChTKSxwKys7dmFyIFg9ITE7VShyKFMsbCsrKSkuc3Vic2NyaWJlKHcodCxmdW5jdGlvbihyZSl7bj09bnVsbHx8bihyZSksaT9kKHJlKTp0Lm5leHQocmUpfSxmdW5jdGlvbigpe1g9ITB9LHZvaWQgMCxmdW5jdGlvbigpe2lmKFgpdHJ5e3AtLTtmb3IodmFyIHJlPWZ1bmN0aW9uKCl7dmFyIGVlPWMuc2hpZnQoKTtzP19lKHQscyxmdW5jdGlvbigpe3JldHVybiB2KGVlKX0pOnYoZWUpfTtjLmxlbmd0aCYmcDxvOylyZSgpO3UoKX1jYXRjaChlZSl7dC5lcnJvcihlZSl9fSkpfTtyZXR1cm4gZS5zdWJzY3JpYmUodyh0LGQsZnVuY3Rpb24oKXtmPSEwLHUoKX0pKSxmdW5jdGlvbigpe2E9PW51bGx8fGEoKX19ZnVuY3Rpb24gSihlLHQscil7cmV0dXJuIHI9PT12b2lkIDAmJihyPTEvMCksSSh0KT9KKGZ1bmN0aW9uKG8sbil7cmV0dXJuIG0oZnVuY3Rpb24oaSxzKXtyZXR1cm4gdChvLGksbixzKX0pKFUoZShvLG4pKSl9LHIpOih0eXBlb2YgdD09Im51bWJlciImJihyPXQpLEUoZnVuY3Rpb24obyxuKXtyZXR1cm4gQm8obyxuLGUscil9KSl9ZnVuY3Rpb24gTXQoZSl7cmV0dXJuIGU9PT12b2lkIDAmJihlPTEvMCksSihiZSxlKX1mdW5jdGlvbiBHbygpe3JldHVybiBNdCgxKX1mdW5jdGlvbiBLZSgpe2Zvcih2YXIgZT1bXSx0PTA7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyllW3RdPWFyZ3VtZW50c1t0XTtyZXR1cm4gR28oKShmZShlLEZlKGUpKSl9ZnVuY3Rpb24gSChlKXtyZXR1cm4gbmV3IEYoZnVuY3Rpb24odCl7VShlKCkpLnN1YnNjcmliZSh0KX0pfXZhciBMYT1bImFkZExpc3RlbmVyIiwicmVtb3ZlTGlzdGVuZXIiXSxNYT1bImFkZEV2ZW50TGlzdGVuZXIiLCJyZW1vdmVFdmVudExpc3RlbmVyIl0sX2E9WyJvbiIsIm9mZiJdO2Z1bmN0aW9uIGgoZSx0LHIsbyl7aWYoSShyKSYmKG89cixyPXZvaWQgMCksbylyZXR1cm4gaChlLHQscikucGlwZShsdChvKSk7dmFyIG49SyhrYShlKT9NYS5tYXAoZnVuY3Rpb24oYSl7cmV0dXJuIGZ1bmN0aW9uKGMpe3JldHVybiBlW2FdKHQsYyxyKX19KTpBYShlKT9MYS5tYXAoSm8oZSx0KSk6Q2EoZSk/X2EubWFwKEpvKGUsdCkpOltdLDIpLGk9blswXSxzPW5bMV07aWYoIWkmJkx0KGUpKXJldHVybiBKKGZ1bmN0aW9uKGEpe3JldHVybiBoKGEsdCxyKX0pKFUoZSkpO2lmKCFpKXRocm93IG5ldyBUeXBlRXJyb3IoIkludmFsaWQgZXZlbnQgdGFyZ2V0Iik7cmV0dXJuIG5ldyBGKGZ1bmN0aW9uKGEpe3ZhciBjPWZ1bmN0aW9uKCl7Zm9yKHZhciBwPVtdLGw9MDtsPGFyZ3VtZW50cy5sZW5ndGg7bCsrKXBbbF09YXJndW1lbnRzW2xdO3JldHVybiBhLm5leHQoMTxwLmxlbmd0aD9wOnBbMF0pfTtyZXR1cm4gaShjKSxmdW5jdGlvbigpe3JldHVybiBzKGMpfX0pfWZ1bmN0aW9uIEpvKGUsdCl7cmV0dXJuIGZ1bmN0aW9uKHIpe3JldHVybiBmdW5jdGlvbihvKXtyZXR1cm4gZVtyXSh0LG8pfX19ZnVuY3Rpb24gQWEoZSl7cmV0dXJuIEkoZS5hZGRMaXN0ZW5lcikmJkkoZS5yZW1vdmVMaXN0ZW5lcil9ZnVuY3Rpb24gQ2EoZSl7cmV0dXJuIEkoZS5vbikmJkkoZS5vZmYpfWZ1bmN0aW9uIGthKGUpe3JldHVybiBJKGUuYWRkRXZlbnRMaXN0ZW5lcikmJkkoZS5yZW1vdmVFdmVudExpc3RlbmVyKX1mdW5jdGlvbiB1cihlLHQscil7cmV0dXJuIHI/dXIoZSx0KS5waXBlKGx0KHIpKTpuZXcgRihmdW5jdGlvbihvKXt2YXIgbj1mdW5jdGlvbigpe2Zvcih2YXIgcz1bXSxhPTA7YTxhcmd1bWVudHMubGVuZ3RoO2ErKylzW2FdPWFyZ3VtZW50c1thXTtyZXR1cm4gby5uZXh0KHMubGVuZ3RoPT09MT9zWzBdOnMpfSxpPWUobik7cmV0dXJuIEkodCk/ZnVuY3Rpb24oKXtyZXR1cm4gdChuLGkpfTp2b2lkIDB9KX1mdW5jdGlvbiBIZShlLHQscil7ZT09PXZvaWQgMCYmKGU9MCkscj09PXZvaWQgMCYmKHI9V3IpO3ZhciBvPS0xO3JldHVybiB0IT1udWxsJiYodHIodCk/cj10Om89dCksbmV3IEYoZnVuY3Rpb24obil7dmFyIGk9cW8oZSk/K2Utci5ub3coKTplO2k8MCYmKGk9MCk7dmFyIHM9MDtyZXR1cm4gci5zY2hlZHVsZShmdW5jdGlvbigpe24uY2xvc2VkfHwobi5uZXh0KHMrKyksMDw9bz90aGlzLnNjaGVkdWxlKHZvaWQgMCxvKTpuLmNvbXBsZXRlKCkpfSxpKX0pfWZ1bmN0aW9uIEwoKXtmb3IodmFyIGU9W10sdD0wO3Q8YXJndW1lbnRzLmxlbmd0aDt0KyspZVt0XT1hcmd1bWVudHNbdF07dmFyIHI9RmUoZSksbz1ycihlLDEvMCksbj1lO3JldHVybiBuLmxlbmd0aD9uLmxlbmd0aD09PTE/VShuWzBdKTpNdChvKShmZShuLHIpKTp5fXZhciB0dD1uZXcgRihnZSk7dmFyIEhhPUFycmF5LmlzQXJyYXk7ZnVuY3Rpb24gZHIoZSl7cmV0dXJuIGUubGVuZ3RoPT09MSYmSGEoZVswXSk/ZVswXTplfWZ1bmN0aW9uIGcoZSx0KXtyZXR1cm4gRShmdW5jdGlvbihyLG8pe3ZhciBuPTA7ci5zdWJzY3JpYmUodyhvLGZ1bmN0aW9uKGkpe3JldHVybiBlLmNhbGwodCxpLG4rKykmJm8ubmV4dChpKX0pKX0pfWZ1bmN0aW9uIHJ0KCl7Zm9yKHZhciBlPVtdLHQ9MDt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKWVbdF09YXJndW1lbnRzW3RdO3ZhciByPXB0KGUpLG89ZHIoZSk7cmV0dXJuIG8ubGVuZ3RoP25ldyBGKGZ1bmN0aW9uKG4pe3ZhciBpPW8ubWFwKGZ1bmN0aW9uKCl7cmV0dXJuW119KSxzPW8ubWFwKGZ1bmN0aW9uKCl7cmV0dXJuITF9KTtuLmFkZChmdW5jdGlvbigpe2k9cz1udWxsfSk7Zm9yKHZhciBhPWZ1bmN0aW9uKHApe1Uob1twXSkuc3Vic2NyaWJlKHcobixmdW5jdGlvbihsKXtpZihpW3BdLnB1c2gobCksaS5ldmVyeShmdW5jdGlvbih1KXtyZXR1cm4gdS5sZW5ndGh9KSl7dmFyIGY9aS5tYXAoZnVuY3Rpb24odSl7cmV0dXJuIHUuc2hpZnQoKX0pO24ubmV4dChyP3IuYXBwbHkodm9pZCAwLEIoW10sSyhmKSkpOmYpLGkuc29tZShmdW5jdGlvbih1LGQpe3JldHVybiF1Lmxlbmd0aCYmc1tkXX0pJiZuLmNvbXBsZXRlKCl9fSxmdW5jdGlvbigpe3NbcF09ITAsIWlbcF0ubGVuZ3RoJiZuLmNvbXBsZXRlKCl9KSl9LGM9MDshbi5jbG9zZWQmJmM8by5sZW5ndGg7YysrKWEoYyk7cmV0dXJuIGZ1bmN0aW9uKCl7aT1zPW51bGx9fSk6eX1mdW5jdGlvbiBYbyhlKXtyZXR1cm4gRShmdW5jdGlvbih0LHIpe3ZhciBvPSExLG49bnVsbCxpPW51bGwscz0hMSxhPWZ1bmN0aW9uKCl7aWYoaT09bnVsbHx8aS51bnN1YnNjcmliZSgpLGk9bnVsbCxvKXtvPSExO3ZhciBwPW47bj1udWxsLHIubmV4dChwKX1zJiZyLmNvbXBsZXRlKCl9LGM9ZnVuY3Rpb24oKXtpPW51bGwscyYmci5jb21wbGV0ZSgpfTt0LnN1YnNjcmliZSh3KHIsZnVuY3Rpb24ocCl7bz0hMCxuPXAsaXx8VShlKHApKS5zdWJzY3JpYmUoaT13KHIsYSxjKSl9LGZ1bmN0aW9uKCl7cz0hMCwoIW98fCFpfHxpLmNsb3NlZCkmJnIuY29tcGxldGUoKX0pKX0pfWZ1bmN0aW9uICRlKGUsdCl7cmV0dXJuIHQ9PT12b2lkIDAmJih0PXBlKSxYbyhmdW5jdGlvbigpe3JldHVybiBIZShlLHQpfSl9ZnVuY3Rpb24gb3QoZSx0KXtyZXR1cm4gdD09PXZvaWQgMCYmKHQ9bnVsbCksdD10IT1udWxsP3Q6ZSxFKGZ1bmN0aW9uKHIsbyl7dmFyIG49W10saT0wO3Iuc3Vic2NyaWJlKHcobyxmdW5jdGlvbihzKXt2YXIgYSxjLHAsbCxmPW51bGw7aSsrJXQ9PT0wJiZuLnB1c2goW10pO3RyeXtmb3IodmFyIHU9T2UobiksZD11Lm5leHQoKTshZC5kb25lO2Q9dS5uZXh0KCkpe3ZhciB2PWQudmFsdWU7di5wdXNoKHMpLGU8PXYubGVuZ3RoJiYoZj1mIT1udWxsP2Y6W10sZi5wdXNoKHYpKX19Y2F0Y2gocmUpe2E9e2Vycm9yOnJlfX1maW5hbGx5e3RyeXtkJiYhZC5kb25lJiYoYz11LnJldHVybikmJmMuY2FsbCh1KX1maW5hbGx5e2lmKGEpdGhyb3cgYS5lcnJvcn19aWYoZil0cnl7Zm9yKHZhciBTPU9lKGYpLFg9Uy5uZXh0KCk7IVguZG9uZTtYPVMubmV4dCgpKXt2YXIgdj1YLnZhbHVlO1plKG4sdiksby5uZXh0KHYpfX1jYXRjaChyZSl7cD17ZXJyb3I6cmV9fWZpbmFsbHl7dHJ5e1gmJiFYLmRvbmUmJihsPVMucmV0dXJuKSYmbC5jYWxsKFMpfWZpbmFsbHl7aWYocCl0aHJvdyBwLmVycm9yfX19LGZ1bmN0aW9uKCl7dmFyIHMsYTt0cnl7Zm9yKHZhciBjPU9lKG4pLHA9Yy5uZXh0KCk7IXAuZG9uZTtwPWMubmV4dCgpKXt2YXIgbD1wLnZhbHVlO28ubmV4dChsKX19Y2F0Y2goZil7cz17ZXJyb3I6Zn19ZmluYWxseXt0cnl7cCYmIXAuZG9uZSYmKGE9Yy5yZXR1cm4pJiZhLmNhbGwoYyl9ZmluYWxseXtpZihzKXRocm93IHMuZXJyb3J9fW8uY29tcGxldGUoKX0sdm9pZCAwLGZ1bmN0aW9uKCl7bj1udWxsfSkpfSl9ZnVuY3Rpb24gdmUoZSl7cmV0dXJuIEUoZnVuY3Rpb24odCxyKXt2YXIgbz1udWxsLG49ITEsaTtvPXQuc3Vic2NyaWJlKHcocix2b2lkIDAsdm9pZCAwLGZ1bmN0aW9uKHMpe2k9VShlKHMsdmUoZSkodCkpKSxvPyhvLnVuc3Vic2NyaWJlKCksbz1udWxsLGkuc3Vic2NyaWJlKHIpKTpuPSEwfSkpLG4mJihvLnVuc3Vic2NyaWJlKCksbz1udWxsLGkuc3Vic2NyaWJlKHIpKX0pfWZ1bmN0aW9uIFpvKGUsdCxyLG8sbil7cmV0dXJuIGZ1bmN0aW9uKGkscyl7dmFyIGE9cixjPXQscD0wO2kuc3Vic2NyaWJlKHcocyxmdW5jdGlvbihsKXt2YXIgZj1wKys7Yz1hP2UoYyxsLGYpOihhPSEwLGwpLG8mJnMubmV4dChjKX0sbiYmKGZ1bmN0aW9uKCl7YSYmcy5uZXh0KGMpLHMuY29tcGxldGUoKX0pKSl9fWZ1bmN0aW9uIHFyKCl7Zm9yKHZhciBlPVtdLHQ9MDt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKWVbdF09YXJndW1lbnRzW3RdO3ZhciByPXB0KGUpO3JldHVybiByP0FvKHFyLmFwcGx5KHZvaWQgMCxCKFtdLEsoZSkpKSxsdChyKSk6RShmdW5jdGlvbihvLG4pe3pyKEIoW29dLEsoZHIoZSkpKSkobil9KX1mdW5jdGlvbiBQZSgpe2Zvcih2YXIgZT1bXSx0PTA7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyllW3RdPWFyZ3VtZW50c1t0XTtyZXR1cm4gcXIuYXBwbHkodm9pZCAwLEIoW10sSyhlKSkpfWZ1bmN0aW9uIGp0KGUpe3JldHVybiBFKGZ1bmN0aW9uKHQscil7dmFyIG89ITEsbj1udWxsLGk9bnVsbCxzPWZ1bmN0aW9uKCl7aWYoaT09bnVsbHx8aS51bnN1YnNjcmliZSgpLGk9bnVsbCxvKXtvPSExO3ZhciBhPW47bj1udWxsLHIubmV4dChhKX19O3Quc3Vic2NyaWJlKHcocixmdW5jdGlvbihhKXtpPT1udWxsfHxpLnVuc3Vic2NyaWJlKCksbz0hMCxuPWEsaT13KHIscyxnZSksVShlKGEpKS5zdWJzY3JpYmUoaSl9LGZ1bmN0aW9uKCl7cygpLHIuY29tcGxldGUoKX0sdm9pZCAwLGZ1bmN0aW9uKCl7bj1pPW51bGx9KSl9KX1mdW5jdGlvbiBBZShlLHQpe3JldHVybiB0PT09dm9pZCAwJiYodD1wZSksRShmdW5jdGlvbihyLG8pe3ZhciBuPW51bGwsaT1udWxsLHM9bnVsbCxhPWZ1bmN0aW9uKCl7aWYobil7bi51bnN1YnNjcmliZSgpLG49bnVsbDt2YXIgcD1pO2k9bnVsbCxvLm5leHQocCl9fTtmdW5jdGlvbiBjKCl7dmFyIHA9cytlLGw9dC5ub3coKTtpZihsPHApe249dGhpcy5zY2hlZHVsZSh2b2lkIDAscC1sKSxvLmFkZChuKTtyZXR1cm59YSgpfXIuc3Vic2NyaWJlKHcobyxmdW5jdGlvbihwKXtpPXAscz10Lm5vdygpLG58fChuPXQuc2NoZWR1bGUoYyxlKSxvLmFkZChuKSl9LGZ1bmN0aW9uKCl7YSgpLG8uY29tcGxldGUoKX0sdm9pZCAwLGZ1bmN0aW9uKCl7aT1uPW51bGx9KSl9KX1mdW5jdGlvbiBRZShlKXtyZXR1cm4gRShmdW5jdGlvbih0LHIpe3ZhciBvPSExO3Quc3Vic2NyaWJlKHcocixmdW5jdGlvbihuKXtvPSEwLHIubmV4dChuKX0sZnVuY3Rpb24oKXtvfHxyLm5leHQoZSksci5jb21wbGV0ZSgpfSkpfSl9ZnVuY3Rpb24gRWUoZSl7cmV0dXJuIGU8PTA/ZnVuY3Rpb24oKXtyZXR1cm4geX06RShmdW5jdGlvbih0LHIpe3ZhciBvPTA7dC5zdWJzY3JpYmUodyhyLGZ1bmN0aW9uKG4peysrbzw9ZSYmKHIubmV4dChuKSxlPD1vJiZyLmNvbXBsZXRlKCkpfSkpfSl9ZnVuY3Rpb24gb2UoKXtyZXR1cm4gRShmdW5jdGlvbihlLHQpe2Uuc3Vic2NyaWJlKHcodCxnZSkpfSl9ZnVuY3Rpb24gZW4oZSl7cmV0dXJuIG0oZnVuY3Rpb24oKXtyZXR1cm4gZX0pfWZ1bmN0aW9uIEtyKGUsdCl7cmV0dXJuIHQ/ZnVuY3Rpb24ocil7cmV0dXJuIEtlKHQucGlwZShFZSgxKSxvZSgpKSxyLnBpcGUoS3IoZSkpKX06SihmdW5jdGlvbihyLG8pe3JldHVybiBVKGUocixvKSkucGlwZShFZSgxKSxlbihyKSl9KX1mdW5jdGlvbiBudChlLHQpe3Q9PT12b2lkIDAmJih0PXBlKTt2YXIgcj1IZShlLHQpO3JldHVybiBLcihmdW5jdGlvbigpe3JldHVybiByfSl9ZnVuY3Rpb24gUXIoZSx0KXtyZXR1cm4gRShmdW5jdGlvbihyLG8pe3ZhciBuPW5ldyBTZXQ7ci5zdWJzY3JpYmUodyhvLGZ1bmN0aW9uKGkpe3ZhciBzPWU/ZShpKTppO24uaGFzKHMpfHwobi5hZGQocyksby5uZXh0KGkpKX0pKSx0JiZVKHQpLnN1YnNjcmliZSh3KG8sZnVuY3Rpb24oKXtyZXR1cm4gbi5jbGVhcigpfSxnZSkpfSl9ZnVuY3Rpb24gWShlLHQpe3JldHVybiB0PT09dm9pZCAwJiYodD1iZSksZT1lIT1udWxsP2U6JGEsRShmdW5jdGlvbihyLG8pe3ZhciBuLGk9ITA7ci5zdWJzY3JpYmUodyhvLGZ1bmN0aW9uKHMpe3ZhciBhPXQocyk7KGl8fCFlKG4sYSkpJiYoaT0hMSxuPWEsby5uZXh0KHMpKX0pKX0pfWZ1bmN0aW9uICRhKGUsdCl7cmV0dXJuIGU9PT10fWZ1bmN0aW9uIG5lKGUsdCl7cmV0dXJuIFkoZnVuY3Rpb24ocixvKXtyZXR1cm4gdD90KHJbZV0sb1tlXSk6cltlXT09PW9bZV19KX1mdW5jdGlvbiB0bihlKXtyZXR1cm4gZT09PXZvaWQgMCYmKGU9UGEpLEUoZnVuY3Rpb24odCxyKXt2YXIgbz0hMTt0LnN1YnNjcmliZSh3KHIsZnVuY3Rpb24obil7bz0hMCxyLm5leHQobil9LGZ1bmN0aW9uKCl7cmV0dXJuIG8/ci5jb21wbGV0ZSgpOnIuZXJyb3IoZSgpKX0pKX0pfWZ1bmN0aW9uIFBhKCl7cmV0dXJuIG5ldyBmcn1mdW5jdGlvbiBhZSgpe2Zvcih2YXIgZT1bXSx0PTA7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyllW3RdPWFyZ3VtZW50c1t0XTtyZXR1cm4gZnVuY3Rpb24ocil7cmV0dXJuIEtlKHIsJC5hcHBseSh2b2lkIDAsQihbXSxLKGUpKSkpfX1mdW5jdGlvbiBocihlLHQpe3JldHVybiB0P2Z1bmN0aW9uKHIpe3JldHVybiByLnBpcGUoaHIoZnVuY3Rpb24obyxuKXtyZXR1cm4gVShlKG8sbikpLnBpcGUobShmdW5jdGlvbihpLHMpe3JldHVybiB0KG8saSxuLHMpfSkpfSkpfTpFKGZ1bmN0aW9uKHIsbyl7dmFyIG49MCxpPW51bGwscz0hMTtyLnN1YnNjcmliZSh3KG8sZnVuY3Rpb24oYSl7aXx8KGk9dyhvLHZvaWQgMCxmdW5jdGlvbigpe2k9bnVsbCxzJiZvLmNvbXBsZXRlKCl9KSxVKGUoYSxuKyspKS5zdWJzY3JpYmUoaSkpfSxmdW5jdGlvbigpe3M9ITAsIWkmJm8uY29tcGxldGUoKX0pKX0pfWZ1bmN0aW9uIEEoZSl7cmV0dXJuIEUoZnVuY3Rpb24odCxyKXt0cnl7dC5zdWJzY3JpYmUocil9ZmluYWxseXtyLmFkZChlKX19KX1mdW5jdGlvbiBSZShlLHQpe3ZhciByPWFyZ3VtZW50cy5sZW5ndGg+PTI7cmV0dXJuIGZ1bmN0aW9uKG8pe3JldHVybiBvLnBpcGUoZT9nKGZ1bmN0aW9uKG4saSl7cmV0dXJuIGUobixpLG8pfSk6YmUsRWUoMSkscj9RZSh0KTp0bihmdW5jdGlvbigpe3JldHVybiBuZXcgZnJ9KSl9fWZ1bmN0aW9uIFlyKGUpe3JldHVybiBlPD0wP2Z1bmN0aW9uKCl7cmV0dXJuIHl9OkUoZnVuY3Rpb24odCxyKXt2YXIgbz1bXTt0LnN1YnNjcmliZSh3KHIsZnVuY3Rpb24obil7by5wdXNoKG4pLGU8by5sZW5ndGgmJm8uc2hpZnQoKX0sZnVuY3Rpb24oKXt2YXIgbixpO3RyeXtmb3IodmFyIHM9T2UobyksYT1zLm5leHQoKTshYS5kb25lO2E9cy5uZXh0KCkpe3ZhciBjPWEudmFsdWU7ci5uZXh0KGMpfX1jYXRjaChwKXtuPXtlcnJvcjpwfX1maW5hbGx5e3RyeXthJiYhYS5kb25lJiYoaT1zLnJldHVybikmJmkuY2FsbChzKX1maW5hbGx5e2lmKG4pdGhyb3cgbi5lcnJvcn19ci5jb21wbGV0ZSgpfSx2b2lkIDAsZnVuY3Rpb24oKXtvPW51bGx9KSl9KX1mdW5jdGlvbiBybigpe2Zvcih2YXIgZT1bXSx0PTA7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyllW3RdPWFyZ3VtZW50c1t0XTt2YXIgcj1GZShlKSxvPXJyKGUsMS8wKTtyZXR1cm4gRShmdW5jdGlvbihuLGkpe010KG8pKGZlKEIoW25dLEsoZSkpLHIpKS5zdWJzY3JpYmUoaSl9KX1mdW5jdGlvbiBWZSgpe2Zvcih2YXIgZT1bXSx0PTA7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyllW3RdPWFyZ3VtZW50c1t0XTtyZXR1cm4gcm4uYXBwbHkodm9pZCAwLEIoW10sSyhlKSkpfWZ1bmN0aW9uIHZ0KGUpe3ZhciB0LHI9MS8wLG87cmV0dXJuIGUhPW51bGwmJih0eXBlb2YgZT09Im9iamVjdCI/KHQ9ZS5jb3VudCxyPXQ9PT12b2lkIDA/MS8wOnQsbz1lLmRlbGF5KTpyPWUpLHI8PTA/ZnVuY3Rpb24oKXtyZXR1cm4geX06RShmdW5jdGlvbihuLGkpe3ZhciBzPTAsYSxjPWZ1bmN0aW9uKCl7aWYoYT09bnVsbHx8YS51bnN1YnNjcmliZSgpLGE9bnVsbCxvIT1udWxsKXt2YXIgbD10eXBlb2Ygbz09Im51bWJlciI/SGUobyk6VShvKHMpKSxmPXcoaSxmdW5jdGlvbigpe2YudW5zdWJzY3JpYmUoKSxwKCl9KTtsLnN1YnNjcmliZShmKX1lbHNlIHAoKX0scD1mdW5jdGlvbigpe3ZhciBsPSExO2E9bi5zdWJzY3JpYmUodyhpLHZvaWQgMCxmdW5jdGlvbigpeysrczxyP2E/YygpOmw9ITA6aS5jb21wbGV0ZSgpfSkpLGwmJmMoKX07cCgpfSl9ZnVuY3Rpb24gVXQoZSx0KXtyZXR1cm4gRShabyhlLHQsYXJndW1lbnRzLmxlbmd0aD49MiwhMCkpfWZ1bmN0aW9uIGxlKGUpe2U9PT12b2lkIDAmJihlPXt9KTt2YXIgdD1lLmNvbm5lY3RvcixyPXQ9PT12b2lkIDA/ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IFR9OnQsbz1lLnJlc2V0T25FcnJvcixuPW89PT12b2lkIDA/ITA6byxpPWUucmVzZXRPbkNvbXBsZXRlLHM9aT09PXZvaWQgMD8hMDppLGE9ZS5yZXNldE9uUmVmQ291bnRaZXJvLGM9YT09PXZvaWQgMD8hMDphO3JldHVybiBmdW5jdGlvbihwKXt2YXIgbCxmLHUsZD0wLHY9ITEsUz0hMSxYPWZ1bmN0aW9uKCl7Zj09bnVsbHx8Zi51bnN1YnNjcmliZSgpLGY9dm9pZCAwfSxyZT1mdW5jdGlvbigpe1goKSxsPXU9dm9pZCAwLHY9Uz0hMX0sZWU9ZnVuY3Rpb24oKXt2YXIgaz1sO3JlKCksaz09bnVsbHx8ay51bnN1YnNjcmliZSgpfTtyZXR1cm4gRShmdW5jdGlvbihrLHV0KXtkKyssIVMmJiF2JiZYKCk7dmFyIGplPXU9dSE9bnVsbD91OnIoKTt1dC5hZGQoZnVuY3Rpb24oKXtkLS0sZD09PTAmJiFTJiYhdiYmKGY9QnIoZWUsYykpfSksamUuc3Vic2NyaWJlKHV0KSwhbCYmZD4wJiYobD1uZXcgYnQoe25leHQ6ZnVuY3Rpb24oUil7cmV0dXJuIGplLm5leHQoUil9LGVycm9yOmZ1bmN0aW9uKFIpe1M9ITAsWCgpLGY9QnIocmUsbixSKSxqZS5lcnJvcihSKX0sY29tcGxldGU6ZnVuY3Rpb24oKXt2PSEwLFgoKSxmPUJyKHJlLHMpLGplLmNvbXBsZXRlKCl9fSksVShrKS5zdWJzY3JpYmUobCkpfSkocCl9fWZ1bmN0aW9uIEJyKGUsdCl7Zm9yKHZhciByPVtdLG89MjtvPGFyZ3VtZW50cy5sZW5ndGg7bysrKXJbby0yXT1hcmd1bWVudHNbb107aWYodD09PSEwKXtlKCk7cmV0dXJufWlmKHQhPT0hMSl7dmFyIG49bmV3IGJ0KHtuZXh0OmZ1bmN0aW9uKCl7bi51bnN1YnNjcmliZSgpLGUoKX19KTtyZXR1cm4gVSh0LmFwcGx5KHZvaWQgMCxCKFtdLEsocikpKSkuc3Vic2NyaWJlKG4pfX1mdW5jdGlvbiBaKGUsdCxyKXt2YXIgbyxuLGkscyxhPSExO3JldHVybiBlJiZ0eXBlb2YgZT09Im9iamVjdCI/KG89ZS5idWZmZXJTaXplLHM9bz09PXZvaWQgMD8xLzA6byxuPWUud2luZG93VGltZSx0PW49PT12b2lkIDA/MS8wOm4saT1lLnJlZkNvdW50LGE9aT09PXZvaWQgMD8hMTppLHI9ZS5zY2hlZHVsZXIpOnM9ZSE9bnVsbD9lOjEvMCxsZSh7Y29ubmVjdG9yOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBJdChzLHQscil9LHJlc2V0T25FcnJvcjohMCxyZXNldE9uQ29tcGxldGU6ITEscmVzZXRPblJlZkNvdW50WmVybzphfSl9ZnVuY3Rpb24gSWUoZSl7cmV0dXJuIGcoZnVuY3Rpb24odCxyKXtyZXR1cm4gZTw9cn0pfWZ1bmN0aW9uIEdyKGUpe3JldHVybiBFKGZ1bmN0aW9uKHQscil7dmFyIG89ITEsbj13KHIsZnVuY3Rpb24oKXtuPT1udWxsfHxuLnVuc3Vic2NyaWJlKCksbz0hMH0sZ2UpO1UoZSkuc3Vic2NyaWJlKG4pLHQuc3Vic2NyaWJlKHcocixmdW5jdGlvbihpKXtyZXR1cm4gbyYmci5uZXh0KGkpfSkpfSl9ZnVuY3Rpb24gUSgpe2Zvcih2YXIgZT1bXSx0PTA7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyllW3RdPWFyZ3VtZW50c1t0XTt2YXIgcj1GZShlKTtyZXR1cm4gRShmdW5jdGlvbihvLG4peyhyP0tlKGUsbyxyKTpLZShlLG8pKS5zdWJzY3JpYmUobil9KX1mdW5jdGlvbiBiKGUsdCl7cmV0dXJuIEUoZnVuY3Rpb24ocixvKXt2YXIgbj1udWxsLGk9MCxzPSExLGE9ZnVuY3Rpb24oKXtyZXR1cm4gcyYmIW4mJm8uY29tcGxldGUoKX07ci5zdWJzY3JpYmUodyhvLGZ1bmN0aW9uKGMpe249PW51bGx8fG4udW5zdWJzY3JpYmUoKTt2YXIgcD0wLGw9aSsrO1UoZShjLGwpKS5zdWJzY3JpYmUobj13KG8sZnVuY3Rpb24oZil7cmV0dXJuIG8ubmV4dCh0P3QoYyxmLGwscCsrKTpmKX0sZnVuY3Rpb24oKXtuPW51bGwsYSgpfSkpfSxmdW5jdGlvbigpe3M9ITAsYSgpfSkpfSl9ZnVuY3Rpb24gVyhlKXtyZXR1cm4gRShmdW5jdGlvbih0LHIpe1UoZSkuc3Vic2NyaWJlKHcocixmdW5jdGlvbigpe3JldHVybiByLmNvbXBsZXRlKCl9LGdlKSksIXIuY2xvc2VkJiZ0LnN1YnNjcmliZShyKX0pfWZ1bmN0aW9uIEpyKGUsdCl7cmV0dXJuIHQ9PT12b2lkIDAmJih0PSExKSxFKGZ1bmN0aW9uKHIsbyl7dmFyIG49MDtyLnN1YnNjcmliZSh3KG8sZnVuY3Rpb24oaSl7dmFyIHM9ZShpLG4rKyk7KHN8fHQpJiZvLm5leHQoaSksIXMmJm8uY29tcGxldGUoKX0pKX0pfWZ1bmN0aW9uIE8oZSx0LHIpe3ZhciBvPUkoZSl8fHR8fHI/e25leHQ6ZSxlcnJvcjp0LGNvbXBsZXRlOnJ9OmU7cmV0dXJuIG8/RShmdW5jdGlvbihuLGkpe3ZhciBzOyhzPW8uc3Vic2NyaWJlKT09PW51bGx8fHM9PT12b2lkIDB8fHMuY2FsbChvKTt2YXIgYT0hMDtuLnN1YnNjcmliZSh3KGksZnVuY3Rpb24oYyl7dmFyIHA7KHA9by5uZXh0KT09PW51bGx8fHA9PT12b2lkIDB8fHAuY2FsbChvLGMpLGkubmV4dChjKX0sZnVuY3Rpb24oKXt2YXIgYzthPSExLChjPW8uY29tcGxldGUpPT09bnVsbHx8Yz09PXZvaWQgMHx8Yy5jYWxsKG8pLGkuY29tcGxldGUoKX0sZnVuY3Rpb24oYyl7dmFyIHA7YT0hMSwocD1vLmVycm9yKT09PW51bGx8fHA9PT12b2lkIDB8fHAuY2FsbChvLGMpLGkuZXJyb3IoYyl9LGZ1bmN0aW9uKCl7dmFyIGMscDthJiYoKGM9by51bnN1YnNjcmliZSk9PT1udWxsfHxjPT09dm9pZCAwfHxjLmNhbGwobykpLChwPW8uZmluYWxpemUpPT09bnVsbHx8cD09PXZvaWQgMHx8cC5jYWxsKG8pfSkpfSk6YmV9ZnVuY3Rpb24gb24oZSx0KXtyZXR1cm4gRShmdW5jdGlvbihyLG8pe3ZhciBuPXQhPW51bGw/dDp7fSxpPW4ubGVhZGluZyxzPWk9PT12b2lkIDA/ITA6aSxhPW4udHJhaWxpbmcsYz1hPT09dm9pZCAwPyExOmEscD0hMSxsPW51bGwsZj1udWxsLHU9ITEsZD1mdW5jdGlvbigpe2Y9PW51bGx8fGYudW5zdWJzY3JpYmUoKSxmPW51bGwsYyYmKFgoKSx1JiZvLmNvbXBsZXRlKCkpfSx2PWZ1bmN0aW9uKCl7Zj1udWxsLHUmJm8uY29tcGxldGUoKX0sUz1mdW5jdGlvbihyZSl7cmV0dXJuIGY9VShlKHJlKSkuc3Vic2NyaWJlKHcobyxkLHYpKX0sWD1mdW5jdGlvbigpe2lmKHApe3A9ITE7dmFyIHJlPWw7bD1udWxsLG8ubmV4dChyZSksIXUmJlMocmUpfX07ci5zdWJzY3JpYmUodyhvLGZ1bmN0aW9uKHJlKXtwPSEwLGw9cmUsIShmJiYhZi5jbG9zZWQpJiYocz9YKCk6UyhyZSkpfSxmdW5jdGlvbigpe3U9ITAsIShjJiZwJiZmJiYhZi5jbG9zZWQpJiZvLmNvbXBsZXRlKCl9KSl9KX1mdW5jdGlvbiBndChlLHQscil7dD09PXZvaWQgMCYmKHQ9cGUpO3ZhciBvPUhlKGUsdCk7cmV0dXJuIG9uKGZ1bmN0aW9uKCl7cmV0dXJuIG99LHIpfWZ1bmN0aW9uIHRlKCl7Zm9yKHZhciBlPVtdLHQ9MDt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKWVbdF09YXJndW1lbnRzW3RdO3ZhciByPXB0KGUpO3JldHVybiBFKGZ1bmN0aW9uKG8sbil7Zm9yKHZhciBpPWUubGVuZ3RoLHM9bmV3IEFycmF5KGkpLGE9ZS5tYXAoZnVuY3Rpb24oKXtyZXR1cm4hMX0pLGM9ITEscD1mdW5jdGlvbihmKXtVKGVbZl0pLnN1YnNjcmliZSh3KG4sZnVuY3Rpb24odSl7c1tmXT11LCFjJiYhYVtmXSYmKGFbZl09ITAsKGM9YS5ldmVyeShiZSkpJiYoYT1udWxsKSl9LGdlKSl9LGw9MDtsPGk7bCsrKXAobCk7by5zdWJzY3JpYmUodyhuLGZ1bmN0aW9uKGYpe2lmKGMpe3ZhciB1PUIoW2ZdLEsocykpO24ubmV4dChyP3IuYXBwbHkodm9pZCAwLEIoW10sSyh1KSkpOnUpfX0pKX0pfWZ1bmN0aW9uIG5uKCl7Zm9yKHZhciBlPVtdLHQ9MDt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKWVbdF09YXJndW1lbnRzW3RdO3JldHVybiBFKGZ1bmN0aW9uKHIsbyl7cnQuYXBwbHkodm9pZCAwLEIoW3JdLEsoZSkpKS5zdWJzY3JpYmUobyl9KX1mdW5jdGlvbiBYcigpe2Zvcih2YXIgZT1bXSx0PTA7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyllW3RdPWFyZ3VtZW50c1t0XTtyZXR1cm4gbm4uYXBwbHkodm9pZCAwLEIoW10sSyhlKSkpfWZ1bmN0aW9uIGFuKCl7bGV0IGU9bmV3IEl0KDEpO3JldHVybiBoKGRvY3VtZW50LCJET01Db250ZW50TG9hZGVkIix7b25jZTohMH0pLnN1YnNjcmliZSgoKT0+ZS5uZXh0KGRvY3VtZW50KSksZX1mdW5jdGlvbiBNKGUsdD1kb2N1bWVudCl7cmV0dXJuIEFycmF5LmZyb20odC5xdWVyeVNlbGVjdG9yQWxsKGUpKX1mdW5jdGlvbiBqKGUsdD1kb2N1bWVudCl7bGV0IHI9dWUoZSx0KTtpZih0eXBlb2Ygcj09InVuZGVmaW5lZCIpdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKGBNaXNzaW5nIGVsZW1lbnQ6IGV4cGVjdGVkICIke2V9IiB0byBiZSBwcmVzZW50YCk7cmV0dXJuIHJ9ZnVuY3Rpb24gdWUoZSx0PWRvY3VtZW50KXtyZXR1cm4gdC5xdWVyeVNlbGVjdG9yKGUpfHx2b2lkIDB9ZnVuY3Rpb24gTmUoKXt2YXIgZSx0LHIsbztyZXR1cm4obz0ocj0odD0oZT1kb2N1bWVudC5hY3RpdmVFbGVtZW50KT09bnVsbD92b2lkIDA6ZS5zaGFkb3dSb290KT09bnVsbD92b2lkIDA6dC5hY3RpdmVFbGVtZW50KSE9bnVsbD9yOmRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpIT1udWxsP286dm9pZCAwfXZhciBSYT1MKGgoZG9jdW1lbnQuYm9keSwiZm9jdXNpbiIpLGgoZG9jdW1lbnQuYm9keSwiZm9jdXNvdXQiKSkucGlwZShBZSgxKSxRKHZvaWQgMCksbSgoKT0+TmUoKXx8ZG9jdW1lbnQuYm9keSksWigxKSk7ZnVuY3Rpb24gWWUoZSl7cmV0dXJuIFJhLnBpcGUobSh0PT5lLmNvbnRhaW5zKHQpKSxZKCkpfWZ1bmN0aW9uIGl0KGUsdCl7cmV0dXJuIEgoKCk9PkwoaChlLCJtb3VzZWVudGVyIikucGlwZShtKCgpPT4hMCkpLGgoZSwibW91c2VsZWF2ZSIpLnBpcGUobSgoKT0+ITEpKSkucGlwZSh0P2p0KHI9PkhlKCshcip0KSk6YmUsUShlLm1hdGNoZXMoIjpob3ZlciIpKSkpfWZ1bmN0aW9uIHNuKGUsdCl7aWYodHlwZW9mIHQ9PSJzdHJpbmcifHx0eXBlb2YgdD09Im51bWJlciIpZS5pbm5lckhUTUwrPXQudG9TdHJpbmcoKTtlbHNlIGlmKHQgaW5zdGFuY2VvZiBOb2RlKWUuYXBwZW5kQ2hpbGQodCk7ZWxzZSBpZihBcnJheS5pc0FycmF5KHQpKWZvcihsZXQgciBvZiB0KXNuKGUscil9ZnVuY3Rpb24geChlLHQsLi4ucil7bGV0IG89ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChlKTtpZih0KWZvcihsZXQgbiBvZiBPYmplY3Qua2V5cyh0KSl0eXBlb2YgdFtuXSE9InVuZGVmaW5lZCImJih0eXBlb2YgdFtuXSE9ImJvb2xlYW4iP28uc2V0QXR0cmlidXRlKG4sdFtuXSk6by5zZXRBdHRyaWJ1dGUobiwiIikpO2ZvcihsZXQgbiBvZiByKXNuKG8sbik7cmV0dXJuIG99ZnVuY3Rpb24gYnIoZSl7aWYoZT45OTkpe2xldCB0PSsoKGUtOTUwKSUxZTM+OTkpO3JldHVybmAkeygoZSsxZS02KS8xZTMpLnRvRml4ZWQodCl9a2B9ZWxzZSByZXR1cm4gZS50b1N0cmluZygpfWZ1bmN0aW9uIF90KGUpe2xldCB0PXgoInNjcmlwdCIse3NyYzplfSk7cmV0dXJuIEgoKCk9Pihkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHQpLEwoaCh0LCJsb2FkIiksaCh0LCJlcnJvciIpLnBpcGUoYigoKT0+TnIoKCk9Pm5ldyBSZWZlcmVuY2VFcnJvcihgSW52YWxpZCBzY3JpcHQ6ICR7ZX1gKSkpKSkucGlwZShtKCgpPT57fSksQSgoKT0+ZG9jdW1lbnQuaGVhZC5yZW1vdmVDaGlsZCh0KSksRWUoMSkpKSl9dmFyIGNuPW5ldyBULElhPUgoKCk9PnR5cGVvZiBSZXNpemVPYnNlcnZlcj09InVuZGVmaW5lZCI/X3QoImh0dHBzOi8vdW5wa2cuY29tL3Jlc2l6ZS1vYnNlcnZlci1wb2x5ZmlsbCIpOiQodm9pZCAwKSkucGlwZShtKCgpPT5uZXcgUmVzaXplT2JzZXJ2ZXIoZT0+ZS5mb3JFYWNoKHQ9PmNuLm5leHQodCkpKSksYihlPT5MKHR0LCQoZSkpLnBpcGUoQSgoKT0+ZS5kaXNjb25uZWN0KCkpKSksWigxKSk7ZnVuY3Rpb24gZGUoZSl7cmV0dXJue3dpZHRoOmUub2Zmc2V0V2lkdGgsaGVpZ2h0OmUub2Zmc2V0SGVpZ2h0fX1mdW5jdGlvbiBMZShlKXtsZXQgdD1lO2Zvcig7dC5jbGllbnRXaWR0aD09PTAmJnQucGFyZW50RWxlbWVudDspdD10LnBhcmVudEVsZW1lbnQ7cmV0dXJuIElhLnBpcGUoTyhyPT5yLm9ic2VydmUodCkpLGIocj0+Y24ucGlwZShnKG89Pm8udGFyZ2V0PT09dCksQSgoKT0+ci51bm9ic2VydmUodCkpKSksbSgoKT0+ZGUoZSkpLFEoZGUoZSkpKX1mdW5jdGlvbiBBdChlKXtyZXR1cm57d2lkdGg6ZS5zY3JvbGxXaWR0aCxoZWlnaHQ6ZS5zY3JvbGxIZWlnaHR9fWZ1bmN0aW9uIHZyKGUpe2xldCB0PWUucGFyZW50RWxlbWVudDtmb3IoO3QmJihlLnNjcm9sbFdpZHRoPD10LnNjcm9sbFdpZHRoJiZlLnNjcm9sbEhlaWdodDw9dC5zY3JvbGxIZWlnaHQpOyl0PShlPXQpLnBhcmVudEVsZW1lbnQ7cmV0dXJuIHQ/ZTp2b2lkIDB9ZnVuY3Rpb24gcG4oZSl7bGV0IHQ9W10scj1lLnBhcmVudEVsZW1lbnQ7Zm9yKDtyOykoZS5jbGllbnRXaWR0aD5yLmNsaWVudFdpZHRofHxlLmNsaWVudEhlaWdodD5yLmNsaWVudEhlaWdodCkmJnQucHVzaChyKSxyPShlPXIpLnBhcmVudEVsZW1lbnQ7cmV0dXJuIHQubGVuZ3RoPT09MCYmdC5wdXNoKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCksdH1mdW5jdGlvbiBCZShlKXtyZXR1cm57eDplLm9mZnNldExlZnQseTplLm9mZnNldFRvcH19ZnVuY3Rpb24gbG4oZSl7bGV0IHQ9ZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtyZXR1cm57eDp0Lngrd2luZG93LnNjcm9sbFgseTp0Lnkrd2luZG93LnNjcm9sbFl9fWZ1bmN0aW9uIG1uKGUpe3JldHVybiBMKGgod2luZG93LCJsb2FkIiksaCh3aW5kb3csInJlc2l6ZSIpKS5waXBlKCRlKDAseWUpLG0oKCk9PkJlKGUpKSxRKEJlKGUpKSl9ZnVuY3Rpb24gZ3IoZSl7cmV0dXJue3g6ZS5zY3JvbGxMZWZ0LHk6ZS5zY3JvbGxUb3B9fWZ1bmN0aW9uIEdlKGUpe3JldHVybiBMKGgoZSwic2Nyb2xsIiksaCh3aW5kb3csInNjcm9sbCIpLGgod2luZG93LCJyZXNpemUiKSkucGlwZSgkZSgwLHllKSxtKCgpPT5ncihlKSksUShncihlKSkpfXZhciBmbj1uZXcgVCxGYT1IKCgpPT4kKG5ldyBJbnRlcnNlY3Rpb25PYnNlcnZlcihlPT57Zm9yKGxldCB0IG9mIGUpZm4ubmV4dCh0KX0se3RocmVzaG9sZDowfSkpKS5waXBlKGIoZT0+TCh0dCwkKGUpKS5waXBlKEEoKCk9PmUuZGlzY29ubmVjdCgpKSkpLFooMSkpO2Z1bmN0aW9uIG10KGUpe3JldHVybiBGYS5waXBlKE8odD0+dC5vYnNlcnZlKGUpKSxiKHQ9PmZuLnBpcGUoZygoe3RhcmdldDpyfSk9PnI9PT1lKSxBKCgpPT50LnVub2JzZXJ2ZShlKSksbSgoe2lzSW50ZXJzZWN0aW5nOnJ9KT0+cikpKSl9ZnVuY3Rpb24gdW4oZSx0PTE2KXtyZXR1cm4gR2UoZSkucGlwZShtKCh7eTpyfSk9PntsZXQgbz1kZShlKSxuPUF0KGUpO3JldHVybiByPj1uLmhlaWdodC1vLmhlaWdodC10fSksWSgpKX12YXIgeXI9e2RyYXdlcjpqKCJbZGF0YS1tZC10b2dnbGU9ZHJhd2VyXSIpLHNlYXJjaDpqKCJbZGF0YS1tZC10b2dnbGU9c2VhcmNoXSIpfTtmdW5jdGlvbiBkbihlKXtyZXR1cm4geXJbZV0uY2hlY2tlZH1mdW5jdGlvbiBhdChlLHQpe3lyW2VdLmNoZWNrZWQhPT10JiZ5cltlXS5jbGljaygpfWZ1bmN0aW9uIEplKGUpe2xldCB0PXlyW2VdO3JldHVybiBoKHQsImNoYW5nZSIpLnBpcGUobSgoKT0+dC5jaGVja2VkKSxRKHQuY2hlY2tlZCkpfWZ1bmN0aW9uIGphKGUsdCl7c3dpdGNoKGUuY29uc3RydWN0b3Ipe2Nhc2UgSFRNTElucHV0RWxlbWVudDpyZXR1cm4gZS50eXBlPT09InJhZGlvIj8vXkFycm93Ly50ZXN0KHQpOiEwO2Nhc2UgSFRNTFNlbGVjdEVsZW1lbnQ6Y2FzZSBIVE1MVGV4dEFyZWFFbGVtZW50OnJldHVybiEwO2RlZmF1bHQ6cmV0dXJuIGUuaXNDb250ZW50RWRpdGFibGV9fWZ1bmN0aW9uIFVhKCl7cmV0dXJuIEwoaCh3aW5kb3csImNvbXBvc2l0aW9uc3RhcnQiKS5waXBlKG0oKCk9PiEwKSksaCh3aW5kb3csImNvbXBvc2l0aW9uZW5kIikucGlwZShtKCgpPT4hMSkpKS5waXBlKFEoITEpKX1mdW5jdGlvbiBobigpe2xldCBlPWgod2luZG93LCJrZXlkb3duIikucGlwZShnKHQ9PiEodC5tZXRhS2V5fHx0LmN0cmxLZXkpKSxtKHQ9Pih7bW9kZTpkbigic2VhcmNoIik/InNlYXJjaCI6Imdsb2JhbCIsdHlwZTp0LmtleSxjbGFpbSgpe3QucHJldmVudERlZmF1bHQoKSx0LnN0b3BQcm9wYWdhdGlvbigpfX0pKSxnKCh7bW9kZTp0LHR5cGU6cn0pPT57aWYodD09PSJnbG9iYWwiKXtsZXQgbz1OZSgpO2lmKHR5cGVvZiBvIT0idW5kZWZpbmVkIilyZXR1cm4hamEobyxyKX1yZXR1cm4hMH0pLGxlKCkpO3JldHVybiBVYSgpLnBpcGUoYih0PT50P3k6ZSkpfWZ1bmN0aW9uIHdlKCl7cmV0dXJuIG5ldyBVUkwobG9jYXRpb24uaHJlZil9ZnVuY3Rpb24gc3QoZSx0PSExKXtpZihWKCJuYXZpZ2F0aW9uLmluc3RhbnQiKSYmIXQpe2xldCByPXgoImEiLHtocmVmOmUuaHJlZn0pO2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQociksci5jbGljaygpLHIucmVtb3ZlKCl9ZWxzZSBsb2NhdGlvbi5ocmVmPWUuaHJlZn1mdW5jdGlvbiBibigpe3JldHVybiBuZXcgVH1mdW5jdGlvbiB2bigpe3JldHVybiBsb2NhdGlvbi5oYXNoLnNsaWNlKDEpfWZ1bmN0aW9uIGduKGUpe2xldCB0PXgoImEiLHtocmVmOmV9KTt0LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIixyPT5yLnN0b3BQcm9wYWdhdGlvbigpKSx0LmNsaWNrKCl9ZnVuY3Rpb24gWnIoZSl7cmV0dXJuIEwoaCh3aW5kb3csImhhc2hjaGFuZ2UiKSxlKS5waXBlKG0odm4pLFEodm4oKSksZyh0PT50Lmxlbmd0aD4wKSxaKDEpKX1mdW5jdGlvbiB5bihlKXtyZXR1cm4gWnIoZSkucGlwZShtKHQ9PnVlKGBbaWQ9IiR7dH0iXWApKSxnKHQ9PnR5cGVvZiB0IT0idW5kZWZpbmVkIikpfWZ1bmN0aW9uIFd0KGUpe2xldCB0PW1hdGNoTWVkaWEoZSk7cmV0dXJuIHVyKHI9PnQuYWRkTGlzdGVuZXIoKCk9PnIodC5tYXRjaGVzKSkpLnBpcGUoUSh0Lm1hdGNoZXMpKX1mdW5jdGlvbiB4bigpe2xldCBlPW1hdGNoTWVkaWEoInByaW50Iik7cmV0dXJuIEwoaCh3aW5kb3csImJlZm9yZXByaW50IikucGlwZShtKCgpPT4hMCkpLGgod2luZG93LCJhZnRlcnByaW50IikucGlwZShtKCgpPT4hMSkpKS5waXBlKFEoZS5tYXRjaGVzKSl9ZnVuY3Rpb24gZW8oZSx0KXtyZXR1cm4gZS5waXBlKGIocj0+cj90KCk6eSkpfWZ1bmN0aW9uIHRvKGUsdCl7cmV0dXJuIG5ldyBGKHI9PntsZXQgbz1uZXcgWE1MSHR0cFJlcXVlc3Q7cmV0dXJuIG8ub3BlbigiR0VUIixgJHtlfWApLG8ucmVzcG9uc2VUeXBlPSJibG9iIixvLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLCgpPT57by5zdGF0dXM+PTIwMCYmby5zdGF0dXM8MzAwPyhyLm5leHQoby5yZXNwb25zZSksci5jb21wbGV0ZSgpKTpyLmVycm9yKG5ldyBFcnJvcihvLnN0YXR1c1RleHQpKX0pLG8uYWRkRXZlbnRMaXN0ZW5lcigiZXJyb3IiLCgpPT57ci5lcnJvcihuZXcgRXJyb3IoIk5ldHdvcmsgZXJyb3IiKSl9KSxvLmFkZEV2ZW50TGlzdGVuZXIoImFib3J0IiwoKT0+e3IuY29tcGxldGUoKX0pLHR5cGVvZih0PT1udWxsP3ZvaWQgMDp0LnByb2dyZXNzJCkhPSJ1bmRlZmluZWQiJiYoby5hZGRFdmVudExpc3RlbmVyKCJwcm9ncmVzcyIsbj0+e3ZhciBpO2lmKG4ubGVuZ3RoQ29tcHV0YWJsZSl0LnByb2dyZXNzJC5uZXh0KG4ubG9hZGVkL24udG90YWwqMTAwKTtlbHNle2xldCBzPShpPW8uZ2V0UmVzcG9uc2VIZWFkZXIoIkNvbnRlbnQtTGVuZ3RoIikpIT1udWxsP2k6MDt0LnByb2dyZXNzJC5uZXh0KG4ubG9hZGVkLytzKjEwMCl9fSksdC5wcm9ncmVzcyQubmV4dCg1KSksby5zZW5kKCksKCk9Pm8uYWJvcnQoKX0pfWZ1bmN0aW9uIHplKGUsdCl7cmV0dXJuIHRvKGUsdCkucGlwZShiKHI9PnIudGV4dCgpKSxtKHI9PkpTT04ucGFyc2UocikpLFooMSkpfWZ1bmN0aW9uIHhyKGUsdCl7bGV0IHI9bmV3IERPTVBhcnNlcjtyZXR1cm4gdG8oZSx0KS5waXBlKGIobz0+by50ZXh0KCkpLG0obz0+ci5wYXJzZUZyb21TdHJpbmcobywidGV4dC9odG1sIikpLFooMSkpfWZ1bmN0aW9uIEVuKGUsdCl7bGV0IHI9bmV3IERPTVBhcnNlcjtyZXR1cm4gdG8oZSx0KS5waXBlKGIobz0+by50ZXh0KCkpLG0obz0+ci5wYXJzZUZyb21TdHJpbmcobywidGV4dC94bWwiKSksWigxKSl9ZnVuY3Rpb24gd24oKXtyZXR1cm57eDpNYXRoLm1heCgwLHNjcm9sbFgpLHk6TWF0aC5tYXgoMCxzY3JvbGxZKX19ZnVuY3Rpb24gVG4oKXtyZXR1cm4gTChoKHdpbmRvdywic2Nyb2xsIix7cGFzc2l2ZTohMH0pLGgod2luZG93LCJyZXNpemUiLHtwYXNzaXZlOiEwfSkpLnBpcGUobSh3biksUSh3bigpKSl9ZnVuY3Rpb24gU24oKXtyZXR1cm57d2lkdGg6aW5uZXJXaWR0aCxoZWlnaHQ6aW5uZXJIZWlnaHR9fWZ1bmN0aW9uIE9uKCl7cmV0dXJuIGgod2luZG93LCJyZXNpemUiLHtwYXNzaXZlOiEwfSkucGlwZShtKFNuKSxRKFNuKCkpKX1mdW5jdGlvbiBMbigpe3JldHVybiB6KFtUbigpLE9uKCldKS5waXBlKG0oKFtlLHRdKT0+KHtvZmZzZXQ6ZSxzaXplOnR9KSksWigxKSl9ZnVuY3Rpb24gRXIoZSx7dmlld3BvcnQkOnQsaGVhZGVyJDpyfSl7bGV0IG89dC5waXBlKG5lKCJzaXplIikpLG49eihbbyxyXSkucGlwZShtKCgpPT5CZShlKSkpO3JldHVybiB6KFtyLHQsbl0pLnBpcGUobSgoW3toZWlnaHQ6aX0se29mZnNldDpzLHNpemU6YX0se3g6Yyx5OnB9XSk9Pih7b2Zmc2V0Ont4OnMueC1jLHk6cy55LXAraX0sc2l6ZTphfSkpKX1mdW5jdGlvbiBXYShlKXtyZXR1cm4gaChlLCJtZXNzYWdlIix0PT50LmRhdGEpfWZ1bmN0aW9uIERhKGUpe2xldCB0PW5ldyBUO3JldHVybiB0LnN1YnNjcmliZShyPT5lLnBvc3RNZXNzYWdlKHIpKSx0fWZ1bmN0aW9uIE1uKGUsdD1uZXcgV29ya2VyKGUpKXtsZXQgcj1XYSh0KSxvPURhKHQpLG49bmV3IFQ7bi5zdWJzY3JpYmUobyk7bGV0IGk9by5waXBlKG9lKCksYWUoITApKTtyZXR1cm4gbi5waXBlKG9lKCksVmUoci5waXBlKFcoaSkpKSxsZSgpKX12YXIgVmE9aigiI19fY29uZmlnIiksQ3Q9SlNPTi5wYXJzZShWYS50ZXh0Q29udGVudCk7Q3QuYmFzZT1gJHtuZXcgVVJMKEN0LmJhc2Usd2UoKSl9YDtmdW5jdGlvbiBUZSgpe3JldHVybiBDdH1mdW5jdGlvbiBWKGUpe3JldHVybiBDdC5mZWF0dXJlcy5pbmNsdWRlcyhlKX1mdW5jdGlvbiBNZShlLHQpe3JldHVybiB0eXBlb2YgdCE9InVuZGVmaW5lZCI/Q3QudHJhbnNsYXRpb25zW2VdLnJlcGxhY2UoIiMiLHQudG9TdHJpbmcoKSk6Q3QudHJhbnNsYXRpb25zW2VdfWZ1bmN0aW9uIENlKGUsdD1kb2N1bWVudCl7cmV0dXJuIGooYFtkYXRhLW1kLWNvbXBvbmVudD0ke2V9XWAsdCl9ZnVuY3Rpb24gbWUoZSx0PWRvY3VtZW50KXtyZXR1cm4gTShgW2RhdGEtbWQtY29tcG9uZW50PSR7ZX1dYCx0KX1mdW5jdGlvbiBOYShlKXtsZXQgdD1qKCIubWQtdHlwZXNldCA+IDpmaXJzdC1jaGlsZCIsZSk7cmV0dXJuIGgodCwiY2xpY2siLHtvbmNlOiEwfSkucGlwZShtKCgpPT5qKCIubWQtdHlwZXNldCIsZSkpLG0ocj0+KHtoYXNoOl9fbWRfaGFzaChyLmlubmVySFRNTCl9KSkpfWZ1bmN0aW9uIF9uKGUpe2lmKCFWKCJhbm5vdW5jZS5kaXNtaXNzIil8fCFlLmNoaWxkRWxlbWVudENvdW50KXJldHVybiB5O2lmKCFlLmhpZGRlbil7bGV0IHQ9aigiLm1kLXR5cGVzZXQiLGUpO19fbWRfaGFzaCh0LmlubmVySFRNTCk9PT1fX21kX2dldCgiX19hbm5vdW5jZSIpJiYoZS5oaWRkZW49ITApfXJldHVybiBIKCgpPT57bGV0IHQ9bmV3IFQ7cmV0dXJuIHQuc3Vic2NyaWJlKCh7aGFzaDpyfSk9PntlLmhpZGRlbj0hMCxfX21kX3NldCgiX19hbm5vdW5jZSIscil9KSxOYShlKS5waXBlKE8ocj0+dC5uZXh0KHIpKSxBKCgpPT50LmNvbXBsZXRlKCkpLG0ocj0+UCh7cmVmOmV9LHIpKSl9KX1mdW5jdGlvbiB6YShlLHt0YXJnZXQkOnR9KXtyZXR1cm4gdC5waXBlKG0ocj0+KHtoaWRkZW46ciE9PWV9KSkpfWZ1bmN0aW9uIEFuKGUsdCl7bGV0IHI9bmV3IFQ7cmV0dXJuIHIuc3Vic2NyaWJlKCh7aGlkZGVuOm99KT0+e2UuaGlkZGVuPW99KSx6YShlLHQpLnBpcGUoTyhvPT5yLm5leHQobykpLEEoKCk9PnIuY29tcGxldGUoKSksbShvPT5QKHtyZWY6ZX0sbykpKX1mdW5jdGlvbiBEdChlLHQpe3JldHVybiB0PT09ImlubGluZSI/eCgiZGl2Iix7Y2xhc3M6Im1kLXRvb2x0aXAgbWQtdG9vbHRpcC0taW5saW5lIixpZDplLHJvbGU6InRvb2x0aXAifSx4KCJkaXYiLHtjbGFzczoibWQtdG9vbHRpcF9faW5uZXIgbWQtdHlwZXNldCJ9KSk6eCgiZGl2Iix7Y2xhc3M6Im1kLXRvb2x0aXAiLGlkOmUscm9sZToidG9vbHRpcCJ9LHgoImRpdiIse2NsYXNzOiJtZC10b29sdGlwX19pbm5lciBtZC10eXBlc2V0In0pKX1mdW5jdGlvbiB3ciguLi5lKXtyZXR1cm4geCgiZGl2Iix7Y2xhc3M6Im1kLXRvb2x0aXAyIixyb2xlOiJkaWFsb2cifSx4KCJkaXYiLHtjbGFzczoibWQtdG9vbHRpcDJfX2lubmVyIG1kLXR5cGVzZXQifSxlKSl9ZnVuY3Rpb24gQ24oLi4uZSl7cmV0dXJuIHgoImRpdiIse2NsYXNzOiJtZC10b29sdGlwMiIscm9sZToidG9vbHRpcCJ9LHgoImRpdiIse2NsYXNzOiJtZC10b29sdGlwMl9faW5uZXIgbWQtdHlwZXNldCJ9LGUpKX1mdW5jdGlvbiBrbihlLHQpe2lmKHQ9dD9gJHt0fV9hbm5vdGF0aW9uXyR7ZX1gOnZvaWQgMCx0KXtsZXQgcj10P2AjJHt0fWA6dm9pZCAwO3JldHVybiB4KCJhc2lkZSIse2NsYXNzOiJtZC1hbm5vdGF0aW9uIix0YWJJbmRleDowfSxEdCh0KSx4KCJhIix7aHJlZjpyLGNsYXNzOiJtZC1hbm5vdGF0aW9uX19pbmRleCIsdGFiSW5kZXg6LTF9LHgoInNwYW4iLHsiZGF0YS1tZC1hbm5vdGF0aW9uLWlkIjplfSkpKX1lbHNlIHJldHVybiB4KCJhc2lkZSIse2NsYXNzOiJtZC1hbm5vdGF0aW9uIix0YWJJbmRleDowfSxEdCh0KSx4KCJzcGFuIix7Y2xhc3M6Im1kLWFubm90YXRpb25fX2luZGV4Iix0YWJJbmRleDotMX0seCgic3BhbiIseyJkYXRhLW1kLWFubm90YXRpb24taWQiOmV9KSkpfWZ1bmN0aW9uIEhuKGUpe3JldHVybiB4KCJidXR0b24iLHtjbGFzczoibWQtY29kZV9fYnV0dG9uIix0aXRsZTpNZSgiY2xpcGJvYXJkLmNvcHkiKSwiZGF0YS1jbGlwYm9hcmQtdGFyZ2V0IjpgIyR7ZX0gPiBjb2RlYCwiZGF0YS1tZC10eXBlIjoiY29weSJ9KX1mdW5jdGlvbiAkbigpe3JldHVybiB4KCJidXR0b24iLHtjbGFzczoibWQtY29kZV9fYnV0dG9uIix0aXRsZToiVG9nZ2xlIGxpbmUgc2VsZWN0aW9uIiwiZGF0YS1tZC10eXBlIjoic2VsZWN0In0pfWZ1bmN0aW9uIFBuKCl7cmV0dXJuIHgoIm5hdiIse2NsYXNzOiJtZC1jb2RlX19uYXYifSl9dmFyIEluPSR0KHJvKCkpO2Z1bmN0aW9uIG9vKGUsdCl7bGV0IHI9dCYyLG89dCYxLG49T2JqZWN0LmtleXMoZS50ZXJtcykuZmlsdGVyKGM9PiFlLnRlcm1zW2NdKS5yZWR1Y2UoKGMscCk9PlsuLi5jLHgoImRlbCIsbnVsbCwoMCxJbi5kZWZhdWx0KShwKSksIiAiXSxbXSkuc2xpY2UoMCwtMSksaT1UZSgpLHM9bmV3IFVSTChlLmxvY2F0aW9uLGkuYmFzZSk7Vigic2VhcmNoLmhpZ2hsaWdodCIpJiZzLnNlYXJjaFBhcmFtcy5zZXQoImgiLE9iamVjdC5lbnRyaWVzKGUudGVybXMpLmZpbHRlcigoWyxjXSk9PmMpLnJlZHVjZSgoYyxbcF0pPT5gJHtjfSAke3B9YC50cmltKCksIiIpKTtsZXR7dGFnczphfT1UZSgpO3JldHVybiB4KCJhIix7aHJlZjpgJHtzfWAsY2xhc3M6Im1kLXNlYXJjaC1yZXN1bHRfX2xpbmsiLHRhYkluZGV4Oi0xfSx4KCJhcnRpY2xlIix7Y2xhc3M6Im1kLXNlYXJjaC1yZXN1bHRfX2FydGljbGUgbWQtdHlwZXNldCIsImRhdGEtbWQtc2NvcmUiOmUuc2NvcmUudG9GaXhlZCgyKX0scj4wJiZ4KCJkaXYiLHtjbGFzczoibWQtc2VhcmNoLXJlc3VsdF9faWNvbiBtZC1pY29uIn0pLHI+MCYmeCgiaDEiLG51bGwsZS50aXRsZSkscjw9MCYmeCgiaDIiLG51bGwsZS50aXRsZSksbz4wJiZlLnRleHQubGVuZ3RoPjAmJmUudGV4dCxlLnRhZ3MmJngoIm5hdiIse2NsYXNzOiJtZC10YWdzIn0sZS50YWdzLm1hcChjPT57bGV0IHA9YT9jIGluIGE/YG1kLXRhZy1pY29uIG1kLXRhZy0tJHthW2NdfWA6Im1kLXRhZy1pY29uIjoiIjtyZXR1cm4geCgic3BhbiIse2NsYXNzOmBtZC10YWcgJHtwfWB9LGMpfSkpLG8+MCYmbi5sZW5ndGg+MCYmeCgicCIse2NsYXNzOiJtZC1zZWFyY2gtcmVzdWx0X190ZXJtcyJ9LE1lKCJzZWFyY2gucmVzdWx0LnRlcm0ubWlzc2luZyIpLCI6ICIsLi4ubikpKX1mdW5jdGlvbiBGbihlKXtsZXQgdD1lWzBdLnNjb3JlLHI9Wy4uLmVdLG89VGUoKSxuPXIuZmluZEluZGV4KGw9PiFgJHtuZXcgVVJMKGwubG9jYXRpb24sby5iYXNlKX1gLmluY2x1ZGVzKCIjIikpLFtpXT1yLnNwbGljZShuLDEpLHM9ci5maW5kSW5kZXgobD0+bC5zY29yZTx0KTtzPT09LTEmJihzPXIubGVuZ3RoKTtsZXQgYT1yLnNsaWNlKDAscyksYz1yLnNsaWNlKHMpLHA9W29vKGksMnwrKCFuJiZzPT09MCkpLC4uLmEubWFwKGw9Pm9vKGwsMSkpLC4uLmMubGVuZ3RoP1t4KCJkZXRhaWxzIix7Y2xhc3M6Im1kLXNlYXJjaC1yZXN1bHRfX21vcmUifSx4KCJzdW1tYXJ5Iix7dGFiSW5kZXg6LTF9LHgoImRpdiIsbnVsbCxjLmxlbmd0aD4wJiZjLmxlbmd0aD09PTE/TWUoInNlYXJjaC5yZXN1bHQubW9yZS5vbmUiKTpNZSgic2VhcmNoLnJlc3VsdC5tb3JlLm90aGVyIixjLmxlbmd0aCkpKSwuLi5jLm1hcChsPT5vbyhsLDEpKSldOltdXTtyZXR1cm4geCgibGkiLHtjbGFzczoibWQtc2VhcmNoLXJlc3VsdF9faXRlbSJ9LHApfWZ1bmN0aW9uIGpuKGUpe3JldHVybiB4KCJ1bCIse2NsYXNzOiJtZC1zb3VyY2VfX2ZhY3RzIn0sT2JqZWN0LmVudHJpZXMoZSkubWFwKChbdCxyXSk9PngoImxpIix7Y2xhc3M6YG1kLXNvdXJjZV9fZmFjdCBtZC1zb3VyY2VfX2ZhY3QtLSR7dH1gfSx0eXBlb2Ygcj09Im51bWJlciI/YnIocik6cikpKX1mdW5jdGlvbiBubyhlKXtsZXQgdD1gdGFiYmVkLWNvbnRyb2wgdGFiYmVkLWNvbnRyb2wtLSR7ZX1gO3JldHVybiB4KCJkaXYiLHtjbGFzczp0LGhpZGRlbjohMH0seCgiYnV0dG9uIix7Y2xhc3M6InRhYmJlZC1idXR0b24iLHRhYkluZGV4Oi0xLCJhcmlhLWhpZGRlbiI6InRydWUifSkpfWZ1bmN0aW9uIFVuKGUpe3JldHVybiB4KCJkaXYiLHtjbGFzczoibWQtdHlwZXNldF9fc2Nyb2xsd3JhcCJ9LHgoImRpdiIse2NsYXNzOiJtZC10eXBlc2V0X190YWJsZSJ9LGUpKX1mdW5jdGlvbiBRYShlKXt2YXIgbztsZXQgdD1UZSgpLHI9bmV3IFVSTChgLi4vJHtlLnZlcnNpb259L2AsdC5iYXNlKTtyZXR1cm4geCgibGkiLHtjbGFzczoibWQtdmVyc2lvbl9faXRlbSJ9LHgoImEiLHtocmVmOmAke3J9YCxjbGFzczoibWQtdmVyc2lvbl9fbGluayJ9LGUudGl0bGUsKChvPXQudmVyc2lvbik9PW51bGw/dm9pZCAwOm8uYWxpYXMpJiZlLmFsaWFzZXMubGVuZ3RoPjAmJngoInNwYW4iLHtjbGFzczoibWQtdmVyc2lvbl9fYWxpYXMifSxlLmFsaWFzZXNbMF0pKSl9ZnVuY3Rpb24gV24oZSx0KXt2YXIgbztsZXQgcj1UZSgpO3JldHVybiBlPWUuZmlsdGVyKG49Pnt2YXIgaTtyZXR1cm4hKChpPW4ucHJvcGVydGllcykhPW51bGwmJmkuaGlkZGVuKX0pLHgoImRpdiIse2NsYXNzOiJtZC12ZXJzaW9uIn0seCgiYnV0dG9uIix7Y2xhc3M6Im1kLXZlcnNpb25fX2N1cnJlbnQiLCJhcmlhLWxhYmVsIjpNZSgic2VsZWN0LnZlcnNpb24iKX0sdC50aXRsZSwoKG89ci52ZXJzaW9uKT09bnVsbD92b2lkIDA6by5hbGlhcykmJnQuYWxpYXNlcy5sZW5ndGg+MCYmeCgic3BhbiIse2NsYXNzOiJtZC12ZXJzaW9uX19hbGlhcyJ9LHQuYWxpYXNlc1swXSkpLHgoInVsIix7Y2xhc3M6Im1kLXZlcnNpb25fX2xpc3QifSxlLm1hcChRYSkpKX12YXIgWWE9MDtmdW5jdGlvbiBCYShlLHQ9MjUwKXtsZXQgcj16KFtZZShlKSxpdChlLHQpXSkucGlwZShtKChbbixpXSk9Pm58fGkpLFkoKSksbz1IKCgpPT5wbihlKSkucGlwZShKKEdlKSxndCgxKSxQZShyKSxtKCgpPT5sbihlKSkpO3JldHVybiByLnBpcGUoUmUobj0+biksYigoKT0+eihbcixvXSkpLG0oKFtuLGldKT0+KHthY3RpdmU6bixvZmZzZXQ6aX0pKSxsZSgpKX1mdW5jdGlvbiBWdChlLHQscj0yNTApe2xldHtjb250ZW50JDpvLHZpZXdwb3J0JDpufT10LGk9YF9fdG9vbHRpcDJfJHtZYSsrfWA7cmV0dXJuIEgoKCk9PntsZXQgcz1uZXcgVCxhPW5ldyBqcighMSk7cy5waXBlKG9lKCksYWUoITEpKS5zdWJzY3JpYmUoYSk7bGV0IGM9YS5waXBlKGp0KGw9PkhlKCshbCoyNTAsRHIpKSxZKCksYihsPT5sP286eSksTyhsPT5sLmlkPWkpLGxlKCkpO3ooW3MucGlwZShtKCh7YWN0aXZlOmx9KT0+bCkpLGMucGlwZShiKGw9Pml0KGwsMjUwKSksUSghMSkpXSkucGlwZShtKGw9Pmwuc29tZShmPT5mKSkpLnN1YnNjcmliZShhKTtsZXQgcD1hLnBpcGUoZyhsPT5sKSx0ZShjLG4pLG0oKFtsLGYse3NpemU6dX1dKT0+e2xldCBkPWUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksdj1kLndpZHRoLzI7aWYoZi5yb2xlPT09InRvb2x0aXAiKXJldHVybnt4OnYseTo4K2QuaGVpZ2h0fTtpZihkLnk+PXUuaGVpZ2h0LzIpe2xldHtoZWlnaHQ6U309ZGUoZik7cmV0dXJue3g6dix5Oi0xNi1TfX1lbHNlIHJldHVybnt4OnYseToxNitkLmhlaWdodH19KSk7cmV0dXJuIHooW2MscyxwXSkuc3Vic2NyaWJlKChbbCx7b2Zmc2V0OmZ9LHVdKT0+e2wuc3R5bGUuc2V0UHJvcGVydHkoIi0tbWQtdG9vbHRpcC1ob3N0LXgiLGAke2YueH1weGApLGwuc3R5bGUuc2V0UHJvcGVydHkoIi0tbWQtdG9vbHRpcC1ob3N0LXkiLGAke2YueX1weGApLGwuc3R5bGUuc2V0UHJvcGVydHkoIi0tbWQtdG9vbHRpcC14IixgJHt1Lnh9cHhgKSxsLnN0eWxlLnNldFByb3BlcnR5KCItLW1kLXRvb2x0aXAteSIsYCR7dS55fXB4YCksbC5jbGFzc0xpc3QudG9nZ2xlKCJtZC10b29sdGlwMi0tdG9wIix1Lnk8MCksbC5jbGFzc0xpc3QudG9nZ2xlKCJtZC10b29sdGlwMi0tYm90dG9tIix1Lnk+PTApfSksYS5waXBlKGcobD0+bCksdGUoYywobCxmKT0+ZiksZyhsPT5sLnJvbGU9PT0idG9vbHRpcCIpKS5zdWJzY3JpYmUobD0+e2xldCBmPWRlKGooIjpzY29wZSA+ICoiLGwpKTtsLnN0eWxlLnNldFByb3BlcnR5KCItLW1kLXRvb2x0aXAtd2lkdGgiLGAke2Yud2lkdGh9cHhgKSxsLnN0eWxlLnNldFByb3BlcnR5KCItLW1kLXRvb2x0aXAtdGFpbCIsIjBweCIpfSksYS5waXBlKFkoKSx4ZSh5ZSksdGUoYykpLnN1YnNjcmliZSgoW2wsZl0pPT57Zi5jbGFzc0xpc3QudG9nZ2xlKCJtZC10b29sdGlwMi0tYWN0aXZlIixsKX0pLHooW2EucGlwZShnKGw9PmwpKSxjXSkuc3Vic2NyaWJlKChbbCxmXSk9PntmLnJvbGU9PT0iZGlhbG9nIj8oZS5zZXRBdHRyaWJ1dGUoImFyaWEtY29udHJvbHMiLGkpLGUuc2V0QXR0cmlidXRlKCJhcmlhLWhhc3BvcHVwIiwiZGlhbG9nIikpOmUuc2V0QXR0cmlidXRlKCJhcmlhLWRlc2NyaWJlZGJ5IixpKX0pLGEucGlwZShnKGw9PiFsKSkuc3Vic2NyaWJlKCgpPT57ZS5yZW1vdmVBdHRyaWJ1dGUoImFyaWEtY29udHJvbHMiKSxlLnJlbW92ZUF0dHJpYnV0ZSgiYXJpYS1kZXNjcmliZWRieSIpLGUucmVtb3ZlQXR0cmlidXRlKCJhcmlhLWhhc3BvcHVwIil9KSxCYShlLHIpLnBpcGUoTyhsPT5zLm5leHQobCkpLEEoKCk9PnMuY29tcGxldGUoKSksbShsPT5QKHtyZWY6ZX0sbCkpKX0pfWZ1bmN0aW9uIFhlKGUse3ZpZXdwb3J0JDp0fSxyPWRvY3VtZW50LmJvZHkpe3JldHVybiBWdChlLHtjb250ZW50JDpuZXcgRihvPT57bGV0IG49ZS50aXRsZSxpPUNuKG4pO3JldHVybiBvLm5leHQoaSksZS5yZW1vdmVBdHRyaWJ1dGUoInRpdGxlIiksci5hcHBlbmQoaSksKCk9PntpLnJlbW92ZSgpLGUuc2V0QXR0cmlidXRlKCJ0aXRsZSIsbil9fSksdmlld3BvcnQkOnR9LDApfWZ1bmN0aW9uIEdhKGUsdCl7bGV0IHI9SCgoKT0+eihbbW4oZSksR2UodCldKSkucGlwZShtKChbe3g6byx5Om59LGldKT0+e2xldHt3aWR0aDpzLGhlaWdodDphfT1kZShlKTtyZXR1cm57eDpvLWkueCtzLzIseTpuLWkueSthLzJ9fSkpO3JldHVybiBZZShlKS5waXBlKGIobz0+ci5waXBlKG0obj0+KHthY3RpdmU6byxvZmZzZXQ6bn0pKSxFZSgrIW98fDEvMCkpKSl9ZnVuY3Rpb24gRG4oZSx0LHt0YXJnZXQkOnJ9KXtsZXRbbyxuXT1BcnJheS5mcm9tKGUuY2hpbGRyZW4pO3JldHVybiBIKCgpPT57bGV0IGk9bmV3IFQscz1pLnBpcGUob2UoKSxhZSghMCkpO3JldHVybiBpLnN1YnNjcmliZSh7bmV4dCh7b2Zmc2V0OmF9KXtlLnN0eWxlLnNldFByb3BlcnR5KCItLW1kLXRvb2x0aXAteCIsYCR7YS54fXB4YCksZS5zdHlsZS5zZXRQcm9wZXJ0eSgiLS1tZC10b29sdGlwLXkiLGAke2EueX1weGApfSxjb21wbGV0ZSgpe2Uuc3R5bGUucmVtb3ZlUHJvcGVydHkoIi0tbWQtdG9vbHRpcC14IiksZS5zdHlsZS5yZW1vdmVQcm9wZXJ0eSgiLS1tZC10b29sdGlwLXkiKX19KSxtdChlKS5waXBlKFcocykpLnN1YnNjcmliZShhPT57ZS50b2dnbGVBdHRyaWJ1dGUoImRhdGEtbWQtdmlzaWJsZSIsYSl9KSxMKGkucGlwZShnKCh7YWN0aXZlOmF9KT0+YSkpLGkucGlwZShBZSgyNTApLGcoKHthY3RpdmU6YX0pPT4hYSkpKS5zdWJzY3JpYmUoe25leHQoe2FjdGl2ZTphfSl7YT9lLnByZXBlbmQobyk6by5yZW1vdmUoKX0sY29tcGxldGUoKXtlLnByZXBlbmQobyl9fSksaS5waXBlKCRlKDE2LHllKSkuc3Vic2NyaWJlKCh7YWN0aXZlOmF9KT0+e28uY2xhc3NMaXN0LnRvZ2dsZSgibWQtdG9vbHRpcC0tYWN0aXZlIixhKX0pLGkucGlwZShndCgxMjUseWUpLGcoKCk9PiEhZS5vZmZzZXRQYXJlbnQpLG0oKCk9PmUub2Zmc2V0UGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKSxtKCh7eDphfSk9PmEpKS5zdWJzY3JpYmUoe25leHQoYSl7YT9lLnN0eWxlLnNldFByb3BlcnR5KCItLW1kLXRvb2x0aXAtMCIsYCR7LWF9cHhgKTplLnN0eWxlLnJlbW92ZVByb3BlcnR5KCItLW1kLXRvb2x0aXAtMCIpfSxjb21wbGV0ZSgpe2Uuc3R5bGUucmVtb3ZlUHJvcGVydHkoIi0tbWQtdG9vbHRpcC0wIil9fSksaChuLCJjbGljayIpLnBpcGUoVyhzKSxnKGE9PiEoYS5tZXRhS2V5fHxhLmN0cmxLZXkpKSkuc3Vic2NyaWJlKGE9PnthLnN0b3BQcm9wYWdhdGlvbigpLGEucHJldmVudERlZmF1bHQoKX0pLGgobiwibW91c2Vkb3duIikucGlwZShXKHMpLHRlKGkpKS5zdWJzY3JpYmUoKFthLHthY3RpdmU6Y31dKT0+e3ZhciBwO2lmKGEuYnV0dG9uIT09MHx8YS5tZXRhS2V5fHxhLmN0cmxLZXkpYS5wcmV2ZW50RGVmYXVsdCgpO2Vsc2UgaWYoYyl7YS5wcmV2ZW50RGVmYXVsdCgpO2xldCBsPWUucGFyZW50RWxlbWVudC5jbG9zZXN0KCIubWQtYW5ub3RhdGlvbiIpO2wgaW5zdGFuY2VvZiBIVE1MRWxlbWVudD9sLmZvY3VzKCk6KHA9TmUoKSk9PW51bGx8fHAuYmx1cigpfX0pLHIucGlwZShXKHMpLGcoYT0+YT09PW8pLG50KDEyNSkpLnN1YnNjcmliZSgoKT0+ZS5mb2N1cygpKSxHYShlLHQpLnBpcGUoTyhhPT5pLm5leHQoYSkpLEEoKCk9PmkuY29tcGxldGUoKSksbShhPT5QKHtyZWY6ZX0sYSkpKX0pfWZ1bmN0aW9uIEphKGUpe2xldCB0PVRlKCk7aWYoZS50YWdOYW1lIT09IkNPREUiKXJldHVybltlXTtsZXQgcj1bIi5jIiwiLmMxIiwiLmNtIl07aWYodC5hbm5vdGF0ZSYmdHlwZW9mIHQuYW5ub3RhdGU9PSJvYmplY3QiKXtsZXQgbz1lLmNsb3Nlc3QoIltjbGFzc3w9bGFuZ3VhZ2VdIik7aWYobylmb3IobGV0IG4gb2YgQXJyYXkuZnJvbShvLmNsYXNzTGlzdCkpe2lmKCFuLnN0YXJ0c1dpdGgoImxhbmd1YWdlLSIpKWNvbnRpbnVlO2xldFssaV09bi5zcGxpdCgiLSIpO2kgaW4gdC5hbm5vdGF0ZSYmci5wdXNoKC4uLnQuYW5ub3RhdGVbaV0pfX1yZXR1cm4gTShyLmpvaW4oIiwgIiksZSl9ZnVuY3Rpb24gWGEoZSl7bGV0IHQ9W107Zm9yKGxldCByIG9mIEphKGUpKXtsZXQgbz1bXSxuPWRvY3VtZW50LmNyZWF0ZU5vZGVJdGVyYXRvcihyLE5vZGVGaWx0ZXIuU0hPV19URVhUKTtmb3IobGV0IGk9bi5uZXh0Tm9kZSgpO2k7aT1uLm5leHROb2RlKCkpby5wdXNoKGkpO2ZvcihsZXQgaSBvZiBvKXtsZXQgcztmb3IoO3M9LyhcKFxkK1wpKSghKT8vLmV4ZWMoaS50ZXh0Q29udGVudCk7KXtsZXRbLGEsY109cztpZih0eXBlb2YgYz09InVuZGVmaW5lZCIpe2xldCBwPWkuc3BsaXRUZXh0KHMuaW5kZXgpO2k9cC5zcGxpdFRleHQoYS5sZW5ndGgpLHQucHVzaChwKX1lbHNle2kudGV4dENvbnRlbnQ9YSx0LnB1c2goaSk7YnJlYWt9fX19cmV0dXJuIHR9ZnVuY3Rpb24gVm4oZSx0KXt0LmFwcGVuZCguLi5BcnJheS5mcm9tKGUuY2hpbGROb2RlcykpfWZ1bmN0aW9uIFRyKGUsdCx7dGFyZ2V0JDpyLHByaW50JDpvfSl7bGV0IG49dC5jbG9zZXN0KCJbaWRdIiksaT1uPT1udWxsP3ZvaWQgMDpuLmlkLHM9bmV3IE1hcDtmb3IobGV0IGEgb2YgWGEodCkpe2xldFssY109YS50ZXh0Q29udGVudC5tYXRjaCgvXCgoXGQrKVwpLyk7dWUoYDpzY29wZSA+IGxpOm50aC1jaGlsZCgke2N9KWAsZSkmJihzLnNldChjLGtuKGMsaSkpLGEucmVwbGFjZVdpdGgocy5nZXQoYykpKX1yZXR1cm4gcy5zaXplPT09MD95OkgoKCk9PntsZXQgYT1uZXcgVCxjPWEucGlwZShvZSgpLGFlKCEwKSkscD1bXTtmb3IobGV0W2wsZl1vZiBzKXAucHVzaChbaigiLm1kLXR5cGVzZXQiLGYpLGooYDpzY29wZSA+IGxpOm50aC1jaGlsZCgke2x9KWAsZSldKTtyZXR1cm4gby5waXBlKFcoYykpLnN1YnNjcmliZShsPT57ZS5oaWRkZW49IWwsZS5jbGFzc0xpc3QudG9nZ2xlKCJtZC1hbm5vdGF0aW9uLWxpc3QiLGwpO2ZvcihsZXRbZix1XW9mIHApbD9WbihmLHUpOlZuKHUsZil9KSxMKC4uLlsuLi5zXS5tYXAoKFssbF0pPT5EbihsLHQse3RhcmdldCQ6cn0pKSkucGlwZShBKCgpPT5hLmNvbXBsZXRlKCkpLGxlKCkpfSl9ZnVuY3Rpb24gTm4oZSl7aWYoZS5uZXh0RWxlbWVudFNpYmxpbmcpe2xldCB0PWUubmV4dEVsZW1lbnRTaWJsaW5nO2lmKHQudGFnTmFtZT09PSJPTCIpcmV0dXJuIHQ7aWYodC50YWdOYW1lPT09IlAiJiYhdC5jaGlsZHJlbi5sZW5ndGgpcmV0dXJuIE5uKHQpfX1mdW5jdGlvbiB6bihlLHQpe3JldHVybiBIKCgpPT57bGV0IHI9Tm4oZSk7cmV0dXJuIHR5cGVvZiByIT0idW5kZWZpbmVkIj9UcihyLGUsdCk6eX0pfXZhciBLbj0kdChhbygpKTt2YXIgWmE9MCxxbj1MKGgod2luZG93LCJrZXlkb3duIikucGlwZShtKCgpPT4hMCkpLEwoaCh3aW5kb3csImtleXVwIiksaCh3aW5kb3csImNvbnRleHRtZW51IikpLnBpcGUobSgoKT0+ITEpKSkucGlwZShRKCExKSxaKDEpKTtmdW5jdGlvbiBRbihlKXtpZihlLm5leHRFbGVtZW50U2libGluZyl7bGV0IHQ9ZS5uZXh0RWxlbWVudFNpYmxpbmc7aWYodC50YWdOYW1lPT09Ik9MIilyZXR1cm4gdDtpZih0LnRhZ05hbWU9PT0iUCImJiF0LmNoaWxkcmVuLmxlbmd0aClyZXR1cm4gUW4odCl9fWZ1bmN0aW9uIGVzKGUpe3JldHVybiBMZShlKS5waXBlKG0oKHt3aWR0aDp0fSk9Pih7c2Nyb2xsYWJsZTpBdChlKS53aWR0aD50fSkpLG5lKCJzY3JvbGxhYmxlIikpfWZ1bmN0aW9uIFluKGUsdCl7bGV0e21hdGNoZXM6cn09bWF0Y2hNZWRpYSgiKGhvdmVyKSIpLG89SCgoKT0+e2xldCBuPW5ldyBULGk9bi5waXBlKFlyKDEpKTtuLnN1YnNjcmliZSgoe3Njcm9sbGFibGU6ZH0pPT57ZCYmcj9lLnNldEF0dHJpYnV0ZSgidGFiaW5kZXgiLCIwIik6ZS5yZW1vdmVBdHRyaWJ1dGUoInRhYmluZGV4Iil9KTtsZXQgcz1bXSxhPWUuY2xvc2VzdCgicHJlIiksYz1hLmNsb3Nlc3QoIltpZF0iKSxwPWM/Yy5pZDpaYSsrO2EuaWQ9YF9fY29kZV8ke3B9YDtsZXQgbD1bXSxmPWUuY2xvc2VzdCgiLmhpZ2hsaWdodCIpO2lmKGYgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCl7bGV0IGQ9UW4oZik7aWYodHlwZW9mIGQhPSJ1bmRlZmluZWQiJiYoZi5jbGFzc0xpc3QuY29udGFpbnMoImFubm90YXRlIil8fFYoImNvbnRlbnQuY29kZS5hbm5vdGF0ZSIpKSl7bGV0IHY9VHIoZCxlLHQpO2wucHVzaChMZShmKS5waXBlKFcoaSksbSgoe3dpZHRoOlMsaGVpZ2h0Olh9KT0+UyYmWCksWSgpLGIoUz0+Uz92OnkpKSl9fWxldCB1PU0oIjpzY29wZSA+IHNwYW5baWRdIixlKTtpZih1Lmxlbmd0aCYmKGUuY2xhc3NMaXN0LmFkZCgibWQtY29kZV9fY29udGVudCIpLGUuY2xvc2VzdCgiLnNlbGVjdCIpfHxWKCJjb250ZW50LmNvZGUuc2VsZWN0IikmJiFlLmNsb3Nlc3QoIi5uby1zZWxlY3QiKSkpe2xldCBkPSt1WzBdLmlkLnNwbGl0KCItIikucG9wKCksdj0kbigpO3MucHVzaCh2KSxWKCJjb250ZW50LnRvb2x0aXBzIikmJmwucHVzaChYZSh2LHt2aWV3cG9ydCR9KSk7bGV0IFM9aCh2LCJjbGljayIpLnBpcGUoVXQoUj0+IVIsITEpLE8oKCk9PnYuYmx1cigpKSxsZSgpKTtTLnN1YnNjcmliZShSPT57di5jbGFzc0xpc3QudG9nZ2xlKCJtZC1jb2RlX19idXR0b24tLWFjdGl2ZSIsUil9KTtsZXQgWD1mZSh1KS5waXBlKEooUj0+aXQoUikucGlwZShtKHNlPT5bUixzZV0pKSkpO1MucGlwZShiKFI9PlI/WDp5KSkuc3Vic2NyaWJlKChbUixzZV0pPT57bGV0IGNlPXVlKCIuaGxsLnNlbGVjdCIsUik7aWYoY2UmJiFzZSljZS5yZXBsYWNlV2l0aCguLi5BcnJheS5mcm9tKGNlLmNoaWxkTm9kZXMpKTtlbHNlIGlmKCFjZSYmc2Upe2xldCBoZT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzcGFuIik7aGUuY2xhc3NOYW1lPSJobGwgc2VsZWN0IixoZS5hcHBlbmQoLi4uQXJyYXkuZnJvbShSLmNoaWxkTm9kZXMpLnNsaWNlKDEpKSxSLmFwcGVuZChoZSl9fSk7bGV0IHJlPWZlKHUpLnBpcGUoSihSPT5oKFIsIm1vdXNlZG93biIpLnBpcGUoTyhzZT0+c2UucHJldmVudERlZmF1bHQoKSksbSgoKT0+UikpKSksZWU9Uy5waXBlKGIoUj0+Uj9yZTp5KSx0ZShxbiksbSgoW1Isc2VdKT0+e3ZhciBoZTtsZXQgY2U9dS5pbmRleE9mKFIpK2Q7aWYoc2U9PT0hMSlyZXR1cm5bY2UsY2VdO3tsZXQgU2U9TSgiLmhsbCIsZSkubWFwKFVlPT51LmluZGV4T2YoVWUucGFyZW50RWxlbWVudCkrZCk7cmV0dXJuKGhlPXdpbmRvdy5nZXRTZWxlY3Rpb24oKSk9PW51bGx8fGhlLnJlbW92ZUFsbFJhbmdlcygpLFtNYXRoLm1pbihjZSwuLi5TZSksTWF0aC5tYXgoY2UsLi4uU2UpXX19KSksaz1acih5KS5waXBlKGcoUj0+Ui5zdGFydHNXaXRoKGBfX2NvZGVsaW5lbm8tJHtwfS1gKSkpO2suc3Vic2NyaWJlKFI9PntsZXRbLCxzZV09Ui5zcGxpdCgiLSIpLGNlPXNlLnNwbGl0KCI6IikubWFwKFNlPT4rU2UtZCsxKTtjZS5sZW5ndGg9PT0xJiZjZS5wdXNoKGNlWzBdKTtmb3IobGV0IFNlIG9mIE0oIi5obGw6bm90KC5zZWxlY3QpIixlKSlTZS5yZXBsYWNlV2l0aCguLi5BcnJheS5mcm9tKFNlLmNoaWxkTm9kZXMpKTtsZXQgaGU9dS5zbGljZShjZVswXS0xLGNlWzFdKTtmb3IobGV0IFNlIG9mIGhlKXtsZXQgVWU9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpO1VlLmNsYXNzTmFtZT0iaGxsIixVZS5hcHBlbmQoLi4uQXJyYXkuZnJvbShTZS5jaGlsZE5vZGVzKS5zbGljZSgxKSksU2UuYXBwZW5kKFVlKX19KSxrLnBpcGUoRWUoMSkseGUocGUpKS5zdWJzY3JpYmUoUj0+e2lmKFIuaW5jbHVkZXMoIjoiKSl7bGV0IHNlPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFIuc3BsaXQoIjoiKVswXSk7c2UmJnNldFRpbWVvdXQoKCk9PntsZXQgY2U9c2UsaGU9LTY0O2Zvcig7Y2UhPT1kb2N1bWVudC5ib2R5OyloZSs9Y2Uub2Zmc2V0VG9wLGNlPWNlLm9mZnNldFBhcmVudDt3aW5kb3cuc2Nyb2xsVG8oe3RvcDpoZX0pfSwxKX19KTtsZXQgamU9ZmUoTSgnYVtocmVmXj0iI19fY29kZWxpbmVubyJdJyxmKSkucGlwZShKKFI9PmgoUiwiY2xpY2siKS5waXBlKE8oc2U9PnNlLnByZXZlbnREZWZhdWx0KCkpLG0oKCk9PlIpKSkpLnBpcGUoVyhpKSx0ZShxbiksbSgoW1Isc2VdKT0+e2xldCBoZT0raihgW2lkPSIke1IuaGFzaC5zbGljZSgxKX0iXWApLnBhcmVudEVsZW1lbnQuaWQuc3BsaXQoIi0iKS5wb3AoKTtpZihzZT09PSExKXJldHVybltoZSxoZV07e2xldCBTZT1NKCIuaGxsIixlKS5tYXAoVWU9PitVZS5wYXJlbnRFbGVtZW50LmlkLnNwbGl0KCItIikucG9wKCkpO3JldHVybltNYXRoLm1pbihoZSwuLi5TZSksTWF0aC5tYXgoaGUsLi4uU2UpXX19KSk7TChlZSxqZSkuc3Vic2NyaWJlKFI9PntsZXQgc2U9YCNfX2NvZGVsaW5lbm8tJHtwfS1gO1JbMF09PT1SWzFdP3NlKz1SWzBdOnNlKz1gJHtSWzBdfToke1JbMV19YCxoaXN0b3J5LnJlcGxhY2VTdGF0ZSh7fSwiIixzZSksd2luZG93LmRpc3BhdGNoRXZlbnQobmV3IEhhc2hDaGFuZ2VFdmVudCgiaGFzaGNoYW5nZSIse25ld1VSTDp3aW5kb3cubG9jYXRpb24ub3JpZ2luK3dpbmRvdy5sb2NhdGlvbi5wYXRobmFtZStzZSxvbGRVUkw6d2luZG93LmxvY2F0aW9uLmhyZWZ9KSl9KX1pZihLbi5kZWZhdWx0LmlzU3VwcG9ydGVkKCkmJihlLmNsb3Nlc3QoIi5jb3B5Iil8fFYoImNvbnRlbnQuY29kZS5jb3B5IikmJiFlLmNsb3Nlc3QoIi5uby1jb3B5IikpKXtsZXQgZD1IbihhLmlkKTtzLnB1c2goZCksVigiY29udGVudC50b29sdGlwcyIpJiZsLnB1c2goWGUoZCx7dmlld3BvcnQkfSkpfWlmKHMubGVuZ3RoKXtsZXQgZD1QbigpO2QuYXBwZW5kKC4uLnMpLGEuaW5zZXJ0QmVmb3JlKGQsZSl9cmV0dXJuIGVzKGUpLnBpcGUoTyhkPT5uLm5leHQoZCkpLEEoKCk9Pm4uY29tcGxldGUoKSksbShkPT5QKHtyZWY6ZX0sZCkpLFZlKEwoLi4ubCkucGlwZShXKGkpKSkpfSk7cmV0dXJuIFYoImNvbnRlbnQubGF6eSIpP210KGUpLnBpcGUoZyhuPT5uKSxFZSgxKSxiKCgpPT5vKSk6b31mdW5jdGlvbiB0cyhlLHt0YXJnZXQkOnQscHJpbnQkOnJ9KXtsZXQgbz0hMDtyZXR1cm4gTCh0LnBpcGUobShuPT5uLmNsb3Nlc3QoImRldGFpbHM6bm90KFtvcGVuXSkiKSksZyhuPT5lPT09biksbSgoKT0+KHthY3Rpb246Im9wZW4iLHJldmVhbDohMH0pKSksci5waXBlKGcobj0+bnx8IW8pLE8oKCk9Pm89ZS5vcGVuKSxtKG49Pih7YWN0aW9uOm4/Im9wZW4iOiJjbG9zZSJ9KSkpKX1mdW5jdGlvbiBCbihlLHQpe3JldHVybiBIKCgpPT57bGV0IHI9bmV3IFQ7cmV0dXJuIHIuc3Vic2NyaWJlKCh7YWN0aW9uOm8scmV2ZWFsOm59KT0+e2UudG9nZ2xlQXR0cmlidXRlKCJvcGVuIixvPT09Im9wZW4iKSxuJiZlLnNjcm9sbEludG9WaWV3KCl9KSx0cyhlLHQpLnBpcGUoTyhvPT5yLm5leHQobykpLEEoKCk9PnIuY29tcGxldGUoKSksbShvPT5QKHtyZWY6ZX0sbykpKX0pfXZhciBHbj0wO2Z1bmN0aW9uIHJzKGUpe2xldCB0PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImgzIik7dC5pbm5lckhUTUw9ZS5pbm5lckhUTUw7bGV0IHI9W3RdLG89ZS5uZXh0RWxlbWVudFNpYmxpbmc7Zm9yKDtvJiYhKG8gaW5zdGFuY2VvZiBIVE1MSGVhZGluZ0VsZW1lbnQpOylyLnB1c2gobyksbz1vLm5leHRFbGVtZW50U2libGluZztyZXR1cm4gcn1mdW5jdGlvbiBvcyhlLHQpe2ZvcihsZXQgciBvZiBNKCJbaHJlZl0sIFtzcmNdIixlKSlmb3IobGV0IG8gb2ZbImhyZWYiLCJzcmMiXSl7bGV0IG49ci5nZXRBdHRyaWJ1dGUobyk7aWYobiYmIS9eKD86W2Etel0rOik/XC9cLy9pLnRlc3Qobikpe3Jbb109bmV3IFVSTChyLmdldEF0dHJpYnV0ZShvKSx0KS50b1N0cmluZygpO2JyZWFrfX1mb3IobGV0IHIgb2YgTSgiW25hbWVePV9fXSwgW2Zvcl0iLGUpKWZvcihsZXQgbyBvZlsiaWQiLCJmb3IiLCJuYW1lIl0pe2xldCBuPXIuZ2V0QXR0cmlidXRlKG8pO24mJnIuc2V0QXR0cmlidXRlKG8sYCR7bn0kcHJldmlld18ke0dufWApfXJldHVybiBHbisrLCQoZSl9ZnVuY3Rpb24gSm4oZSx0KXtsZXR7c2l0ZW1hcCQ6cn09dDtpZighKGUgaW5zdGFuY2VvZiBIVE1MQW5jaG9yRWxlbWVudCkpcmV0dXJuIHk7aWYoIShWKCJuYXZpZ2F0aW9uLmluc3RhbnQucHJldmlldyIpfHxlLmhhc0F0dHJpYnV0ZSgiZGF0YS1wcmV2aWV3IikpKXJldHVybiB5O2UucmVtb3ZlQXR0cmlidXRlKCJ0aXRsZSIpO2xldCBvPXooW1llKGUpLGl0KGUpXSkucGlwZShtKChbaSxzXSk9Pml8fHMpLFkoKSxnKGk9PmkpKTtyZXR1cm4gcnQoW3Isb10pLnBpcGUoYigoW2ldKT0+e2xldCBzPW5ldyBVUkwoZS5ocmVmKTtyZXR1cm4gcy5zZWFyY2g9cy5oYXNoPSIiLGkuaGFzKGAke3N9YCk/JChzKTp5fSksYihpPT54cihpKS5waXBlKGIocz0+b3MocyxpKSkpKSxiKGk9PntsZXQgcz1lLmhhc2g/YGFydGljbGUgW2lkPSIke2UuaGFzaC5zbGljZSgxKX0iXWA6ImFydGljbGUgaDEiLGE9dWUocyxpKTtyZXR1cm4gdHlwZW9mIGE9PSJ1bmRlZmluZWQiP3k6JChycyhhKSl9KSkucGlwZShiKGk9PntsZXQgcz1uZXcgRihhPT57bGV0IGM9d3IoLi4uaSk7cmV0dXJuIGEubmV4dChjKSxkb2N1bWVudC5ib2R5LmFwcGVuZChjKSwoKT0+Yy5yZW1vdmUoKX0pO3JldHVybiBWdChlLFAoe2NvbnRlbnQkOnN9LHQpKX0pKX12YXIgWG49Ii5ub2RlIGNpcmNsZSwubm9kZSBlbGxpcHNlLC5ub2RlIHBhdGgsLm5vZGUgcG9seWdvbiwubm9kZSByZWN0e2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1ub2RlLWJnLWNvbG9yKTtzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1ub2RlLWZnLWNvbG9yKX1tYXJrZXJ7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLWVkZ2UtY29sb3IpIWltcG9ydGFudH0uZWRnZUxhYmVsIC5sYWJlbCByZWN0e2ZpbGw6IzAwMDB9LmZsb3djaGFydFRpdGxlVGV4dHtmaWxsOnZhcigtLW1kLW1lcm1haWQtbGFiZWwtZmctY29sb3IpfS5sYWJlbHtjb2xvcjp2YXIoLS1tZC1tZXJtYWlkLWxhYmVsLWZnLWNvbG9yKTtmb250LWZhbWlseTp2YXIoLS1tZC1tZXJtYWlkLWZvbnQtZmFtaWx5KX0ubGFiZWwgZm9yZWlnbk9iamVjdHtsaW5lLWhlaWdodDpub3JtYWw7b3ZlcmZsb3c6dmlzaWJsZX0ubGFiZWwgZGl2IC5lZGdlTGFiZWx7Y29sb3I6dmFyKC0tbWQtbWVybWFpZC1sYWJlbC1mZy1jb2xvcil9LmVkZ2VMYWJlbCwuZWRnZUxhYmVsIHAsLmxhYmVsIGRpdiAuZWRnZUxhYmVse2JhY2tncm91bmQtY29sb3I6dmFyKC0tbWQtbWVybWFpZC1sYWJlbC1iZy1jb2xvcil9LmVkZ2VMYWJlbCwuZWRnZUxhYmVsIHB7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLWxhYmVsLWJnLWNvbG9yKTtjb2xvcjp2YXIoLS1tZC1tZXJtYWlkLWVkZ2UtY29sb3IpfS5lZGdlUGF0aCAucGF0aCwuZmxvd2NoYXJ0LWxpbmt7c3Ryb2tlOnZhcigtLW1kLW1lcm1haWQtZWRnZS1jb2xvcil9LmVkZ2VQYXRoIC5hcnJvd2hlYWRQYXRoe2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1lZGdlLWNvbG9yKTtzdHJva2U6bm9uZX0uY2x1c3RlciByZWN0e2ZpbGw6dmFyKC0tbWQtZGVmYXVsdC1mZy1jb2xvci0tbGlnaHRlc3QpO3N0cm9rZTp2YXIoLS1tZC1kZWZhdWx0LWZnLWNvbG9yLS1saWdodGVyKX0uY2x1c3RlciBzcGFue2NvbG9yOnZhcigtLW1kLW1lcm1haWQtbGFiZWwtZmctY29sb3IpO2ZvbnQtZmFtaWx5OnZhcigtLW1kLW1lcm1haWQtZm9udC1mYW1pbHkpfWcgI2Zsb3djaGFydC1jaXJjbGVFbmQsZyAjZmxvd2NoYXJ0LWNpcmNsZVN0YXJ0LGcgI2Zsb3djaGFydC1jcm9zc0VuZCxnICNmbG93Y2hhcnQtY3Jvc3NTdGFydCxnICNmbG93Y2hhcnQtcG9pbnRFbmQsZyAjZmxvd2NoYXJ0LXBvaW50U3RhcnR7c3Ryb2tlOm5vbmV9LmNsYXNzRGlhZ3JhbVRpdGxlVGV4dHtmaWxsOnZhcigtLW1kLW1lcm1haWQtbGFiZWwtZmctY29sb3IpfWcuY2xhc3NHcm91cCBsaW5lLGcuY2xhc3NHcm91cCByZWN0e2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1ub2RlLWJnLWNvbG9yKTtzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1ub2RlLWZnLWNvbG9yKX1nLmNsYXNzR3JvdXAgdGV4dHtmaWxsOnZhcigtLW1kLW1lcm1haWQtbGFiZWwtZmctY29sb3IpO2ZvbnQtZmFtaWx5OnZhcigtLW1kLW1lcm1haWQtZm9udC1mYW1pbHkpfS5jbGFzc0xhYmVsIC5ib3h7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLWxhYmVsLWJnLWNvbG9yKTtiYWNrZ3JvdW5kLWNvbG9yOnZhcigtLW1kLW1lcm1haWQtbGFiZWwtYmctY29sb3IpO29wYWNpdHk6MX0uY2xhc3NMYWJlbCAubGFiZWx7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLWxhYmVsLWZnLWNvbG9yKTtmb250LWZhbWlseTp2YXIoLS1tZC1tZXJtYWlkLWZvbnQtZmFtaWx5KX0ubm9kZSAuZGl2aWRlcntzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1ub2RlLWZnLWNvbG9yKX0ucmVsYXRpb257c3Ryb2tlOnZhcigtLW1kLW1lcm1haWQtZWRnZS1jb2xvcil9LmNhcmRpbmFsaXR5e2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1sYWJlbC1mZy1jb2xvcik7Zm9udC1mYW1pbHk6dmFyKC0tbWQtbWVybWFpZC1mb250LWZhbWlseSl9LmNhcmRpbmFsaXR5IHRleHR7ZmlsbDppbmhlcml0IWltcG9ydGFudH1kZWZzIG1hcmtlci5tYXJrZXIuY29tcG9zaXRpb24uY2xhc3MgcGF0aCxkZWZzIG1hcmtlci5tYXJrZXIuZGVwZW5kZW5jeS5jbGFzcyBwYXRoLGRlZnMgbWFya2VyLm1hcmtlci5leHRlbnNpb24uY2xhc3MgcGF0aHtmaWxsOnZhcigtLW1kLW1lcm1haWQtZWRnZS1jb2xvcikhaW1wb3J0YW50O3N0cm9rZTp2YXIoLS1tZC1tZXJtYWlkLWVkZ2UtY29sb3IpIWltcG9ydGFudH1kZWZzIG1hcmtlci5tYXJrZXIuYWdncmVnYXRpb24uY2xhc3MgcGF0aHtmaWxsOnZhcigtLW1kLW1lcm1haWQtbGFiZWwtYmctY29sb3IpIWltcG9ydGFudDtzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1lZGdlLWNvbG9yKSFpbXBvcnRhbnR9LnN0YXRlZGlhZ3JhbVRpdGxlVGV4dHtmaWxsOnZhcigtLW1kLW1lcm1haWQtbGFiZWwtZmctY29sb3IpfWcuc3RhdGVHcm91cCByZWN0e2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1ub2RlLWJnLWNvbG9yKTtzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1ub2RlLWZnLWNvbG9yKX1nLnN0YXRlR3JvdXAgLnN0YXRlLXRpdGxle2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1sYWJlbC1mZy1jb2xvcikhaW1wb3J0YW50O2ZvbnQtZmFtaWx5OnZhcigtLW1kLW1lcm1haWQtZm9udC1mYW1pbHkpfWcuc3RhdGVHcm91cCAuY29tcG9zaXR7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLWxhYmVsLWJnLWNvbG9yKX0ubm9kZUxhYmVsLC5ub2RlTGFiZWwgcHtjb2xvcjp2YXIoLS1tZC1tZXJtYWlkLWxhYmVsLWZnLWNvbG9yKTtmb250LWZhbWlseTp2YXIoLS1tZC1tZXJtYWlkLWZvbnQtZmFtaWx5KX1hIC5ub2RlTGFiZWx7dGV4dC1kZWNvcmF0aW9uOnVuZGVybGluZX0ubm9kZSBjaXJjbGUuc3RhdGUtZW5kLC5ub2RlIGNpcmNsZS5zdGF0ZS1zdGFydCwuc3RhcnQtc3RhdGV7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLWVkZ2UtY29sb3IpO3N0cm9rZTpub25lfS5lbmQtc3RhdGUtaW5uZXIsLmVuZC1zdGF0ZS1vdXRlcntmaWxsOnZhcigtLW1kLW1lcm1haWQtZWRnZS1jb2xvcil9LmVuZC1zdGF0ZS1pbm5lciwubm9kZSBjaXJjbGUuc3RhdGUtZW5ke3N0cm9rZTp2YXIoLS1tZC1tZXJtYWlkLWxhYmVsLWJnLWNvbG9yKX0udHJhbnNpdGlvbntzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1lZGdlLWNvbG9yKX1baWRePXN0YXRlLWZvcmtdIHJlY3QsW2lkXj1zdGF0ZS1qb2luXSByZWN0e2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1lZGdlLWNvbG9yKSFpbXBvcnRhbnQ7c3Ryb2tlOm5vbmUhaW1wb3J0YW50fS5zdGF0ZWRpYWdyYW0tY2x1c3Rlci5zdGF0ZWRpYWdyYW0tY2x1c3RlciAuaW5uZXJ7ZmlsbDp2YXIoLS1tZC1kZWZhdWx0LWJnLWNvbG9yKX0uc3RhdGVkaWFncmFtLWNsdXN0ZXIgcmVjdHtmaWxsOnZhcigtLW1kLW1lcm1haWQtbm9kZS1iZy1jb2xvcik7c3Ryb2tlOnZhcigtLW1kLW1lcm1haWQtbm9kZS1mZy1jb2xvcil9LnN0YXRlZGlhZ3JhbS1zdGF0ZSByZWN0LmRpdmlkZXJ7ZmlsbDp2YXIoLS1tZC1kZWZhdWx0LWZnLWNvbG9yLS1saWdodGVzdCk7c3Ryb2tlOnZhcigtLW1kLWRlZmF1bHQtZmctY29sb3ItLWxpZ2h0ZXIpfWRlZnMgI3N0YXRlZGlhZ3JhbS1iYXJiRW5ke3N0cm9rZTp2YXIoLS1tZC1tZXJtYWlkLWVkZ2UtY29sb3IpfVtpZF49ZW50aXR5XSBwYXRoLFtpZF49ZW50aXR5XSByZWN0e2ZpbGw6dmFyKC0tbWQtZGVmYXVsdC1iZy1jb2xvcil9LnJlbGF0aW9uc2hpcExpbmV7c3Ryb2tlOnZhcigtLW1kLW1lcm1haWQtZWRnZS1jb2xvcil9ZGVmcyAubWFya2VyLm9uZU9yTW9yZS5lciAqLGRlZnMgLm1hcmtlci5vbmx5T25lLmVyICosZGVmcyAubWFya2VyLnplcm9Pck1vcmUuZXIgKixkZWZzIC5tYXJrZXIuemVyb09yT25lLmVyICp7c3Ryb2tlOnZhcigtLW1kLW1lcm1haWQtZWRnZS1jb2xvcikhaW1wb3J0YW50fXRleHQ6bm90KFtjbGFzc10pOmxhc3QtY2hpbGR7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLWxhYmVsLWZnLWNvbG9yKX0uYWN0b3J7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLXNlcXVlbmNlLWFjdG9yLWJnLWNvbG9yKTtzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1hY3Rvci1ib3JkZXItY29sb3IpfXRleHQuYWN0b3I+dHNwYW57ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLXNlcXVlbmNlLWFjdG9yLWZnLWNvbG9yKTtmb250LWZhbWlseTp2YXIoLS1tZC1tZXJtYWlkLWZvbnQtZmFtaWx5KX1saW5le3N0cm9rZTp2YXIoLS1tZC1tZXJtYWlkLXNlcXVlbmNlLWFjdG9yLWxpbmUtY29sb3IpfS5hY3Rvci1tYW4gY2lyY2xlLC5hY3Rvci1tYW4gbGluZXtmaWxsOnZhcigtLW1kLW1lcm1haWQtc2VxdWVuY2UtYWN0b3JtYW4tYmctY29sb3IpO3N0cm9rZTp2YXIoLS1tZC1tZXJtYWlkLXNlcXVlbmNlLWFjdG9ybWFuLWxpbmUtY29sb3IpfS5tZXNzYWdlTGluZTAsLm1lc3NhZ2VMaW5lMXtzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1tZXNzYWdlLWxpbmUtY29sb3IpfS5ub3Rle2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1ub3RlLWJnLWNvbG9yKTtzdHJva2U6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1ub3RlLWJvcmRlci1jb2xvcil9Lmxvb3BUZXh0LC5sb29wVGV4dD50c3BhbiwubWVzc2FnZVRleHQsLm5vdGVUZXh0PnRzcGFue3N0cm9rZTpub25lO2ZvbnQtZmFtaWx5OnZhcigtLW1kLW1lcm1haWQtZm9udC1mYW1pbHkpIWltcG9ydGFudH0ubWVzc2FnZVRleHR7ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLXNlcXVlbmNlLW1lc3NhZ2UtZmctY29sb3IpfS5sb29wVGV4dCwubG9vcFRleHQ+dHNwYW57ZmlsbDp2YXIoLS1tZC1tZXJtYWlkLXNlcXVlbmNlLWxvb3AtZmctY29sb3IpfS5ub3RlVGV4dD50c3BhbntmaWxsOnZhcigtLW1kLW1lcm1haWQtc2VxdWVuY2Utbm90ZS1mZy1jb2xvcil9I2Fycm93aGVhZCBwYXRoe2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1tZXNzYWdlLWxpbmUtY29sb3IpO3N0cm9rZTpub25lfS5sb29wTGluZXtmaWxsOnZhcigtLW1kLW1lcm1haWQtc2VxdWVuY2UtbG9vcC1iZy1jb2xvcik7c3Ryb2tlOnZhcigtLW1kLW1lcm1haWQtc2VxdWVuY2UtbG9vcC1ib3JkZXItY29sb3IpfS5sYWJlbEJveHtmaWxsOnZhcigtLW1kLW1lcm1haWQtc2VxdWVuY2UtbGFiZWwtYmctY29sb3IpO3N0cm9rZTpub25lfS5sYWJlbFRleHQsLmxhYmVsVGV4dD5zcGFue2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1sYWJlbC1mZy1jb2xvcik7Zm9udC1mYW1pbHk6dmFyKC0tbWQtbWVybWFpZC1mb250LWZhbWlseSl9LnNlcXVlbmNlTnVtYmVye2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1udW1iZXItZmctY29sb3IpfXJlY3QucmVjdHtmaWxsOnZhcigtLW1kLW1lcm1haWQtc2VxdWVuY2UtYm94LWJnLWNvbG9yKTtzdHJva2U6bm9uZX1yZWN0LnJlY3QrdGV4dC50ZXh0e2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1ib3gtZmctY29sb3IpfWRlZnMgI3NlcXVlbmNlbnVtYmVye2ZpbGw6dmFyKC0tbWQtbWVybWFpZC1zZXF1ZW5jZS1udW1iZXItYmctY29sb3IpIWltcG9ydGFudH0iO3ZhciBzbyxpcz0wO2Z1bmN0aW9uIGFzKCl7cmV0dXJuIHR5cGVvZiBtZXJtYWlkPT0idW5kZWZpbmVkInx8bWVybWFpZCBpbnN0YW5jZW9mIEVsZW1lbnQ/X3QoImh0dHBzOi8vdW5wa2cuY29tL21lcm1haWRAMTEvZGlzdC9tZXJtYWlkLm1pbi5qcyIpOiQodm9pZCAwKX1mdW5jdGlvbiBabihlKXtyZXR1cm4gZS5jbGFzc0xpc3QucmVtb3ZlKCJtZXJtYWlkIiksc298fChzbz1hcygpLnBpcGUoTygoKT0+bWVybWFpZC5pbml0aWFsaXplKHtzdGFydE9uTG9hZDohMSx0aGVtZUNTUzpYbixzZXF1ZW5jZTp7YWN0b3JGb250U2l6ZToiMTZweCIsbWVzc2FnZUZvbnRTaXplOiIxNnB4Iixub3RlRm9udFNpemU6IjE2cHgifX0pKSxtKCgpPT57fSksWigxKSkpLHNvLnN1YnNjcmliZSgoKT0+Z28obnVsbCxudWxsLGZ1bmN0aW9uKigpe2UuY2xhc3NMaXN0LmFkZCgibWVybWFpZCIpO2xldCB0PWBfX21lcm1haWRfJHtpcysrfWAscj14KCJkaXYiLHtjbGFzczoibWVybWFpZCJ9KSxvPWUudGV4dENvbnRlbnQse3N2ZzpuLGZuOml9PXlpZWxkIG1lcm1haWQucmVuZGVyKHQsbykscz1yLmF0dGFjaFNoYWRvdyh7bW9kZToiY2xvc2VkIn0pO3MuaW5uZXJIVE1MPW4sZS5yZXBsYWNlV2l0aChyKSxpPT1udWxsfHxpKHMpfSkpLHNvLnBpcGUobSgoKT0+KHtyZWY6ZX0pKSl9dmFyIGVpPXgoInRhYmxlIik7ZnVuY3Rpb24gdGkoZSl7cmV0dXJuIGUucmVwbGFjZVdpdGgoZWkpLGVpLnJlcGxhY2VXaXRoKFVuKGUpKSwkKHtyZWY6ZX0pfWZ1bmN0aW9uIHNzKGUpe2xldCB0PWUuZmluZChyPT5yLmNoZWNrZWQpfHxlWzBdO3JldHVybiBMKC4uLmUubWFwKHI9PmgociwiY2hhbmdlIikucGlwZShtKCgpPT5qKGBsYWJlbFtmb3I9IiR7ci5pZH0iXWApKSkpKS5waXBlKFEoaihgbGFiZWxbZm9yPSIke3QuaWR9Il1gKSksbShyPT4oe2FjdGl2ZTpyfSkpKX1mdW5jdGlvbiByaShlLHt2aWV3cG9ydCQ6dCx0YXJnZXQkOnJ9KXtsZXQgbz1qKCIudGFiYmVkLWxhYmVscyIsZSksbj1NKCI6c2NvcGUgPiBpbnB1dCIsZSksaT1ubygicHJldiIpO2UuYXBwZW5kKGkpO2xldCBzPW5vKCJuZXh0Iik7cmV0dXJuIGUuYXBwZW5kKHMpLEgoKCk9PntsZXQgYT1uZXcgVCxjPWEucGlwZShvZSgpLGFlKCEwKSk7eihbYSxMZShlKSxtdChlKV0pLnBpcGUoVyhjKSwkZSgxLHllKSkuc3Vic2NyaWJlKHtuZXh0KFt7YWN0aXZlOnB9LGxdKXtsZXQgZj1CZShwKSx7d2lkdGg6dX09ZGUocCk7ZS5zdHlsZS5zZXRQcm9wZXJ0eSgiLS1tZC1pbmRpY2F0b3IteCIsYCR7Zi54fXB4YCksZS5zdHlsZS5zZXRQcm9wZXJ0eSgiLS1tZC1pbmRpY2F0b3Itd2lkdGgiLGAke3V9cHhgKTtsZXQgZD1ncihvKTsoZi54PGQueHx8Zi54K3U+ZC54K2wud2lkdGgpJiZvLnNjcm9sbFRvKHtsZWZ0Ok1hdGgubWF4KDAsZi54LTE2KSxiZWhhdmlvcjoic21vb3RoIn0pfSxjb21wbGV0ZSgpe2Uuc3R5bGUucmVtb3ZlUHJvcGVydHkoIi0tbWQtaW5kaWNhdG9yLXgiKSxlLnN0eWxlLnJlbW92ZVByb3BlcnR5KCItLW1kLWluZGljYXRvci13aWR0aCIpfX0pLHooW0dlKG8pLExlKG8pXSkucGlwZShXKGMpKS5zdWJzY3JpYmUoKFtwLGxdKT0+e2xldCBmPUF0KG8pO2kuaGlkZGVuPXAueDwxNixzLmhpZGRlbj1wLng+Zi53aWR0aC1sLndpZHRoLTE2fSksTChoKGksImNsaWNrIikucGlwZShtKCgpPT4tMSkpLGgocywiY2xpY2siKS5waXBlKG0oKCk9PjEpKSkucGlwZShXKGMpKS5zdWJzY3JpYmUocD0+e2xldHt3aWR0aDpsfT1kZShvKTtvLnNjcm9sbEJ5KHtsZWZ0OmwqcCxiZWhhdmlvcjoic21vb3RoIn0pfSksci5waXBlKFcoYyksZyhwPT5uLmluY2x1ZGVzKHApKSkuc3Vic2NyaWJlKHA9PnAuY2xpY2soKSksby5jbGFzc0xpc3QuYWRkKCJ0YWJiZWQtbGFiZWxzLS1saW5rZWQiKTtmb3IobGV0IHAgb2Ygbil7bGV0IGw9aihgbGFiZWxbZm9yPSIke3AuaWR9Il1gKTtsLnJlcGxhY2VDaGlsZHJlbih4KCJhIix7aHJlZjpgIyR7bC5odG1sRm9yfWAsdGFiSW5kZXg6LTF9LC4uLkFycmF5LmZyb20obC5jaGlsZE5vZGVzKSkpLGgobC5maXJzdEVsZW1lbnRDaGlsZCwiY2xpY2siKS5waXBlKFcoYyksZyhmPT4hKGYubWV0YUtleXx8Zi5jdHJsS2V5KSksTyhmPT57Zi5wcmV2ZW50RGVmYXVsdCgpLGYuc3RvcFByb3BhZ2F0aW9uKCl9KSkuc3Vic2NyaWJlKCgpPT57aGlzdG9yeS5yZXBsYWNlU3RhdGUoe30sIiIsYCMke2wuaHRtbEZvcn1gKSxsLmNsaWNrKCl9KX1yZXR1cm4gVigiY29udGVudC50YWJzLmxpbmsiKSYmYS5waXBlKEllKDEpLHRlKHQpKS5zdWJzY3JpYmUoKFt7YWN0aXZlOnB9LHtvZmZzZXQ6bH1dKT0+e2xldCBmPXAuaW5uZXJUZXh0LnRyaW0oKTtpZihwLmhhc0F0dHJpYnV0ZSgiZGF0YS1tZC1zd2l0Y2hpbmciKSlwLnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1tZC1zd2l0Y2hpbmciKTtlbHNle2xldCB1PWUub2Zmc2V0VG9wLWwueTtmb3IobGV0IHYgb2YgTSgiW2RhdGEtdGFic10iKSlmb3IobGV0IFMgb2YgTSgiOnNjb3BlID4gaW5wdXQiLHYpKXtsZXQgWD1qKGBsYWJlbFtmb3I9IiR7Uy5pZH0iXWApO2lmKFghPT1wJiZYLmlubmVyVGV4dC50cmltKCk9PT1mKXtYLnNldEF0dHJpYnV0ZSgiZGF0YS1tZC1zd2l0Y2hpbmciLCIiKSxTLmNsaWNrKCk7YnJlYWt9fXdpbmRvdy5zY3JvbGxUbyh7dG9wOmUub2Zmc2V0VG9wLXV9KTtsZXQgZD1fX21kX2dldCgiX190YWJzIil8fFtdO19fbWRfc2V0KCJfX3RhYnMiLFsuLi5uZXcgU2V0KFtmLC4uLmRdKV0pfX0pLGEucGlwZShXKGMpKS5zdWJzY3JpYmUoKCk9Pntmb3IobGV0IHAgb2YgTSgiYXVkaW8sIHZpZGVvIixlKSlwLm9mZnNldFdpZHRoJiZwLmF1dG9wbGF5P3AucGxheSgpLmNhdGNoKCgpPT57fSk6cC5wYXVzZSgpfSksc3MobikucGlwZShPKHA9PmEubmV4dChwKSksQSgoKT0+YS5jb21wbGV0ZSgpKSxtKHA9PlAoe3JlZjplfSxwKSkpfSkucGlwZShldChwZSkpfWZ1bmN0aW9uIG9pKGUsdCl7bGV0e3ZpZXdwb3J0JDpyLHRhcmdldCQ6byxwcmludCQ6bn09dDtyZXR1cm4gTCguLi5NKCIuYW5ub3RhdGU6bm90KC5oaWdobGlnaHQpIixlKS5tYXAoaT0+em4oaSx7dGFyZ2V0JDpvLHByaW50JDpufSkpLC4uLk0oInByZTpub3QoLm1lcm1haWQpID4gY29kZSIsZSkubWFwKGk9PlluKGkse3RhcmdldCQ6byxwcmludCQ6bn0pKSwuLi5NKCJhIixlKS5tYXAoaT0+Sm4oaSx0KSksLi4uTSgicHJlLm1lcm1haWQiLGUpLm1hcChpPT5abihpKSksLi4uTSgidGFibGU6bm90KFtjbGFzc10pIixlKS5tYXAoaT0+dGkoaSkpLC4uLk0oImRldGFpbHMiLGUpLm1hcChpPT5CbihpLHt0YXJnZXQkOm8scHJpbnQkOm59KSksLi4uTSgiW2RhdGEtdGFic10iLGUpLm1hcChpPT5yaShpLHt2aWV3cG9ydCQ6cix0YXJnZXQkOm99KSksLi4uTSgiW3RpdGxlXTpub3QoW2RhdGEtcHJldmlld10pIixlKS5maWx0ZXIoKCk9PlYoImNvbnRlbnQudG9vbHRpcHMiKSkubWFwKGk9PlhlKGkse3ZpZXdwb3J0JDpyfSkpLC4uLk0oIi5mb290bm90ZS1yZWYiLGUpLmZpbHRlcigoKT0+VigiY29udGVudC5mb290bm90ZS50b29sdGlwcyIpKS5tYXAoaT0+VnQoaSx7Y29udGVudCQ6bmV3IEYocz0+e2xldCBhPW5ldyBVUkwoaS5ocmVmKS5oYXNoLnNsaWNlKDEpLGM9QXJyYXkuZnJvbShkb2N1bWVudC5nZXRFbGVtZW50QnlJZChhKS5jbG9uZU5vZGUoITApLmNoaWxkcmVuKSxwPXdyKC4uLmMpO3JldHVybiBzLm5leHQocCksZG9jdW1lbnQuYm9keS5hcHBlbmQocCksKCk9PnAucmVtb3ZlKCl9KSx2aWV3cG9ydCQ6cn0pKSl9ZnVuY3Rpb24gY3MoZSx7YWxlcnQkOnR9KXtyZXR1cm4gdC5waXBlKGIocj0+TCgkKCEwKSwkKCExKS5waXBlKG50KDJlMykpKS5waXBlKG0obz0+KHttZXNzYWdlOnIsYWN0aXZlOm99KSkpKSl9ZnVuY3Rpb24gbmkoZSx0KXtsZXQgcj1qKCIubWQtdHlwZXNldCIsZSk7cmV0dXJuIEgoKCk9PntsZXQgbz1uZXcgVDtyZXR1cm4gby5zdWJzY3JpYmUoKHttZXNzYWdlOm4sYWN0aXZlOml9KT0+e2UuY2xhc3NMaXN0LnRvZ2dsZSgibWQtZGlhbG9nLS1hY3RpdmUiLGkpLHIudGV4dENvbnRlbnQ9bn0pLGNzKGUsdCkucGlwZShPKG49Pm8ubmV4dChuKSksQSgoKT0+by5jb21wbGV0ZSgpKSxtKG49PlAoe3JlZjplfSxuKSkpfSl9dmFyIHBzPTA7ZnVuY3Rpb24gbHMoZSx0KXtkb2N1bWVudC5ib2R5LmFwcGVuZChlKTtsZXR7d2lkdGg6cn09ZGUoZSk7ZS5zdHlsZS5zZXRQcm9wZXJ0eSgiLS1tZC10b29sdGlwLXdpZHRoIixgJHtyfXB4YCksZS5yZW1vdmUoKTtsZXQgbz12cih0KSxuPXR5cGVvZiBvIT0idW5kZWZpbmVkIj9HZShvKTokKHt4OjAseTowfSksaT1MKFllKHQpLGl0KHQpKS5waXBlKFkoKSk7cmV0dXJuIHooW2ksbl0pLnBpcGUobSgoW3MsYV0pPT57bGV0e3g6Yyx5OnB9PUJlKHQpLGw9ZGUodCksZj10LmNsb3Nlc3QoInRhYmxlIik7cmV0dXJuIGYmJnQucGFyZW50RWxlbWVudCYmKGMrPWYub2Zmc2V0TGVmdCt0LnBhcmVudEVsZW1lbnQub2Zmc2V0TGVmdCxwKz1mLm9mZnNldFRvcCt0LnBhcmVudEVsZW1lbnQub2Zmc2V0VG9wKSx7YWN0aXZlOnMsb2Zmc2V0Ont4OmMtYS54K2wud2lkdGgvMi1yLzIseTpwLWEueStsLmhlaWdodCs4fX19KSl9ZnVuY3Rpb24gaWkoZSl7bGV0IHQ9ZS50aXRsZTtpZighdC5sZW5ndGgpcmV0dXJuIHk7bGV0IHI9YF9fdG9vbHRpcF8ke3BzKyt9YCxvPUR0KHIsImlubGluZSIpLG49aigiLm1kLXR5cGVzZXQiLG8pO3JldHVybiBuLmlubmVySFRNTD10LEgoKCk9PntsZXQgaT1uZXcgVDtyZXR1cm4gaS5zdWJzY3JpYmUoe25leHQoe29mZnNldDpzfSl7by5zdHlsZS5zZXRQcm9wZXJ0eSgiLS1tZC10b29sdGlwLXgiLGAke3MueH1weGApLG8uc3R5bGUuc2V0UHJvcGVydHkoIi0tbWQtdG9vbHRpcC15IixgJHtzLnl9cHhgKX0sY29tcGxldGUoKXtvLnN0eWxlLnJlbW92ZVByb3BlcnR5KCItLW1kLXRvb2x0aXAteCIpLG8uc3R5bGUucmVtb3ZlUHJvcGVydHkoIi0tbWQtdG9vbHRpcC15Iil9fSksTChpLnBpcGUoZygoe2FjdGl2ZTpzfSk9PnMpKSxpLnBpcGUoQWUoMjUwKSxnKCh7YWN0aXZlOnN9KT0+IXMpKSkuc3Vic2NyaWJlKHtuZXh0KHthY3RpdmU6c30pe3M/KGUuaW5zZXJ0QWRqYWNlbnRFbGVtZW50KCJhZnRlcmVuZCIsbyksZS5zZXRBdHRyaWJ1dGUoImFyaWEtZGVzY3JpYmVkYnkiLHIpLGUucmVtb3ZlQXR0cmlidXRlKCJ0aXRsZSIpKTooby5yZW1vdmUoKSxlLnJlbW92ZUF0dHJpYnV0ZSgiYXJpYS1kZXNjcmliZWRieSIpLGUuc2V0QXR0cmlidXRlKCJ0aXRsZSIsdCkpfSxjb21wbGV0ZSgpe28ucmVtb3ZlKCksZS5yZW1vdmVBdHRyaWJ1dGUoImFyaWEtZGVzY3JpYmVkYnkiKSxlLnNldEF0dHJpYnV0ZSgidGl0bGUiLHQpfX0pLGkucGlwZSgkZSgxNix5ZSkpLnN1YnNjcmliZSgoe2FjdGl2ZTpzfSk9PntvLmNsYXNzTGlzdC50b2dnbGUoIm1kLXRvb2x0aXAtLWFjdGl2ZSIscyl9KSxpLnBpcGUoZ3QoMTI1LHllKSxnKCgpPT4hIWUub2Zmc2V0UGFyZW50KSxtKCgpPT5lLm9mZnNldFBhcmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSksbSgoe3g6c30pPT5zKSkuc3Vic2NyaWJlKHtuZXh0KHMpe3M/by5zdHlsZS5zZXRQcm9wZXJ0eSgiLS1tZC10b29sdGlwLTAiLGAkey1zfXB4YCk6by5zdHlsZS5yZW1vdmVQcm9wZXJ0eSgiLS1tZC10b29sdGlwLTAiKX0sY29tcGxldGUoKXtvLnN0eWxlLnJlbW92ZVByb3BlcnR5KCItLW1kLXRvb2x0aXAtMCIpfX0pLGxzKG8sZSkucGlwZShPKHM9PmkubmV4dChzKSksQSgoKT0+aS5jb21wbGV0ZSgpKSxtKHM9PlAoe3JlZjplfSxzKSkpfSkucGlwZShldChwZSkpfWZ1bmN0aW9uIG1zKHt2aWV3cG9ydCQ6ZX0pe2lmKCFWKCJoZWFkZXIuYXV0b2hpZGUiKSlyZXR1cm4gJCghMSk7bGV0IHQ9ZS5waXBlKG0oKHtvZmZzZXQ6e3k6bn19KT0+biksb3QoMiwxKSxtKChbbixpXSk9PltuPGksaV0pLG5lKDApKSxyPXooW2UsdF0pLnBpcGUoZygoW3tvZmZzZXQ6bn0sWyxpXV0pPT5NYXRoLmFicyhpLW4ueSk+MTAwKSxtKChbLFtuXV0pPT5uKSxZKCkpLG89SmUoInNlYXJjaCIpO3JldHVybiB6KFtlLG9dKS5waXBlKG0oKFt7b2Zmc2V0Om59LGldKT0+bi55PjQwMCYmIWkpLFkoKSxiKG49Pm4/cjokKCExKSksUSghMSkpfWZ1bmN0aW9uIGFpKGUsdCl7cmV0dXJuIEgoKCk9PnooW0xlKGUpLG1zKHQpXSkpLnBpcGUobSgoW3toZWlnaHQ6cn0sb10pPT4oe2hlaWdodDpyLGhpZGRlbjpvfSkpLFkoKHIsbyk9PnIuaGVpZ2h0PT09by5oZWlnaHQmJnIuaGlkZGVuPT09by5oaWRkZW4pLFooMSkpfWZ1bmN0aW9uIHNpKGUse2hlYWRlciQ6dCxtYWluJDpyfSl7cmV0dXJuIEgoKCk9PntsZXQgbz1uZXcgVCxuPW8ucGlwZShvZSgpLGFlKCEwKSk7by5waXBlKG5lKCJhY3RpdmUiKSxQZSh0KSkuc3Vic2NyaWJlKChbe2FjdGl2ZTpzfSx7aGlkZGVuOmF9XSk9PntlLmNsYXNzTGlzdC50b2dnbGUoIm1kLWhlYWRlci0tc2hhZG93IixzJiYhYSksZS5oaWRkZW49YX0pO2xldCBpPWZlKE0oIlt0aXRsZV0iLGUpKS5waXBlKGcoKCk9PlYoImNvbnRlbnQudG9vbHRpcHMiKSksSihzPT5paShzKSkpO3JldHVybiByLnN1YnNjcmliZShvKSx0LnBpcGUoVyhuKSxtKHM9PlAoe3JlZjplfSxzKSksVmUoaS5waXBlKFcobikpKSl9KX1mdW5jdGlvbiBmcyhlLHt2aWV3cG9ydCQ6dCxoZWFkZXIkOnJ9KXtyZXR1cm4gRXIoZSx7dmlld3BvcnQkOnQsaGVhZGVyJDpyfSkucGlwZShtKCh7b2Zmc2V0Ont5Om99fSk9PntsZXR7aGVpZ2h0Om59PWRlKGUpO3JldHVybnthY3RpdmU6bj4wJiZvPj1ufX0pLG5lKCJhY3RpdmUiKSl9ZnVuY3Rpb24gY2koZSx0KXtyZXR1cm4gSCgoKT0+e2xldCByPW5ldyBUO3Iuc3Vic2NyaWJlKHtuZXh0KHthY3RpdmU6bn0pe2UuY2xhc3NMaXN0LnRvZ2dsZSgibWQtaGVhZGVyX190aXRsZS0tYWN0aXZlIixuKX0sY29tcGxldGUoKXtlLmNsYXNzTGlzdC5yZW1vdmUoIm1kLWhlYWRlcl9fdGl0bGUtLWFjdGl2ZSIpfX0pO2xldCBvPXVlKCIubWQtY29udGVudCBoMSIpO3JldHVybiB0eXBlb2Ygbz09InVuZGVmaW5lZCI/eTpmcyhvLHQpLnBpcGUoTyhuPT5yLm5leHQobikpLEEoKCk9PnIuY29tcGxldGUoKSksbShuPT5QKHtyZWY6ZX0sbikpKX0pfWZ1bmN0aW9uIHBpKGUse3ZpZXdwb3J0JDp0LGhlYWRlciQ6cn0pe2xldCBvPXIucGlwZShtKCh7aGVpZ2h0Oml9KT0+aSksWSgpKSxuPW8ucGlwZShiKCgpPT5MZShlKS5waXBlKG0oKHtoZWlnaHQ6aX0pPT4oe3RvcDplLm9mZnNldFRvcCxib3R0b206ZS5vZmZzZXRUb3AraX0pKSxuZSgiYm90dG9tIikpKSk7cmV0dXJuIHooW28sbix0XSkucGlwZShtKChbaSx7dG9wOnMsYm90dG9tOmF9LHtvZmZzZXQ6e3k6Y30sc2l6ZTp7aGVpZ2h0OnB9fV0pPT4ocD1NYXRoLm1heCgwLHAtTWF0aC5tYXgoMCxzLWMsaSktTWF0aC5tYXgoMCxwK2MtYSkpLHtvZmZzZXQ6cy1pLGhlaWdodDpwLGFjdGl2ZTpzLWk8PWN9KSksWSgoaSxzKT0+aS5vZmZzZXQ9PT1zLm9mZnNldCYmaS5oZWlnaHQ9PT1zLmhlaWdodCYmaS5hY3RpdmU9PT1zLmFjdGl2ZSkpfWZ1bmN0aW9uIHVzKGUpe2xldCB0PV9fbWRfZ2V0KCJfX3BhbGV0dGUiKXx8e2luZGV4OmUuZmluZEluZGV4KG89Pm1hdGNoTWVkaWEoby5nZXRBdHRyaWJ1dGUoImRhdGEtbWQtY29sb3ItbWVkaWEiKSkubWF0Y2hlcyl9LHI9TWF0aC5tYXgoMCxNYXRoLm1pbih0LmluZGV4LGUubGVuZ3RoLTEpKTtyZXR1cm4gJCguLi5lKS5waXBlKEoobz0+aChvLCJjaGFuZ2UiKS5waXBlKG0oKCk9Pm8pKSksUShlW3JdKSxtKG89Pih7aW5kZXg6ZS5pbmRleE9mKG8pLGNvbG9yOnttZWRpYTpvLmdldEF0dHJpYnV0ZSgiZGF0YS1tZC1jb2xvci1tZWRpYSIpLHNjaGVtZTpvLmdldEF0dHJpYnV0ZSgiZGF0YS1tZC1jb2xvci1zY2hlbWUiKSxwcmltYXJ5Om8uZ2V0QXR0cmlidXRlKCJkYXRhLW1kLWNvbG9yLXByaW1hcnkiKSxhY2NlbnQ6by5nZXRBdHRyaWJ1dGUoImRhdGEtbWQtY29sb3ItYWNjZW50Iil9fSkpLFooMSkpfWZ1bmN0aW9uIGxpKGUpe2xldCB0PU0oImlucHV0IixlKSxyPXgoIm1ldGEiLHtuYW1lOiJ0aGVtZS1jb2xvciJ9KTtkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHIpO2xldCBvPXgoIm1ldGEiLHtuYW1lOiJjb2xvci1zY2hlbWUifSk7ZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChvKTtsZXQgbj1XdCgiKHByZWZlcnMtY29sb3Itc2NoZW1lOiBsaWdodCkiKTtyZXR1cm4gSCgoKT0+e2xldCBpPW5ldyBUO3JldHVybiBpLnN1YnNjcmliZShzPT57aWYoZG9jdW1lbnQuYm9keS5zZXRBdHRyaWJ1dGUoImRhdGEtbWQtY29sb3Itc3dpdGNoaW5nIiwiIikscy5jb2xvci5tZWRpYT09PSIocHJlZmVycy1jb2xvci1zY2hlbWUpIil7bGV0IGE9bWF0Y2hNZWRpYSgiKHByZWZlcnMtY29sb3Itc2NoZW1lOiBsaWdodCkiKSxjPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYS5tYXRjaGVzPyJbZGF0YS1tZC1jb2xvci1tZWRpYT0nKHByZWZlcnMtY29sb3Itc2NoZW1lOiBsaWdodCknXSI6IltkYXRhLW1kLWNvbG9yLW1lZGlhPScocHJlZmVycy1jb2xvci1zY2hlbWU6IGRhcmspJ10iKTtzLmNvbG9yLnNjaGVtZT1jLmdldEF0dHJpYnV0ZSgiZGF0YS1tZC1jb2xvci1zY2hlbWUiKSxzLmNvbG9yLnByaW1hcnk9Yy5nZXRBdHRyaWJ1dGUoImRhdGEtbWQtY29sb3ItcHJpbWFyeSIpLHMuY29sb3IuYWNjZW50PWMuZ2V0QXR0cmlidXRlKCJkYXRhLW1kLWNvbG9yLWFjY2VudCIpfWZvcihsZXRbYSxjXW9mIE9iamVjdC5lbnRyaWVzKHMuY29sb3IpKWRvY3VtZW50LmJvZHkuc2V0QXR0cmlidXRlKGBkYXRhLW1kLWNvbG9yLSR7YX1gLGMpO2ZvcihsZXQgYT0wO2E8dC5sZW5ndGg7YSsrKXtsZXQgYz10W2FdLm5leHRFbGVtZW50U2libGluZztjIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQmJihjLmhpZGRlbj1zLmluZGV4IT09YSl9X19tZF9zZXQoIl9fcGFsZXR0ZSIscyl9KSxoKGUsImtleWRvd24iKS5waXBlKGcocz0+cy5rZXk9PT0iRW50ZXIiKSx0ZShpLChzLGEpPT5hKSkuc3Vic2NyaWJlKCh7aW5kZXg6c30pPT57cz0ocysxKSV0Lmxlbmd0aCx0W3NdLmNsaWNrKCksdFtzXS5mb2N1cygpfSksaS5waXBlKG0oKCk9PntsZXQgcz1DZSgiaGVhZGVyIiksYT13aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShzKTtyZXR1cm4gby5jb250ZW50PWEuY29sb3JTY2hlbWUsYS5iYWNrZ3JvdW5kQ29sb3IubWF0Y2goL1xkKy9nKS5tYXAoYz0+KCtjKS50b1N0cmluZygxNikucGFkU3RhcnQoMiwiMCIpKS5qb2luKCIiKX0pKS5zdWJzY3JpYmUocz0+ci5jb250ZW50PWAjJHtzfWApLGkucGlwZSh4ZShwZSkpLnN1YnNjcmliZSgoKT0+e2RvY3VtZW50LmJvZHkucmVtb3ZlQXR0cmlidXRlKCJkYXRhLW1kLWNvbG9yLXN3aXRjaGluZyIpfSksdXModCkucGlwZShXKG4ucGlwZShJZSgxKSkpLHZ0KCksTyhzPT5pLm5leHQocykpLEEoKCk9PmkuY29tcGxldGUoKSksbShzPT5QKHtyZWY6ZX0scykpKX0pfWZ1bmN0aW9uIG1pKGUse3Byb2dyZXNzJDp0fSl7cmV0dXJuIEgoKCk9PntsZXQgcj1uZXcgVDtyZXR1cm4gci5zdWJzY3JpYmUoKHt2YWx1ZTpvfSk9PntlLnN0eWxlLnNldFByb3BlcnR5KCItLW1kLXByb2dyZXNzLXZhbHVlIixgJHtvfWApfSksdC5waXBlKE8obz0+ci5uZXh0KHt2YWx1ZTpvfSkpLEEoKCk9PnIuY29tcGxldGUoKSksbShvPT4oe3JlZjplLHZhbHVlOm99KSkpfSl9ZnVuY3Rpb24gZmkoZSx0KXtyZXR1cm4gZS5wcm90b2NvbD10LnByb3RvY29sLGUuaG9zdG5hbWU9dC5ob3N0bmFtZSxlfWZ1bmN0aW9uIGRzKGUsdCl7bGV0IHI9bmV3IE1hcDtmb3IobGV0IG8gb2YgTSgidXJsIixlKSl7bGV0IG49aigibG9jIixvKSxpPVtmaShuZXcgVVJMKG4udGV4dENvbnRlbnQpLHQpXTtyLnNldChgJHtpWzBdfWAsaSk7Zm9yKGxldCBzIG9mIE0oIltyZWw9YWx0ZXJuYXRlXSIsbykpe2xldCBhPXMuZ2V0QXR0cmlidXRlKCJocmVmIik7YSE9bnVsbCYmaS5wdXNoKGZpKG5ldyBVUkwoYSksdCkpfX1yZXR1cm4gcn1mdW5jdGlvbiBrdChlKXtyZXR1cm4gRW4obmV3IFVSTCgic2l0ZW1hcC54bWwiLGUpKS5waXBlKG0odD0+ZHModCxuZXcgVVJMKGUpKSksdmUoKCk9PiQobmV3IE1hcCkpLGxlKCkpfWZ1bmN0aW9uIHVpKHtkb2N1bWVudCQ6ZX0pe2xldCB0PW5ldyBNYXA7ZS5waXBlKGIoKCk9Pk0oImxpbmtbcmVsPWFsdGVybmF0ZV0iKSksbShyPT5uZXcgVVJMKHIuaHJlZikpLGcocj0+IXQuaGFzKHIudG9TdHJpbmcoKSkpLEoocj0+a3QocikucGlwZShtKG89PltyLG9dKSx2ZSgoKT0+eSkpKSkuc3Vic2NyaWJlKChbcixvXSk9Pnt0LnNldChyLnRvU3RyaW5nKCkucmVwbGFjZSgvXC8kLywiIiksbyl9KSxoKGRvY3VtZW50LmJvZHksImNsaWNrIikucGlwZShnKHI9PiFyLm1ldGFLZXkmJiFyLmN0cmxLZXkpLGIocj0+e2lmKHIudGFyZ2V0IGluc3RhbmNlb2YgRWxlbWVudCl7bGV0IG89ci50YXJnZXQuY2xvc2VzdCgiYSIpO2lmKG8mJiFvLnRhcmdldCl7bGV0IG49Wy4uLnRdLmZpbmQoKFtmXSk9Pm8uaHJlZi5zdGFydHNXaXRoKGAke2Z9L2ApKTtpZih0eXBlb2Ygbj09InVuZGVmaW5lZCIpcmV0dXJuIHk7bGV0W2ksc109bixhPXdlKCk7aWYoYS5ocmVmLnN0YXJ0c1dpdGgoaSkpcmV0dXJuIHk7bGV0IGM9VGUoKSxwPWEuaHJlZi5yZXBsYWNlKGMuYmFzZSwiIik7cD1gJHtpfS8ke3B9YDtsZXQgbD1zLmhhcyhwLnNwbGl0KCIjIilbMF0pP25ldyBVUkwocCxjLmJhc2UpOm5ldyBVUkwoaSk7cmV0dXJuIHIucHJldmVudERlZmF1bHQoKSwkKGwpfX1yZXR1cm4geX0pKS5zdWJzY3JpYmUocj0+c3QociwhMCkpfXZhciBjbz0kdChhbygpKTtmdW5jdGlvbiBocyhlKXtlLnNldEF0dHJpYnV0ZSgiZGF0YS1tZC1jb3B5aW5nIiwiIik7bGV0IHQ9ZS5jbG9zZXN0KCJbZGF0YS1jb3B5XSIpLHI9dD90LmdldEF0dHJpYnV0ZSgiZGF0YS1jb3B5Iik6ZS5pbm5lclRleHQ7cmV0dXJuIGUucmVtb3ZlQXR0cmlidXRlKCJkYXRhLW1kLWNvcHlpbmciKSxyLnRyaW1FbmQoKX1mdW5jdGlvbiBkaSh7YWxlcnQkOmV9KXtjby5kZWZhdWx0LmlzU3VwcG9ydGVkKCkmJm5ldyBGKHQ9PntuZXcgY28uZGVmYXVsdCgiW2RhdGEtY2xpcGJvYXJkLXRhcmdldF0sIFtkYXRhLWNsaXBib2FyZC10ZXh0XSIse3RleHQ6cj0+ci5nZXRBdHRyaWJ1dGUoImRhdGEtY2xpcGJvYXJkLXRleHQiKXx8aHMoaihyLmdldEF0dHJpYnV0ZSgiZGF0YS1jbGlwYm9hcmQtdGFyZ2V0IikpKX0pLm9uKCJzdWNjZXNzIixyPT50Lm5leHQocikpfSkucGlwZShPKHQ9Pnt0LnRyaWdnZXIuZm9jdXMoKX0pLG0oKCk9Pk1lKCJjbGlwYm9hcmQuY29waWVkIikpKS5zdWJzY3JpYmUoZSl9ZnVuY3Rpb24gaGkoZSx0KXtpZighKGUudGFyZ2V0IGluc3RhbmNlb2YgRWxlbWVudCkpcmV0dXJuIHk7bGV0IHI9ZS50YXJnZXQuY2xvc2VzdCgiYSIpO2lmKHI9PT1udWxsKXJldHVybiB5O2lmKHIudGFyZ2V0fHxlLm1ldGFLZXl8fGUuY3RybEtleSlyZXR1cm4geTtsZXQgbz1uZXcgVVJMKHIuaHJlZik7cmV0dXJuIG8uc2VhcmNoPW8uaGFzaD0iIix0LmhhcyhgJHtvfWApPyhlLnByZXZlbnREZWZhdWx0KCksJChyKSk6eX1mdW5jdGlvbiBiaShlKXtsZXQgdD1uZXcgTWFwO2ZvcihsZXQgciBvZiBNKCI6c2NvcGUgPiAqIixlLmhlYWQpKXQuc2V0KHIub3V0ZXJIVE1MLHIpO3JldHVybiB0fWZ1bmN0aW9uIHZpKGUpe2ZvcihsZXQgdCBvZiBNKCJbaHJlZl0sIFtzcmNdIixlKSlmb3IobGV0IHIgb2ZbImhyZWYiLCJzcmMiXSl7bGV0IG89dC5nZXRBdHRyaWJ1dGUocik7aWYobyYmIS9eKD86W2Etel0rOik/XC9cLy9pLnRlc3Qobykpe3Rbcl09dFtyXTticmVha319cmV0dXJuICQoZSl9ZnVuY3Rpb24gYnMoZSl7Zm9yKGxldCBvIG9mWyJbZGF0YS1tZC1jb21wb25lbnQ9YW5ub3VuY2VdIiwiW2RhdGEtbWQtY29tcG9uZW50PWNvbnRhaW5lcl0iLCJbZGF0YS1tZC1jb21wb25lbnQ9aGVhZGVyLXRvcGljXSIsIltkYXRhLW1kLWNvbXBvbmVudD1vdXRkYXRlZF0iLCJbZGF0YS1tZC1jb21wb25lbnQ9bG9nb10iLCJbZGF0YS1tZC1jb21wb25lbnQ9c2tpcF0iLC4uLlYoIm5hdmlnYXRpb24udGFicy5zdGlja3kiKT9bIltkYXRhLW1kLWNvbXBvbmVudD10YWJzXSJdOltdXSl7bGV0IG49dWUobyksaT11ZShvLGUpO3R5cGVvZiBuIT0idW5kZWZpbmVkIiYmdHlwZW9mIGkhPSJ1bmRlZmluZWQiJiZuLnJlcGxhY2VXaXRoKGkpfWxldCB0PWJpKGRvY3VtZW50KTtmb3IobGV0W28sbl1vZiBiaShlKSl0LmhhcyhvKT90LmRlbGV0ZShvKTpkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKG4pO2ZvcihsZXQgbyBvZiB0LnZhbHVlcygpKXtsZXQgbj1vLmdldEF0dHJpYnV0ZSgibmFtZSIpO24hPT0idGhlbWUtY29sb3IiJiZuIT09ImNvbG9yLXNjaGVtZSImJm8ucmVtb3ZlKCl9bGV0IHI9Q2UoImNvbnRhaW5lciIpO3JldHVybiBLZShNKCJzY3JpcHQiLHIpKS5waXBlKGIobz0+e2xldCBuPWUuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7aWYoby5zcmMpe2ZvcihsZXQgaSBvZiBvLmdldEF0dHJpYnV0ZU5hbWVzKCkpbi5zZXRBdHRyaWJ1dGUoaSxvLmdldEF0dHJpYnV0ZShpKSk7cmV0dXJuIG8ucmVwbGFjZVdpdGgobiksbmV3IEYoaT0+e24ub25sb2FkPSgpPT5pLmNvbXBsZXRlKCl9KX1lbHNlIHJldHVybiBuLnRleHRDb250ZW50PW8udGV4dENvbnRlbnQsby5yZXBsYWNlV2l0aChuKSx5fSksb2UoKSxhZShkb2N1bWVudCkpfWZ1bmN0aW9uIGdpKHtzaXRlbWFwJDplLGxvY2F0aW9uJDp0LHZpZXdwb3J0JDpyLHByb2dyZXNzJDpvfSl7aWYobG9jYXRpb24ucHJvdG9jb2w9PT0iZmlsZToiKXJldHVybiB5OyQoZG9jdW1lbnQpLnN1YnNjcmliZSh2aSk7bGV0IG49aChkb2N1bWVudC5ib2R5LCJjbGljayIpLnBpcGUoUGUoZSksYigoW2EsY10pPT5oaShhLGMpKSxtKCh7aHJlZjphfSk9Pm5ldyBVUkwoYSkpLGxlKCkpLGk9aCh3aW5kb3csInBvcHN0YXRlIikucGlwZShtKHdlKSxsZSgpKTtuLnBpcGUodGUocikpLnN1YnNjcmliZSgoW2Ese29mZnNldDpjfV0pPT57aGlzdG9yeS5yZXBsYWNlU3RhdGUoYywiIiksaGlzdG9yeS5wdXNoU3RhdGUobnVsbCwiIixhKX0pLEwobixpKS5zdWJzY3JpYmUodCk7bGV0IHM9dC5waXBlKG5lKCJwYXRobmFtZSIpLGIoYT0+eHIoYSx7cHJvZ3Jlc3MkOm99KS5waXBlKHZlKCgpPT4oc3QoYSwhMCkseSkpKSksYih2aSksYihicyksbGUoKSk7cmV0dXJuIEwocy5waXBlKHRlKHQsKGEsYyk9PmMpKSxzLnBpcGUoYigoKT0+dCksbmUoImhhc2giKSksdC5waXBlKFkoKGEsYyk9PmEucGF0aG5hbWU9PT1jLnBhdGhuYW1lJiZhLmhhc2g9PT1jLmhhc2gpLGIoKCk9Pm4pLE8oKCk9Pmhpc3RvcnkuYmFjaygpKSkpLnN1YnNjcmliZShhPT57dmFyIGMscDtoaXN0b3J5LnN0YXRlIT09bnVsbHx8IWEuaGFzaD93aW5kb3cuc2Nyb2xsVG8oMCwocD0oYz1oaXN0b3J5LnN0YXRlKT09bnVsbD92b2lkIDA6Yy55KSE9bnVsbD9wOjApOihoaXN0b3J5LnNjcm9sbFJlc3RvcmF0aW9uPSJhdXRvIixnbihhLmhhc2gpLGhpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb249Im1hbnVhbCIpfSksdC5zdWJzY3JpYmUoKCk9PntoaXN0b3J5LnNjcm9sbFJlc3RvcmF0aW9uPSJtYW51YWwifSksaCh3aW5kb3csImJlZm9yZXVubG9hZCIpLnN1YnNjcmliZSgoKT0+e2hpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb249ImF1dG8ifSksci5waXBlKG5lKCJvZmZzZXQiKSxBZSgxMDApKS5zdWJzY3JpYmUoKHtvZmZzZXQ6YX0pPT57aGlzdG9yeS5yZXBsYWNlU3RhdGUoYSwiIil9KSxWKCJuYXZpZ2F0aW9uLmluc3RhbnQucHJlZmV0Y2giKSYmTChoKGRvY3VtZW50LmJvZHksIm1vdXNlbW92ZSIpLGgoZG9jdW1lbnQuYm9keSwiZm9jdXNpbiIpKS5waXBlKFBlKGUpLGIoKFthLGNdKT0+aGkoYSxjKSksQWUoMjUpLFFyKCh7aHJlZjphfSk9PmEpLGhyKGE9PntsZXQgYz1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJsaW5rIik7cmV0dXJuIGMucmVsPSJwcmVmZXRjaCIsYy5ocmVmPWEudG9TdHJpbmcoKSxkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKGMpLGgoYywibG9hZCIpLnBpcGUobSgoKT0+YyksRWUoMSkpfSkpLnN1YnNjcmliZShhPT5hLnJlbW92ZSgpKSxzfXZhciB5aT0kdChybygpKTtmdW5jdGlvbiB4aShlKXtsZXQgdD1lLnNlcGFyYXRvci5zcGxpdCgifCIpLm1hcChuPT5uLnJlcGxhY2UoLyhcKFw/WyE9PF1bXildK1wpKS9nLCIiKS5sZW5ndGg9PT0wPyJcdUZGRkQiOm4pLmpvaW4oInwiKSxyPW5ldyBSZWdFeHAodCwiaW1nIiksbz0obixpLHMpPT5gJHtpfTxtYXJrIGRhdGEtbWQtaGlnaGxpZ2h0PiR7c308L21hcms+YDtyZXR1cm4gbj0+e249bi5yZXBsYWNlKC9bXHMqK1wtOn5eXSsvZywiICIpLnJlcGxhY2UoLyYvZywiJmFtcDsiKS50cmltKCk7bGV0IGk9bmV3IFJlZ0V4cChgKF58JHtlLnNlcGFyYXRvcn18KSgke24ucmVwbGFjZSgvW3xcXHt9KClbXF1eJCsqPy4tXS9nLCJcXCQmIikucmVwbGFjZShyLCJ8Iil9KWAsImltZyIpO3JldHVybiBzPT4oMCx5aS5kZWZhdWx0KShzKS5yZXBsYWNlKGksbykucmVwbGFjZSgvPFwvbWFyaz4oXHMrKTxtYXJrW14+XSo+L2ltZywiJDEiKX19ZnVuY3Rpb24genQoZSl7cmV0dXJuIGUudHlwZT09PTF9ZnVuY3Rpb24gU3IoZSl7cmV0dXJuIGUudHlwZT09PTN9ZnVuY3Rpb24gRWkoZSx0KXtsZXQgcj1NbihlKTtyZXR1cm4gTCgkKGxvY2F0aW9uLnByb3RvY29sIT09ImZpbGU6IiksSmUoInNlYXJjaCIpKS5waXBlKFJlKG89Pm8pLGIoKCk9PnQpKS5zdWJzY3JpYmUoKHtjb25maWc6byxkb2NzOm59KT0+ci5uZXh0KHt0eXBlOjAsZGF0YTp7Y29uZmlnOm8sZG9jczpuLG9wdGlvbnM6e3N1Z2dlc3Q6Vigic2VhcmNoLnN1Z2dlc3QiKX19fSkpLHJ9ZnVuY3Rpb24gd2koZSl7dmFyIGw7bGV0e3NlbGVjdGVkVmVyc2lvblNpdGVtYXA6dCxzZWxlY3RlZFZlcnNpb25CYXNlVVJMOnIsY3VycmVudExvY2F0aW9uOm8sY3VycmVudEJhc2VVUkw6bn09ZSxpPShsPXBvKG4pKT09bnVsbD92b2lkIDA6bC5wYXRobmFtZTtpZihpPT09dm9pZCAwKXJldHVybjtsZXQgcz15cyhvLnBhdGhuYW1lLGkpO2lmKHM9PT12b2lkIDApcmV0dXJuO2xldCBhPUVzKHQua2V5cygpKTtpZighdC5oYXMoYSkpcmV0dXJuO2xldCBjPXBvKHMsYSk7aWYoIWN8fCF0LmhhcyhjLmhyZWYpKXJldHVybjtsZXQgcD1wbyhzLHIpO2lmKHApcmV0dXJuIHAuaGFzaD1vLmhhc2gscC5zZWFyY2g9by5zZWFyY2gscH1mdW5jdGlvbiBwbyhlLHQpe3RyeXtyZXR1cm4gbmV3IFVSTChlLHQpfWNhdGNoKHIpe3JldHVybn19ZnVuY3Rpb24geXMoZSx0KXtpZihlLnN0YXJ0c1dpdGgodCkpcmV0dXJuIGUuc2xpY2UodC5sZW5ndGgpfWZ1bmN0aW9uIHhzKGUsdCl7bGV0IHI9TWF0aC5taW4oZS5sZW5ndGgsdC5sZW5ndGgpLG87Zm9yKG89MDtvPHImJmVbb109PT10W29dOysrbyk7cmV0dXJuIG99ZnVuY3Rpb24gRXMoZSl7bGV0IHQ7Zm9yKGxldCByIG9mIGUpdD09PXZvaWQgMD90PXI6dD10LnNsaWNlKDAseHModCxyKSk7cmV0dXJuIHQhPW51bGw/dDoiIn1mdW5jdGlvbiBUaSh7ZG9jdW1lbnQkOmV9KXtsZXQgdD1UZSgpLHI9emUobmV3IFVSTCgiLi4vdmVyc2lvbnMuanNvbiIsdC5iYXNlKSkucGlwZSh2ZSgoKT0+eSkpLG89ci5waXBlKG0obj0+e2xldFssaV09dC5iYXNlLm1hdGNoKC8oW14vXSspXC8/JC8pO3JldHVybiBuLmZpbmQoKHt2ZXJzaW9uOnMsYWxpYXNlczphfSk9PnM9PT1pfHxhLmluY2x1ZGVzKGkpKXx8blswXX0pKTtyLnBpcGUobShuPT5uZXcgTWFwKG4ubWFwKGk9PltgJHtuZXcgVVJMKGAuLi8ke2kudmVyc2lvbn0vYCx0LmJhc2UpfWAsaV0pKSksYihuPT5oKGRvY3VtZW50LmJvZHksImNsaWNrIikucGlwZShnKGk9PiFpLm1ldGFLZXkmJiFpLmN0cmxLZXkpLHRlKG8pLGIoKFtpLHNdKT0+e2lmKGkudGFyZ2V0IGluc3RhbmNlb2YgRWxlbWVudCl7bGV0IGE9aS50YXJnZXQuY2xvc2VzdCgiYSIpO2lmKGEmJiFhLnRhcmdldCYmbi5oYXMoYS5ocmVmKSl7bGV0IGM9YS5ocmVmO3JldHVybiFpLnRhcmdldC5jbG9zZXN0KCIubWQtdmVyc2lvbiIpJiZuLmdldChjKT09PXM/eTooaS5wcmV2ZW50RGVmYXVsdCgpLCQobmV3IFVSTChjKSkpfX1yZXR1cm4geX0pLGIoaT0+a3QoaSkucGlwZShtKHM9Pnt2YXIgYTtyZXR1cm4oYT13aSh7c2VsZWN0ZWRWZXJzaW9uU2l0ZW1hcDpzLHNlbGVjdGVkVmVyc2lvbkJhc2VVUkw6aSxjdXJyZW50TG9jYXRpb246d2UoKSxjdXJyZW50QmFzZVVSTDp0LmJhc2V9KSkhPW51bGw/YTppfSkpKSkpKS5zdWJzY3JpYmUobj0+c3QobiwhMCkpLHooW3Isb10pLnN1YnNjcmliZSgoW24saV0pPT57aigiLm1kLWhlYWRlcl9fdG9waWMiKS5hcHBlbmRDaGlsZChXbihuLGkpKX0pLGUucGlwZShiKCgpPT5vKSkuc3Vic2NyaWJlKG49Pnt2YXIgYTtsZXQgaT1uZXcgVVJMKHQuYmFzZSkscz1fX21kX2dldCgiX19vdXRkYXRlZCIsc2Vzc2lvblN0b3JhZ2UsaSk7aWYocz09PW51bGwpe3M9ITA7bGV0IGM9KChhPXQudmVyc2lvbik9PW51bGw/dm9pZCAwOmEuZGVmYXVsdCl8fCJsYXRlc3QiO0FycmF5LmlzQXJyYXkoYyl8fChjPVtjXSk7ZTpmb3IobGV0IHAgb2YgYylmb3IobGV0IGwgb2Ygbi5hbGlhc2VzLmNvbmNhdChuLnZlcnNpb24pKWlmKG5ldyBSZWdFeHAocCwiaSIpLnRlc3QobCkpe3M9ITE7YnJlYWsgZX1fX21kX3NldCgiX19vdXRkYXRlZCIscyxzZXNzaW9uU3RvcmFnZSxpKX1pZihzKWZvcihsZXQgYyBvZiBtZSgib3V0ZGF0ZWQiKSljLmhpZGRlbj0hMX0pfWZ1bmN0aW9uIHdzKGUse3dvcmtlciQ6dH0pe2xldHtzZWFyY2hQYXJhbXM6cn09d2UoKTtyLmhhcygicSIpJiYoYXQoInNlYXJjaCIsITApLGUudmFsdWU9ci5nZXQoInEiKSxlLmZvY3VzKCksSmUoInNlYXJjaCIpLnBpcGUoUmUoaT0+IWkpKS5zdWJzY3JpYmUoKCk9PntsZXQgaT13ZSgpO2kuc2VhcmNoUGFyYW1zLmRlbGV0ZSgicSIpLGhpc3RvcnkucmVwbGFjZVN0YXRlKHt9LCIiLGAke2l9YCl9KSk7bGV0IG89WWUoZSksbj1MKHQucGlwZShSZSh6dCkpLGgoZSwia2V5dXAiKSxvKS5waXBlKG0oKCk9PmUudmFsdWUpLFkoKSk7cmV0dXJuIHooW24sb10pLnBpcGUobSgoW2ksc10pPT4oe3ZhbHVlOmksZm9jdXM6c30pKSxaKDEpKX1mdW5jdGlvbiBTaShlLHt3b3JrZXIkOnR9KXtsZXQgcj1uZXcgVCxvPXIucGlwZShvZSgpLGFlKCEwKSk7eihbdC5waXBlKFJlKHp0KSkscl0sKGkscyk9PnMpLnBpcGUobmUoInZhbHVlIikpLnN1YnNjcmliZSgoe3ZhbHVlOml9KT0+dC5uZXh0KHt0eXBlOjIsZGF0YTppfSkpLHIucGlwZShuZSgiZm9jdXMiKSkuc3Vic2NyaWJlKCh7Zm9jdXM6aX0pPT57aSYmYXQoInNlYXJjaCIsaSl9KSxoKGUuZm9ybSwicmVzZXQiKS5waXBlKFcobykpLnN1YnNjcmliZSgoKT0+ZS5mb2N1cygpKTtsZXQgbj1qKCJoZWFkZXIgW2Zvcj1fX3NlYXJjaF0iKTtyZXR1cm4gaChuLCJjbGljayIpLnN1YnNjcmliZSgoKT0+ZS5mb2N1cygpKSx3cyhlLHt3b3JrZXIkOnR9KS5waXBlKE8oaT0+ci5uZXh0KGkpKSxBKCgpPT5yLmNvbXBsZXRlKCkpLG0oaT0+UCh7cmVmOmV9LGkpKSxaKDEpKX1mdW5jdGlvbiBPaShlLHt3b3JrZXIkOnQscXVlcnkkOnJ9KXtsZXQgbz1uZXcgVCxuPXVuKGUucGFyZW50RWxlbWVudCkucGlwZShnKEJvb2xlYW4pKSxpPWUucGFyZW50RWxlbWVudCxzPWooIjpzY29wZSA+IDpmaXJzdC1jaGlsZCIsZSksYT1qKCI6c2NvcGUgPiA6bGFzdC1jaGlsZCIsZSk7SmUoInNlYXJjaCIpLnN1YnNjcmliZShsPT57YS5zZXRBdHRyaWJ1dGUoInJvbGUiLGw/Imxpc3QiOiJwcmVzZW50YXRpb24iKSxhLmhpZGRlbj0hbH0pLG8ucGlwZSh0ZShyKSxHcih0LnBpcGUoUmUoenQpKSkpLnN1YnNjcmliZSgoW3tpdGVtczpsfSx7dmFsdWU6Zn1dKT0+e3N3aXRjaChsLmxlbmd0aCl7Y2FzZSAwOnMudGV4dENvbnRlbnQ9Zi5sZW5ndGg/TWUoInNlYXJjaC5yZXN1bHQubm9uZSIpOk1lKCJzZWFyY2gucmVzdWx0LnBsYWNlaG9sZGVyIik7YnJlYWs7Y2FzZSAxOnMudGV4dENvbnRlbnQ9TWUoInNlYXJjaC5yZXN1bHQub25lIik7YnJlYWs7ZGVmYXVsdDpsZXQgdT1icihsLmxlbmd0aCk7cy50ZXh0Q29udGVudD1NZSgic2VhcmNoLnJlc3VsdC5vdGhlciIsdSl9fSk7bGV0IGM9by5waXBlKE8oKCk9PmEuaW5uZXJIVE1MPSIiKSxiKCh7aXRlbXM6bH0pPT5MKCQoLi4ubC5zbGljZSgwLDEwKSksJCguLi5sLnNsaWNlKDEwKSkucGlwZShvdCg0KSxYcihuKSxiKChbZl0pPT5mKSkpKSxtKEZuKSxsZSgpKTtyZXR1cm4gYy5zdWJzY3JpYmUobD0+YS5hcHBlbmRDaGlsZChsKSksYy5waXBlKEoobD0+e2xldCBmPXVlKCJkZXRhaWxzIixsKTtyZXR1cm4gdHlwZW9mIGY9PSJ1bmRlZmluZWQiP3k6aChmLCJ0b2dnbGUiKS5waXBlKFcobyksbSgoKT0+ZikpfSkpLnN1YnNjcmliZShsPT57bC5vcGVuPT09ITEmJmwub2Zmc2V0VG9wPD1pLnNjcm9sbFRvcCYmaS5zY3JvbGxUbyh7dG9wOmwub2Zmc2V0VG9wfSl9KSx0LnBpcGUoZyhTciksbSgoe2RhdGE6bH0pPT5sKSkucGlwZShPKGw9Pm8ubmV4dChsKSksQSgoKT0+by5jb21wbGV0ZSgpKSxtKGw9PlAoe3JlZjplfSxsKSkpfWZ1bmN0aW9uIFRzKGUse3F1ZXJ5JDp0fSl7cmV0dXJuIHQucGlwZShtKCh7dmFsdWU6cn0pPT57bGV0IG89d2UoKTtyZXR1cm4gby5oYXNoPSIiLHI9ci5yZXBsYWNlKC9ccysvZywiKyIpLnJlcGxhY2UoLyYvZywiJTI2IikucmVwbGFjZSgvPS9nLCIlM0QiKSxvLnNlYXJjaD1gcT0ke3J9YCx7dXJsOm99fSkpfWZ1bmN0aW9uIExpKGUsdCl7bGV0IHI9bmV3IFQsbz1yLnBpcGUob2UoKSxhZSghMCkpO3JldHVybiByLnN1YnNjcmliZSgoe3VybDpufSk9PntlLnNldEF0dHJpYnV0ZSgiZGF0YS1jbGlwYm9hcmQtdGV4dCIsZS5ocmVmKSxlLmhyZWY9YCR7bn1gfSksaChlLCJjbGljayIpLnBpcGUoVyhvKSkuc3Vic2NyaWJlKG49Pm4ucHJldmVudERlZmF1bHQoKSksVHMoZSx0KS5waXBlKE8obj0+ci5uZXh0KG4pKSxBKCgpPT5yLmNvbXBsZXRlKCkpLG0obj0+UCh7cmVmOmV9LG4pKSl9ZnVuY3Rpb24gTWkoZSx7d29ya2VyJDp0LGtleWJvYXJkJDpyfSl7bGV0IG89bmV3IFQsbj1DZSgic2VhcmNoLXF1ZXJ5IiksaT1MKGgobiwia2V5ZG93biIpLGgobiwiZm9jdXMiKSkucGlwZSh4ZShwZSksbSgoKT0+bi52YWx1ZSksWSgpKTtyZXR1cm4gby5waXBlKFBlKGkpLG0oKFt7c3VnZ2VzdDphfSxjXSk9PntsZXQgcD1jLnNwbGl0KC8oW1xzLV0rKS8pO2lmKGEhPW51bGwmJmEubGVuZ3RoJiZwW3AubGVuZ3RoLTFdKXtsZXQgbD1hW2EubGVuZ3RoLTFdO2wuc3RhcnRzV2l0aChwW3AubGVuZ3RoLTFdKSYmKHBbcC5sZW5ndGgtMV09bCl9ZWxzZSBwLmxlbmd0aD0wO3JldHVybiBwfSkpLnN1YnNjcmliZShhPT5lLmlubmVySFRNTD1hLmpvaW4oIiIpLnJlcGxhY2UoL1xzL2csIiZuYnNwOyIpKSxyLnBpcGUoZygoe21vZGU6YX0pPT5hPT09InNlYXJjaCIpKS5zdWJzY3JpYmUoYT0+e2EudHlwZT09PSJBcnJvd1JpZ2h0IiYmZS5pbm5lclRleHQubGVuZ3RoJiZuLnNlbGVjdGlvblN0YXJ0PT09bi52YWx1ZS5sZW5ndGgmJihuLnZhbHVlPWUuaW5uZXJUZXh0KX0pLHQucGlwZShnKFNyKSxtKCh7ZGF0YTphfSk9PmEpKS5waXBlKE8oYT0+by5uZXh0KGEpKSxBKCgpPT5vLmNvbXBsZXRlKCkpLG0oKCk9Pih7cmVmOmV9KSkpfWZ1bmN0aW9uIF9pKGUse2luZGV4JDp0LGtleWJvYXJkJDpyfSl7bGV0IG89VGUoKTt0cnl7bGV0IG49RWkoby5zZWFyY2gsdCksaT1DZSgic2VhcmNoLXF1ZXJ5IixlKSxzPUNlKCJzZWFyY2gtcmVzdWx0IixlKTtoKGUsImNsaWNrIikucGlwZShnKCh7dGFyZ2V0OmN9KT0+YyBpbnN0YW5jZW9mIEVsZW1lbnQmJiEhYy5jbG9zZXN0KCJhIikpKS5zdWJzY3JpYmUoKCk9PmF0KCJzZWFyY2giLCExKSksci5waXBlKGcoKHttb2RlOmN9KT0+Yz09PSJzZWFyY2giKSkuc3Vic2NyaWJlKGM9PntsZXQgcD1OZSgpO3N3aXRjaChjLnR5cGUpe2Nhc2UiRW50ZXIiOmlmKHA9PT1pKXtsZXQgbD1uZXcgTWFwO2ZvcihsZXQgZiBvZiBNKCI6Zmlyc3QtY2hpbGQgW2hyZWZdIixzKSl7bGV0IHU9Zi5maXJzdEVsZW1lbnRDaGlsZDtsLnNldChmLHBhcnNlRmxvYXQodS5nZXRBdHRyaWJ1dGUoImRhdGEtbWQtc2NvcmUiKSkpfWlmKGwuc2l6ZSl7bGV0W1tmXV09Wy4uLmxdLnNvcnQoKFssdV0sWyxkXSk9PmQtdSk7Zi5jbGljaygpfWMuY2xhaW0oKX1icmVhaztjYXNlIkVzY2FwZSI6Y2FzZSJUYWIiOmF0KCJzZWFyY2giLCExKSxpLmJsdXIoKTticmVhaztjYXNlIkFycm93VXAiOmNhc2UiQXJyb3dEb3duIjppZih0eXBlb2YgcD09InVuZGVmaW5lZCIpaS5mb2N1cygpO2Vsc2V7bGV0IGw9W2ksLi4uTSgiOm5vdChkZXRhaWxzKSA+IFtocmVmXSwgc3VtbWFyeSwgZGV0YWlsc1tvcGVuXSBbaHJlZl0iLHMpXSxmPU1hdGgubWF4KDAsKE1hdGgubWF4KDAsbC5pbmRleE9mKHApKStsLmxlbmd0aCsoYy50eXBlPT09IkFycm93VXAiPy0xOjEpKSVsLmxlbmd0aCk7bFtmXS5mb2N1cygpfWMuY2xhaW0oKTticmVhaztkZWZhdWx0OmkhPT1OZSgpJiZpLmZvY3VzKCl9fSksci5waXBlKGcoKHttb2RlOmN9KT0+Yz09PSJnbG9iYWwiKSkuc3Vic2NyaWJlKGM9Pntzd2l0Y2goYy50eXBlKXtjYXNlImYiOmNhc2UicyI6Y2FzZSIvIjppLmZvY3VzKCksaS5zZWxlY3QoKSxjLmNsYWltKCk7YnJlYWt9fSk7bGV0IGE9U2koaSx7d29ya2VyJDpufSk7cmV0dXJuIEwoYSxPaShzLHt3b3JrZXIkOm4scXVlcnkkOmF9KSkucGlwZShWZSguLi5tZSgic2VhcmNoLXNoYXJlIixlKS5tYXAoYz0+TGkoYyx7cXVlcnkkOmF9KSksLi4ubWUoInNlYXJjaC1zdWdnZXN0IixlKS5tYXAoYz0+TWkoYyx7d29ya2VyJDpuLGtleWJvYXJkJDpyfSkpKSl9Y2F0Y2gobil7cmV0dXJuIGUuaGlkZGVuPSEwLHR0fX1mdW5jdGlvbiBBaShlLHtpbmRleCQ6dCxsb2NhdGlvbiQ6cn0pe3JldHVybiB6KFt0LHIucGlwZShRKHdlKCkpLGcobz0+ISFvLnNlYXJjaFBhcmFtcy5nZXQoImgiKSkpXSkucGlwZShtKChbbyxuXSk9PnhpKG8uY29uZmlnKShuLnNlYXJjaFBhcmFtcy5nZXQoImgiKSkpLG0obz0+e3ZhciBzO2xldCBuPW5ldyBNYXAsaT1kb2N1bWVudC5jcmVhdGVOb2RlSXRlcmF0b3IoZSxOb2RlRmlsdGVyLlNIT1dfVEVYVCk7Zm9yKGxldCBhPWkubmV4dE5vZGUoKTthO2E9aS5uZXh0Tm9kZSgpKWlmKChzPWEucGFyZW50RWxlbWVudCkhPW51bGwmJnMub2Zmc2V0SGVpZ2h0KXtsZXQgYz1hLnRleHRDb250ZW50LHA9byhjKTtwLmxlbmd0aD5jLmxlbmd0aCYmbi5zZXQoYSxwKX1mb3IobGV0W2EsY11vZiBuKXtsZXR7Y2hpbGROb2RlczpwfT14KCJzcGFuIixudWxsLGMpO2EucmVwbGFjZVdpdGgoLi4uQXJyYXkuZnJvbShwKSl9cmV0dXJue3JlZjplLG5vZGVzOm59fSkpfWZ1bmN0aW9uIFNzKGUse3ZpZXdwb3J0JDp0LG1haW4kOnJ9KXtsZXQgbz1lLmNsb3Nlc3QoIi5tZC1ncmlkIiksbj1vLm9mZnNldFRvcC1vLnBhcmVudEVsZW1lbnQub2Zmc2V0VG9wO3JldHVybiB6KFtyLHRdKS5waXBlKG0oKFt7b2Zmc2V0OmksaGVpZ2h0OnN9LHtvZmZzZXQ6e3k6YX19XSk9PihzPXMrTWF0aC5taW4obixNYXRoLm1heCgwLGEtaSkpLW4se2hlaWdodDpzLGxvY2tlZDphPj1pK259KSksWSgoaSxzKT0+aS5oZWlnaHQ9PT1zLmhlaWdodCYmaS5sb2NrZWQ9PT1zLmxvY2tlZCkpfWZ1bmN0aW9uIGxvKGUsbyl7dmFyIG49byx7aGVhZGVyJDp0fT1uLHI9dm8obixbImhlYWRlciQiXSk7bGV0IGk9aigiLm1kLXNpZGViYXJfX3Njcm9sbHdyYXAiLGUpLHt5OnN9PUJlKGkpO3JldHVybiBIKCgpPT57bGV0IGE9bmV3IFQsYz1hLnBpcGUob2UoKSxhZSghMCkpLHA9YS5waXBlKCRlKDAseWUpKTtyZXR1cm4gcC5waXBlKHRlKHQpKS5zdWJzY3JpYmUoe25leHQoW3toZWlnaHQ6bH0se2hlaWdodDpmfV0pe2kuc3R5bGUuaGVpZ2h0PWAke2wtMipzfXB4YCxlLnN0eWxlLnRvcD1gJHtmfXB4YH0sY29tcGxldGUoKXtpLnN0eWxlLmhlaWdodD0iIixlLnN0eWxlLnRvcD0iIn19KSxwLnBpcGUoUmUoKSkuc3Vic2NyaWJlKCgpPT57Zm9yKGxldCBsIG9mIE0oIi5tZC1uYXZfX2xpbmstLWFjdGl2ZVtocmVmXSIsZSkpe2lmKCFsLmNsaWVudEhlaWdodCljb250aW51ZTtsZXQgZj1sLmNsb3Nlc3QoIi5tZC1zaWRlYmFyX19zY3JvbGx3cmFwIik7aWYodHlwZW9mIGYhPSJ1bmRlZmluZWQiKXtsZXQgdT1sLm9mZnNldFRvcC1mLm9mZnNldFRvcCx7aGVpZ2h0OmR9PWRlKGYpO2Yuc2Nyb2xsVG8oe3RvcDp1LWQvMn0pfX19KSxmZShNKCJsYWJlbFt0YWJpbmRleF0iLGUpKS5waXBlKEoobD0+aChsLCJjbGljayIpLnBpcGUoeGUocGUpLG0oKCk9PmwpLFcoYykpKSkuc3Vic2NyaWJlKGw9PntsZXQgZj1qKGBbaWQ9IiR7bC5odG1sRm9yfSJdYCk7aihgW2FyaWEtbGFiZWxsZWRieT0iJHtsLmlkfSJdYCkuc2V0QXR0cmlidXRlKCJhcmlhLWV4cGFuZGVkIixgJHtmLmNoZWNrZWR9YCl9KSxWKCJjb250ZW50LnRvb2x0aXBzIikmJmZlKE0oImFiYnJbdGl0bGVdIixlKSkucGlwZShKKGw9PlhlKGwse3ZpZXdwb3J0JH0pKSxXKGMpKS5zdWJzY3JpYmUoKSxTcyhlLHIpLnBpcGUoTyhsPT5hLm5leHQobCkpLEEoKCk9PmEuY29tcGxldGUoKSksbShsPT5QKHtyZWY6ZX0sbCkpKX0pfWZ1bmN0aW9uIENpKGUsdCl7aWYodHlwZW9mIHQhPSJ1bmRlZmluZWQiKXtsZXQgcj1gaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy8ke2V9LyR7dH1gO3JldHVybiBydCh6ZShgJHtyfS9yZWxlYXNlcy9sYXRlc3RgKS5waXBlKHZlKCgpPT55KSxtKG89Pih7dmVyc2lvbjpvLnRhZ19uYW1lfSkpLFFlKHt9KSksemUocikucGlwZSh2ZSgoKT0+eSksbShvPT4oe3N0YXJzOm8uc3RhcmdhemVyc19jb3VudCxmb3JrczpvLmZvcmtzX2NvdW50fSkpLFFlKHt9KSkpLnBpcGUobSgoW28sbl0pPT5QKFAoe30sbyksbikpKX1lbHNle2xldCByPWBodHRwczovL2FwaS5naXRodWIuY29tL3VzZXJzLyR7ZX1gO3JldHVybiB6ZShyKS5waXBlKG0obz0+KHtyZXBvc2l0b3JpZXM6by5wdWJsaWNfcmVwb3N9KSksUWUoe30pKX19ZnVuY3Rpb24ga2koZSx0KXtsZXQgcj1gaHR0cHM6Ly8ke2V9L2FwaS92NC9wcm9qZWN0cy8ke2VuY29kZVVSSUNvbXBvbmVudCh0KX1gO3JldHVybiBydCh6ZShgJHtyfS9yZWxlYXNlcy9wZXJtYWxpbmsvbGF0ZXN0YCkucGlwZSh2ZSgoKT0+eSksbSgoe3RhZ19uYW1lOm99KT0+KHt2ZXJzaW9uOm99KSksUWUoe30pKSx6ZShyKS5waXBlKHZlKCgpPT55KSxtKCh7c3Rhcl9jb3VudDpvLGZvcmtzX2NvdW50Om59KT0+KHtzdGFyczpvLGZvcmtzOm59KSksUWUoe30pKSkucGlwZShtKChbbyxuXSk9PlAoUCh7fSxvKSxuKSkpfWZ1bmN0aW9uIEhpKGUpe2xldCB0PWUubWF0Y2goL14uK2dpdGh1YlwuY29tXC8oW14vXSspXC8/KFteL10rKT8vaSk7aWYodCl7bGV0WyxyLG9dPXQ7cmV0dXJuIENpKHIsbyl9aWYodD1lLm1hdGNoKC9eLis/KFteL10qZ2l0bGFiW14vXSspXC8oLis/KVwvPyQvaSksdCl7bGV0WyxyLG9dPXQ7cmV0dXJuIGtpKHIsbyl9cmV0dXJuIHl9dmFyIE9zO2Z1bmN0aW9uIExzKGUpe3JldHVybiBPc3x8KE9zPUgoKCk9PntsZXQgdD1fX21kX2dldCgiX19zb3VyY2UiLHNlc3Npb25TdG9yYWdlKTtpZih0KXJldHVybiAkKHQpO2lmKG1lKCJjb25zZW50IikubGVuZ3RoKXtsZXQgbz1fX21kX2dldCgiX19jb25zZW50Iik7aWYoIShvJiZvLmdpdGh1YikpcmV0dXJuIHl9cmV0dXJuIEhpKGUuaHJlZikucGlwZShPKG89Pl9fbWRfc2V0KCJfX3NvdXJjZSIsbyxzZXNzaW9uU3RvcmFnZSkpKX0pLnBpcGUodmUoKCk9PnkpLGcodD0+T2JqZWN0LmtleXModCkubGVuZ3RoPjApLG0odD0+KHtmYWN0czp0fSkpLFooMSkpKX1mdW5jdGlvbiAkaShlKXtsZXQgdD1qKCI6c2NvcGUgPiA6bGFzdC1jaGlsZCIsZSk7cmV0dXJuIEgoKCk9PntsZXQgcj1uZXcgVDtyZXR1cm4gci5zdWJzY3JpYmUoKHtmYWN0czpvfSk9Pnt0LmFwcGVuZENoaWxkKGpuKG8pKSx0LmNsYXNzTGlzdC5hZGQoIm1kLXNvdXJjZV9fcmVwb3NpdG9yeS0tYWN0aXZlIil9KSxMcyhlKS5waXBlKE8obz0+ci5uZXh0KG8pKSxBKCgpPT5yLmNvbXBsZXRlKCkpLG0obz0+UCh7cmVmOmV9LG8pKSl9KX1mdW5jdGlvbiBNcyhlLHt2aWV3cG9ydCQ6dCxoZWFkZXIkOnJ9KXtyZXR1cm4gTGUoZG9jdW1lbnQuYm9keSkucGlwZShiKCgpPT5FcihlLHtoZWFkZXIkOnIsdmlld3BvcnQkOnR9KSksbSgoe29mZnNldDp7eTpvfX0pPT4oe2hpZGRlbjpvPj0xMH0pKSxuZSgiaGlkZGVuIikpfWZ1bmN0aW9uIFBpKGUsdCl7cmV0dXJuIEgoKCk9PntsZXQgcj1uZXcgVDtyZXR1cm4gci5zdWJzY3JpYmUoe25leHQoe2hpZGRlbjpvfSl7ZS5oaWRkZW49b30sY29tcGxldGUoKXtlLmhpZGRlbj0hMX19KSwoVigibmF2aWdhdGlvbi50YWJzLnN0aWNreSIpPyQoe2hpZGRlbjohMX0pOk1zKGUsdCkpLnBpcGUoTyhvPT5yLm5leHQobykpLEEoKCk9PnIuY29tcGxldGUoKSksbShvPT5QKHtyZWY6ZX0sbykpKX0pfWZ1bmN0aW9uIF9zKGUse3ZpZXdwb3J0JDp0LGhlYWRlciQ6cn0pe2xldCBvPW5ldyBNYXAsbj1NKCIubWQtbmF2X19saW5rIixlKTtmb3IobGV0IGEgb2Ygbil7bGV0IGM9ZGVjb2RlVVJJQ29tcG9uZW50KGEuaGFzaC5zdWJzdHJpbmcoMSkpLHA9dWUoYFtpZD0iJHtjfSJdYCk7dHlwZW9mIHAhPSJ1bmRlZmluZWQiJiZvLnNldChhLHApfWxldCBpPXIucGlwZShuZSgiaGVpZ2h0IiksbSgoe2hlaWdodDphfSk9PntsZXQgYz1DZSgibWFpbiIpLHA9aigiOnNjb3BlID4gOmZpcnN0LWNoaWxkIixjKTtyZXR1cm4gYSsuOCoocC5vZmZzZXRUb3AtYy5vZmZzZXRUb3ApfSksbGUoKSk7cmV0dXJuIExlKGRvY3VtZW50LmJvZHkpLnBpcGUobmUoImhlaWdodCIpLGIoYT0+SCgoKT0+e2xldCBjPVtdO3JldHVybiAkKFsuLi5vXS5yZWR1Y2UoKHAsW2wsZl0pPT57Zm9yKDtjLmxlbmd0aCYmby5nZXQoY1tjLmxlbmd0aC0xXSkudGFnTmFtZT49Zi50YWdOYW1lOyljLnBvcCgpO2xldCB1PWYub2Zmc2V0VG9wO2Zvcig7IXUmJmYucGFyZW50RWxlbWVudDspZj1mLnBhcmVudEVsZW1lbnQsdT1mLm9mZnNldFRvcDtsZXQgZD1mLm9mZnNldFBhcmVudDtmb3IoO2Q7ZD1kLm9mZnNldFBhcmVudCl1Kz1kLm9mZnNldFRvcDtyZXR1cm4gcC5zZXQoWy4uLmM9Wy4uLmMsbF1dLnJldmVyc2UoKSx1KX0sbmV3IE1hcCkpfSkucGlwZShtKGM9Pm5ldyBNYXAoWy4uLmNdLnNvcnQoKFsscF0sWyxsXSk9PnAtbCkpKSxQZShpKSxiKChbYyxwXSk9PnQucGlwZShVdCgoW2wsZl0se29mZnNldDp7eTp1fSxzaXplOmR9KT0+e2xldCB2PXUrZC5oZWlnaHQ+PU1hdGguZmxvb3IoYS5oZWlnaHQpO2Zvcig7Zi5sZW5ndGg7KXtsZXRbLFNdPWZbMF07aWYoUy1wPHV8fHYpbD1bLi4ubCxmLnNoaWZ0KCldO2Vsc2UgYnJlYWt9Zm9yKDtsLmxlbmd0aDspe2xldFssU109bFtsLmxlbmd0aC0xXTtpZihTLXA+PXUmJiF2KWY9W2wucG9wKCksLi4uZl07ZWxzZSBicmVha31yZXR1cm5bbCxmXX0sW1tdLFsuLi5jXV0pLFkoKGwsZik9PmxbMF09PT1mWzBdJiZsWzFdPT09ZlsxXSkpKSkpKS5waXBlKG0oKFthLGNdKT0+KHtwcmV2OmEubWFwKChbcF0pPT5wKSxuZXh0OmMubWFwKChbcF0pPT5wKX0pKSxRKHtwcmV2OltdLG5leHQ6W119KSxvdCgyLDEpLG0oKFthLGNdKT0+YS5wcmV2Lmxlbmd0aDxjLnByZXYubGVuZ3RoP3twcmV2OmMucHJldi5zbGljZShNYXRoLm1heCgwLGEucHJldi5sZW5ndGgtMSksYy5wcmV2Lmxlbmd0aCksbmV4dDpbXX06e3ByZXY6Yy5wcmV2LnNsaWNlKC0xKSxuZXh0OmMubmV4dC5zbGljZSgwLGMubmV4dC5sZW5ndGgtYS5uZXh0Lmxlbmd0aCl9KSl9ZnVuY3Rpb24gUmkoZSx7dmlld3BvcnQkOnQsaGVhZGVyJDpyLG1haW4kOm8sdGFyZ2V0JDpufSl7cmV0dXJuIEgoKCk9PntsZXQgaT1uZXcgVCxzPWkucGlwZShvZSgpLGFlKCEwKSk7aWYoaS5zdWJzY3JpYmUoKHtwcmV2OmEsbmV4dDpjfSk9Pntmb3IobGV0W3Bdb2YgYylwLmNsYXNzTGlzdC5yZW1vdmUoIm1kLW5hdl9fbGluay0tcGFzc2VkIikscC5jbGFzc0xpc3QucmVtb3ZlKCJtZC1uYXZfX2xpbmstLWFjdGl2ZSIpO2ZvcihsZXRbcCxbbF1db2YgYS5lbnRyaWVzKCkpbC5jbGFzc0xpc3QuYWRkKCJtZC1uYXZfX2xpbmstLXBhc3NlZCIpLGwuY2xhc3NMaXN0LnRvZ2dsZSgibWQtbmF2X19saW5rLS1hY3RpdmUiLHA9PT1hLmxlbmd0aC0xKX0pLFYoInRvYy5mb2xsb3ciKSl7bGV0IGE9TCh0LnBpcGUoQWUoMSksbSgoKT0+e30pKSx0LnBpcGUoQWUoMjUwKSxtKCgpPT4ic21vb3RoIikpKTtpLnBpcGUoZygoe3ByZXY6Y30pPT5jLmxlbmd0aD4wKSxQZShvLnBpcGUoeGUocGUpKSksdGUoYSkpLnN1YnNjcmliZSgoW1t7cHJldjpjfV0scF0pPT57bGV0W2xdPWNbYy5sZW5ndGgtMV07aWYobC5vZmZzZXRIZWlnaHQpe2xldCBmPXZyKGwpO2lmKHR5cGVvZiBmIT0idW5kZWZpbmVkIil7bGV0IHU9bC5vZmZzZXRUb3AtZi5vZmZzZXRUb3Ase2hlaWdodDpkfT1kZShmKTtmLnNjcm9sbFRvKHt0b3A6dS1kLzIsYmVoYXZpb3I6cH0pfX19KX1yZXR1cm4gVigibmF2aWdhdGlvbi50cmFja2luZyIpJiZ0LnBpcGUoVyhzKSxuZSgib2Zmc2V0IiksQWUoMjUwKSxJZSgxKSxXKG4ucGlwZShJZSgxKSkpLHZ0KHtkZWxheToyNTB9KSx0ZShpKSkuc3Vic2NyaWJlKChbLHtwcmV2OmF9XSk9PntsZXQgYz13ZSgpLHA9YVthLmxlbmd0aC0xXTtpZihwJiZwLmxlbmd0aCl7bGV0W2xdPXAse2hhc2g6Zn09bmV3IFVSTChsLmhyZWYpO2MuaGFzaCE9PWYmJihjLmhhc2g9ZixoaXN0b3J5LnJlcGxhY2VTdGF0ZSh7fSwiIixgJHtjfWApKX1lbHNlIGMuaGFzaD0iIixoaXN0b3J5LnJlcGxhY2VTdGF0ZSh7fSwiIixgJHtjfWApfSksX3MoZSx7dmlld3BvcnQkOnQsaGVhZGVyJDpyfSkucGlwZShPKGE9PmkubmV4dChhKSksQSgoKT0+aS5jb21wbGV0ZSgpKSxtKGE9PlAoe3JlZjplfSxhKSkpfSl9ZnVuY3Rpb24gQXMoZSx7dmlld3BvcnQkOnQsbWFpbiQ6cix0YXJnZXQkOm99KXtsZXQgbj10LnBpcGUobSgoe29mZnNldDp7eTpzfX0pPT5zKSxvdCgyLDEpLG0oKFtzLGFdKT0+cz5hJiZhPjApLFkoKSksaT1yLnBpcGUobSgoe2FjdGl2ZTpzfSk9PnMpKTtyZXR1cm4geihbaSxuXSkucGlwZShtKChbcyxhXSk9PiEocyYmYSkpLFkoKSxXKG8ucGlwZShJZSgxKSkpLGFlKCEwKSx2dCh7ZGVsYXk6MjUwfSksbShzPT4oe2hpZGRlbjpzfSkpKX1mdW5jdGlvbiBJaShlLHt2aWV3cG9ydCQ6dCxoZWFkZXIkOnIsbWFpbiQ6byx0YXJnZXQkOm59KXtsZXQgaT1uZXcgVCxzPWkucGlwZShvZSgpLGFlKCEwKSk7cmV0dXJuIGkuc3Vic2NyaWJlKHtuZXh0KHtoaWRkZW46YX0pe2UuaGlkZGVuPWEsYT8oZS5zZXRBdHRyaWJ1dGUoInRhYmluZGV4IiwiLTEiKSxlLmJsdXIoKSk6ZS5yZW1vdmVBdHRyaWJ1dGUoInRhYmluZGV4Iil9LGNvbXBsZXRlKCl7ZS5zdHlsZS50b3A9IiIsZS5oaWRkZW49ITAsZS5yZW1vdmVBdHRyaWJ1dGUoInRhYmluZGV4Iil9fSksci5waXBlKFcocyksbmUoImhlaWdodCIpKS5zdWJzY3JpYmUoKHtoZWlnaHQ6YX0pPT57ZS5zdHlsZS50b3A9YCR7YSsxNn1weGB9KSxoKGUsImNsaWNrIikuc3Vic2NyaWJlKGE9PnthLnByZXZlbnREZWZhdWx0KCksd2luZG93LnNjcm9sbFRvKHt0b3A6MH0pfSksQXMoZSx7dmlld3BvcnQkOnQsbWFpbiQ6byx0YXJnZXQkOm59KS5waXBlKE8oYT0+aS5uZXh0KGEpKSxBKCgpPT5pLmNvbXBsZXRlKCkpLG0oYT0+UCh7cmVmOmV9LGEpKSl9ZnVuY3Rpb24gRmkoe2RvY3VtZW50JDplLHZpZXdwb3J0JDp0fSl7ZS5waXBlKGIoKCk9Pk0oIi5tZC1lbGxpcHNpcyIpKSxKKHI9Pm10KHIpLnBpcGUoVyhlLnBpcGUoSWUoMSkpKSxnKG89Pm8pLG0oKCk9PnIpLEVlKDEpKSksZyhyPT5yLm9mZnNldFdpZHRoPHIuc2Nyb2xsV2lkdGgpLEoocj0+e2xldCBvPXIuaW5uZXJUZXh0LG49ci5jbG9zZXN0KCJhIil8fHI7cmV0dXJuIG4udGl0bGU9byxWKCJjb250ZW50LnRvb2x0aXBzIik/WGUobix7dmlld3BvcnQkOnR9KS5waXBlKFcoZS5waXBlKEllKDEpKSksQSgoKT0+bi5yZW1vdmVBdHRyaWJ1dGUoInRpdGxlIikpKTp5fSkpLnN1YnNjcmliZSgpLFYoImNvbnRlbnQudG9vbHRpcHMiKSYmZS5waXBlKGIoKCk9Pk0oIi5tZC1zdGF0dXMiKSksSihyPT5YZShyLHt2aWV3cG9ydCQ6dH0pKSkuc3Vic2NyaWJlKCl9ZnVuY3Rpb24gamkoe2RvY3VtZW50JDplLHRhYmxldCQ6dH0pe2UucGlwZShiKCgpPT5NKCIubWQtdG9nZ2xlLS1pbmRldGVybWluYXRlIikpLE8ocj0+e3IuaW5kZXRlcm1pbmF0ZT0hMCxyLmNoZWNrZWQ9ITF9KSxKKHI9PmgociwiY2hhbmdlIikucGlwZShKcigoKT0+ci5jbGFzc0xpc3QuY29udGFpbnMoIm1kLXRvZ2dsZS0taW5kZXRlcm1pbmF0ZSIpKSxtKCgpPT5yKSkpLHRlKHQpKS5zdWJzY3JpYmUoKFtyLG9dKT0+e3IuY2xhc3NMaXN0LnJlbW92ZSgibWQtdG9nZ2xlLS1pbmRldGVybWluYXRlIiksbyYmKHIuY2hlY2tlZD0hMSl9KX1mdW5jdGlvbiBDcygpe3JldHVybi8oaVBhZHxpUGhvbmV8aVBvZCkvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCl9ZnVuY3Rpb24gVWkoe2RvY3VtZW50JDplfSl7ZS5waXBlKGIoKCk9Pk0oIltkYXRhLW1kLXNjcm9sbGZpeF0iKSksTyh0PT50LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1tZC1zY3JvbGxmaXgiKSksZyhDcyksSih0PT5oKHQsInRvdWNoc3RhcnQiKS5waXBlKG0oKCk9PnQpKSkpLnN1YnNjcmliZSh0PT57bGV0IHI9dC5zY3JvbGxUb3A7cj09PTA/dC5zY3JvbGxUb3A9MTpyK3Qub2Zmc2V0SGVpZ2h0PT09dC5zY3JvbGxIZWlnaHQmJih0LnNjcm9sbFRvcD1yLTEpfSl9ZnVuY3Rpb24gV2koe3ZpZXdwb3J0JDplLHRhYmxldCQ6dH0pe3ooW0plKCJzZWFyY2giKSx0XSkucGlwZShtKChbcixvXSk9PnImJiFvKSxiKHI9PiQocikucGlwZShudChyPzQwMDoxMDApKSksdGUoZSkpLnN1YnNjcmliZSgoW3Ise29mZnNldDp7eTpvfX1dKT0+e2lmKHIpZG9jdW1lbnQuYm9keS5zZXRBdHRyaWJ1dGUoImRhdGEtbWQtc2Nyb2xsbG9jayIsIiIpLGRvY3VtZW50LmJvZHkuc3R5bGUudG9wPWAtJHtvfXB4YDtlbHNle2xldCBuPS0xKnBhcnNlSW50KGRvY3VtZW50LmJvZHkuc3R5bGUudG9wLDEwKTtkb2N1bWVudC5ib2R5LnJlbW92ZUF0dHJpYnV0ZSgiZGF0YS1tZC1zY3JvbGxsb2NrIiksZG9jdW1lbnQuYm9keS5zdHlsZS50b3A9IiIsbiYmd2luZG93LnNjcm9sbFRvKDAsbil9fSl9T2JqZWN0LmVudHJpZXN8fChPYmplY3QuZW50cmllcz1mdW5jdGlvbihlKXtsZXQgdD1bXTtmb3IobGV0IHIgb2YgT2JqZWN0LmtleXMoZSkpdC5wdXNoKFtyLGVbcl1dKTtyZXR1cm4gdH0pO09iamVjdC52YWx1ZXN8fChPYmplY3QudmFsdWVzPWZ1bmN0aW9uKGUpe2xldCB0PVtdO2ZvcihsZXQgciBvZiBPYmplY3Qua2V5cyhlKSl0LnB1c2goZVtyXSk7cmV0dXJuIHR9KTt0eXBlb2YgRWxlbWVudCE9InVuZGVmaW5lZCImJihFbGVtZW50LnByb3RvdHlwZS5zY3JvbGxUb3x8KEVsZW1lbnQucHJvdG90eXBlLnNjcm9sbFRvPWZ1bmN0aW9uKGUsdCl7dHlwZW9mIGU9PSJvYmplY3QiPyh0aGlzLnNjcm9sbExlZnQ9ZS5sZWZ0LHRoaXMuc2Nyb2xsVG9wPWUudG9wKToodGhpcy5zY3JvbGxMZWZ0PWUsdGhpcy5zY3JvbGxUb3A9dCl9KSxFbGVtZW50LnByb3RvdHlwZS5yZXBsYWNlV2l0aHx8KEVsZW1lbnQucHJvdG90eXBlLnJlcGxhY2VXaXRoPWZ1bmN0aW9uKC4uLmUpe2xldCB0PXRoaXMucGFyZW50Tm9kZTtpZih0KXtlLmxlbmd0aD09PTAmJnQucmVtb3ZlQ2hpbGQodGhpcyk7Zm9yKGxldCByPWUubGVuZ3RoLTE7cj49MDtyLS0pe2xldCBvPWVbcl07dHlwZW9mIG89PSJzdHJpbmciP289ZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUobyk6by5wYXJlbnROb2RlJiZvLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobykscj90Lmluc2VydEJlZm9yZSh0aGlzLnByZXZpb3VzU2libGluZyxvKTp0LnJlcGxhY2VDaGlsZChvLHRoaXMpfX19KSk7ZnVuY3Rpb24ga3MoKXtyZXR1cm4gbG9jYXRpb24ucHJvdG9jb2w9PT0iZmlsZToiP190KGAke25ldyBVUkwoInNlYXJjaC9zZWFyY2hfaW5kZXguanMiLE9yLmJhc2UpfWApLnBpcGUobSgoKT0+X19pbmRleCksWigxKSk6emUobmV3IFVSTCgic2VhcmNoL3NlYXJjaF9pbmRleC5qc29uIixPci5iYXNlKSl9ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoIm5vLWpzIik7ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5hZGQoImpzIik7dmFyIGN0PWFuKCksS3Q9Ym4oKSxIdD15bihLdCksbW89aG4oKSxrZT1MbigpLExyPVd0KCIobWluLXdpZHRoOiA2MGVtKSIpLFZpPVd0KCIobWluLXdpZHRoOiA3Ni4yNWVtKSIpLE5pPXhuKCksT3I9VGUoKSx6aT1kb2N1bWVudC5mb3Jtcy5uYW1lZEl0ZW0oInNlYXJjaCIpP2tzKCk6dHQsZm89bmV3IFQ7ZGkoe2FsZXJ0JDpmb30pO3VpKHtkb2N1bWVudCQ6Y3R9KTt2YXIgdW89bmV3IFQscWk9a3QoT3IuYmFzZSk7VigibmF2aWdhdGlvbi5pbnN0YW50IikmJmdpKHtzaXRlbWFwJDpxaSxsb2NhdGlvbiQ6S3Qsdmlld3BvcnQkOmtlLHByb2dyZXNzJDp1b30pLnN1YnNjcmliZShjdCk7dmFyIERpOygoRGk9T3IudmVyc2lvbik9PW51bGw/dm9pZCAwOkRpLnByb3ZpZGVyKT09PSJtaWtlIiYmVGkoe2RvY3VtZW50JDpjdH0pO0woS3QsSHQpLnBpcGUobnQoMTI1KSkuc3Vic2NyaWJlKCgpPT57YXQoImRyYXdlciIsITEpLGF0KCJzZWFyY2giLCExKX0pO21vLnBpcGUoZygoe21vZGU6ZX0pPT5lPT09Imdsb2JhbCIpKS5zdWJzY3JpYmUoZT0+e3N3aXRjaChlLnR5cGUpe2Nhc2UicCI6Y2FzZSIsIjpsZXQgdD11ZSgibGlua1tyZWw9cHJldl0iKTt0eXBlb2YgdCE9InVuZGVmaW5lZCImJnN0KHQpO2JyZWFrO2Nhc2UibiI6Y2FzZSIuIjpsZXQgcj11ZSgibGlua1tyZWw9bmV4dF0iKTt0eXBlb2YgciE9InVuZGVmaW5lZCImJnN0KHIpO2JyZWFrO2Nhc2UiRW50ZXIiOmxldCBvPU5lKCk7byBpbnN0YW5jZW9mIEhUTUxMYWJlbEVsZW1lbnQmJm8uY2xpY2soKX19KTtGaSh7dmlld3BvcnQkOmtlLGRvY3VtZW50JDpjdH0pO2ppKHtkb2N1bWVudCQ6Y3QsdGFibGV0JDpMcn0pO1VpKHtkb2N1bWVudCQ6Y3R9KTtXaSh7dmlld3BvcnQkOmtlLHRhYmxldCQ6THJ9KTt2YXIgZnQ9YWkoQ2UoImhlYWRlciIpLHt2aWV3cG9ydCQ6a2V9KSxxdD1jdC5waXBlKG0oKCk9PkNlKCJtYWluIikpLGIoZT0+cGkoZSx7dmlld3BvcnQkOmtlLGhlYWRlciQ6ZnR9KSksWigxKSksSHM9TCguLi5tZSgiY29uc2VudCIpLm1hcChlPT5BbihlLHt0YXJnZXQkOkh0fSkpLC4uLm1lKCJkaWFsb2ciKS5tYXAoZT0+bmkoZSx7YWxlcnQkOmZvfSkpLC4uLm1lKCJwYWxldHRlIikubWFwKGU9PmxpKGUpKSwuLi5tZSgicHJvZ3Jlc3MiKS5tYXAoZT0+bWkoZSx7cHJvZ3Jlc3MkOnVvfSkpLC4uLm1lKCJzZWFyY2giKS5tYXAoZT0+X2koZSx7aW5kZXgkOnppLGtleWJvYXJkJDptb30pKSwuLi5tZSgic291cmNlIikubWFwKGU9PiRpKGUpKSksJHM9SCgoKT0+TCguLi5tZSgiYW5ub3VuY2UiKS5tYXAoZT0+X24oZSkpLC4uLm1lKCJjb250ZW50IikubWFwKGU9Pm9pKGUse3NpdGVtYXAkOnFpLHZpZXdwb3J0JDprZSx0YXJnZXQkOkh0LHByaW50JDpOaX0pKSwuLi5tZSgiY29udGVudCIpLm1hcChlPT5WKCJzZWFyY2guaGlnaGxpZ2h0Iik/QWkoZSx7aW5kZXgkOnppLGxvY2F0aW9uJDpLdH0pOnkpLC4uLm1lKCJoZWFkZXIiKS5tYXAoZT0+c2koZSx7dmlld3BvcnQkOmtlLGhlYWRlciQ6ZnQsbWFpbiQ6cXR9KSksLi4ubWUoImhlYWRlci10aXRsZSIpLm1hcChlPT5jaShlLHt2aWV3cG9ydCQ6a2UsaGVhZGVyJDpmdH0pKSwuLi5tZSgic2lkZWJhciIpLm1hcChlPT5lLmdldEF0dHJpYnV0ZSgiZGF0YS1tZC10eXBlIik9PT0ibmF2aWdhdGlvbiI/ZW8oVmksKCk9PmxvKGUse3ZpZXdwb3J0JDprZSxoZWFkZXIkOmZ0LG1haW4kOnF0fSkpOmVvKExyLCgpPT5sbyhlLHt2aWV3cG9ydCQ6a2UsaGVhZGVyJDpmdCxtYWluJDpxdH0pKSksLi4ubWUoInRhYnMiKS5tYXAoZT0+UGkoZSx7dmlld3BvcnQkOmtlLGhlYWRlciQ6ZnR9KSksLi4ubWUoInRvYyIpLm1hcChlPT5SaShlLHt2aWV3cG9ydCQ6a2UsaGVhZGVyJDpmdCxtYWluJDpxdCx0YXJnZXQkOkh0fSkpLC4uLm1lKCJ0b3AiKS5tYXAoZT0+SWkoZSx7dmlld3BvcnQkOmtlLGhlYWRlciQ6ZnQsbWFpbiQ6cXQsdGFyZ2V0JDpIdH0pKSkpLEtpPWN0LnBpcGUoYigoKT0+JHMpLFZlKEhzKSxaKDEpKTtLaS5zdWJzY3JpYmUoKTt3aW5kb3cuZG9jdW1lbnQkPWN0O3dpbmRvdy5sb2NhdGlvbiQ9S3Q7d2luZG93LnRhcmdldCQ9SHQ7d2luZG93LmtleWJvYXJkJD1tbzt3aW5kb3cudmlld3BvcnQkPWtlO3dpbmRvdy50YWJsZXQkPUxyO3dpbmRvdy5zY3JlZW4kPVZpO3dpbmRvdy5wcmludCQ9Tmk7d2luZG93LmFsZXJ0JD1mbzt3aW5kb3cucHJvZ3Jlc3MkPXVvO3dpbmRvdy5jb21wb25lbnQkPUtpO30pKCk7Ci8vIyBzb3VyY2VNYXBwaW5nVVJMPWJ1bmRsZS43OWFlNTE5ZS5taW4uanMubWFwCgo="></script><!--URL:../assets/javascripts/bundle.79ae519e.min.js-->
<script src="data:text/javascript;base64,LyogCkphdmFzY3JpcHQgZnVuY3Rpb25zIHRvIGhlbHAgbWFrZSB0aGUgcHJpbnQgcGFnZSBtb3JlIFBERiBmcmllbmRseQoqLwoKLyoKQ29weSB0aGUgdGFibGUgb2YgY29udGVudHMgZnJvbSB0aGUgc2lkZWJhcidzLgpPbmx5IGNhbGxlZCB3aGVuIHByaW50LXNpdGUtcGx1Z2luIG9wdGlvbiAnYWRkX3RhYmxlX29mX2NvbnRlbnRzJyBpcyBzZXQgdG8gdHJ1ZQoqLwpmdW5jdGlvbiBnZW5lcmF0ZV90b2MoKSB7CiAgY29uc3Qgc2lkZWJhciA9IGRvY3VtZW50LmJvZHkuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgibWQtc2lkZWJhci0tc2Vjb25kYXJ5IilbMF0gPz8KICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ0b2MtY29sbGFwc2UiKTsKCiAgY29uc3Qgc2lkZWJhclRvYyA9IHNpZGViYXIuZ2V0RWxlbWVudHNCeVRhZ05hbWUoInVsIilbMF07CgogIHZhciBjbG9uZWRUb2MgPSBzaWRlYmFyVG9jLmNsb25lTm9kZSh0cnVlKTsKICBjbG9uZWRUb2MucmVtb3ZlQXR0cmlidXRlKCJkYXRhLW1kLWNvbXBvbmVudCIpOwogIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoIiNwcmludC1wYWdlLXRvYyBuYXYiKVswXS5pbnNlcnRBZGphY2VudEhUTUwoImJlZm9yZWVuZCIsIGNsb25lZFRvYy5vdXRlckhUTUwpOwp9CgoKZnVuY3Rpb24gcmVtb3ZlX21hdGVyaWFsX25hdmlnYXRpb24oKSB7CiAgLy8gUmVtb3ZlIGxlZnQgc2lkZWJhciBvbiBwcmludCBwYWdlCiAgcmVtb3ZlX2VsZW1lbnRfYnlfY2xhc3NuYW1lKCJtZC1zaWRlYmFyLS1wcmltYXJ5IikKICAvLyBSZW1vdmUgdGFicyBuYXZpZ2F0aW9uIG9uIHByaW50IHBhZ2UKICByZW1vdmVfZWxlbWVudF9ieV9jbGFzc25hbWUoIm1kLXRhYnMiKQogIC8vIFJlbW92ZSBzZWFyY2gKICByZW1vdmVfZWxlbWVudF9ieV9jbGFzc25hbWUoIm1kLXNlYXJjaCIpCgp9CgpmdW5jdGlvbiByZW1vdmVfbWtkb2NzX3RoZW1lX25hdmlnYXRpb24oKSB7CiAgLy8gUmVtb3ZlIHRvcCBuYXZpZ2F0aW9uIGJhcgogIHJlbW92ZV9lbGVtZW50X2J5X2NsYXNzbmFtZSgibmF2YmFyIikKfQoKCmZ1bmN0aW9uIHJlbW92ZV9lbGVtZW50X2J5X2NsYXNzbmFtZShjbGFzc19uYW1lKSB7CiAgdmFyIGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShjbGFzc19uYW1lKTsKICBpZiggZWwubGVuZ3RoID4gMCkgewogICAgZWxbMF0uc3R5bGUuZGlzcGxheSA9ICJub25lIgogIH0KfQo="></script><!--URL:../js/print-site.js-->
<script src="data:text/javascript;base64,d2luZG93Lk1hdGhKYXggPSB7CiAgbG9hZGVyOiB7CiAgICBsb2FkOiBbImlucHV0L3RleC1mdWxsIiwgIm91dHB1dC9jaHRtbCJdCiAgfSwKICB0ZXg6IHsKICAgIHByb2Nlc3NFc2NhcGVzOiB0cnVlLAogICAgcHJvY2Vzc0Vudmlyb25tZW50czogdHJ1ZQogIH0sCiAgb3B0aW9uczogewogICAgaWdub3JlSHRtbENsYXNzOiAiLip8IiwKICAgIHByb2Nlc3NIdG1sQ2xhc3M6ICJhcml0aG1hdGV4IgogIH0KfTsKCmRvY3VtZW50JC5zdWJzY3JpYmUoKCkgPT4gewogIE1hdGhKYXgudHlwZXNldFByb21pc2U/LigKICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoIi5hcml0aG1hdGV4IikKICApLmNhdGNoKChlcnJvcikgPT4gY29uc29sZS5lcnJvcihlcnJvcikpOwp9KTsK"></script><!--URL:../javascripts/mathjax.js-->
<script src="data:text/javascript;base64,IWZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO3ZhciBlPXs1MTU6ZnVuY3Rpb24oZSx0LHIpe3ZhciBuPXRoaXMmJnRoaXMuX192YWx1ZXN8fGZ1bmN0aW9uKGUpe3ZhciB0PSJmdW5jdGlvbiI9PXR5cGVvZiBTeW1ib2wmJlN5bWJvbC5pdGVyYXRvcixyPXQmJmVbdF0sbj0wO2lmKHIpcmV0dXJuIHIuY2FsbChlKTtpZihlJiYibnVtYmVyIj09dHlwZW9mIGUubGVuZ3RoKXJldHVybntuZXh0OmZ1bmN0aW9uKCl7cmV0dXJuIGUmJm4+PWUubGVuZ3RoJiYoZT12b2lkIDApLHt2YWx1ZTplJiZlW24rK10sZG9uZTohZX19fTt0aHJvdyBuZXcgVHlwZUVycm9yKHQ/Ik9iamVjdCBpcyBub3QgaXRlcmFibGUuIjoiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLiIpfTtmdW5jdGlvbiBvKGUpe3JldHVybiJvYmplY3QiPT10eXBlb2YgZSYmbnVsbCE9PWV9ZnVuY3Rpb24gYShlLHQpe3ZhciByLGk7dHJ5e2Zvcih2YXIgdT1uKE9iamVjdC5rZXlzKHQpKSxjPXUubmV4dCgpOyFjLmRvbmU7Yz11Lm5leHQoKSl7dmFyIHM9Yy52YWx1ZTsiX19lc01vZHVsZSIhPT1zJiYoIW8oZVtzXSl8fCFvKHRbc10pfHx0W3NdaW5zdGFuY2VvZiBQcm9taXNlP251bGwhPT10W3NdJiZ2b2lkIDAhPT10W3NdJiYoZVtzXT10W3NdKTphKGVbc10sdFtzXSkpfX1jYXRjaChlKXtyPXtlcnJvcjplfX1maW5hbGx5e3RyeXtjJiYhYy5kb25lJiYoaT11LnJldHVybikmJmkuY2FsbCh1KX1maW5hbGx5e2lmKHIpdGhyb3cgci5lcnJvcn19cmV0dXJuIGV9T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pLHQuTWF0aEpheD10LmNvbWJpbmVXaXRoTWF0aEpheD10LmNvbWJpbmVEZWZhdWx0cz10LmNvbWJpbmVDb25maWc9dC5pc09iamVjdD12b2lkIDAsdC5pc09iamVjdD1vLHQuY29tYmluZUNvbmZpZz1hLHQuY29tYmluZURlZmF1bHRzPWZ1bmN0aW9uIGUodCxyLGEpe3ZhciBpLHU7dFtyXXx8KHRbcl09e30pLHQ9dFtyXTt0cnl7Zm9yKHZhciBjPW4oT2JqZWN0LmtleXMoYSkpLHM9Yy5uZXh0KCk7IXMuZG9uZTtzPWMubmV4dCgpKXt2YXIgbD1zLnZhbHVlO28odFtsXSkmJm8oYVtsXSk/ZSh0LGwsYVtsXSk6bnVsbD09dFtsXSYmbnVsbCE9YVtsXSYmKHRbbF09YVtsXSl9fWNhdGNoKGUpe2k9e2Vycm9yOmV9fWZpbmFsbHl7dHJ5e3MmJiFzLmRvbmUmJih1PWMucmV0dXJuKSYmdS5jYWxsKGMpfWZpbmFsbHl7aWYoaSl0aHJvdyBpLmVycm9yfX1yZXR1cm4gdH0sdC5jb21iaW5lV2l0aE1hdGhKYXg9ZnVuY3Rpb24oZSl7cmV0dXJuIGEodC5NYXRoSmF4LGUpfSx2b2lkIDA9PT1yLmcuTWF0aEpheCYmKHIuZy5NYXRoSmF4PXt9KSxyLmcuTWF0aEpheC52ZXJzaW9ufHwoci5nLk1hdGhKYXg9e3ZlcnNpb246IjMuMS40IixfOnt9LGNvbmZpZzpyLmcuTWF0aEpheH0pLHQuTWF0aEpheD1yLmcuTWF0aEpheH0sMjM1OmZ1bmN0aW9uKGUsdCxyKXt2YXIgbj10aGlzJiZ0aGlzLl9fdmFsdWVzfHxmdW5jdGlvbihlKXt2YXIgdD0iZnVuY3Rpb24iPT10eXBlb2YgU3ltYm9sJiZTeW1ib2wuaXRlcmF0b3Iscj10JiZlW3RdLG49MDtpZihyKXJldHVybiByLmNhbGwoZSk7aWYoZSYmIm51bWJlciI9PXR5cGVvZiBlLmxlbmd0aClyZXR1cm57bmV4dDpmdW5jdGlvbigpe3JldHVybiBlJiZuPj1lLmxlbmd0aCYmKGU9dm9pZCAwKSx7dmFsdWU6ZSYmZVtuKytdLGRvbmU6IWV9fX07dGhyb3cgbmV3IFR5cGVFcnJvcih0PyJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLiI6IlN5bWJvbC5pdGVyYXRvciBpcyBub3QgZGVmaW5lZC4iKX07T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pLHQuQ09ORklHPXQuTWF0aEpheD10LkxvYWRlcj10LlBhdGhGaWx0ZXJzPXQuUGFja2FnZUVycm9yPXQuUGFja2FnZT12b2lkIDA7dmFyIG89cig1MTUpLGE9cigyNjUpLGk9cigyNjUpO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LCJQYWNrYWdlIix7ZW51bWVyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gaS5QYWNrYWdlfX0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LCJQYWNrYWdlRXJyb3IiLHtlbnVtZXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiBpLlBhY2thZ2VFcnJvcn19KTt2YXIgdSxjPXIoNTI1KTt0LlBhdGhGaWx0ZXJzPXtzb3VyY2U6ZnVuY3Rpb24oZSl7cmV0dXJuIHQuQ09ORklHLnNvdXJjZS5oYXNPd25Qcm9wZXJ0eShlLm5hbWUpJiYoZS5uYW1lPXQuQ09ORklHLnNvdXJjZVtlLm5hbWVdKSwhMH0sbm9ybWFsaXplOmZ1bmN0aW9uKGUpe3ZhciB0PWUubmFtZTtyZXR1cm4gdC5tYXRjaCgvXig/OlthLXpdKzpcLyk/XC98W2Etel06XFx8XFsvaSl8fChlLm5hbWU9IlttYXRoamF4XS8iK3QucmVwbGFjZSgvXlwuXC8vLCIiKSksZS5hZGRFeHRlbnNpb24mJiF0Lm1hdGNoKC9cLlteXC9dKyQvKSYmKGUubmFtZSs9Ii5qcyIpLCEwfSxwcmVmaXg6ZnVuY3Rpb24oZSl7Zm9yKHZhciByOyhyPWUubmFtZS5tYXRjaCgvXlxbKFteXF1dKilcXS8pKSYmdC5DT05GSUcucGF0aHMuaGFzT3duUHJvcGVydHkoclsxXSk7KWUubmFtZT10LkNPTkZJRy5wYXRoc1tyWzFdXStlLm5hbWUuc3Vic3RyKHJbMF0ubGVuZ3RoKTtyZXR1cm4hMH19LGZ1bmN0aW9uKGUpe2UucmVhZHk9ZnVuY3Rpb24oKXtmb3IodmFyIGUsdCxyPVtdLG89MDtvPGFyZ3VtZW50cy5sZW5ndGg7bysrKXJbb109YXJndW1lbnRzW29dOzA9PT1yLmxlbmd0aCYmKHI9QXJyYXkuZnJvbShhLlBhY2thZ2UucGFja2FnZXMua2V5cygpKSk7dmFyIGk9W107dHJ5e2Zvcih2YXIgdT1uKHIpLGM9dS5uZXh0KCk7IWMuZG9uZTtjPXUubmV4dCgpKXt2YXIgcz1jLnZhbHVlLGw9YS5QYWNrYWdlLnBhY2thZ2VzLmdldChzKXx8bmV3IGEuUGFja2FnZShzLCEwKTtpLnB1c2gobC5wcm9taXNlKX19Y2F0Y2godCl7ZT17ZXJyb3I6dH19ZmluYWxseXt0cnl7YyYmIWMuZG9uZSYmKHQ9dS5yZXR1cm4pJiZ0LmNhbGwodSl9ZmluYWxseXtpZihlKXRocm93IGUuZXJyb3J9fXJldHVybiBQcm9taXNlLmFsbChpKX0sZS5sb2FkPWZ1bmN0aW9uKCl7Zm9yKHZhciBlLHIsbz1bXSxpPTA7aTxhcmd1bWVudHMubGVuZ3RoO2krKylvW2ldPWFyZ3VtZW50c1tpXTtpZigwPT09by5sZW5ndGgpcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO3ZhciB1PVtdO3RyeXtmb3IodmFyIGM9bihvKSxzPWMubmV4dCgpOyFzLmRvbmU7cz1jLm5leHQoKSl7dmFyIGw9cy52YWx1ZSxkPWEuUGFja2FnZS5wYWNrYWdlcy5nZXQobCk7ZHx8KGQ9bmV3IGEuUGFja2FnZShsKSkucHJvdmlkZXModC5DT05GSUcucHJvdmlkZXNbbF0pLGQuY2hlY2tOb0xvYWQoKSx1LnB1c2goZC5wcm9taXNlKX19Y2F0Y2godCl7ZT17ZXJyb3I6dH19ZmluYWxseXt0cnl7cyYmIXMuZG9uZSYmKHI9Yy5yZXR1cm4pJiZyLmNhbGwoYyl9ZmluYWxseXtpZihlKXRocm93IGUuZXJyb3J9fXJldHVybiBhLlBhY2thZ2UubG9hZEFsbCgpLFByb21pc2UuYWxsKHUpfSxlLnByZUxvYWQ9ZnVuY3Rpb24oKXtmb3IodmFyIGUscixvPVtdLGk9MDtpPGFyZ3VtZW50cy5sZW5ndGg7aSsrKW9baV09YXJndW1lbnRzW2ldO3RyeXtmb3IodmFyIHU9bihvKSxjPXUubmV4dCgpOyFjLmRvbmU7Yz11Lm5leHQoKSl7dmFyIHM9Yy52YWx1ZSxsPWEuUGFja2FnZS5wYWNrYWdlcy5nZXQocyk7bHx8KGw9bmV3IGEuUGFja2FnZShzLCEwKSkucHJvdmlkZXModC5DT05GSUcucHJvdmlkZXNbc10pLGwubG9hZGVkKCl9fWNhdGNoKHQpe2U9e2Vycm9yOnR9fWZpbmFsbHl7dHJ5e2MmJiFjLmRvbmUmJihyPXUucmV0dXJuKSYmci5jYWxsKHUpfWZpbmFsbHl7aWYoZSl0aHJvdyBlLmVycm9yfX19LGUuZGVmYXVsdFJlYWR5PWZ1bmN0aW9uKCl7dm9pZCAwIT09dC5NYXRoSmF4LnN0YXJ0dXAmJnQuTWF0aEpheC5jb25maWcuc3RhcnR1cC5yZWFkeSgpfSxlLmdldFJvb3Q9ZnVuY3Rpb24oKXt2YXIgZT0iLy8uLi8uLi9lczUiO2lmKCJ1bmRlZmluZWQiIT10eXBlb2YgZG9jdW1lbnQpe3ZhciB0PWRvY3VtZW50LmN1cnJlbnRTY3JpcHR8fGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJNYXRoSmF4LXNjcmlwdCIpO3QmJihlPXQuc3JjLnJlcGxhY2UoL1wvW15cL10qJC8sIiIpKX1yZXR1cm4gZX0sZS5wYXRoRmlsdGVycz1uZXcgYy5GdW5jdGlvbkxpc3QsZS5wYXRoRmlsdGVycy5hZGQodC5QYXRoRmlsdGVycy5zb3VyY2UsMSksZS5wYXRoRmlsdGVycy5hZGQodC5QYXRoRmlsdGVycy5ub3JtYWxpemUsMiksZS5wYXRoRmlsdGVycy5hZGQodC5QYXRoRmlsdGVycy5wcmVmaXgsNSl9KHU9dC5Mb2FkZXJ8fCh0LkxvYWRlcj17fSkpLHQuTWF0aEpheD1vLk1hdGhKYXgsdm9pZCAwPT09dC5NYXRoSmF4LmxvYWRlciYmKG8uY29tYmluZURlZmF1bHRzKHQuTWF0aEpheC5jb25maWcsImxvYWRlciIse3BhdGhzOnttYXRoamF4OnUuZ2V0Um9vdCgpfSxzb3VyY2U6e30sZGVwZW5kZW5jaWVzOnt9LHByb3ZpZGVzOnt9LGxvYWQ6W10scmVhZHk6dS5kZWZhdWx0UmVhZHkuYmluZCh1KSxmYWlsZWQ6ZnVuY3Rpb24oZSl7cmV0dXJuIGNvbnNvbGUubG9nKCJNYXRoSmF4KCIrKGUucGFja2FnZXx8Ij8iKSsiKTogIitlLm1lc3NhZ2UpfSxyZXF1aXJlOm51bGx9KSxvLmNvbWJpbmVXaXRoTWF0aEpheCh7bG9hZGVyOnV9KSksdC5DT05GSUc9dC5NYXRoSmF4LmNvbmZpZy5sb2FkZXJ9LDI2NTpmdW5jdGlvbihlLHQscil7dmFyIG4sbz10aGlzJiZ0aGlzLl9fZXh0ZW5kc3x8KG49ZnVuY3Rpb24oZSx0KXtyZXR1cm4obj1PYmplY3Quc2V0UHJvdG90eXBlT2Z8fHtfX3Byb3RvX186W119aW5zdGFuY2VvZiBBcnJheSYmZnVuY3Rpb24oZSx0KXtlLl9fcHJvdG9fXz10fXx8ZnVuY3Rpb24oZSx0KXtmb3IodmFyIHIgaW4gdClPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodCxyKSYmKGVbcl09dFtyXSl9KShlLHQpfSxmdW5jdGlvbihlLHQpe2lmKCJmdW5jdGlvbiIhPXR5cGVvZiB0JiZudWxsIT09dCl0aHJvdyBuZXcgVHlwZUVycm9yKCJDbGFzcyBleHRlbmRzIHZhbHVlICIrU3RyaW5nKHQpKyIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbCIpO2Z1bmN0aW9uIHIoKXt0aGlzLmNvbnN0cnVjdG9yPWV9bihlLHQpLGUucHJvdG90eXBlPW51bGw9PT10P09iamVjdC5jcmVhdGUodCk6KHIucHJvdG90eXBlPXQucHJvdG90eXBlLG5ldyByKX0pLGE9dGhpcyYmdGhpcy5fX3ZhbHVlc3x8ZnVuY3Rpb24oZSl7dmFyIHQ9ImZ1bmN0aW9uIj09dHlwZW9mIFN5bWJvbCYmU3ltYm9sLml0ZXJhdG9yLHI9dCYmZVt0XSxuPTA7aWYocilyZXR1cm4gci5jYWxsKGUpO2lmKGUmJiJudW1iZXIiPT10eXBlb2YgZS5sZW5ndGgpcmV0dXJue25leHQ6ZnVuY3Rpb24oKXtyZXR1cm4gZSYmbj49ZS5sZW5ndGgmJihlPXZvaWQgMCkse3ZhbHVlOmUmJmVbbisrXSxkb25lOiFlfX19O3Rocm93IG5ldyBUeXBlRXJyb3IodD8iT2JqZWN0IGlzIG5vdCBpdGVyYWJsZS4iOiJTeW1ib2wuaXRlcmF0b3IgaXMgbm90IGRlZmluZWQuIil9LGk9dGhpcyYmdGhpcy5fX3JlYWR8fGZ1bmN0aW9uKGUsdCl7dmFyIHI9ImZ1bmN0aW9uIj09dHlwZW9mIFN5bWJvbCYmZVtTeW1ib2wuaXRlcmF0b3JdO2lmKCFyKXJldHVybiBlO3ZhciBuLG8sYT1yLmNhbGwoZSksaT1bXTt0cnl7Zm9yKDsodm9pZCAwPT09dHx8dC0tID4wKSYmIShuPWEubmV4dCgpKS5kb25lOylpLnB1c2gobi52YWx1ZSl9Y2F0Y2goZSl7bz17ZXJyb3I6ZX19ZmluYWxseXt0cnl7biYmIW4uZG9uZSYmKHI9YS5yZXR1cm4pJiZyLmNhbGwoYSl9ZmluYWxseXtpZihvKXRocm93IG8uZXJyb3J9fXJldHVybiBpfSx1PXRoaXMmJnRoaXMuX19zcHJlYWRBcnJheXx8ZnVuY3Rpb24oZSx0KXtmb3IodmFyIHI9MCxuPXQubGVuZ3RoLG89ZS5sZW5ndGg7cjxuO3IrKyxvKyspZVtvXT10W3JdO3JldHVybiBlfTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCwiX19lc01vZHVsZSIse3ZhbHVlOiEwfSksdC5QYWNrYWdlPXQuUGFja2FnZUVycm9yPXZvaWQgMDt2YXIgYz1yKDIzNSkscz1mdW5jdGlvbihlKXtmdW5jdGlvbiB0KHQscil7dmFyIG49ZS5jYWxsKHRoaXMsdCl8fHRoaXM7cmV0dXJuIG4ucGFja2FnZT1yLG59cmV0dXJuIG8odCxlKSx0fShFcnJvcik7dC5QYWNrYWdlRXJyb3I9czt2YXIgbD1mdW5jdGlvbigpe2Z1bmN0aW9uIGUodCxyKXt2b2lkIDA9PT1yJiYocj0hMSksdGhpcy5pc0xvYWRlZD0hMSx0aGlzLmlzTG9hZGluZz0hMSx0aGlzLmhhc0ZhaWxlZD0hMSx0aGlzLmRlcGVuZGVudHM9W10sdGhpcy5kZXBlbmRlbmNpZXM9W10sdGhpcy5kZXBlbmRlbmN5Q291bnQ9MCx0aGlzLnByb3ZpZGVkPVtdLHRoaXMubmFtZT10LHRoaXMubm9Mb2FkPXIsZS5wYWNrYWdlcy5zZXQodCx0aGlzKSx0aGlzLnByb21pc2U9dGhpcy5tYWtlUHJvbWlzZSh0aGlzLm1ha2VEZXBlbmRlbmNpZXMoKSl9cmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlLnByb3RvdHlwZSwiY2FuTG9hZCIse2dldDpmdW5jdGlvbigpe3JldHVybiAwPT09dGhpcy5kZXBlbmRlbmN5Q291bnQmJiF0aGlzLm5vTG9hZCYmIXRoaXMuaXNMb2FkaW5nJiYhdGhpcy5oYXNGYWlsZWR9LGVudW1lcmFibGU6ITEsY29uZmlndXJhYmxlOiEwfSksZS5yZXNvbHZlUGF0aD1mdW5jdGlvbihlLHQpe3ZvaWQgMD09PXQmJih0PSEwKTt2YXIgcj17bmFtZTplLGFkZEV4dGVuc2lvbjp0fTtyZXR1cm4gYy5Mb2FkZXIucGF0aEZpbHRlcnMuZXhlY3V0ZShyKSxyLm5hbWV9LGUubG9hZEFsbD1mdW5jdGlvbigpe3ZhciBlLHQ7dHJ5e2Zvcih2YXIgcj1hKHRoaXMucGFja2FnZXMudmFsdWVzKCkpLG49ci5uZXh0KCk7IW4uZG9uZTtuPXIubmV4dCgpKXt2YXIgbz1uLnZhbHVlO28uY2FuTG9hZCYmby5sb2FkKCl9fWNhdGNoKHQpe2U9e2Vycm9yOnR9fWZpbmFsbHl7dHJ5e24mJiFuLmRvbmUmJih0PXIucmV0dXJuKSYmdC5jYWxsKHIpfWZpbmFsbHl7aWYoZSl0aHJvdyBlLmVycm9yfX19LGUucHJvdG90eXBlLm1ha2VEZXBlbmRlbmNpZXM9ZnVuY3Rpb24oKXt2YXIgdCxyLG49W10sbz1lLnBhY2thZ2VzLHM9dGhpcy5ub0xvYWQsbD10aGlzLm5hbWUsZD1bXTtjLkNPTkZJRy5kZXBlbmRlbmNpZXMuaGFzT3duUHJvcGVydHkobCk/ZC5wdXNoLmFwcGx5KGQsdShbXSxpKGMuQ09ORklHLmRlcGVuZGVuY2llc1tsXSkpKToiY29yZSIhPT1sJiZkLnB1c2goImNvcmUiKTt0cnl7Zm9yKHZhciBmPWEoZCksaD1mLm5leHQoKTshaC5kb25lO2g9Zi5uZXh0KCkpe3ZhciBwPWgudmFsdWUsbT1vLmdldChwKXx8bmV3IGUocCxzKTt0aGlzLmRlcGVuZGVuY2llcy5pbmRleE9mKG0pPDAmJihtLmFkZERlcGVuZGVudCh0aGlzLHMpLHRoaXMuZGVwZW5kZW5jaWVzLnB1c2gobSksbS5pc0xvYWRlZHx8KHRoaXMuZGVwZW5kZW5jeUNvdW50Kyssbi5wdXNoKG0ucHJvbWlzZSkpKX19Y2F0Y2goZSl7dD17ZXJyb3I6ZX19ZmluYWxseXt0cnl7aCYmIWguZG9uZSYmKHI9Zi5yZXR1cm4pJiZyLmNhbGwoZil9ZmluYWxseXtpZih0KXRocm93IHQuZXJyb3J9fXJldHVybiBufSxlLnByb3RvdHlwZS5tYWtlUHJvbWlzZT1mdW5jdGlvbihlKXt2YXIgdD10aGlzLHI9bmV3IFByb21pc2UoKGZ1bmN0aW9uKGUscil7dC5yZXNvbHZlPWUsdC5yZWplY3Q9cn0pKSxuPWMuQ09ORklHW3RoaXMubmFtZV18fHt9O3JldHVybiBuLnJlYWR5JiYocj1yLnRoZW4oKGZ1bmN0aW9uKGUpe3JldHVybiBuLnJlYWR5KHQubmFtZSl9KSkpLGUubGVuZ3RoJiYoZS5wdXNoKHIpLHI9UHJvbWlzZS5hbGwoZSkudGhlbigoZnVuY3Rpb24oZSl7cmV0dXJuIGUuam9pbigiLCAiKX0pKSksbi5mYWlsZWQmJnIuY2F0Y2goKGZ1bmN0aW9uKGUpe3JldHVybiBuLmZhaWxlZChuZXcgcyhlLHQubmFtZSkpfSkpLHJ9LGUucHJvdG90eXBlLmxvYWQ9ZnVuY3Rpb24oKXtpZighdGhpcy5pc0xvYWRlZCYmIXRoaXMuaXNMb2FkaW5nJiYhdGhpcy5ub0xvYWQpe3RoaXMuaXNMb2FkaW5nPSEwO3ZhciB0PWUucmVzb2x2ZVBhdGgodGhpcy5uYW1lKTtjLkNPTkZJRy5yZXF1aXJlP3RoaXMubG9hZEN1c3RvbSh0KTp0aGlzLmxvYWRTY3JpcHQodCl9fSxlLnByb3RvdHlwZS5sb2FkQ3VzdG9tPWZ1bmN0aW9uKGUpe3ZhciB0PXRoaXM7dHJ5e3ZhciByPWMuQ09ORklHLnJlcXVpcmUoZSk7ciBpbnN0YW5jZW9mIFByb21pc2U/ci50aGVuKChmdW5jdGlvbigpe3JldHVybiB0LmNoZWNrTG9hZCgpfSkpLmNhdGNoKChmdW5jdGlvbihyKXtyZXR1cm4gdC5mYWlsZWQoIkNhbid0IGxvYWQgXCIiK2UrJyJcbicrci5tZXNzYWdlLnRyaW0oKSl9KSk6dGhpcy5jaGVja0xvYWQoKX1jYXRjaChlKXt0aGlzLmZhaWxlZChlLm1lc3NhZ2UpfX0sZS5wcm90b3R5cGUubG9hZFNjcmlwdD1mdW5jdGlvbihlKXt2YXIgdD10aGlzLHI9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7ci5zcmM9ZSxyLmNoYXJzZXQ9IlVURi04IixyLm9ubG9hZD1mdW5jdGlvbihlKXtyZXR1cm4gdC5jaGVja0xvYWQoKX0sci5vbmVycm9yPWZ1bmN0aW9uKHIpe3JldHVybiB0LmZhaWxlZCgiQ2FuJ3QgbG9hZCBcIiIrZSsnIicpfSxkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHIpfSxlLnByb3RvdHlwZS5sb2FkZWQ9ZnVuY3Rpb24oKXt2YXIgZSx0LHIsbjt0aGlzLmlzTG9hZGVkPSEwLHRoaXMuaXNMb2FkaW5nPSExO3RyeXtmb3IodmFyIG89YSh0aGlzLmRlcGVuZGVudHMpLGk9by5uZXh0KCk7IWkuZG9uZTtpPW8ubmV4dCgpKXtpLnZhbHVlLnJlcXVpcmVtZW50U2F0aXNmaWVkKCl9fWNhdGNoKHQpe2U9e2Vycm9yOnR9fWZpbmFsbHl7dHJ5e2kmJiFpLmRvbmUmJih0PW8ucmV0dXJuKSYmdC5jYWxsKG8pfWZpbmFsbHl7aWYoZSl0aHJvdyBlLmVycm9yfX10cnl7Zm9yKHZhciB1PWEodGhpcy5wcm92aWRlZCksYz11Lm5leHQoKTshYy5kb25lO2M9dS5uZXh0KCkpe2MudmFsdWUubG9hZGVkKCl9fWNhdGNoKGUpe3I9e2Vycm9yOmV9fWZpbmFsbHl7dHJ5e2MmJiFjLmRvbmUmJihuPXUucmV0dXJuKSYmbi5jYWxsKHUpfWZpbmFsbHl7aWYocil0aHJvdyByLmVycm9yfX10aGlzLnJlc29sdmUodGhpcy5uYW1lKX0sZS5wcm90b3R5cGUuZmFpbGVkPWZ1bmN0aW9uKGUpe3RoaXMuaGFzRmFpbGVkPSEwLHRoaXMuaXNMb2FkaW5nPSExLHRoaXMucmVqZWN0KG5ldyBzKGUsdGhpcy5uYW1lKSl9LGUucHJvdG90eXBlLmNoZWNrTG9hZD1mdW5jdGlvbigpe3ZhciBlPXRoaXM7KChjLkNPTkZJR1t0aGlzLm5hbWVdfHx7fSkuY2hlY2tSZWFkeXx8ZnVuY3Rpb24oKXtyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCl9KSgpLnRoZW4oKGZ1bmN0aW9uKCl7cmV0dXJuIGUubG9hZGVkKCl9KSkuY2F0Y2goKGZ1bmN0aW9uKHQpe3JldHVybiBlLmZhaWxlZCh0KX0pKX0sZS5wcm90b3R5cGUucmVxdWlyZW1lbnRTYXRpc2ZpZWQ9ZnVuY3Rpb24oKXt0aGlzLmRlcGVuZGVuY3lDb3VudCYmKHRoaXMuZGVwZW5kZW5jeUNvdW50LS0sdGhpcy5jYW5Mb2FkJiZ0aGlzLmxvYWQoKSl9LGUucHJvdG90eXBlLnByb3ZpZGVzPWZ1bmN0aW9uKHQpe3ZhciByLG47dm9pZCAwPT09dCYmKHQ9W10pO3RyeXtmb3IodmFyIG89YSh0KSxpPW8ubmV4dCgpOyFpLmRvbmU7aT1vLm5leHQoKSl7dmFyIHU9aS52YWx1ZSxzPWUucGFja2FnZXMuZ2V0KHUpO3N8fChjLkNPTkZJRy5kZXBlbmRlbmNpZXNbdV18fChjLkNPTkZJRy5kZXBlbmRlbmNpZXNbdV09W10pLGMuQ09ORklHLmRlcGVuZGVuY2llc1t1XS5wdXNoKHUpLChzPW5ldyBlKHUsITApKS5pc0xvYWRpbmc9ITApLHRoaXMucHJvdmlkZWQucHVzaChzKX19Y2F0Y2goZSl7cj17ZXJyb3I6ZX19ZmluYWxseXt0cnl7aSYmIWkuZG9uZSYmKG49by5yZXR1cm4pJiZuLmNhbGwobyl9ZmluYWxseXtpZihyKXRocm93IHIuZXJyb3J9fX0sZS5wcm90b3R5cGUuYWRkRGVwZW5kZW50PWZ1bmN0aW9uKGUsdCl7dGhpcy5kZXBlbmRlbnRzLnB1c2goZSksdHx8dGhpcy5jaGVja05vTG9hZCgpfSxlLnByb3RvdHlwZS5jaGVja05vTG9hZD1mdW5jdGlvbigpe3ZhciBlLHQ7aWYodGhpcy5ub0xvYWQpe3RoaXMubm9Mb2FkPSExO3RyeXtmb3IodmFyIHI9YSh0aGlzLmRlcGVuZGVuY2llcyksbj1yLm5leHQoKTshbi5kb25lO249ci5uZXh0KCkpe24udmFsdWUuY2hlY2tOb0xvYWQoKX19Y2F0Y2godCl7ZT17ZXJyb3I6dH19ZmluYWxseXt0cnl7biYmIW4uZG9uZSYmKHQ9ci5yZXR1cm4pJiZ0LmNhbGwocil9ZmluYWxseXtpZihlKXRocm93IGUuZXJyb3J9fX19LGUucGFja2FnZXM9bmV3IE1hcCxlfSgpO3QuUGFja2FnZT1sfSwzODg6ZnVuY3Rpb24oZSx0LHIpe3ZhciBuPXRoaXMmJnRoaXMuX19hc3NpZ258fGZ1bmN0aW9uKCl7cmV0dXJuKG49T2JqZWN0LmFzc2lnbnx8ZnVuY3Rpb24oZSl7Zm9yKHZhciB0LHI9MSxuPWFyZ3VtZW50cy5sZW5ndGg7cjxuO3IrKylmb3IodmFyIG8gaW4gdD1hcmd1bWVudHNbcl0pT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHQsbykmJihlW29dPXRbb10pO3JldHVybiBlfSkuYXBwbHkodGhpcyxhcmd1bWVudHMpfSxvPXRoaXMmJnRoaXMuX192YWx1ZXN8fGZ1bmN0aW9uKGUpe3ZhciB0PSJmdW5jdGlvbiI9PXR5cGVvZiBTeW1ib2wmJlN5bWJvbC5pdGVyYXRvcixyPXQmJmVbdF0sbj0wO2lmKHIpcmV0dXJuIHIuY2FsbChlKTtpZihlJiYibnVtYmVyIj09dHlwZW9mIGUubGVuZ3RoKXJldHVybntuZXh0OmZ1bmN0aW9uKCl7cmV0dXJuIGUmJm4+PWUubGVuZ3RoJiYoZT12b2lkIDApLHt2YWx1ZTplJiZlW24rK10sZG9uZTohZX19fTt0aHJvdyBuZXcgVHlwZUVycm9yKHQ/Ik9iamVjdCBpcyBub3QgaXRlcmFibGUuIjoiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLiIpfSxhPXRoaXMmJnRoaXMuX19yZWFkfHxmdW5jdGlvbihlLHQpe3ZhciByPSJmdW5jdGlvbiI9PXR5cGVvZiBTeW1ib2wmJmVbU3ltYm9sLml0ZXJhdG9yXTtpZighcilyZXR1cm4gZTt2YXIgbixvLGE9ci5jYWxsKGUpLGk9W107dHJ5e2Zvcig7KHZvaWQgMD09PXR8fHQtLSA+MCkmJiEobj1hLm5leHQoKSkuZG9uZTspaS5wdXNoKG4udmFsdWUpfWNhdGNoKGUpe289e2Vycm9yOmV9fWZpbmFsbHl7dHJ5e24mJiFuLmRvbmUmJihyPWEucmV0dXJuKSYmci5jYWxsKGEpfWZpbmFsbHl7aWYobyl0aHJvdyBvLmVycm9yfX1yZXR1cm4gaX0saT10aGlzJiZ0aGlzLl9fc3ByZWFkQXJyYXl8fGZ1bmN0aW9uKGUsdCl7Zm9yKHZhciByPTAsbj10Lmxlbmd0aCxvPWUubGVuZ3RoO3I8bjtyKyssbysrKWVbb109dFtyXTtyZXR1cm4gZX07T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pLHQuQ09ORklHPXQuTWF0aEpheD10LlN0YXJ0dXA9dm9pZCAwO3ZhciB1LGM9cig1MTUpLHM9cig2NjYpOyFmdW5jdGlvbihlKXt2YXIgdSxjLGQ9bmV3IHMuUHJpb3JpdGl6ZWRMaXN0O2Z1bmN0aW9uIGYodCl7cmV0dXJuIHUudmlzaXRUcmVlKHQsZS5kb2N1bWVudCl9ZnVuY3Rpb24gaCgpe3U9bmV3IHQuTWF0aEpheC5fLmNvcmUuTW1sVHJlZS5TZXJpYWxpemVkTW1sVmlzaXRvci5TZXJpYWxpemVkTW1sVmlzaXRvcixjPXQuTWF0aEpheC5fLm1hdGhqYXgubWF0aGpheCxlLmlucHV0PWcoKSxlLm91dHB1dD1iKCksZS5hZGFwdG9yPXcoKSxlLmhhbmRsZXImJmMuaGFuZGxlcnMudW5yZWdpc3RlcihlLmhhbmRsZXIpLGUuaGFuZGxlcj1PKCksZS5oYW5kbGVyJiYoYy5oYW5kbGVycy5yZWdpc3RlcihlLmhhbmRsZXIpLGUuZG9jdW1lbnQ9TSgpKX1mdW5jdGlvbiBwKCl7dmFyIHQscjtlLmlucHV0JiZlLm91dHB1dCYmbSgpO3ZhciBuPWUub3V0cHV0P2Uub3V0cHV0Lm5hbWUudG9Mb3dlckNhc2UoKToiIjt0cnl7Zm9yKHZhciBhPW8oZS5pbnB1dCksaT1hLm5leHQoKTshaS5kb25lO2k9YS5uZXh0KCkpe3ZhciB1PWkudmFsdWUsYz11Lm5hbWUudG9Mb3dlckNhc2UoKTt4KGMsdSksdihjLHUpLGUub3V0cHV0JiZ5KGMsbix1KX19Y2F0Y2goZSl7dD17ZXJyb3I6ZX19ZmluYWxseXt0cnl7aSYmIWkuZG9uZSYmKHI9YS5yZXR1cm4pJiZyLmNhbGwoYSl9ZmluYWxseXtpZih0KXRocm93IHQuZXJyb3J9fX1mdW5jdGlvbiBtKCl7dC5NYXRoSmF4LnR5cGVzZXQ9ZnVuY3Rpb24odCl7dm9pZCAwPT09dCYmKHQ9bnVsbCksZS5kb2N1bWVudC5vcHRpb25zLmVsZW1lbnRzPXQsZS5kb2N1bWVudC5yZXNldCgpLGUuZG9jdW1lbnQucmVuZGVyKCl9LHQuTWF0aEpheC50eXBlc2V0UHJvbWlzZT1mdW5jdGlvbih0KXtyZXR1cm4gdm9pZCAwPT09dCYmKHQ9bnVsbCksZS5kb2N1bWVudC5vcHRpb25zLmVsZW1lbnRzPXQsZS5kb2N1bWVudC5yZXNldCgpLGMuaGFuZGxlUmV0cmllc0ZvcigoZnVuY3Rpb24oKXtlLmRvY3VtZW50LnJlbmRlcigpfSkpfSx0Lk1hdGhKYXgudHlwZXNldENsZWFyPWZ1bmN0aW9uKHQpe3ZvaWQgMD09PXQmJih0PW51bGwpLHQ/ZS5kb2N1bWVudC5jbGVhck1hdGhJdGVtc1dpdGhpbih0KTplLmRvY3VtZW50LmNsZWFyKCl9fWZ1bmN0aW9uIHkocixuLG8pe3ZhciBhPXIrIjIiK247dC5NYXRoSmF4W2FdPWZ1bmN0aW9uKHQscil7cmV0dXJuIHZvaWQgMD09PXImJihyPXt9KSxyLmZvcm1hdD1vLm5hbWUsZS5kb2N1bWVudC5jb252ZXJ0KHQscil9LHQuTWF0aEpheFthKyJQcm9taXNlIl09ZnVuY3Rpb24odCxyKXtyZXR1cm4gdm9pZCAwPT09ciYmKHI9e30pLHIuZm9ybWF0PW8ubmFtZSxjLmhhbmRsZVJldHJpZXNGb3IoKGZ1bmN0aW9uKCl7cmV0dXJuIGUuZG9jdW1lbnQuY29udmVydCh0LHIpfSkpfSx0Lk1hdGhKYXhbbisiU3R5bGVzaGVldCJdPWZ1bmN0aW9uKCl7cmV0dXJuIGUub3V0cHV0LnN0eWxlU2hlZXQoZS5kb2N1bWVudCl9LCJnZXRNZXRyaWNzRm9yImluIGUub3V0cHV0JiYodC5NYXRoSmF4LmdldE1ldHJpY3NGb3I9ZnVuY3Rpb24odCxyKXtyZXR1cm4gZS5vdXRwdXQuZ2V0TWV0cmljc0Zvcih0LHIpfSl9ZnVuY3Rpb24geChyLG4pe3ZhciBvPXQuTWF0aEpheC5fLmNvcmUuTWF0aEl0ZW0uU1RBVEU7dC5NYXRoSmF4W3IrIjJtbWwiXT1mdW5jdGlvbih0LHIpe3JldHVybiB2b2lkIDA9PT1yJiYocj17fSksci5lbmQ9by5DT05WRVJULHIuZm9ybWF0PW4ubmFtZSxmKGUuZG9jdW1lbnQuY29udmVydCh0LHIpKX0sdC5NYXRoSmF4W3IrIjJtbWxQcm9taXNlIl09ZnVuY3Rpb24odCxyKXtyZXR1cm4gdm9pZCAwPT09ciYmKHI9e30pLHIuZW5kPW8uQ09OVkVSVCxyLmZvcm1hdD1uLm5hbWUsYy5oYW5kbGVSZXRyaWVzRm9yKChmdW5jdGlvbigpe3JldHVybiBmKGUuZG9jdW1lbnQuY29udmVydCh0LHIpKX0pKX19ZnVuY3Rpb24gdihlLHIpe3QuTWF0aEpheFtlKyJSZXNldCJdPWZ1bmN0aW9uKCl7Zm9yKHZhciBlPVtdLHQ9MDt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKWVbdF09YXJndW1lbnRzW3RdO3JldHVybiByLnJlc2V0LmFwcGx5KHIsaShbXSxhKGUpKSl9fWZ1bmN0aW9uIGcoKXt2YXIgcixuLGE9W107dHJ5e2Zvcih2YXIgaT1vKHQuQ09ORklHLmlucHV0KSx1PWkubmV4dCgpOyF1LmRvbmU7dT1pLm5leHQoKSl7dmFyIGM9dS52YWx1ZSxzPWUuY29uc3RydWN0b3JzW2NdO2lmKCFzKXRocm93IEVycm9yKCdJbnB1dCBKYXggIicrYysnIiBpcyBub3QgZGVmaW5lZCAoaGFzIGl0IGJlZW4gbG9hZGVkPyknKTthLnB1c2gobmV3IHModC5NYXRoSmF4LmNvbmZpZ1tjXSkpfX1jYXRjaChlKXtyPXtlcnJvcjplfX1maW5hbGx5e3RyeXt1JiYhdS5kb25lJiYobj1pLnJldHVybikmJm4uY2FsbChpKX1maW5hbGx5e2lmKHIpdGhyb3cgci5lcnJvcn19cmV0dXJuIGF9ZnVuY3Rpb24gYigpe3ZhciByPXQuQ09ORklHLm91dHB1dDtpZighcilyZXR1cm4gbnVsbDt2YXIgbj1lLmNvbnN0cnVjdG9yc1tyXTtpZighbil0aHJvdyBFcnJvcignT3V0cHV0IEpheCAiJytyKyciIGlzIG5vdCBkZWZpbmVkIChoYXMgaXQgYmVlbiBsb2FkZWQ/KScpO3JldHVybiBuZXcgbih0Lk1hdGhKYXguY29uZmlnW3JdKX1mdW5jdGlvbiB3KCl7dmFyIHI9dC5DT05GSUcuYWRhcHRvcjtpZighcnx8Im5vbmUiPT09cilyZXR1cm4gbnVsbDt2YXIgbj1lLmNvbnN0cnVjdG9yc1tyXTtpZighbil0aHJvdyBFcnJvcignRE9NQWRhcHRvciAiJytyKyciIGlzIG5vdCBkZWZpbmVkIChoYXMgaXQgYmVlbiBsb2FkZWQ/KScpO3JldHVybiBuKHQuTWF0aEpheC5jb25maWdbcl0pfWZ1bmN0aW9uIE8oKXt2YXIgcixuLGE9dC5DT05GSUcuaGFuZGxlcjtpZighYXx8Im5vbmUiPT09YXx8IWUuYWRhcHRvcilyZXR1cm4gbnVsbDt2YXIgaT1lLmNvbnN0cnVjdG9yc1thXTtpZighaSl0aHJvdyBFcnJvcignSGFuZGxlciAiJythKyciIGlzIG5vdCBkZWZpbmVkIChoYXMgaXQgYmVlbiBsb2FkZWQ/KScpO3ZhciB1PW5ldyBpKGUuYWRhcHRvciw1KTt0cnl7Zm9yKHZhciBjPW8oZCkscz1jLm5leHQoKTshcy5kb25lO3M9Yy5uZXh0KCkpe3U9cy52YWx1ZS5pdGVtKHUpfX1jYXRjaChlKXtyPXtlcnJvcjplfX1maW5hbGx5e3RyeXtzJiYhcy5kb25lJiYobj1jLnJldHVybikmJm4uY2FsbChjKX1maW5hbGx5e2lmKHIpdGhyb3cgci5lcnJvcn19cmV0dXJuIHV9ZnVuY3Rpb24gTShyKXtyZXR1cm4gdm9pZCAwPT09ciYmKHI9bnVsbCksYy5kb2N1bWVudChyfHx0LkNPTkZJRy5kb2N1bWVudCxuKG4oe30sdC5NYXRoSmF4LmNvbmZpZy5vcHRpb25zKSx7SW5wdXRKYXg6ZS5pbnB1dCxPdXRwdXRKYXg6ZS5vdXRwdXR9KSl9ZS5jb25zdHJ1Y3RvcnM9e30sZS5pbnB1dD1bXSxlLm91dHB1dD1udWxsLGUuaGFuZGxlcj1udWxsLGUuYWRhcHRvcj1udWxsLGUuZWxlbWVudHM9bnVsbCxlLmRvY3VtZW50PW51bGwsZS5wcm9taXNlPW5ldyBQcm9taXNlKChmdW5jdGlvbih0LHIpe2UucHJvbWlzZVJlc29sdmU9dCxlLnByb21pc2VSZWplY3Q9cn0pKSxlLnBhZ2VQcm9taXNlPW5ldyBQcm9taXNlKChmdW5jdGlvbihlLHQpe3ZhciBuPXIuZy5kb2N1bWVudDtpZihuJiZuLnJlYWR5U3RhdGUmJiJjb21wbGV0ZSIhPT1uLnJlYWR5U3RhdGUmJiJpbnRlcmFjdGl2ZSIhPT1uLnJlYWR5U3RhdGUpe3ZhciBvPWZ1bmN0aW9uKCl7cmV0dXJuIGUoKX07bi5kZWZhdWx0Vmlldy5hZGRFdmVudExpc3RlbmVyKCJsb2FkIixvLCEwKSxuLmRlZmF1bHRWaWV3LmFkZEV2ZW50TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLG8sITApfWVsc2UgZSgpfSkpLGUudG9NTUw9ZixlLnJlZ2lzdGVyQ29uc3RydWN0b3I9ZnVuY3Rpb24odCxyKXtlLmNvbnN0cnVjdG9yc1t0XT1yfSxlLnVzZUhhbmRsZXI9ZnVuY3Rpb24oZSxyKXt2b2lkIDA9PT1yJiYocj0hMSksdC5DT05GSUcuaGFuZGxlciYmIXJ8fCh0LkNPTkZJRy5oYW5kbGVyPWUpfSxlLnVzZUFkYXB0b3I9ZnVuY3Rpb24oZSxyKXt2b2lkIDA9PT1yJiYocj0hMSksdC5DT05GSUcuYWRhcHRvciYmIXJ8fCh0LkNPTkZJRy5hZGFwdG9yPWUpfSxlLnVzZUlucHV0PWZ1bmN0aW9uKGUscil7dm9pZCAwPT09ciYmKHI9ITEpLGwmJiFyfHx0LkNPTkZJRy5pbnB1dC5wdXNoKGUpfSxlLnVzZU91dHB1dD1mdW5jdGlvbihlLHIpe3ZvaWQgMD09PXImJihyPSExKSx0LkNPTkZJRy5vdXRwdXQmJiFyfHwodC5DT05GSUcub3V0cHV0PWUpfSxlLmV4dGVuZEhhbmRsZXI9ZnVuY3Rpb24oZSx0KXt2b2lkIDA9PT10JiYodD0xMCksZC5hZGQoZSx0KX0sZS5kZWZhdWx0UmVhZHk9ZnVuY3Rpb24oKXtoKCkscCgpLGUucGFnZVByb21pc2UudGhlbigoZnVuY3Rpb24oKXtyZXR1cm4gdC5DT05GSUcucGFnZVJlYWR5KCl9KSkudGhlbigoZnVuY3Rpb24oKXtyZXR1cm4gZS5wcm9taXNlUmVzb2x2ZSgpfSkpLmNhdGNoKChmdW5jdGlvbih0KXtyZXR1cm4gZS5wcm9taXNlUmVqZWN0KHQpfSkpfSxlLmRlZmF1bHRQYWdlUmVhZHk9ZnVuY3Rpb24oKXtyZXR1cm4gdC5DT05GSUcudHlwZXNldCYmdC5NYXRoSmF4LnR5cGVzZXRQcm9taXNlP3QuTWF0aEpheC50eXBlc2V0UHJvbWlzZSh0LkNPTkZJRy5lbGVtZW50cyk6UHJvbWlzZS5yZXNvbHZlKCl9LGUuZ2V0Q29tcG9uZW50cz1oLGUubWFrZU1ldGhvZHM9cCxlLm1ha2VUeXBlc2V0TWV0aG9kcz1tLGUubWFrZU91dHB1dE1ldGhvZHM9eSxlLm1ha2VNbWxNZXRob2RzPXgsZS5tYWtlUmVzZXRNZXRob2Q9dixlLmdldElucHV0SmF4PWcsZS5nZXRPdXRwdXRKYXg9YixlLmdldEFkYXB0b3I9dyxlLmdldEhhbmRsZXI9TyxlLmdldERvY3VtZW50PU19KHU9dC5TdGFydHVwfHwodC5TdGFydHVwPXt9KSksdC5NYXRoSmF4PWMuTWF0aEpheCx2b2lkIDA9PT10Lk1hdGhKYXguXy5zdGFydHVwJiYoYy5jb21iaW5lRGVmYXVsdHModC5NYXRoSmF4LmNvbmZpZywic3RhcnR1cCIse2lucHV0OltdLG91dHB1dDoiIixoYW5kbGVyOm51bGwsYWRhcHRvcjpudWxsLGRvY3VtZW50OiJ1bmRlZmluZWQiPT10eXBlb2YgZG9jdW1lbnQ/IiI6ZG9jdW1lbnQsZWxlbWVudHM6bnVsbCx0eXBlc2V0OiEwLHJlYWR5OnUuZGVmYXVsdFJlYWR5LmJpbmQodSkscGFnZVJlYWR5OnUuZGVmYXVsdFBhZ2VSZWFkeS5iaW5kKHUpfSksYy5jb21iaW5lV2l0aE1hdGhKYXgoe3N0YXJ0dXA6dSxvcHRpb25zOnt9fSkpLHQuQ09ORklHPXQuTWF0aEpheC5jb25maWcuc3RhcnR1cDt2YXIgbD0wIT09dC5DT05GSUcuaW5wdXQubGVuZ3RofSw1MjU6ZnVuY3Rpb24oZSx0LHIpe3ZhciBuLG89dGhpcyYmdGhpcy5fX2V4dGVuZHN8fChuPWZ1bmN0aW9uKGUsdCl7cmV0dXJuKG49T2JqZWN0LnNldFByb3RvdHlwZU9mfHx7X19wcm90b19fOltdfWluc3RhbmNlb2YgQXJyYXkmJmZ1bmN0aW9uKGUsdCl7ZS5fX3Byb3RvX189dH18fGZ1bmN0aW9uKGUsdCl7Zm9yKHZhciByIGluIHQpT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHQscikmJihlW3JdPXRbcl0pfSkoZSx0KX0sZnVuY3Rpb24oZSx0KXtpZigiZnVuY3Rpb24iIT10eXBlb2YgdCYmbnVsbCE9PXQpdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2xhc3MgZXh0ZW5kcyB2YWx1ZSAiK1N0cmluZyh0KSsiIGlzIG5vdCBhIGNvbnN0cnVjdG9yIG9yIG51bGwiKTtmdW5jdGlvbiByKCl7dGhpcy5jb25zdHJ1Y3Rvcj1lfW4oZSx0KSxlLnByb3RvdHlwZT1udWxsPT09dD9PYmplY3QuY3JlYXRlKHQpOihyLnByb3RvdHlwZT10LnByb3RvdHlwZSxuZXcgcil9KSxhPXRoaXMmJnRoaXMuX192YWx1ZXN8fGZ1bmN0aW9uKGUpe3ZhciB0PSJmdW5jdGlvbiI9PXR5cGVvZiBTeW1ib2wmJlN5bWJvbC5pdGVyYXRvcixyPXQmJmVbdF0sbj0wO2lmKHIpcmV0dXJuIHIuY2FsbChlKTtpZihlJiYibnVtYmVyIj09dHlwZW9mIGUubGVuZ3RoKXJldHVybntuZXh0OmZ1bmN0aW9uKCl7cmV0dXJuIGUmJm4+PWUubGVuZ3RoJiYoZT12b2lkIDApLHt2YWx1ZTplJiZlW24rK10sZG9uZTohZX19fTt0aHJvdyBuZXcgVHlwZUVycm9yKHQ/Ik9iamVjdCBpcyBub3QgaXRlcmFibGUuIjoiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLiIpfSxpPXRoaXMmJnRoaXMuX19yZWFkfHxmdW5jdGlvbihlLHQpe3ZhciByPSJmdW5jdGlvbiI9PXR5cGVvZiBTeW1ib2wmJmVbU3ltYm9sLml0ZXJhdG9yXTtpZighcilyZXR1cm4gZTt2YXIgbixvLGE9ci5jYWxsKGUpLGk9W107dHJ5e2Zvcig7KHZvaWQgMD09PXR8fHQtLSA+MCkmJiEobj1hLm5leHQoKSkuZG9uZTspaS5wdXNoKG4udmFsdWUpfWNhdGNoKGUpe289e2Vycm9yOmV9fWZpbmFsbHl7dHJ5e24mJiFuLmRvbmUmJihyPWEucmV0dXJuKSYmci5jYWxsKGEpfWZpbmFsbHl7aWYobyl0aHJvdyBvLmVycm9yfX1yZXR1cm4gaX0sdT10aGlzJiZ0aGlzLl9fc3ByZWFkQXJyYXl8fGZ1bmN0aW9uKGUsdCl7Zm9yKHZhciByPTAsbj10Lmxlbmd0aCxvPWUubGVuZ3RoO3I8bjtyKyssbysrKWVbb109dFtyXTtyZXR1cm4gZX07T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pLHQuRnVuY3Rpb25MaXN0PXZvaWQgMDt2YXIgYz1mdW5jdGlvbihlKXtmdW5jdGlvbiB0KCl7cmV0dXJuIG51bGwhPT1lJiZlLmFwcGx5KHRoaXMsYXJndW1lbnRzKXx8dGhpc31yZXR1cm4gbyh0LGUpLHQucHJvdG90eXBlLmV4ZWN1dGU9ZnVuY3Rpb24oKXtmb3IodmFyIGUsdCxyPVtdLG49MDtuPGFyZ3VtZW50cy5sZW5ndGg7bisrKXJbbl09YXJndW1lbnRzW25dO3RyeXtmb3IodmFyIG89YSh0aGlzKSxjPW8ubmV4dCgpOyFjLmRvbmU7Yz1vLm5leHQoKSl7dmFyIHM9Yy52YWx1ZSxsPXMuaXRlbS5hcHBseShzLHUoW10saShyKSkpO2lmKCExPT09bClyZXR1cm4hMX19Y2F0Y2godCl7ZT17ZXJyb3I6dH19ZmluYWxseXt0cnl7YyYmIWMuZG9uZSYmKHQ9by5yZXR1cm4pJiZ0LmNhbGwobyl9ZmluYWxseXtpZihlKXRocm93IGUuZXJyb3J9fXJldHVybiEwfSx0LnByb3RvdHlwZS5hc3luY0V4ZWN1dGU9ZnVuY3Rpb24oKXtmb3IodmFyIGU9W10sdD0wO3Q8YXJndW1lbnRzLmxlbmd0aDt0KyspZVt0XT1hcmd1bWVudHNbdF07dmFyIHI9LTEsbj10aGlzLml0ZW1zO3JldHVybiBuZXcgUHJvbWlzZSgoZnVuY3Rpb24odCxvKXshZnVuY3Rpb24gYSgpe2Zvcih2YXIgYzsrK3I8bi5sZW5ndGg7KXt2YXIgcz0oYz1uW3JdKS5pdGVtLmFwcGx5KGMsdShbXSxpKGUpKSk7aWYocyBpbnN0YW5jZW9mIFByb21pc2UpcmV0dXJuIHZvaWQgcy50aGVuKGEpLmNhdGNoKChmdW5jdGlvbihlKXtyZXR1cm4gbyhlKX0pKTtpZighMT09PXMpcmV0dXJuIHZvaWQgdCghMSl9dCghMCl9KCl9KSl9LHR9KHIoNjY2KS5Qcmlvcml0aXplZExpc3QpO3QuRnVuY3Rpb25MaXN0PWN9LDY2NjpmdW5jdGlvbihlLHQpe09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LCJfX2VzTW9kdWxlIix7dmFsdWU6ITB9KSx0LlByaW9yaXRpemVkTGlzdD12b2lkIDA7dmFyIHI9ZnVuY3Rpb24oKXtmdW5jdGlvbiBlKCl7dGhpcy5pdGVtcz1bXSx0aGlzLml0ZW1zPVtdfXJldHVybiBlLnByb3RvdHlwZVtTeW1ib2wuaXRlcmF0b3JdPWZ1bmN0aW9uKCl7dmFyIGU9MCx0PXRoaXMuaXRlbXM7cmV0dXJue25leHQ6ZnVuY3Rpb24oKXtyZXR1cm57dmFsdWU6dFtlKytdLGRvbmU6ZT50Lmxlbmd0aH19fX0sZS5wcm90b3R5cGUuYWRkPWZ1bmN0aW9uKHQscil7dm9pZCAwPT09ciYmKHI9ZS5ERUZBVUxUUFJJT1JJVFkpO3ZhciBuPXRoaXMuaXRlbXMubGVuZ3RoO2Rve24tLX13aGlsZShuPj0wJiZyPHRoaXMuaXRlbXNbbl0ucHJpb3JpdHkpO3JldHVybiB0aGlzLml0ZW1zLnNwbGljZShuKzEsMCx7aXRlbTp0LHByaW9yaXR5OnJ9KSx0fSxlLnByb3RvdHlwZS5yZW1vdmU9ZnVuY3Rpb24oZSl7dmFyIHQ9dGhpcy5pdGVtcy5sZW5ndGg7ZG97dC0tfXdoaWxlKHQ+PTAmJnRoaXMuaXRlbXNbdF0uaXRlbSE9PWUpO3Q+PTAmJnRoaXMuaXRlbXMuc3BsaWNlKHQsMSl9LGUucHJvdG90eXBlLnRvQXJyYXk9ZnVuY3Rpb24oKXtyZXR1cm4gQXJyYXkuZnJvbSh0aGlzKX0sZS5ERUZBVUxUUFJJT1JJVFk9NSxlfSgpO3QuUHJpb3JpdGl6ZWRMaXN0PXJ9fSx0PXt9O2Z1bmN0aW9uIHIobil7dmFyIG89dFtuXTtpZih2b2lkIDAhPT1vKXJldHVybiBvLmV4cG9ydHM7dmFyIGE9dFtuXT17ZXhwb3J0czp7fX07cmV0dXJuIGVbbl0uY2FsbChhLmV4cG9ydHMsYSxhLmV4cG9ydHMsciksYS5leHBvcnRzfXIuZz1mdW5jdGlvbigpe2lmKCJvYmplY3QiPT10eXBlb2YgZ2xvYmFsVGhpcylyZXR1cm4gZ2xvYmFsVGhpczt0cnl7cmV0dXJuIHRoaXN8fG5ldyBGdW5jdGlvbigicmV0dXJuIHRoaXMiKSgpfWNhdGNoKGUpe2lmKCJvYmplY3QiPT10eXBlb2Ygd2luZG93KXJldHVybiB3aW5kb3d9fSgpLGZ1bmN0aW9uKCl7dmFyIGU9cig1MTUpLHQ9cigyMzUpLG49cigyNjUpLG89cigzODgpOygwLGUuY29tYmluZVdpdGhNYXRoSmF4KSh7Xzp7Y29tcG9uZW50czp7bG9hZGVyOnQscGFja2FnZTpuLHN0YXJ0dXA6b319fSk7dmFyIGEsaT17dGV4OiJbbWF0aGpheF0vaW5wdXQvdGV4L2V4dGVuc2lvbnMiLHNyZToiW21hdGhqYXhdL3NyZS8iKygidW5kZWZpbmVkIj09dHlwZW9mIHdpbmRvdz8ic3JlLW5vZGUiOiJzcmVfYnJvd3NlciIpfSx1PVsiW3RleF0vYWN0aW9uIiwiW3RleF0vYW1zIiwiW3RleF0vYW1zY2QiLCJbdGV4XS9iYm94IiwiW3RleF0vYm9sZHN5bWJvbCIsIlt0ZXhdL2JyYWtldCIsIlt0ZXhdL2J1c3Nwcm9vZnMiLCJbdGV4XS9jYW5jZWwiLCJbdGV4XS9jb2xvciIsIlt0ZXhdL2NvbmZpZ21hY3JvcyIsIlt0ZXhdL2VuY2xvc2UiLCJbdGV4XS9leHRwZmVpbCIsIlt0ZXhdL2h0bWwiLCJbdGV4XS9taGNoZW0iLCJbdGV4XS9uZXdjb21tYW5kIiwiW3RleF0vbm9lcnJvcnMiLCJbdGV4XS9ub3VuZGVmaW5lZCIsIlt0ZXhdL3BoeXNpY3MiLCJbdGV4XS9yZXF1aXJlIiwiW3RleF0vdGFnZm9ybWF0IiwiW3RleF0vdGV4dG1hY3JvcyIsIlt0ZXhdL3VuaWNvZGUiLCJbdGV4XS92ZXJiIl0sYz17c3RhcnR1cDpbImxvYWRlciJdLCJpbnB1dC90ZXgiOlsiaW5wdXQvdGV4LWJhc2UiLCJbdGV4XS9hbXMiLCJbdGV4XS9uZXdjb21tYW5kIiwiW3RleF0vbm91bmRlZmluZWQiLCJbdGV4XS9yZXF1aXJlIiwiW3RleF0vYXV0b2xvYWQiLCJbdGV4XS9jb25maWdtYWNyb3MiXSwiaW5wdXQvdGV4LWZ1bGwiOlsiaW5wdXQvdGV4LWJhc2UiLCJbdGV4XS9hbGwtcGFja2FnZXMiXS5jb25jYXQodSksIlt0ZXhdL2FsbC1wYWNrYWdlcyI6dX07ZnVuY3Rpb24gcyhlLHQpeyhudWxsPT10fHx0PmUubGVuZ3RoKSYmKHQ9ZS5sZW5ndGgpO2Zvcih2YXIgcj0wLG49bmV3IEFycmF5KHQpO3I8dDtyKyspbltyXT1lW3JdO3JldHVybiBufSgwLGUuY29tYmluZURlZmF1bHRzKShNYXRoSmF4LmNvbmZpZy5sb2FkZXIsImRlcGVuZGVuY2llcyIseyJhMTF5L3NlbWFudGljLWVucmljaCI6WyJpbnB1dC9tbWwiLCJbc3JlXSJdLCJhMTF5L2NvbXBsZXhpdHkiOlsiYTExeS9zZW1hbnRpYy1lbnJpY2giXSwiYTExeS9leHBsb3JlciI6WyJhMTF5L3NlbWFudGljLWVucmljaCIsInVpL21lbnUiXSwiW3RleF0vYWxsLXBhY2thZ2VzIjpbImlucHV0L3RleC1iYXNlIl0sIlt0ZXhdL2FjdGlvbiI6WyJpbnB1dC90ZXgtYmFzZSIsIlt0ZXhdL25ld2NvbW1hbmQiXSwiW3RleF0vYXV0b2xvYWQiOlsiaW5wdXQvdGV4LWJhc2UiLCJbdGV4XS9yZXF1aXJlIl0sIlt0ZXhdL2FtcyI6WyJpbnB1dC90ZXgtYmFzZSJdLCJbdGV4XS9hbXNjZCI6WyJpbnB1dC90ZXgtYmFzZSJdLCJbdGV4XS9iYm94IjpbImlucHV0L3RleC1iYXNlIiwiW3RleF0vYW1zIiwiW3RleF0vbmV3Y29tbWFuZCJdLCJbdGV4XS9ib2xkc3ltYm9sIjpbImlucHV0L3RleC1iYXNlIl0sIlt0ZXhdL2JyYWtldCI6WyJpbnB1dC90ZXgtYmFzZSJdLCJbdGV4XS9idXNzcHJvb2ZzIjpbImlucHV0L3RleC1iYXNlIl0sIlt0ZXhdL2NhbmNlbCI6WyJpbnB1dC90ZXgtYmFzZSIsIlt0ZXhdL2VuY2xvc2UiXSwiW3RleF0vY29sb3IiOlsiaW5wdXQvdGV4LWJhc2UiXSwiW3RleF0vY29sb3J2MiI6WyJpbnB1dC90ZXgtYmFzZSJdLCJbdGV4XS9jb25maWdtYWNyb3MiOlsiaW5wdXQvdGV4LWJhc2UiLCJbdGV4XS9uZXdjb21tYW5kIl0sIlt0ZXhdL2VuY2xvc2UiOlsiaW5wdXQvdGV4LWJhc2UiXSwiW3RleF0vZXh0cGZlaWwiOlsiaW5wdXQvdGV4LWJhc2UiLCJbdGV4XS9uZXdjb21tYW5kIiwiW3RleF0vYW1zIl0sIlt0ZXhdL2h0bWwiOlsiaW5wdXQvdGV4LWJhc2UiXSwiW3RleF0vbWhjaGVtIjpbImlucHV0L3RleC1iYXNlIiwiW3RleF0vYW1zIl0sIlt0ZXhdL25ld2NvbW1hbmQiOlsiaW5wdXQvdGV4LWJhc2UiXSwiW3RleF0vbm9lcnJvcnMiOlsiaW5wdXQvdGV4LWJhc2UiXSwiW3RleF0vbm91bmRlZmluZWQiOlsiaW5wdXQvdGV4LWJhc2UiXSwiW3RleF0vcGh5c2ljcyI6WyJpbnB1dC90ZXgtYmFzZSJdLCJbdGV4XS9yZXF1aXJlIjpbImlucHV0L3RleC1iYXNlIl0sIlt0ZXhdL3RhZ2Zvcm1hdCI6WyJpbnB1dC90ZXgtYmFzZSJdLCJbdGV4XS90ZXh0bWFjcm9zIjpbImlucHV0L3RleC1iYXNlIl0sIlt0ZXhdL3VuaWNvZGUiOlsiaW5wdXQvdGV4LWJhc2UiXSwiW3RleF0vdmVyYiI6WyJpbnB1dC90ZXgtYmFzZSJdfSksKDAsZS5jb21iaW5lRGVmYXVsdHMpKE1hdGhKYXguY29uZmlnLmxvYWRlciwicGF0aHMiLGkpLCgwLGUuY29tYmluZURlZmF1bHRzKShNYXRoSmF4LmNvbmZpZy5sb2FkZXIsInByb3ZpZGVzIixjKSwoMCxlLmNvbWJpbmVEZWZhdWx0cykoTWF0aEpheC5jb25maWcubG9hZGVyLCJzb3VyY2UiLHsiW3RleF0vYW1zQ2QiOiJbdGV4XS9hbXNjZCIsIlt0ZXhdL2NvbG9yVjIiOiJbdGV4XS9jb2xvcnYyIiwiW3RleF0vY29uZmlnTWFjcm9zIjoiW3RleF0vY29uZmlnbWFjcm9zIiwiW3RleF0vdGFnRm9ybWF0IjoiW3RleF0vdGFnZm9ybWF0In0pLHQuTG9hZGVyLnByZUxvYWQoImxvYWRlciIpLHQuTG9hZGVyLmxvYWQuYXBwbHkodC5Mb2FkZXIsKGE9dC5DT05GSUcubG9hZCxmdW5jdGlvbihlKXtpZihBcnJheS5pc0FycmF5KGUpKXJldHVybiBzKGUpfShhKXx8ZnVuY3Rpb24oZSl7aWYoInVuZGVmaW5lZCIhPXR5cGVvZiBTeW1ib2wmJm51bGwhPWVbU3ltYm9sLml0ZXJhdG9yXXx8bnVsbCE9ZVsiQEBpdGVyYXRvciJdKXJldHVybiBBcnJheS5mcm9tKGUpfShhKXx8ZnVuY3Rpb24oZSx0KXtpZihlKXtpZigic3RyaW5nIj09dHlwZW9mIGUpcmV0dXJuIHMoZSx0KTt2YXIgcj1PYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZSkuc2xpY2UoOCwtMSk7cmV0dXJuIk9iamVjdCI9PT1yJiZlLmNvbnN0cnVjdG9yJiYocj1lLmNvbnN0cnVjdG9yLm5hbWUpLCJNYXAiPT09cnx8IlNldCI9PT1yP0FycmF5LmZyb20oZSk6IkFyZ3VtZW50cyI9PT1yfHwvXig/OlVpfEkpbnQoPzo4fDE2fDMyKSg/OkNsYW1wZWQpP0FycmF5JC8udGVzdChyKT9zKGUsdCk6dm9pZCAwfX0oYSl8fGZ1bmN0aW9uKCl7dGhyb3cgbmV3IFR5cGVFcnJvcigiSW52YWxpZCBhdHRlbXB0IHRvIHNwcmVhZCBub24taXRlcmFibGUgaW5zdGFuY2UuXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuIil9KCkpKS50aGVuKChmdW5jdGlvbigpe3JldHVybiB0LkNPTkZJRy5yZWFkeSgpfSkpLmNhdGNoKChmdW5jdGlvbihlKXtyZXR1cm4gdC5DT05GSUcuZmFpbGVkKGUpfSkpfSgpfSgpOw=="></script><!--URL:../assets/vendor/mathjax/startup.js-->
</body>
</html><!--Generated by HTMLArk 2026-04-19 00:22:41.877094. Original URL site/print_page/index.html-->