mirror of
https://gitlab.easter-eggs.com/ee/ldapsaisie.git
synced 2024-11-23 02:19:07 +01:00
8476 lines
No EOL
986 KiB
HTML
8476 lines
No EOL
986 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<html class="no-js" lang="fr"><head>
|
||
<meta charset="utf-8"/>
|
||
<meta content="width=device-width,initial-scale=1" name="viewport"/>
|
||
<meta content="Documentation" name="description"/>
|
||
<meta content="Benjamin Renard <brenard@easter-eggs.com / brenard@zionetrix.net>" name="author"/>
|
||
<link href="https://ldapsaisie.org/doc/print_page/" rel="canonical"/>
|
||
<link href="../assets/images/favicon.png" rel="icon"/>
|
||
<meta content="mkdocs-1.5.3, mkdocs-material-9.5.10" name="generator"/>
|
||
<title>Documentation - LdapSaisie</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-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%207V5h4v2H2Z%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%206h7v2H2v-2Z%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%206h7v2H2v-2Z%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%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%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%7D.md-typeset%20a%20code%7Bcolor%3Acurrentcolor%3Btransition%3Abackground-color%20125ms%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%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%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%7Bborder-bottom%3A.05rem%20dotted%20var%28--md-default-fg-color--light%29%3Bcursor%3Ahelp%3Btext-decoration%3Anone%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%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%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%3A-webkit-fit-content%3Bwidth%3A-moz-fit-content%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%7Bfilter%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%202v14h2V3h12V1Z%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%3Bposition%3Aabsolute%3Bright%3A.5em%3Btop%3A.5em%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%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.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%2011h12Z%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%206-1.41-1.42Z%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%209h14V7H3v2m0%204h14v-2H3v2m0%204h14v-2H3v2m16%200h2v-2h-2v2m0-10v2h2V7h-2m0%206h2v-2h-2v2Z%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%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%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%20svg%7Bfill%3Acurrentcolor%3Bflex-shrink%3A0%3Bheight%3A1.3em%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.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%7B-webkit-backface-visibility%3Ahidden%3Bbackface-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%3A0fr%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%3A1fr%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%3A1fr%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.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-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%7Bmin-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.82V8l-6-6m6.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%2022l-3.08-3.1m-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.5Z%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%7B-webkit-backface-visibility%3Ahidden%3Bbackface-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%7B-webkit-backface-visibility%3Ahidden%3Bbackface-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%7Bscrollbar-gutter%3Astable%3B-webkit-backface-visibility%3Ahidden%3Bbackface-visibility%3Ahidden%3Bmargin%3A0%20.2rem%3Boverflow-y%3Aauto%3Bscrollbar-color%3Avar%28--md-default-fg-color--lighter%29%20%230000%3Bscrollbar-width%3Athin%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%200ZM5%203.25a.75.75%200%201%200-1.5%200%20.75.75%200%200%200%201.5%200Zm6.75.75a.75.75%200%201%200%200-1.5.75.75%200%200%200%200%201.5Zm-3%208.75a.75.75%200%201%200-1.5%200%20.75.75%200%200%200%201.5%200Z%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.495%202.495%200%200%201%202%2011.5Zm10.5-1h-8a1%201%200%200%200-1%201v6.708A2.486%202.486%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.249.249%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.25Zm0%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-.41L8%202.694Z%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.752%201.752%200%200%201%201%207.775Zm1.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-2Z%22/%3E%3C/svg%3E%27%29%7D.md-source%7B-webkit-backface-visibility%3Ahidden%3Bbackface-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-2v6Z%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.68L23%2012m-10%205h-2v-2h2v2m0-4h-2V7h2v6Z%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-5V3H9m0%205h2v9H9V8m4%200h2v9h-2V8Z%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-12V5l-9-4m0%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.3Z%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%7B-webkit-backface-visibility%3Ahidden%3Bbackface-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%204h-2M9.53%209l-1.06%206h6l1.06-6h-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-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%202Z%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%202Z%22/%3E%3C/svg%3E%27%29%3B--md-tooltip-width%3A20rem%7D.md-tooltip%7B-webkit-backface-visibility%3Ahidden%3Bbackface-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-weight%3A400%3Boutline%3Anone%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%3Axxx%3Blist-style%3Anone%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%28xxx%29%3Bcounter-increment%3Axxx%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%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%206.5.1%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%202023%20Fonticons%2C%20Inc.--%3E%3Cpath%20d%3D%22M137.4%20374.6c12.5%2012.5%2032.8%2012.5%2045.3%200l128-128c9.2-9.2%2011.9-22.9%206.9-34.9S301%20191.9%20288%20191.9L32%20192c-12.9%200-24.6%207.8-29.6%2019.8s-2.2%2025.7%206.9%2034.9l128%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__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.06l6.06-6.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%201c-1.3%200-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-2Z%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%202Z%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.58.58%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.27Z%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.59%2021%207Z%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-10Z%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%202%201%2021Z%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%2012%2019%206.41Z%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.5V20M12%202c2.75%200%205.1%201%207.05%202.95C21%206.9%2022%209.25%2022%2012s-1%205.1-2.95%207.05C17.1%2021%2014.75%2022%2012%2022s-5.1-1-7.05-2.95C3%2017.1%202%2014.75%202%2012s1-5.1%202.95-7.05C6.9%203%209.25%202%2012%202Z%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-2v-1m10-8v6c0%205.5-3.8%2010.7-9%2012-5.2-1.3-9-6.5-9-12V5l9-4%209%204m-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-1h2v-1m-6%202h2v-1h-2v1Z%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-4V4h1V2H7m4%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-4V4h4v3Z%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-4V7H5v6h3l-2%204Z%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%2013H21V7h-2Z%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%20svg%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%3A-webkit-min-content%3Bwidth%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%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%206-1.41-1.42Z%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%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%3Bpadding-right%3A.5882352941em%7D.highlighttable%20.linenodiv%20pre%7Bcolor%3Avar%28--md-default-fg-color--light%29%3Btext-align%3Aright%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%206%201.41-1.42Z%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%206-1.41-1.42Z%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.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%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%2012Zm16.28-2.72a.751.751%200%200%200-.018-1.042.751.751%200%200%200-1.042-.018l-5.97%205.97-2.47-2.47a.751.751%200%200%200-1.042.018.751.751%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%2012Zm16.28-2.72a.751.751%200%200%200-.018-1.042.751.751%200%200%200-1.042-.018l-5.97%205.97-2.47-2.47a.751.751%200%200%200-1.042.018.751.751%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%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.7e359304.min.css-->
|
||
<link href="data:text/css,%40media%20screen%7B%5Bdata-md-color-scheme%3Dslate%5D%7B--md-default-fg-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C90%25%2C0.82%29%3B--md-default-fg-color--light%3Ahsla%28var%28--md-hue%29%2C15%25%2C90%25%2C0.56%29%3B--md-default-fg-color--lighter%3Ahsla%28var%28--md-hue%29%2C15%25%2C90%25%2C0.32%29%3B--md-default-fg-color--lightest%3Ahsla%28var%28--md-hue%29%2C15%25%2C90%25%2C0.12%29%3B--md-default-bg-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C14%25%2C1%29%3B--md-default-bg-color--light%3Ahsla%28var%28--md-hue%29%2C15%25%2C14%25%2C0.54%29%3B--md-default-bg-color--lighter%3Ahsla%28var%28--md-hue%29%2C15%25%2C14%25%2C0.26%29%3B--md-default-bg-color--lightest%3Ahsla%28var%28--md-hue%29%2C15%25%2C14%25%2C0.07%29%3B--md-code-fg-color%3Ahsla%28var%28--md-hue%29%2C18%25%2C86%25%2C0.82%29%3B--md-code-bg-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C18%25%2C1%29%3B--md-code-hl-color%3A%232977ff%3B--md-code-hl-color--light%3A%232977ff1a%3B--md-code-hl-number-color%3A%23e6695b%3B--md-code-hl-special-color%3A%23f06090%3B--md-code-hl-function-color%3A%23c973d9%3B--md-code-hl-constant-color%3A%239383e2%3B--md-code-hl-keyword-color%3A%236791e0%3B--md-code-hl-string-color%3A%232fb170%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-kbd-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C90%25%2C0.12%29%3B--md-typeset-kbd-accent-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C90%25%2C0.2%29%3B--md-typeset-kbd-border-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C14%25%2C1%29%3B--md-typeset-mark-color%3A%234287ff4d%3B--md-typeset-table-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C95%25%2C0.12%29%3B--md-typeset-table-color--light%3Ahsla%28var%28--md-hue%29%2C15%25%2C95%25%2C0.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-footer-bg-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C10%25%2C0.87%29%3B--md-footer-bg-color--dark%3Ahsla%28var%28--md-hue%29%2C15%25%2C8%25%2C1%29%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%2300000040%2C0%200%200.05rem%20%2300000040%3B--md-shadow-z3%3A0%200.2rem%200.5rem%20%230006%2C0%200%200.05rem%20%2300000059%3Bcolor-scheme%3Adark%7D%5Bdata-md-color-scheme%3Dslate%5D%20img%5Bsrc%24%3D%22%23gh-light-mode-only%22%5D%2C%5Bdata-md-color-scheme%3Dslate%5D%20img%5Bsrc%24%3D%22%23only-light%22%5D%7Bdisplay%3Anone%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dpink%5D%7B--md-typeset-a-color%3A%23ed5487%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dpurple%5D%7B--md-typeset-a-color%3A%23c46fd3%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Ddeep-purple%5D%7B--md-typeset-a-color%3A%23a47bea%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dindigo%5D%7B--md-typeset-a-color%3A%235488e8%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dteal%5D%7B--md-typeset-a-color%3A%2300ccb8%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dgreen%5D%7B--md-typeset-a-color%3A%2371c174%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Ddeep-orange%5D%7B--md-typeset-a-color%3A%23ff764d%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dbrown%5D%7B--md-typeset-a-color%3A%23c1775c%7D%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dblack%5D%2C%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dblue-grey%5D%2C%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dgrey%5D%2C%5Bdata-md-color-scheme%3Dslate%5D%5Bdata-md-color-primary%3Dwhite%5D%7B--md-typeset-a-color%3A%235e8bde%7D%5Bdata-md-color-switching%5D%20%2A%2C%5Bdata-md-color-switching%5D%20%3Aafter%2C%5Bdata-md-color-switching%5D%20%3Abefore%7Btransition-duration%3A0ms%21important%7D%7D%5Bdata-md-color-accent%3Dred%5D%7B--md-accent-fg-color%3A%23ff1947%3B--md-accent-fg-color--transparent%3A%23ff19471a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dpink%5D%7B--md-accent-fg-color%3A%23f50056%3B--md-accent-fg-color--transparent%3A%23f500561a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dpurple%5D%7B--md-accent-fg-color%3A%23df41fb%3B--md-accent-fg-color--transparent%3A%23df41fb1a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Ddeep-purple%5D%7B--md-accent-fg-color%3A%237c4dff%3B--md-accent-fg-color--transparent%3A%237c4dff1a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dindigo%5D%7B--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-accent%3Dblue%5D%7B--md-accent-fg-color%3A%234287ff%3B--md-accent-fg-color--transparent%3A%234287ff1a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dlight-blue%5D%7B--md-accent-fg-color%3A%230091eb%3B--md-accent-fg-color--transparent%3A%230091eb1a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dcyan%5D%7B--md-accent-fg-color%3A%2300bad6%3B--md-accent-fg-color--transparent%3A%2300bad61a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dteal%5D%7B--md-accent-fg-color%3A%2300bda4%3B--md-accent-fg-color--transparent%3A%2300bda41a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dgreen%5D%7B--md-accent-fg-color%3A%2300c753%3B--md-accent-fg-color--transparent%3A%2300c7531a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dlight-green%5D%7B--md-accent-fg-color%3A%2363de17%3B--md-accent-fg-color--transparent%3A%2363de171a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-accent%3Dlime%5D%7B--md-accent-fg-color%3A%23b0eb00%3B--md-accent-fg-color--transparent%3A%23b0eb001a%3B--md-accent-bg-color%3A%23000000de%3B--md-accent-bg-color--light%3A%230000008a%7D%5Bdata-md-color-accent%3Dyellow%5D%7B--md-accent-fg-color%3A%23ffd500%3B--md-accent-fg-color--transparent%3A%23ffd5001a%3B--md-accent-bg-color%3A%23000000de%3B--md-accent-bg-color--light%3A%230000008a%7D%5Bdata-md-color-accent%3Damber%5D%7B--md-accent-fg-color%3A%23fa0%3B--md-accent-fg-color--transparent%3A%23ffaa001a%3B--md-accent-bg-color%3A%23000000de%3B--md-accent-bg-color--light%3A%230000008a%7D%5Bdata-md-color-accent%3Dorange%5D%7B--md-accent-fg-color%3A%23ff9100%3B--md-accent-fg-color--transparent%3A%23ff91001a%3B--md-accent-bg-color%3A%23000000de%3B--md-accent-bg-color--light%3A%230000008a%7D%5Bdata-md-color-accent%3Ddeep-orange%5D%7B--md-accent-fg-color%3A%23ff6e42%3B--md-accent-fg-color--transparent%3A%23ff6e421a%3B--md-accent-bg-color%3A%23fff%3B--md-accent-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dred%5D%7B--md-primary-fg-color%3A%23ef5552%3B--md-primary-fg-color--light%3A%23e57171%3B--md-primary-fg-color--dark%3A%23e53734%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dpink%5D%7B--md-primary-fg-color%3A%23e92063%3B--md-primary-fg-color--light%3A%23ec417a%3B--md-primary-fg-color--dark%3A%23c3185d%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dpurple%5D%7B--md-primary-fg-color%3A%23ab47bd%3B--md-primary-fg-color--light%3A%23bb69c9%3B--md-primary-fg-color--dark%3A%238c24a8%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Ddeep-purple%5D%7B--md-primary-fg-color%3A%237e56c2%3B--md-primary-fg-color--light%3A%239574cd%3B--md-primary-fg-color--dark%3A%23673ab6%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dindigo%5D%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%7D%5Bdata-md-color-primary%3Dblue%5D%7B--md-primary-fg-color%3A%232094f3%3B--md-primary-fg-color--light%3A%2342a5f5%3B--md-primary-fg-color--dark%3A%231975d2%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dlight-blue%5D%7B--md-primary-fg-color%3A%2302a6f2%3B--md-primary-fg-color--light%3A%2328b5f6%3B--md-primary-fg-color--dark%3A%230287cf%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dcyan%5D%7B--md-primary-fg-color%3A%2300bdd6%3B--md-primary-fg-color--light%3A%2325c5da%3B--md-primary-fg-color--dark%3A%230097a8%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dteal%5D%7B--md-primary-fg-color%3A%23009485%3B--md-primary-fg-color--light%3A%2326a699%3B--md-primary-fg-color--dark%3A%23007a6c%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dgreen%5D%7B--md-primary-fg-color%3A%234cae4f%3B--md-primary-fg-color--light%3A%2368bb6c%3B--md-primary-fg-color--dark%3A%23398e3d%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dlight-green%5D%7B--md-primary-fg-color%3A%238bc34b%3B--md-primary-fg-color--light%3A%239ccc66%3B--md-primary-fg-color--dark%3A%23689f38%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dlime%5D%7B--md-primary-fg-color%3A%23cbdc38%3B--md-primary-fg-color--light%3A%23d3e156%3B--md-primary-fg-color--dark%3A%23b0b52c%3B--md-primary-bg-color%3A%23000000de%3B--md-primary-bg-color--light%3A%230000008a%7D%5Bdata-md-color-primary%3Dyellow%5D%7B--md-primary-fg-color%3A%23ffec3d%3B--md-primary-fg-color--light%3A%23ffee57%3B--md-primary-fg-color--dark%3A%23fbc02d%3B--md-primary-bg-color%3A%23000000de%3B--md-primary-bg-color--light%3A%230000008a%7D%5Bdata-md-color-primary%3Damber%5D%7B--md-primary-fg-color%3A%23ffc105%3B--md-primary-fg-color--light%3A%23ffc929%3B--md-primary-fg-color--dark%3A%23ffa200%3B--md-primary-bg-color%3A%23000000de%3B--md-primary-bg-color--light%3A%230000008a%7D%5Bdata-md-color-primary%3Dorange%5D%7B--md-primary-fg-color%3A%23ffa724%3B--md-primary-fg-color--light%3A%23ffa724%3B--md-primary-fg-color--dark%3A%23fa8900%3B--md-primary-bg-color%3A%23000000de%3B--md-primary-bg-color--light%3A%230000008a%7D%5Bdata-md-color-primary%3Ddeep-orange%5D%7B--md-primary-fg-color%3A%23ff6e42%3B--md-primary-fg-color--light%3A%23ff8a66%3B--md-primary-fg-color--dark%3A%23f4511f%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dbrown%5D%7B--md-primary-fg-color%3A%23795649%3B--md-primary-fg-color--light%3A%238d6e62%3B--md-primary-fg-color--dark%3A%235d4037%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%7D%5Bdata-md-color-primary%3Dgrey%5D%7B--md-primary-fg-color%3A%23757575%3B--md-primary-fg-color--light%3A%239e9e9e%3B--md-primary-fg-color--dark%3A%23616161%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%3B--md-typeset-a-color%3A%234051b5%7D%5Bdata-md-color-primary%3Dblue-grey%5D%7B--md-primary-fg-color%3A%23546d78%3B--md-primary-fg-color--light%3A%23607c8a%3B--md-primary-fg-color--dark%3A%23455a63%3B--md-primary-bg-color%3A%23fff%3B--md-primary-bg-color--light%3A%23ffffffb3%3B--md-typeset-a-color%3A%234051b5%7D%5Bdata-md-color-primary%3Dlight-green%5D%3Anot%28%5Bdata-md-color-scheme%3Dslate%5D%29%7B--md-typeset-a-color%3A%2372ad2e%7D%5Bdata-md-color-primary%3Dlime%5D%3Anot%28%5Bdata-md-color-scheme%3Dslate%5D%29%7B--md-typeset-a-color%3A%238b990a%7D%5Bdata-md-color-primary%3Dyellow%5D%3Anot%28%5Bdata-md-color-scheme%3Dslate%5D%29%7B--md-typeset-a-color%3A%23b8a500%7D%5Bdata-md-color-primary%3Damber%5D%3Anot%28%5Bdata-md-color-scheme%3Dslate%5D%29%7B--md-typeset-a-color%3A%23d19d00%7D%5Bdata-md-color-primary%3Dorange%5D%3Anot%28%5Bdata-md-color-scheme%3Dslate%5D%29%7B--md-typeset-a-color%3A%23e68a00%7D%5Bdata-md-color-primary%3Dwhite%5D%7B--md-primary-fg-color%3Ahsla%28var%28--md-hue%29%2C0%25%2C100%25%2C1%29%3B--md-primary-fg-color--light%3Ahsla%28var%28--md-hue%29%2C0%25%2C100%25%2C0.7%29%3B--md-primary-fg-color--dark%3Ahsla%28var%28--md-hue%29%2C0%25%2C0%25%2C0.07%29%3B--md-primary-bg-color%3Ahsla%28var%28--md-hue%29%2C0%25%2C0%25%2C0.87%29%3B--md-primary-bg-color--light%3Ahsla%28var%28--md-hue%29%2C0%25%2C0%25%2C0.54%29%3B--md-typeset-a-color%3A%234051b5%7D%5Bdata-md-color-primary%3Dwhite%5D%20.md-button%7Bcolor%3Avar%28--md-typeset-a-color%29%7D%5Bdata-md-color-primary%3Dwhite%5D%20.md-button--primary%7Bbackground-color%3Avar%28--md-typeset-a-color%29%3Bborder-color%3Avar%28--md-typeset-a-color%29%3Bcolor%3Ahsla%28var%28--md-hue%29%2C0%25%2C100%25%2C1%29%7D%40media%20screen%20and%20%28min-width%3A60em%29%7B%5Bdata-md-color-primary%3Dwhite%5D%20.md-search__form%7Bbackground-color%3Ahsla%28var%28--md-hue%29%2C0%25%2C0%25%2C.07%29%7D%5Bdata-md-color-primary%3Dwhite%5D%20.md-search__form%3Ahover%7Bbackground-color%3Ahsla%28var%28--md-hue%29%2C0%25%2C0%25%2C.32%29%7D%5Bdata-md-color-primary%3Dwhite%5D%20.md-search__input%2B.md-search__icon%7Bcolor%3Ahsla%28var%28--md-hue%29%2C0%25%2C0%25%2C.87%29%7D%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B%5Bdata-md-color-primary%3Dwhite%5D%20.md-tabs%7Bborder-bottom%3A.05rem%20solid%20%2300000012%7D%7D%5Bdata-md-color-primary%3Dblack%5D%7B--md-primary-fg-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C9%25%2C1%29%3B--md-primary-fg-color--light%3Ahsla%28var%28--md-hue%29%2C15%25%2C9%25%2C0.54%29%3B--md-primary-fg-color--dark%3Ahsla%28var%28--md-hue%29%2C15%25%2C9%25%2C1%29%3B--md-primary-bg-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C100%25%2C1%29%3B--md-primary-bg-color--light%3Ahsla%28var%28--md-hue%29%2C15%25%2C100%25%2C0.7%29%3B--md-typeset-a-color%3A%234051b5%7D%5Bdata-md-color-primary%3Dblack%5D%20.md-button%7Bcolor%3Avar%28--md-typeset-a-color%29%7D%5Bdata-md-color-primary%3Dblack%5D%20.md-button--primary%7Bbackground-color%3Avar%28--md-typeset-a-color%29%3Bborder-color%3Avar%28--md-typeset-a-color%29%3Bcolor%3Ahsla%28var%28--md-hue%29%2C0%25%2C100%25%2C1%29%7D%5Bdata-md-color-primary%3Dblack%5D%20.md-header%7Bbackground-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C9%25%2C1%29%7D%40media%20screen%20and%20%28max-width%3A59.984375em%29%7B%5Bdata-md-color-primary%3Dblack%5D%20.md-nav__source%7Bbackground-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C11%25%2C.87%29%7D%7D%40media%20screen%20and%20%28max-width%3A76.234375em%29%7Bhtml%20%5Bdata-md-color-primary%3Dblack%5D%20.md-nav--primary%20.md-nav__title%5Bfor%3D__drawer%5D%7Bbackground-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C9%25%2C1%29%7D%7D%40media%20screen%20and%20%28min-width%3A76.25em%29%7B%5Bdata-md-color-primary%3Dblack%5D%20.md-tabs%7Bbackground-color%3Ahsla%28var%28--md-hue%29%2C15%25%2C9%25%2C1%29%7D%7D" rel="stylesheet"/><!--URL:../assets/stylesheets/palette.06af60db.min.css-->
|
||
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
|
||
<link href="data:text/css; charset=utf-8;base64,QGZvbnQtZmFjZSB7CiAgZm9udC1mYW1pbHk6ICdSb2JvdG8nOwogIGZvbnQtc3R5bGU6IGl0YWxpYzsKICBmb250LXdlaWdodDogMzAwOwogIGZvbnQtZGlzcGxheTogZmFsbGJhY2s7CiAgc3JjOiB1cmwoaHR0cHM6Ly9mb250cy5nc3RhdGljLmNvbS9zL3JvYm90by92MzAvS0ZPakNucUV1OTJGcjFNdTUxVGpBU2M2Q3NFLnR0ZikgZm9ybWF0KCd0cnVldHlwZScpOwp9CkBmb250LWZhY2UgewogIGZvbnQtZmFtaWx5OiAnUm9ib3RvJzsKICBmb250LXN0eWxlOiBpdGFsaWM7CiAgZm9udC13ZWlnaHQ6IDQwMDsKICBmb250LWRpc3BsYXk6IGZhbGxiYWNrOwogIHNyYzogdXJsKGh0dHBzOi8vZm9udHMuZ3N0YXRpYy5jb20vcy9yb2JvdG8vdjMwL0tGT2tDbnFFdTkyRnIxTXU1MXhJSXpjLnR0ZikgZm9ybWF0KCd0cnVldHlwZScpOwp9CkBmb250LWZhY2UgewogIGZvbnQtZmFtaWx5OiAnUm9ib3RvJzsKICBmb250LXN0eWxlOiBpdGFsaWM7CiAgZm9udC13ZWlnaHQ6IDcwMDsKICBmb250LWRpc3BsYXk6IGZhbGxiYWNrOwogIHNyYzogdXJsKGh0dHBzOi8vZm9udHMuZ3N0YXRpYy5jb20vcy9yb2JvdG8vdjMwL0tGT2pDbnFFdTkyRnIxTXU1MVR6QmljNkNzRS50dGYpIGZvcm1hdCgndHJ1ZXR5cGUnKTsKfQpAZm9udC1mYWNlIHsKICBmb250LWZhbWlseTogJ1JvYm90byc7CiAgZm9udC1zdHlsZTogbm9ybWFsOwogIGZvbnQtd2VpZ2h0OiAzMDA7CiAgZm9udC1kaXNwbGF5OiBmYWxsYmFjazsKICBzcmM6IHVybChodHRwczovL2ZvbnRzLmdzdGF0aWMuY29tL3Mvcm9ib3RvL3YzMC9LRk9sQ25xRXU5MkZyMU1tU1U1ZkJCYzkudHRmKSBmb3JtYXQoJ3RydWV0eXBlJyk7Cn0KQGZvbnQtZmFjZSB7CiAgZm9udC1mYW1pbHk6ICdSb2JvdG8nOwogIGZvbnQtc3R5bGU6IG5vcm1hbDsKICBmb250LXdlaWdodDogNDAwOwogIGZvbnQtZGlzcGxheTogZmFsbGJhY2s7CiAgc3JjOiB1cmwoaHR0cHM6Ly9mb250cy5nc3RhdGljLmNvbS9zL3JvYm90by92MzAvS0ZPbUNucUV1OTJGcjFNdTRteFAudHRmKSBmb3JtYXQoJ3RydWV0eXBlJyk7Cn0KQGZvbnQtZmFjZSB7CiAgZm9udC1mYW1pbHk6ICdSb2JvdG8nOwogIGZvbnQtc3R5bGU6IG5vcm1hbDsKICBmb250LXdlaWdodDogNzAwOwogIGZvbnQtZGlzcGxheTogZmFsbGJhY2s7CiAgc3JjOiB1cmwoaHR0cHM6Ly9mb250cy5nc3RhdGljLmNvbS9zL3JvYm90by92MzAvS0ZPbENucUV1OTJGcjFNbVdVbGZCQmM5LnR0ZikgZm9ybWF0KCd0cnVldHlwZScpOwp9CkBmb250LWZhY2UgewogIGZvbnQtZmFtaWx5OiAnUm9ib3RvIE1vbm8nOwogIGZvbnQtc3R5bGU6IGl0YWxpYzsKICBmb250LXdlaWdodDogNDAwOwogIGZvbnQtZGlzcGxheTogZmFsbGJhY2s7CiAgc3JjOiB1cmwoaHR0cHM6Ly9mb250cy5nc3RhdGljLmNvbS9zL3JvYm90b21vbm8vdjIzL0wweG9ERjR4bFZNRi1CZlI4YlhNSWpoT3NYRy1xMm9ldUZvcUZybG5BTlc2Q3B3LnR0ZikgZm9ybWF0KCd0cnVldHlwZScpOwp9CkBmb250LWZhY2UgewogIGZvbnQtZmFtaWx5OiAnUm9ib3RvIE1vbm8nOwogIGZvbnQtc3R5bGU6IGl0YWxpYzsKICBmb250LXdlaWdodDogNzAwOwogIGZvbnQtZGlzcGxheTogZmFsbGJhY2s7CiAgc3JjOiB1cmwoaHR0cHM6Ly9mb250cy5nc3RhdGljLmNvbS9zL3JvYm90b21vbm8vdjIzL0wweG9ERjR4bFZNRi1CZlI4YlhNSWpoT3NYRy1xMm9ldUZvcUZybUFCOVc2Q3B3LnR0ZikgZm9ybWF0KCd0cnVldHlwZScpOwp9CkBmb250LWZhY2UgewogIGZvbnQtZmFtaWx5OiAnUm9ib3RvIE1vbm8nOwogIGZvbnQtc3R5bGU6IG5vcm1hbDsKICBmb250LXdlaWdodDogNDAwOwogIGZvbnQtZGlzcGxheTogZmFsbGJhY2s7CiAgc3JjOiB1cmwoaHR0cHM6Ly9mb250cy5nc3RhdGljLmNvbS9zL3JvYm90b21vbm8vdjIzL0wweHVERjR4bFZNRi1CZlI4YlhNSWhKSGc0NW13Z0dFRmwwXzN2cV9ST1c5LnR0ZikgZm9ybWF0KCd0cnVldHlwZScpOwp9CkBmb250LWZhY2UgewogIGZvbnQtZmFtaWx5OiAnUm9ib3RvIE1vbm8nOwogIGZvbnQtc3R5bGU6IG5vcm1hbDsKICBmb250LXdlaWdodDogNzAwOwogIGZvbnQtZGlzcGxheTogZmFsbGJhY2s7CiAgc3JjOiB1cmwoaHR0cHM6Ly9mb250cy5nc3RhdGljLmNvbS9zL3JvYm90b21vbm8vdjIzL0wweHVERjR4bFZNRi1CZlI4YlhNSWhKSGc0NW13Z0dFRmwwX09mMl9ST1c5LnR0ZikgZm9ybWF0KCd0cnVldHlwZScpOwp9Cg==" rel="stylesheet"/><!--URL:https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback-->
|
||
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
|
||
<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%0A/%2A%20%0AEnumerate%20headings%0A%0AOnly%20displayed%20when%20set%20in%20mkdocs.yml%0A%0Aprint-site%3A%0A%20%20%20%20-%20print-site-enumerate_headings%3A%20true%0A%2A/%0A%0A/%2A%20Ensure%20that%20when%20adding%20enumeration%20to%20headings%2C%20this%20happens%20inline%20%2A/%0A.print-site-enumerate-headings%20h1%3Abefore%2C%0A.print-site-enumerate-headings%20h2%3Abefore%2C%0A.print-site-enumerate-headings%20h3%3Abefore%2C%0A.print-site-enumerate-headings%20h4%3Abefore%2C%0A.print-site-enumerate-headings%20h5%3Abefore%2C%0A.print-site-enumerate-headings%20h6%3Abefore%20%7B%0A%20%20%20%20display%3A%20inline%20%21important%3B%0A%7D%0A%0A/%2A%20Reset%20all%20enumeration%20at%20start%20of%20page%20%2A/%0Abody%20%7Bcounter-reset%3A%20chapter%20sec-top%20toc-chapter%20toc-sec-chapter%20figurecounter%3B%7D%0A%0A/%2A%20Enumerate%20headings%20of%20CHAPTERS%2C%0Athat%20are%20part%20of%20an%20original%20included%20page%20%2A/%0A.print-site-enumerate-headings%20.print-page%20h1%20%7Bcounter-reset%3A%20section%20sub-section%20composite%20detail%20last%3B%20%7D%0A.print-site-enumerate-headings%20.print-page%20h2%20%7Bcounter-reset%3A%20sub-section%20composite%20detail%20last%3B%20%7D%0A.print-site-enumerate-headings%20.print-page%20h3%20%7Bcounter-reset%3A%20composite%20detail%20last%3B%20%7D%0A.print-site-enumerate-headings%20.print-page%20h4%20%7Bcounter-reset%3A%20detail%20last%3B%20%7D%0A.print-site-enumerate-headings%20.print-page%20h5%20%7Bcounter-reset%3A%20last%3B%20%7D%0A.print-site-enumerate-headings%20.print-page%20h1%3Abefore%20%7B%0A%20%20%20%20counter-increment%3A%20chapter%3B%0A%20%20%20%20content%3A%20counter%28chapter%29%20%22%20%22%20%21important%3B%0A%7D%0A.print-site-enumerate-headings%20h1.print-page-toc-title%3Abefore%2C%0A%23print-site-cover-page%20h1%3Abefore%2C%0A%23print-site-cover-page%20h2%3Abefore%2C%0A%23print-site-cover-page%20h3%3Abefore%2C%0A%23print-site-cover-page%20h4%3Abefore%2C%0A%23print-site-cover-page%20h5%3Abefore%2C%0A%23print-site-cover-page%20h6%3Abefore%20%7B%0A%20%20%20%20content%3A%20none%20%21important%3B%0A%20%20%20%20counter-increment%3A%20none%3B%0A%7D%0A.print-site-enumerate-headings%20.print-page%20h2%3Abefore%20%7B%0A%20%20counter-increment%3A%20section%3B%0A%20%20content%3A%20counter%28chapter%29%20%22.%22%20counter%28section%29%20%22%20%22%20%21important%3B%0A%7D%0A.print-site-enumerate-headings%20.print-page%20h3%3Abefore%20%7B%0A%20%20counter-increment%3A%20sub-section%3B%0A%20%20content%3A%20counter%28chapter%29%20%22.%22%20counter%28section%29%20%22.%22%20counter%28sub-section%29%20%22%20%22%20%21important%3B%0A%7D%0A.print-site-enumerate-headings%20.print-page%20h4%3Abefore%20%7B%0A%20%20counter-increment%3A%20composite%3B%0A%20%20content%3A%20counter%28chapter%29%20%22.%22%20counter%28section%29%20%22.%22%20counter%28sub-section%29%20%22.%22%20counter%28composite%29%20%22%20%22%20%21important%3B%0A%7D%0A.print-site-enumerate-headings%20.print-page%20h5%3Abefore%20%7B%0A%20%20counter-increment%3A%20detail%3B%0A%20%20content%3A%20counter%28chapter%29%20%22.%22%20counter%28section%29%20%22.%22%20counter%28sub-section%29%20%22.%22%20counter%28composite%29%20%22.%22%20counter%28detail%29%20%22%20%22%20%21important%3B%0A%7D%0A.print-site-enumerate-headings%20.print-page%20h6%3Abefore%20%7B%0A%20%20%20%20counter-increment%3A%20last%3B%0A%20%20%20%20content%3A%20counter%28chapter%29%20%22.%22%20counter%28section%29%20%22.%22%20counter%28sub-section%29%20%22.%22%20counter%28composite%29%20%22.%22%20counter%28detail%29%20%22.%22%20counter%28last%29%20%21important%3B%0A%7D%0A%0A/%2A%20Enumerate%20headings%20of%20SECTIONS%2C%0Athat%20are%20part%20of%20an%20original%20included%20page%20%2A/%0A.print-site-enumerate-headings%20h1%20%7Bcounter-reset%3A%20sec-section%20sec-sub-section%20sec-composite%20sec-detail%20sec-last%3B%20%7D%0A.print-site-enumerate-headings%20h2.nav-section-title%20%7Bcounter-reset%3A%20sec-sub-section%20sec-composite%20sec-detail%20sec-last%3B%20%7D%0A.print-site-enumerate-headings%20h3.nav-section-title%20%7Bcounter-reset%3A%20sec-composite%20sec-detail%20sec-last%3B%20%7D%0A.print-site-enumerate-headings%20h4.nav-section-title%20%7Bcounter-reset%3A%20sec-detail%20sec-last%3B%20%7D%0A.print-site-enumerate-headings%20h5.nav-section-title%20%7Bcounter-reset%3A%20sec-last%3B%20%7D%0A.print-site-enumerate-headings%20h1.nav-section-title%3Abefore%20%7B%0A%20%20%20%20counter-increment%3A%20sec-top%3B%0A%20%20%20%20content%3A%20counter%28sec-top%2C%20upper-roman%29%20%22.%20%22%20%21important%3B%0A%7D%0A.print-site-enumerate-headings%20h2.nav-section-title%3Abefore%20%7B%0A%20%20counter-increment%3A%20sec-section%3B%0A%20%20content%3A%20counter%28sec-top%2C%20upper-roman%29%20%22.%22%20counter%28sec-section%2C%20upper-roman%29%20%22%20%22%20%21important%3B%0A%7D%0A.print-site-enumerate-headings%20h3.nav-section-title%3Abefore%20%7B%0A%20%20counter-increment%3A%20sec-sub-section%3B%0A%20%20content%3A%20counter%28sec-top%2C%20upper-roman%29%20%22.%22%20counter%28sec-section%2C%20upper-roman%29%20%22.%22%20counter%28sec-sub-section%2C%20upper-roman%29%20%22%20%22%20%21important%3B%0A%7D%0A.print-site-enumerate-headings%20h4.nav-section-title%3Abefore%20%7B%0A%20%20counter-increment%3A%20sec-composite%3B%0A%20%20content%3A%20counter%28sec-top%2C%20upper-roman%29%20%22.%22%20counter%28sec-section%2C%20upper-roman%29%20%22.%22%20counter%28sec-sub-section%2C%20upper-roman%29%20%22.%22%20counter%28sec-composite%2C%20upper-roman%29%20%22%20%22%20%21important%3B%0A%7D%0A.print-site-enumerate-headings%20h5.nav-section-title%3Abefore%20%7B%0A%20%20counter-increment%3A%20sec-detail%3B%0A%20%20content%3A%20counter%28sec-top%2C%20upper-roman%29%20%22.%22%20counter%28sec-section%2C%20upper-roman%29%20%22.%22%20counter%28sec-sub-section%2C%20upper-roman%29%20%22.%22%20counter%28sec-composite%2C%20upper-roman%29%20%22.%22%20counter%28sec-detail%2C%20upper-roman%29%20%22%20%22%20%21important%3B%0A%7D%0A.print-site-enumerate-headings%20h6.nav-section-title%3Abefore%20%7B%0A%20%20%20%20counter-increment%3A%20sec-last%3B%0A%20%20%20%20content%3A%20counter%28sec-top%2C%20upper-roman%29%20%22.%22%20counter%28sec-section%2C%20upper-roman%29%20%22.%22%20counter%28sec-sub-section%2C%20upper-roman%29%20%22.%22%20counter%28sec-composite%2C%20upper-roman%29%20%22.%22%20counter%28sec-detail%2C%20upper-roman%29%20%22.%22%20counter%28sec-last%2C%20upper-roman%29%20%21important%3B%0A%7D%0A%0A%0A/%2A%20Enumerate%20CHAPTERS%20in%20table%20of%20contents%20also%20%2A/%0A.print-site-enumerate-headings%20.print-site-toc-level-1%20%3E%20ul%20%7B%20counter-reset%3A%20toc-section%3B%20%7D%0A.print-site-enumerate-headings%20.print-site-toc-level-2%20%3E%20ul%20%7B%20counter-reset%3A%20toc-sub-section%3B%20%7D%0A.print-site-enumerate-headings%20.print-site-toc-level-3%20%3E%20ul%20%7B%20counter-reset%3A%20toc-composite%3B%20%7D%0A.print-site-enumerate-headings%20.print-site-toc-level-4%20%3E%20ul%20%7B%20counter-reset%3A%20toc-detail%3B%20%7D%0A.print-site-enumerate-headings%20.print-site-toc-level-5%20%3E%20ul%20%7B%20counter-reset%3A%20toc-last%3B%20%7D%0A.print-site-enumerate-headings%20.print-site-toc-level-1%20%3E%20li%20a%3Abefore%20%7B%0A%20%20%20%20counter-increment%3A%20toc-chapter%3B%0A%20%20%20%20content%3A%20counter%28toc-chapter%29%20%22%20%22%3B%20%0A%7D%0A.print-site-enumerate-headings%20.print-site-toc-level-2%20%3E%20li%20a%3Abefore%20%7B%0A%20%20%20%20counter-increment%3A%20toc-section%3B%20%0A%20%20%20%20content%3A%20counter%28toc-chapter%29%20%22.%22%20counter%28toc-section%29%20%22%20%22%3B%0A%7D%0A.print-site-enumerate-headings%20.print-site-toc-level-3%20%3E%20li%20a%3Abefore%20%7B%0A%20%20%20%20counter-increment%3A%20toc-sub-section%3B%0A%20%20%20%20content%3A%20counter%28toc-chapter%29%20%22.%22%20counter%28toc-section%29%20%22.%22%20counter%28toc-sub-section%29%20%22%20%22%3B%0A%7D%0A.print-site-enumerate-headings%20.print-site-toc-level-4%20%3E%20li%20a%3Abefore%20%7B%0A%20%20%20%20counter-increment%3A%20toc-composite%3B%0A%20%20%20%20content%3A%20counter%28toc-chapter%29%20%22.%22%20counter%28toc-section%29%20%22.%22%20counter%28toc-sub-section%29%20%22.%22%20counter%28toc-composite%29%20%22%20%22%3B%0A%7D%0A.print-site-enumerate-headings%20.print-site-toc-level-5%20%3E%20li%20a%3Abefore%20%7B%0A%20%20%20%20counter-increment%3A%20toc-detail%3B%0A%20%20%20%20content%3A%20counter%28toc-chapter%29%20%22.%22%20counter%28toc-section%29%20%22.%22%20counter%28toc-sub-section%29%20%22.%22%20counter%28toc-composite%29%20%22.%22%20counter%28toc-detail%29%20%22%20%22%3B%0A%7D%0A.print-site-enumerate-headings%20.print-site-toc-level-6%20%3E%20li%20a%3Abefore%20%7B%0A%20%20%20%20counter-increment%3A%20toc-last%3B%0A%20%20%20%20content%3A%20counter%28toc-chapter%29%20%22.%22%20counter%28toc-section%29%20%22.%22%20counter%28toc-sub-section%29%20%22.%22%20counter%28toc-composite%29%20%22.%22%20counter%28toc-detail%29%20%22.%22%20counter%28toc-last%29%3B%0A%7D%0A%0A/%2A%20Enumerate%20SECTIONS%20in%20table%20of%20contents%20also%20%2A/%0A.print-site-enumerate-headings%20li.toc-nav-section-title-level-1%20%7B%20counter-reset%3A%20toc-sec-section%3B%20%7D%0A.print-site-enumerate-headings%20li.toc-nav-section-title-level-2%20%7B%20counter-reset%3A%20toc-sec-sub-section%3B%20%7D%0A.print-site-enumerate-headings%20li.toc-nav-section-title-level-3%20%7B%20counter-reset%3A%20toc-sec-composite%3B%20%7D%0A.print-site-enumerate-headings%20li.toc-nav-section-title-level-4%20%7B%20counter-reset%3A%20toc-sec-detail%3B%20%7D%0A.print-site-enumerate-headings%20li.toc-nav-section-title-level-5%20%7B%20counter-reset%3A%20toc-sec-last%3B%20%7D%0A.print-site-enumerate-headings%20li.toc-nav-section-title-level-1%3Abefore%20%7B%0A%20%20%20%20counter-increment%3A%20toc-sec-chapter%3B%0A%20%20%20%20content%3A%20counter%28toc-sec-chapter%2C%20upper-roman%29%20%22%20%22%3B%20%0A%7D%0A.print-site-enumerate-headings%20li.toc-nav-section-title-level-2%3Abefore%20%7B%0A%20%20%20%20counter-increment%3A%20toc-sec-section%3B%20%0A%20%20%20%20content%3A%20counter%28toc-sec-chapter%2C%20upper-roman%29%20%22.%22%20counter%28toc-sec-section%2C%20upper-roman%29%20%22%20%22%3B%0A%7D%0A.print-site-enumerate-headings%20li.toc-nav-section-title-level-3%3Abefore%20%7B%0A%20%20%20%20counter-increment%3A%20toc-sec-sub-section%3B%0A%20%20%20%20content%3A%20counter%28toc-sec-chapter%2C%20upper-roman%29%20%22.%22%20counter%28toc-sec-section%2C%20upper-roman%29%20%22.%22%20counter%28toc-sec-sub-section%2C%20upper-roman%29%20%22%20%22%3B%0A%7D%0A.print-site-enumerate-headings%20li.toc-nav-section-title-level-4before%20%7B%0A%20%20%20%20counter-increment%3A%20toc-sec-composite%3B%0A%20%20%20%20content%3A%20counter%28toc-sec-chapter%2C%20upper-roman%29%20%22.%22%20counter%28toc-sec-section%2C%20upper-roman%29%20%22.%22%20counter%28toc-sec-sub-section%2C%20upper-roman%29%20%22.%22%20counter%28toc-sec-composite%2C%20upper-roman%29%20%22%20%22%3B%0A%7D%0A.print-site-enumerate-headings%20li.toc-nav-section-title-level-5%3Abefore%20%7B%0A%20%20%20%20counter-increment%3A%20toc-detail%3B%0A%20%20%20%20content%3A%20counter%28toc-sec-chapter%2C%20upper-roman%29%20%22.%22%20counter%28toc-sec-section%2C%20upper-roman%29%20%22.%22%20counter%28toc-sec-sub-section%2C%20upper-roman%29%20%22.%22%20counter%28toc-sec-composite%2C%20upper-roman%29%20%22.%22%20counter%28toc-sec-detail%2C%20upper-roman%29%20%22%20%22%3B%0A%7D%0A.print-site-enumerate-headings%20li.toc-nav-section-title-level-6%3Abefore%20%7B%0A%20%20%20%20counter-increment%3A%20toc-sec-last%3B%0A%20%20%20%20content%3A%20counter%28toc-sec-chapter%2C%20upper-roman%29%20%22.%22%20counter%28toc-sec-section%2C%20upper-roman%29%20%22.%22%20counter%28toc-sec-sub-section%2C%20upper-roman%29%20%22.%22%20counter%28toc-sec-composite%2C%20upper-roman%29%20%22.%22%20counter%28toc-sec-detail%2C%20upper-roman%29%20%22.%22%20counter%28toc-last%2C%20upper-roman%29%3B%0A%7D%0A%0A%23print-page-toc%20li%20a.headerlink%3Abefore%20%7B%0A%20%20%20%20content%3A%20none%20%21important%3B%0A%20%20%20%20counter-increment%3A%20none%3B%0A%7D%0A%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%20%0APrint%20site%20table%20of%20contents%20styling%0A%20%2A/%0A.print-page-toc-nav%20%7B%0A%20%20%20%20padding-bottom%3A%202em%3B%0A%7D%0A%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%201s%20ease%3B%0A%7D%0A%40keyframes%20highlight%20%7B%0A%20%20%20%20from%20%7B%20background%3A%20yellow%3B%20%7D%0A%20%20%20%20to%20%7B%20background%3A%20white%3B%20%7D%0A%7D%0A%0A%23print-page-toc%20ul%20%7B%0A%20%20%20%20/%2A%20margin-left%3A%201.6em%3B%20%2A/%0A%20%20%20%20margin-top%3A%200%3B%0A%20%20%20%20margin-bottom%3A%200%3B%0A%20%20%20%20padding-left%3A%200%3B%0A%20%20%20%20list-style-position%3A%20inside%3B%0A%7D%0A%23print-page-toc%20ul.print-site-toc-level-2%2C%0A%23print-page-toc%20ul.print-site-toc-level-3%2C%0A%23print-page-toc%20ul.print-site-toc-level-4%2C%0A%23print-page-toc%20ul.print-site-toc-level-5%2C%0A%23print-page-toc%20ul.print-site-toc-level-6%20%7B%0A%20%20%20%20margin-left%3A%201.6em%3B%0A%7D%0A%23print-page-toc%20ul%20li%20%7B%0A%20%20%20%20margin-left%3A%200%3B%0A%20%20%20%20margin-bottom%3A%200.2em%3B%0A%7D%0Aul.print-site-toc-level-1%20%7B%0A%20%20%20%20list-style-type%3A%20none%3B%0A%7D%0Aul.print-site-toc-level-1%20li%20a%20%7B%0A%20%20%20%20font-weight%3A%20bold%3B%0A%20%20%20%20font-size%3A%20120%25%3B%0A%7D%0Aul.print-site-toc-level-2%20li%20a%20%7B%0A%20%20%20%20font-weight%3A%20normal%3B%0A%20%20%20%20font-size%3A%20100%25%3B%0A%20%20%20%20margin-bottom%3A%200em%3B%0A%7D%0A%23print-site-page%20ul%20li.toc-nav-section-title%20%7B%0A%20%20%20%20padding-top%3A%201em%3B%0A%20%20%20%20padding-bottom%3A%200em%3B%0A%20%20%20%20font-size%3A%20110%25%3B%0A%20%20%20%20letter-spacing%3A%201px%3B%0A%7D%0A%23print-site-page%20ul.toc-section-line-border%20%7B%20%0A%20%20%20%20border-left%3A%205px%20solid%20grey%3B%0A%20%20%20%20padding-left%3A%201.5em%3B%0A%20%20%20%20margin-top%3A%200.5em%3B%0A%20%20%20%20margin-bottom%3A%201em%3B%0A%7D%0A%0A%0A%23print-site-page%20ul%20%7B%0A%20%20%20%20margin-left%3A%200em%3B%0A%7D%0A%0A%0A%0A/%2A%20Don%27t%20display%20cover%20page%20when%20not%20in%20print%20mode%20%2A/%0A%23print-site-cover-page%20%7B%20display%3A%20none%3B%20%7D%0A%0A/%2A%20Don%27t%20display%20the%20section%20headings%20that%20we%20added%0AFor%20now%2C%20we%20added%20them%20for%20use%20only%20in%20the%20table%20of%20contents%20%2A/%0A%23print-site-page%20h1.nav-section-title%2C%0A%23print-site-page%20h2.nav-section-title%2C%0A%23print-site-page%20h3.nav-section-title%2C%0A%23print-site-page%20h4.nav-section-title%2C%0A%23print-site-page%20h5.nav-section-title%2C%0A%23print-site-page%20h6.nav-section-title%20%7B%20%0A%20%20%20%20padding-top%3A%201.5em%3B%0A%20%20%20%20padding-bottom%3A%201em%3B%0A%20%20%20%20padding-left%3A%201em%3B%0A%20%20%20%20font-size%3A%202.2em%3B%0A%20%20%20%20font-weight%3A%20300%3B%0A%20%20%20%20line-height%3A%201.3%3B%0A%20%20%20%20color%3A%20var%28--md-default-fg-color--light%29%3B%0A%7D%0A%0A%23print-site-page%20h1.nav-section-title-end%2C%0A%23print-site-page%20h2.nav-section-title-end%2C%0A%23print-site-page%20h3.nav-section-title-end%2C%0A%23print-site-page%20h4.nav-section-title-end%2C%0A%23print-site-page%20h5.nav-section-title-end%2C%0A%23print-site-page%20h6.nav-section-title-end%20%7B%20display%3A%20none%3B%20%7D%0A%0A/%2A%20In%20the%20TOC%2C%20we%20want%20lines%20that%20are%20children%20of%20a%20section%20to%20be%20displayed%20with%20a%20left%20margin%20%2A/%0A%23print-site-page%20ul%20li.toc-nav-section-child%20%7B%20padding-left%3A%201em%3B%20%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%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%20Ensure%20all%20tabbed%20content%20is%20displayed%20and%20printed%0A%20%20%20%20https%3A//squidfunk.github.io/mkdocs-material/reference/content-tabs/%20%2A/%0A%20%20%20%20/%2A%20%23print-site-page%20div.tabbed-content%20%7B%20display%3A%20block%20%21important%3B%20%7D%20%2A/%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%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%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%20.nav-section-title%20%7B%0A%20%20%20%20%20%20%20%20page-break-before%3A%20always%3B%0A%20%20%20%20%20%20%20%20page-break-after%3A%20always%3B%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-top%3A%20150px%20%21important%3B%0A%20%20%20%20%20%20%20%20padding-bottom%3A%200em%3B%0A%20%20%20%20%20%20%20%20padding-left%3A%200em%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%20display%3A%20block%3B%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%0A%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%0A%7D%0A%0A%0A/%2A%20%40page%20%7B%20%2A/%0A%0A%20%20%20%20/%2A%20%0A%20%20%20%20%20%20%20%20Note%20this%20CSS%20file%20is%20added%20to%20all%20MkDocs%20pages%0A%20%20%20%20%20%20%20%20So%20this%20%40page%20logic%20will%20affect%20print%20of%20all%20pages%0A%20%20%20%20%2A/%0A%0A%20%20%20%20/%2A%20Prevent%20image%20page%20overflow%20%2A/%0A%20%20%20%20/%2A%20img%20%7B%20max-width%3A500px%20%21important%3B%20%7D%20%2A/%0A%0A/%2A%20%7D%20%2A/" 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.print-page-toc-title%20%7B%0A%20%20%20%20padding-bottom%3A%200em%3B%0A%20%20%20%20margin-bottom%3A%200%3B%0A%7D%0A%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%7D%0A%0A%40page%20%7B%0A%0A%20%20%20%20/%2A%20%0A%20%20%20%20%20%20%20%20Note%20this%20CSS%20file%20is%20added%20to%20all%20MkDocs%20pages%0A%20%20%20%20%20%20%20%20So%20this%20%40page%20logic%20will%20affect%20print%20of%20all%20pages%0A%20%20%20%20%2A/%0A%0A%20%20%20%20size%3A%20a4%20portrait%3B%0A%20%20%20%20margin%3A%2015mm%2010mm%2025mm%2010mm%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-->
|
||
<script>__md_scope=new URL("../..",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 () {
|
||
generate_toc();
|
||
})
|
||
</script>
|
||
</head>
|
||
<body data-md-color-accent="blue" data-md-color-primary="light-blue" data-md-color-scheme="default" 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">
|
||
</div>
|
||
<div data-md-component="announce">
|
||
</div>
|
||
<div data-md-color-scheme="default" data-md-component="outdated" hidden="">
|
||
</div>
|
||
<header class="md-header md-header--shadow" data-md-component="header">
|
||
<nav aria-label="En-tête" class="md-header__inner md-grid">
|
||
<a aria-label="LdapSaisie" class="md-header__button md-logo" data-md-component="logo" href="javascript:window.scrollTo(0,0)" title="LdapSaisie">
|
||
<img alt="logo" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAAAuCAYAAABtRVYBAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAZ5QAAGeUBblTa3gAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABQqSURBVHic7Z17lBTVncc/35oZBnkjKKKODyDGB2bjK0GjCRKdh2KMm+DqbqIeo8H1GM1MDyHqbpATjQGZIWsSs2qymA3HqLhRI8r0EAMmisFoYqLGSEBFBZG3g8hrpn/7x62eru6p6tf0gOB8z7mnq6pv/X63u+t37+95W2ZGL3rRi3B4e3oAvejFhxnle3oApYCks4C5/umzZvaFPTmeUkJTWg8k0TEK84ZgrEW73mXryLV250m79sh4Yi2Xgb4PgNkca669vud4xacC9f7p962p5gc9xSsKJRMQSb8FRvmnzWZ2e6lo54FPAyP84zd3I98egRoWVqPEjcBJQH/wQLhGBQxYn1As/mewRcAiPO9Ju616624aXX+S37XnDephZgM7eTm+ux0lERBJ/YDPkVLZdvdDemLg+E+7mXfJoG8tGE2Hdw/i9BxdPeAk0ElAIwn7OnB3z4/wo4dSrSD/RLo9s7sf0qCA/Hk38y4JNHl+Pwb0eQjs+MDl9cB8sJWY1iCNwGw0YjRwClCx+wfKDoz3ALDEBz3MbBvYe/7Jjp7lFTGCUnixJF0N/Ng/3WBmw7tNNH/e+wMb/NOdwAAz2yP6eXegWHwOcJl/ahhTGFz5Y5s2fnto/ymtB5LgErCvAc3WVNO7gvQASrWCnBA43t0zeJD3S3ulcEx+voIBXJy6oFusqbop2z12W/VaYBYwS1Na94h+/lFAqQSkR1UcSQOB4bjVqS0L74JUO0mDgaHAGjMLnamLgSThxlthZqtz3jBo3TEkVJkiwP8Uwq9QA13XPzaUHX2H4m1rY+DzG23atEQh9xcDTX6+gv02jaTS2tm1eZM1T9rWo/ymT/dYd/pQ+u0cgpVtYeV7G+yBSR0F0+muiiWpAngf6ONfutjM7usWUUd3EHAd8G/AxwNvLQOagLvNzCT9ErjIf+9qM/tJFnpnAecCnwUOAfYLdFkL/BH4rpktzWN89wAH+adXmtlbkmqByUAdkHzgN+EEt8HM/hpKK9byFdAv/NOd1lRTGdavGGj64r60bZ+AdB7GBFAVWPBzb8VsKehnvN12f66HSLHWiWDX+KePWlPNjyP7NracgmkqcCruuwraqdtBL0AijiX+z5rPebHL/Q2tlyJzK6vZPdZcm/O5UqxlEugSYALQL/DWFlALZrOsuebZXHSSKMUKchwp4YASrCCSaoD/BQ4Mefso4E7gTElfwblCkwhdQSRVASvIbtQeiBOecyX9l5l9M8v4BgBfxf3gO4EtkubihDkTQ4HPA0slXWVmPw/pszFw3Eex1iprqn4ry1jzR9uOF0Fj6JwHu0yI/ZEmABOoGnSVGuf/s82auD6aoB0O1AAgrYjqpVj8Z6DLs4ysL9g40DjkjQG+0pWIfSzFy/t9FlqoYf4heBXzQKdGdBkINgkxSbF4M801jWZdv4xMlEJAgjbA+8A/ukNM0iTgXlJjWw/8zm+VOHfyObhV40VgjN+vAwidoXFqWFI4XgFeBlYCbwNDfBpfBJK6/HWSnjazeRH0gl675cD9QDXQDjwLLAS24YT3y7gIRl/gDkmtZvZOGrUEf0vPabCbgK9F8C4UydVoM7AU9AYkViJ1YByB8RnEJ/w+Z2AVv9KF884sRh1JQrGW6zOEYwniNyRYhzDQIZgdivgscHixfDr5NTwxCvX5HWaH+JcM+A3G35C9ibzRYKdhfNJ/v4H6eBnURE6CSZRaQP5iZkXrs5KOBeaQGtcvgUvMrD3QbaakK4G7gO/ih8+AV8wsSq8dDtwK3GtmL0XwHgzMA872LzX652EIfuZj/fYyUGtmb2fQrQEexglIP+AG4Btp1H5Qu5KG+J9I2VOXKxY/GmwG5TsX2YwvbIkYRz74PaKFRNuDYXq/hKiPX4z0U1/1OoOqwZdCYXZQJ73p0z0Yd4N/2oF0kc2qfjC0rxCNrWeSsIOL4eX4zeuDBj2AU5kBXiJhX7fZtc904dXQ8g3QTKAScZ2mxBfabTWPZaNfCgEpiYEuqQ/wIKlZ/E6cTdFF4MzsbkkX4HT9JCINdDP7WS7+ZvaepAtxK1YZcKwkWbiRdmLG+TPAuWa2KYRuXNJdwLX+pYlkCIgZpoaOy1DZc6TU1dNAj9Be2a6G+PNISxHPws54dhUog39TTZjal8Ybau5VQ7wy5RywqylSQGg7ZQwwwD9bEiUcKd7Vvy2KTye/QZeSUrM3kqDaZte+k9nN8aq9XQ3xIYjpACS4AcgqIN1KVpTk4dSNJLoTILwcOMY//jsRwhHATzPOu237mNlmnBMA3I8cFc8JCshaoC5MOAIICmiV79hI5+2M1Fqsi4pajvg02LWYzcUq1igW/50aW+s1eX6/TDrFwppr5uAcCgAn6Nu/GVwcIY0MnJXM2ZAF13YeGY02u6aLcKRhcOVMINnnNE1dcGi27t3N5g3OFlDkQ+qvHjcELt2ah6q2POO8VNH7oFB0iRRLqsSpVEncZNYZ7Y1C0JgtA44I62RNNYsYXPkJxFSw5wixqP37z8CsmQEVf1FD/IwcvAuAkjacx65dx2TtGoVyezVw9inn9eoZ+A/32M4L3q5Hc93jB15TXsr2ss9k699dFSs4k+7E6eHFoAao8o/fwBnpufB+4NjIIZy+5+l8nMtxLHAAMIiunq0D/Nd3zSwsvjA2cM9W4BchfdJgZlslbcfZIQCRwu//gDOBmZq68GDaE+cC4zBORhxPyuYCGIN4Ug2t51tzddaHQ42PHw5ll2M2GnQwTmcflEFvSOqGsoG5Plfo+Gees0aN8WcwfG+S/Vqx+GOYPUyFxW1G3dvZKRSAXd5pgdGvpKN8gOpbBmS5w8FTYJVJjIru2H0BKVUUOzjL3JthlEfhqMDxcjMLNWR9wbgRtxQXopJECXvwMy8ws/cj+gXHcBgp4QBYk88AbMbZq3FJiHcD6JtPjKBsVx3oRlLeO4HdoWsXPGm312UGUd0s2+7NgLILgfJ0eciCRNp4C0OCK/F4EmOYGx8TkSbSLhSLrwAWYDxGe2KR3V5XfI6Vx8jAGns4nl4vnIiypkWVcgXpjopzduD4b3neE1QBouIfhwCtpKtEbcBTONthPU7vTs7odbggYiRN0j/zMxF9MnFc4HhzxMqUE/aDz78L3KPpi++jbcdc4EsAiEMp967EBVA7oemL+9LuPUx6rGg1ZkuQtwGzDXhKTSxml5D+vRYFa655WVNaj8VocmNMC0yOBq5BXEOF964aW+ptVu0vi2OkIeFaaEFEsiZ8lnIFKdb+ECn1CvIXkOBD3+VhllQOPBLo93dgCrDQzEJnLUlBQY0SkOBnfiXPsY4NHC/O855I2LTx21W/+Aq8HWcC+wPgpWUBO2zZ2URKOFYj+xeaap+OCpApFq+jBAICnbliX9Xk+ZPpX3E2ogY4Ezg60G0EpnsVix9jTTXfKZxLYktgRXwWz6YWTKJDWVW+ogXEj04PC1wq1os0PGMcmcZ3GO9BuABcEmEPczDK/gow3szWZqF5IC4ImcTzIX3KSPfaRdLLwL8GjlvyvCcrbPb4zYq1PAeqdhd0bNdOdl7q2Dvfms5+jllZyR6V9d0iYHdO/AA3UT0CvsrXUXYBZo3AYX63G9Tw+LywdJPsxLUmoDEeZrfVLi7JoAPojhcrqGokgL8USacs43xYaK90XE3QoAwXzosCx3OyCYePSYGxbCE8I+Bo0vO3chqykuqgM4K7FfhVrnvyh4J2V5+0d65/bCiplXmzNZ/9XFZK9YuHkMot6zHYjLq3bVb1D9mVOJ7UZFiGV35WwcTUEfxMBzlHRGnRHQEJqhqvmllRxTNmtgb34CTxsWz9Je1Hqk4ZYKWZbQjpGqST/eFwtspNgUsvRAQIT8g4H52Nro9vB45/ZGbr8rgnX6QmKSNdVWgvC6ittpFcKNt5VclGlQd8h8KvA1cKXr2s6ZxluJQh/4J3TXTv4lAqAeluDOK1wPEVUZ38GMQDpCcxRql2QU9YVUSfpK1yL+nxj3wMdEhXncJo30TK6F8L3Bbar77lVMXil+jCeZmraTTthtZLgSNTFywjIu2toNOC1RG65onIlVnXPDEMK0J/D6OlfN1kQPA7T9hrWfplYxhwTKhe9Qs/Gd0589bcYy2VivWSpL4FtEy+gZmEL0v6csb7SOqPSwvIDDxFPcxBle/bvrs3k+bxuKDRZzPeysdAB5jg54Vl0vUk3QFM8y91ABdFrHRQxkjg51QNelWx1htV33JEBH80pbW/GuPXIbsrcPk9PG9usJ9fI5IMUHpUtt+pyc938dhoSutYKtufIl1lLR6x+LWKxR9SY2udy8sKh2ILxpH0wrkrfyiK386OuxAv+GdleIm4Yi2XZXv49a0Fo9XQcisN8SdzkS/KSJc0HAiG6G/1W744FQh+ITNxdRTDcUI7T9IDOHes4dLFx+N+xBeB7biabIh+mO/B2RXgPDPL/BqOFTjj8ARcgLIP8BDOTkjOyGFeMZEuID8B/h24S9J5wCJc8HI8rhYhqM/HzGxRxDiDGA12M55uViz+OtJSsFUkaMPTCEhUYTodl0KfRAKzq+y2mhAbS/8BnbU5X2LA+lcUa5kLLMcYieediNsiqR/iBYwNuO+6eCQoR3wRsy/SNu4tFzTUCmSvkeADYKTL4vXOIfn8mT3I7NqnaC6cnd1et0P1LRfg6WngYOBA0Bzq4/WKsRS0DNgIdgToSKfKeacgFJLW0wVpAiLpIOA7OMkWroDo+pBCn0xVoxC0k2HQm1mbpCtwe1slZ/oL/RbEYuBinJAkESogZva4pDtxggcwEsjcw8lwtfTTgKRtsI1w9+2RQDI/6Q2cy/hknKCe57dMbAO+kTNZ0rw1wCroTNd2/MycwAowIyTItwbjKmuufSSUbFP1/YrFq3F5bgCjQdPSaQLoRdq98ylv/xFWiIaUE1UYVWDumw4n3cLgvl/NpzYjCja79g3Vx0/G4z6S2oBL4f9Eepwkg4XoEljNRKeASDoSWIJLtUjqwnXA6ZLONbOnAvcNBnIuTxFYGZaWbmaPSDoZuAMYRyrqbf647sYVUe1PKsrd1qW2Ip3mVZKWALeQvuJ9ADwK/NDMnpZ0HK7eBGCZmYXVQqRlLfvpI+Nxxv0VpM/q63Gr0s1mlnMLJGuqXgIcqvqFn8SzcyFRB/o4dEaig/gA+BPG/fQp+4V9/6yseWDWVPM1NbQ+jLgF7FiCXkM3g85lcJ+ZNm38djXEX8S50EGEq4PSKiz529uyLu+3J+6m3FvuirBsAs7zl6mpbET2NDDTZtU+1YVG5/jsdeT5vBIrI/sBfpLi5xRrOQc0GScomWrjDpxR/zjSQwx85qlkPVYUOktuJc3HCUSY3rgOGBHh2Sk5fBsl6YVaHZVGUiDNobjinI3AO4WmxUj6HqkV6Dtm9t3Ae+W45X0YboeVVRFCVtiYp8/rw5b+I6F8uNtup30LA//4VrE15K4ufN0oyq2M7X3etR99PlwISggJEZs/jETFCKwsQXnizd2xyZ2mT/f44LSD2LVrGGXlxrayd4r5vDKzpHdoM0Tm32zG1Tss6c6g92ZIWgDU+qfnmdn8PTmeXuweJFeLAUC2GdVID5B9FBFUsV6I7NWLfQpJ3XAjLl09W7/IAv19HZJ87wgA6zLLavdW+KrhEL8NzfO1Ejp3ChZuklWO5uFc3ZtxKujGPF43dad8O8tn7lvIFk/lAP72ObOBqXRNnzDgD2b2RslGufdhr1o9/JjRobiaj7A2EvfA566d2HNISHoPZ/++ArwUaK92o7TivyXNMLO8Ek07vQtmdotft3AxzoOUlPpyoK+k/sWmae8D2JM7R6bBr748ElcPUkW4IOQql03g0v5fx83qm/y2OeM17Hg7btJMtkTGeZdmZgk/0XN/nCNjGC7mNSykBa/vjxPko3DFbknskrQMJywvkxKcFXmsOuXAEklfMsvMPgjv3AkzmyypGbc/VD9cHORm4Azgcd/dm7NAaB9EJakyzcU9zUxSX1ye15iQdhjZMyC24urqV+G2NVoVcrymJ9SXbPC9eutIxZvygu99PBpXMjAWV1uTfD0uo/s2ScnV5q+40obMGF4Cpyq2SJpsZnOy8s/lufW3w2nBxSb+iNs58SNrj5QKvhoUJgBjcKtAWFjNgNW4LNjluIDlqkB7O4/6+H0CfjbH2JCWuXq+iUtRehSX7fBn0mtSbgH+MyqEkdfWo/7euL/GpVFsxW2jeVfWm3qRrFuJEoKREbclcLP9P0gJQrKtyLL3Vy8AScmNHD6F04ROITXZbCPcG3sfcFlYIV3ee/P6OuRUXOS4Ard74A1mljWVfF+HpANw6tAougrBARG3deAiupkCsBx4LarisReFQ9IInKBM9FtUie0S4HwzS9tzrODNqyWdiMuZSpZmPobb+mafFBR/YqjCCUFYiyqa2oVTgZbTdTV4Y2/8m4a9GZJOwtmR2UoK2oBPm9nfO+8rJnvE96Rchku9OMK//BLOVmkBfm9m2eIqHyrI/YXcKMIF4HCiZ52tuFqW13BxohWkhGBlKdJNetF9SDoVN5EPzdUX5627wMyehCIFJMC4HLfL+TehcwNkcA/Ob/EFxqzIYpgSIqAKhbVspabvkBKAtFcze7cnx9yL0kDSGbgtbTv/CjXjVbg9wvbHGfU7cc+tleQv2PxBHIrLVarF/Q9H0JuwHOevXo3ztqwOHpvlURLalV8/XHT7gJDXzGvDSO35m4kdOFUouAokj18vtpS4F/sGSiYgaUTdynIqTliSmxZkKzTYjhOYdpyOmKtVkLFJQQ5swvcC0XU1WLW7YwK92HvQIwLShYn7o83DcP79g/2WeXwA0ULUkdHacVHddbha73XZjntXgV4Ui90iIPnA3/F8PzKEoXd278WexIdGQHrRiw8j/h+c20IoEFD+pgAAAABJRU5ErkJggg=="/><!--URL:../assets/images/logo.png-->
|
||
</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 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2Z"></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">
|
||
LdapSaisie
|
||
</span>
|
||
</div>
|
||
<div class="md-header__topic" data-md-component="header-topic">
|
||
<span class="md-ellipsis">
|
||
|
||
Documentation
|
||
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</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-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 id="print-site-cover-page">
|
||
<div style="padding-bottom: 3em">
|
||
<h1>LdapSaisie</h1>
|
||
<h2>Documentation</h2>
|
||
</div>
|
||
<p>
|
||
<small>
|
||
Auteur: Benjamin Renard
|
||
(<a href="mailto:brenard@easter-eggs.com">brenard@easter-eggs.com</a> /
|
||
<a href="mailto:brenard@zionetrix.net">brenard@zionetrix.net</a>)
|
||
</small><br/>
|
||
<small>Site web: <a href="https://ldapsaisie.org/doc/">https://ldapsaisie.org/doc/</a></small><br/>
|
||
<small>Repo: <a href="https://gitlab.easter-eggs.com/ee/ldapsaisie">https://gitlab.easter-eggs.com/ee/ldapsaisie</a></small><br/>
|
||
<small>Easter-eggs</small><br/>
|
||
</p>
|
||
</section>
|
||
|
||
<section class="print-page">
|
||
<div data-toc-depth="6" id="print-page-toc">
|
||
<nav class="print-page-toc-nav" role="navigation">
|
||
<h1 class="print-page-toc-title">Table des matières</h1>
|
||
</nav>
|
||
</div>
|
||
</section>
|
||
<section class="print-page" id="index"><h1 id="index-introduction">Introduction</h1>
|
||
<p>LdapSaisie est une application web d'administration d'annuaire LDAP développée en PHP/Javascript.
|
||
Cette application a pour but d'abstraire la complexité d'un annuaire par l'intermédiraire d'une
|
||
interface d'administration simple et intuitive. L'application a été concue avec pour objectif
|
||
premier une modularité maximum, ce qui permet l'extention ou l'adaptation facile de l'application
|
||
par l'intermédiaire de modules, d'extentions et de greffons. Cette application peut être utilisée
|
||
pour administrer le système d'information basé sur l'annuaire LDAP et également en paralèlle pour
|
||
permettre aux utilisateurs d'avoir accès aux données les concernants et éventuellement de les
|
||
modifier.</p>
|
||
<h2 id="index-fonctionnalites">Fonctionnalités</h2>
|
||
<p>De part sa modularité, LdapSaisie est facilement extensible. Cependant, voici une liste
|
||
non-exhaustive de ses fonctionnalités :</p>
|
||
<ul>
|
||
<li>Gestion d'annuaire simple et multi-branches</li>
|
||
<li>Gestion d'un nombre illimité de types d'objets</li>
|
||
<li>Gestion d'un nombre illimité de populations se connectant à l'interface</li>
|
||
<li>Gestion fine des droits des utilisateurs, permettant la maitrise des droits d'accès sur les objets
|
||
de l'annuaire et leurs atributs, tout en permettant la délégation de droits.</li>
|
||
<li>
|
||
<p>Gestion d'un grand nombre de types d'attributs :</p>
|
||
<ul>
|
||
<li>Texte (court ou long)</li>
|
||
<li>Date (format paramétrable)</li>
|
||
<li>Booléen (valeurs paramétrables)</li>
|
||
<li>Image/Photo</li>
|
||
<li>Mot de passe (génération de mot passe avec gestion d'une politique fine)</li>
|
||
<li>Adresse mail</li>
|
||
<li>Flux RSS</li>
|
||
<li>Lien web (URL)</li>
|
||
<li>Adresse XMPP</li>
|
||
<li>Maildir</li>
|
||
<li>Quota de mails</li>
|
||
<li>Clef publique SSH</li>
|
||
<li>Liste déroulante à choix simple ou multiple</li>
|
||
<li>
|
||
<p>Relation à d'autres objets de l'annuaire/ Exemple : membres d'un groupe, parrain d'un
|
||
utilisateur, ... (valeur clé paramétrable)</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Chaque type d'attribut à des fonctionnalités qui lui sont propres et qui rendent plus facile
|
||
et agréable l'utilisation de l'interface (génération automatique de mot de passe, génération
|
||
des valeurs d'un champ à partir d'autres, ...).</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Gestion d'un grand nombre de règles de vérification des valeurs des attributs :<ul>
|
||
<li>Alpha-numérique</li>
|
||
<li>Lettres uniquement</li>
|
||
<li>Longeur maximale/minimale d'une chaine de caractères</li>
|
||
<li>Valeur différente de zéro</li>
|
||
<li>Pas de signe de ponctuation</li>
|
||
<li>Valeur numérique</li>
|
||
<li>Comparaison de valeur</li>
|
||
<li>Date</li>
|
||
<li>Adresse mail</li>
|
||
<li>Poids d'une image</li>
|
||
<li>Taille d'une image</li>
|
||
<li>Type de fichiers images</li>
|
||
<li>Politique de mot de passe (longueur/caractères autorisés/caractères obligatoires)</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Gestion simplifiée des relations entre les objets de l'annuaire</li>
|
||
<li>Interface facilement personnalisable grâce à l'utilisation d'un système de template.</li>
|
||
<li>Possibilité de postionner des déclencheurs permettant d'exécuter vos propres scripts, fonctions ou
|
||
méthodes au moments précis ou l'utilisateur créé, modifie ou supprime un objet ou un de ses
|
||
attributs. Ces déclencheurs, en fonction de leur positionnement, peuvent influencer le
|
||
comportement de l'application en empêchant par exemple, la validation des données d'un formulaire.</li>
|
||
<li>Gestion fine de l'affichage des attributs en fonction de l'écran (=vue) sur lequel se trouve
|
||
l'utilisateur.</li>
|
||
<li>Gestion des dépendances entre attributs, permettant par exemple de regénérer automatiquement la
|
||
valeur d'un attribut caché lors de la modification d'un autre.</li>
|
||
<li>Possibilité de gérer des attributs entièrement cachés, dont les valeurs seront modifiées lors de
|
||
la modification d'attribut en dépendance.</li>
|
||
</ul></section><h1 class="nav-section-title">Installation</h1><section class="print-page" id="install-requirements"><h1 id="install-requirements-pre-requis">Pré-requis</h1>
|
||
<ul>
|
||
<li>Le service Apache HTTP avec le module mod_rewrite d'activé. Les règles de réécriture d'URL sont
|
||
définies dans le fichier <code>.htaccess</code> fourni avec l'application et il est donc nécessaire
|
||
d'autoriser une telle configuration à ce niveau via la directive <code>AllowOverride</code> devant inclure à
|
||
minima <code>FileInfo</code>.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>L'utisateur exécutant le serveur web doit avoir les droits d'écriture sur le dossier <code>tmp</code>. En cas
|
||
d'installation à partir du paquet Debian, ce dossier est remplacé par un lien symbolique vers
|
||
le dossier <code>/var/cache/ldapsaisie/</code>.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>PHP 5.6 (ou supérieur) avec <code>magic_quotes_gpc</code> et <code>register_globals</code> à <code>off</code>. L'outil CLI de PHP
|
||
est par ailleurs nécessaire pour l'utilisation des outils CLI fournis avec l'application (fourni
|
||
par le paquet <code>php-cli</code> dans Debian).</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Le support LDAP dans PHP (paquet <code>php-ldap</code> dans Debian)</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Le support mhash dans PHP (paquet <code>php5-mhash</code> dans Debian Lenny, intégré à <code>php-common</code> dans les
|
||
versions supérieurs)</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Le support json dans PHP (<code>pear install pecl/json</code> sur RedHat, intégré au paquet <code>php5-common</code>
|
||
précédement)</li>
|
||
</ul>
|
||
<ul>
|
||
<li><a href="http://pear.php.net/package/Net_LDAP2">Net_LDAP2</a> (paquet <code>php-net-ldap2</code> dans Debian ou
|
||
<code>pear install net_ldap2</code>)</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Le support mbstring dans PHP (paquet <code>php-mbstring</code> depuis Debian Stretch, intégré au paquet
|
||
<code>php-common</code> dans Debian)</li>
|
||
</ul>
|
||
<ul>
|
||
<li><a href="http://www.smarty.net/">Smarty</a> (paquet <code>smarty3</code> dans Debian)</li>
|
||
</ul>
|
||
<ul>
|
||
<li>La librairie <a href="https://pear.php.net/package/Console_Table">Console_Table</a> (nécessaire pour le
|
||
fonctionnement de l'outil CLI, paquet <code>php-console-table</code> dans Debian)</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Les librairies <a href="https://pear.php.net/package/Mail">Mail</a> et
|
||
<a href="https://pear.php.net/package/Mail_Mime">PEAR_Mail_Mime</a> (nécessaire pour l'envoi de courriels,
|
||
paquets <code>php-mail</code> et <code>php-mail-mime</code> dans Debian)</li>
|
||
</ul>
|
||
<ul>
|
||
<li>L'<a href="https://www.php.net/manual/fr/intro.ftp.php">extension PHP <code>ftp</code></a> (nécessaire pour le
|
||
fonctionnement du <a href="#conf-configuration-des-lsaddons">LSaddon</a> FTP, paquet <code>php-ftp</code>
|
||
dans Debian)</li>
|
||
</ul>
|
||
<ul>
|
||
<li>La librairie <a href="https://github.com/phpseclib/phpseclib">PhpSecLib</a> (nécessaire pour le
|
||
fonctionnement du <a href="#conf-configuration-des-lsaddons">LSaddon</a> SSH, paquet
|
||
<code>php-phpseclib</code> dans Debian)</li>
|
||
</ul>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">Warning</p>
|
||
<p>La librairie <a href="http://pear.php.net/package/Net_LDAP2">Net_LDAP2</a> oblige le fait que la racine DSE
|
||
de l'annuaire soit lisible en anonyme sinon la connexion à l'annuaire échouera systématiquement.</p>
|
||
</div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Cette documentation est écrite à l'aide du langage Markdown et est mis en forme pour une
|
||
consultation en ligne à l'aide de <a href="https://www.mkdocs.org/">mkdocs</a> et son thème
|
||
<a href="https://squidfunk.github.io/mkdocs-material/">mkdocs-material</a>. Le dépendances pour construire
|
||
cette documentation sont listées dans le fichier <code>doc/requirements.txt</code> et sont installables à
|
||
l'aide de la commande <code>pip install -r doc/requirements.txt</code>.</p>
|
||
</div></section><section class="print-page" id="install-download"><h1 id="install-download-telechargement">Téléchargement</h1>
|
||
<h2 id="install-download-a-partir-du-paquet-debian">À partir du paquet Debian</h2>
|
||
<p>L'installation à partir du paquet Debian peut être réalisée soit en téléchargeant manuellement le
|
||
paquet, soit en déclarant le dépôt APT suivant dans votre fichier <code>/etc/apt/sources.list</code> :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#install-download-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>deb http://ldapsaisie.org/debian stable main
|
||
</code></pre></div>
|
||
<p>Il ne vous restera ensuite plus qu'a installer le paquet <code>ldapsaisie</code> avec la commande suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#install-download-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a>apt-get install ldapsaisie
|
||
</code></pre></div>
|
||
<p>Le fichier <code>/etc/ldapsaisie/apache.conf</code> est un example de configuration du serveur web Apache. La
|
||
configuration du logiciel ce fera ensuite dans le dossier <code>/etc/ldapsaisie/local/</code>.</p>
|
||
<h2 id="install-download-a-partir-de-git">À partir de Git</h2>
|
||
<p>Le dépôt Git peut être récupéré anonymement en utilisant la commande suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#install-download-__codelineno-2-1" id="__codelineno-2-1" name="__codelineno-2-1"></a>git clone https://gitlab.easter-eggs.com/ee/ldapsaisie.git
|
||
</code></pre></div>
|
||
<p>La racine web de l'application se trouvera alors dans le dossier <code>/ldapsaisie/src/public_html/</code>.</p>
|
||
<h2 id="install-download-a-partir-des-snapshot">À partir des snapshot</h2>
|
||
<p>Toutes les nuits, un snapshot de l'arbre Git est réalisé et est téléchargeable au format <em>tar.gz</em> à
|
||
l'adresse suivante :</p>
|
||
<p><a href="http://ldapsaisie.org/download/ldapsaisie-snapshoot.tar.gz">http://ldapsaisie.org/download/ldapsaisie-snapshoot.tar.gz</a></p></section><section class="print-page" id="install-arbo"><h1 id="install-arbo-arborescence-du-projet">Arborescence du projet</h1>
|
||
<ul>
|
||
<li>
|
||
<p><code>doc/</code></p>
|
||
<p>Les fichiers sources de la documentation (Markdown & configuration Mkdocs).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>lsexample/</code></p>
|
||
<p>Les fichiers relatifs à l'annuaire d'exemple.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>src/</code></p>
|
||
<p>Les sources de l'application.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>public_html/</code></p>
|
||
<p>La racine web de l'application : celle-ci ne contient que les fichiers <code>.htaccess</code> et
|
||
<code>index.php</code> qui configure et déclenche la réécriture d'URL.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>conf/</code></p>
|
||
<p>Contient les fichiers de configuration.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSobjects/</code></p>
|
||
<p>Configuration des <a href="#conf-configuration-lsobject">LSobjects</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSaddons/</code></p>
|
||
<p>Configuration des <a href="#conf-configuration-des-lsaddons">LSaddons</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSauth/</code></p>
|
||
<p>Configuration des <a href="#conf-configuration-des-lsauthmethods">LSauthMethod</a>.</p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>includes/</code></p>
|
||
<p>Contient les fichiers des ressources.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>addons/</code></p>
|
||
<p>Les addons au projet.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>class/</code></p>
|
||
<p>Les fichiers de définition des classes PHP.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>js/</code></p>
|
||
<p>Les fichiers Javascript.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>libs/</code></p>
|
||
<p>Les librairies utilisées.</p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>lang/</code></p>
|
||
<p>Les fichiers d'internationalisation.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>templates/</code></p>
|
||
<p>Les fichiers <em>template</em> de l'interface. Il y a un sous-dossier par template.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>css/</code></p>
|
||
<p>Les fichiers css de l'interface. Il y a un sous-dossier par template CSS.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>images/</code></p>
|
||
<p>Les images de l'interface. Il y a un sous-dossier par template d'image.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>local/</code></p>
|
||
<p>Les fichiers personnalisés de l'installation.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>tmp/</code></p>
|
||
<p>Les fichiers temporaires (y compris le cache des templates).</p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul></section><section class="print-page" id="install-howto"><h1 id="install-howto-tutoriel-dinstallation">Tutoriel d'installation</h1>
|
||
<p>Cette section décrit les différentes étapes de l'installation de LdapSaisie. Deux méthodes
|
||
d'installation sont présentées ici, l'une à partir des sources du projet et l'autre à partir du
|
||
paquet Debian.</p>
|
||
<p>Dans ce tutoriel, nous partirons du principe que vous avez pleinement la main sur votre serveur
|
||
(installation de nouveau paquet et configuration de votre serveur web). Nous partons également du
|
||
principe que votre annuaire LDAP est déjà en place. Nous utiliserons pour cette exemple de mise en
|
||
oeuvre l'annuaire correspondant au schéma et à la configuration présente dans les sources du projet
|
||
dans le dossier <code>lsexample</code>.</p>
|
||
<p>La première étape consiste à installer le locigiel en tant que tel. Pour cela, référez vous au
|
||
chapitre <a href="#install-howto-telechargement">Téléchargement</a>.</p>
|
||
<p>En cas d'installation à partir du paquet Debian, la configuration du logiciel se fera dans le
|
||
dossier <code>/etc/ldapsaisie/local/</code>. Les fichiers placés dans ce dossier prévaleront toujours aux
|
||
fichiers fournis par le paquet Debian, vous permettant facilement de modifier un composant existant
|
||
ou dans écrire de nouveaux. Ainsi, pour modifier un fichier CSS par exemple, il vous suffira de le
|
||
placer dans le dossier <code>/etc/ldapsaisie/local/css/</code>.</p>
|
||
<p>Pour une installation à partir du code source, il vous faut cloner le dépôt Git du projet dans le
|
||
dossier <code>/var/www/ldapsaisie</code>. Pour cela il vous faut avoir installés les outils de Git contenu,
|
||
dans Debian, dans le paquet <code>git-core</code>. Le dépôt Git doit ensuite être récupéré anonymement en
|
||
utilisant la commande suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#install-howto-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>git clone https://gitlab.easter-eggs.com/ee/ldapsaisie.git /var/www/ldapsaisie
|
||
</code></pre></div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Pour que cette commande se déroule correctement, vous devez avoir accès au port TCP 443 du
|
||
serveur <code>gitlab.easter-eggs.com</code>. En cas de problème vérifiez votre parefeu.</p>
|
||
</div>
|
||
<p>La suite des opérations se déroulera donc maintenant dans le dossier <code>/var/www/ldapsaisie</code>. Pour
|
||
avoir plus de détails sur les élements qu'on retrouve dans ce dossier, vous pouvez consulter
|
||
<a href="#install-howto-arborescence-du-projet">la section concernée</a>. Nous allons nous instérésser plus particulièrement :</p>
|
||
<ul>
|
||
<li>au script <code>upgradeFromGit.sh</code> permettant la mise à jour de votre repos tout en concervant les
|
||
adaptations que nous ferons pour l'usage d'LdapSaisie adapté à notre annuaire ;</li>
|
||
</ul>
|
||
<ul>
|
||
<li>au dossier <code>config.local</code> dans lequel seront stockés vos fichiers et vos adaptations de
|
||
l'application ;</li>
|
||
</ul>
|
||
<ul>
|
||
<li>au dossier <code>src/public_html</code> qui correspond à la futur racine du site web de l'application.</li>
|
||
</ul>
|
||
<p>Le principe de l'adaptation est ici de mettre vos fichiers personnalisés dans le dossier
|
||
<code>config.local</code>, de les déclarer dans votre fichier <code>config.local/local.sh</code> contenant la liste des
|
||
fichiers devant être installés. Le fichier <code>local.sh</code> est la source de configuration du script
|
||
<code>upgradeFromGit.sh</code>. Il faut donc dans un premier temps créer votre fichier <code>local.sh</code> en copiant le
|
||
fichier d'example <code>local.sh.example</code>. Ce fichier est un script bash déclarant les variables de
|
||
configurations suivantes :</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>LOCAL_FILES</code></p>
|
||
<p>La liste des chemins des fichiers à installer dans l'arboressence du site. Cette élément doivent
|
||
être séparés par des espaces ou des retour à la liste. Exemple :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#install-howto-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a>conf/config.inc.php
|
||
<a href="#install-howto-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a>lang/fr_FR.UTF8/lang.php
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LOG_FILE</code></p>
|
||
<p>Nom du fichier de log des mises à jour.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>THEME</code></p>
|
||
<p>Le nom du theme à installer (facultatif et non traité dans ce tutoriel).</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Il est possible d'utiliser dans ce fichier de configuration la variable bash <code>$ROOT_DIR</code>
|
||
correspondant au chemin du dossier d'installation, c'est à dire dans notre exemple
|
||
<code>/var/www/ldapsaisie</code>.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<p>La deuxième étape concerne la configuration globale de l'application : Cette partie est
|
||
principalement contenue dans le fichier <code>src/conf/config.inc.php</code> (ou
|
||
<code>/etc/ldapsaisie/local/conf/config.inc.php</code> en cas d'installation à partir du paquet Debian). En cas
|
||
d'installation à partir du code source, il faut donc dans un premier temps copier ce fichier dans le
|
||
dossier <code>config.local</code> et le déclarer dans la liste des fichiers à déployer lors des mises à jour
|
||
(variable <code>LOCAL_FILES</code> dans le fichier <code>local.sh</code>). Il s'agit en particulier dans ce fichier de
|
||
configurer la connexion à votre annuaire. Vous pouvez vous inspirer du fichier d'exemple fourni et
|
||
pour plus de détails, reportez-vous à <a href="#install-howto-configuration-globale">la section concernée</a>.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Notez qu'il est possible de passer l'application en mode <em>debug</em> ce qui peut être utile par la
|
||
suite.</p>
|
||
</div>
|
||
<p>La troisième étape concerne la configuration des types de
|
||
<a href="#conf-lsobject-configuration-lsobject">LSobjects</a> : Chaque type d'objet manipulé par
|
||
LdapSaisie doit correspondre avec un type de LSobject.</p>
|
||
<ol>
|
||
<li>
|
||
<p>Création du fichier de classe <em>(optionnel)</em> : Ce fichier contient la déclaration de la classe PHP
|
||
correspondant au type de LSobject. Cette classe étend la classe <code>LSldapObject</code> qui contient pour
|
||
ainsi dire toute les méthodes et proprités nécessaires pour les types de LSobject simples. Si
|
||
votre type de LSobject nécessite des méthodes ou propriétés particulières, vous pouvez implémenter
|
||
cette classe. À défaut, une classe vierge d'adaptation sera automatiquement déclarée.</p>
|
||
<p>Les fichiers des classes sont contenus dans le dossier <code>/includes/class/</code> et portent les noms
|
||
composés de la manière suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#install-howto-__codelineno-2-1" id="__codelineno-2-1" name="__codelineno-2-1"></a>class.LSobjects.[nom du type d'LSobject].php
|
||
</code></pre></div>
|
||
</li>
|
||
<li>
|
||
<p>Configurer vos LSobject : Cette partie est certainement la plus longue et consiste à déclarer
|
||
l'ensemble des informations relatives aux types des objets LDAP manipulés. Les fichiers d'exemples
|
||
fournis vous seront alors d'une aide précieuse. Basez vous sur l'un de pour créer le votre. Pour
|
||
cela le fichier de configuration du type d'LSobjet <code>LSpeople</code> est le plus complet et est un bon
|
||
point de départ. Pour plus de détails sur les élements de configuration de ce fichier,
|
||
reportez-vous à <a href="#conf-lsobject-configuration-lsobject">la section concernée</a>.</p>
|
||
</li>
|
||
<li>
|
||
<p>Configurer si nécessaire les relations entre les objets appelés <a href="#install-howto-lsrelation">LSrelations</a>. Les
|
||
relations les plus simples (via un attribut de liaison) pourront être implémentées à l'aide d'un
|
||
simple paramètrage. Pour des relations, plus complexes, il sera possible d'implémenter des
|
||
méthodes personnalisées pour les gérer. Pour plus de détails, reportez-vous à
|
||
<a href="#conf-lsrelation">la section concernée</a>.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Pour avoir un exemple de fichier de classe PHP implémentant des methodes de gestion de
|
||
<a href="#install-howto-lsrelation">LSrelations</a> complexes, vous pouvez consulter le fichier de classe <code>LSgroup</code>.</p>
|
||
</div>
|
||
</li>
|
||
</ol>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>En cas d'installation à partir du code source, pensez à déclarer les fichiers que vous venez de
|
||
créer dans la variable <code>LOCAL_FILES</code> du fichier <code>local.sh</code>. Exemple pour le type d'LSobjet
|
||
portant comme nom <code>LSexample</code> :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#install-howto-__codelineno-3-1" id="__codelineno-3-1" name="__codelineno-3-1"></a>src/conf/LSobjects/config.LSobjects.LSexample.php
|
||
<a href="#install-howto-__codelineno-3-2" id="__codelineno-3-2" name="__codelineno-3-2"></a>src/includes/class/class.LSobjects.LSexample.php
|
||
</code></pre></div>
|
||
</div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Vous pouvez également personnaliser l'interface : Il est possible de personnaliser à votre goût
|
||
l'interface en écrivant votre template ou en modifiant simplement les fichiers CSS. Une partie
|
||
de cette documentation concernera bientôt cette problématique. Patience...</p>
|
||
</div>
|
||
<p>En cas d'installation à partir du code source, une dernière étape à ce niveau consiste à lancer le
|
||
script <code>upgradeFromGit.sh</code> pour qu'il installe les fichiers que vous venez de créer. Ce script est
|
||
conçu pour dire tout ce qu'il fait donc en cas de problème vous devriez rapidement comprendre où
|
||
cela coince. Dans tout les cas, n'hésitez pas à poser vos questions à la communauté sur la liste
|
||
<a href="mailto:ldapsaisie-users@lists.ldapsaisie.org">ldapsaisie-users@lists.ldapsaisie.org</a>.</p></section><h1 class="nav-section-title-end">Ended: Installation</h1><h1 class="nav-section-title">Mise à jour</h1><section class="print-page" id="upgrade"><h1 id="upgrade-mise-a-jour">Mise à jour</h1>
|
||
<p>Cette section de la documentation détaille la procédure de mise à jour d'une installation existante
|
||
et regroupe des informations pratiques et utiles pour des montées de versions spécifiques entraînant
|
||
par exemple une perte de rétrocompatibilité de la configuration.</p></section><section class="print-page" id="upgrade-method"><h1 id="upgrade-method-procedure-de-mise-a-jour">Procédure de mise à jour</h1>
|
||
<h2 id="upgrade-method-installation-via-paquet-debian">Installation via paquet Debian</h2>
|
||
<p>Lors d’une installation par paquet Debian, la mise à jour est grandement facilité par le packaging :
|
||
Il vous suffit de mettre à jour le paquet <code>ldapsaisie</code> :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-method-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>apt<span class="w"> </span>update
|
||
<a href="#upgrade-method-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a>apt<span class="w"> </span>install<span class="w"> </span>ldapsaisie
|
||
</code></pre></div>
|
||
<p>Une fois l’application mise à jour, prêté attention aux nouveautés et point de vigilances décrite
|
||
dans la section suivante.</p>
|
||
<h2 id="upgrade-method-installation-a-partir-des-sources">Installation à partir des sources</h2>
|
||
<p>Lors d’une installation par à partir des sources, le script <code>upgradeFromGit.sh</code> permet d’automatiser
|
||
la mise à jour, à condition que vous ayez suivi la procédure d’installation à ce sujet.</p>
|
||
<p>Ce script s’occupera alors de :</p>
|
||
<ul>
|
||
<li>Nettoyer <code>working-tree</code> Git des liens symboliques des fichiers locaux (et éventuellement du
|
||
thème) mis en place lors d’une précédente exécution ;</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Vider le cache des templates ;</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Mettre à jour le <code>working-tree</code> Git via un <code>git pull</code> de la mise à jour ;</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Installer des liens symboliques pour les fichiers locaux. En cas de fichier remplacant un fichier
|
||
livré avec l’application, le script vous notifiera en cas de changement intervenu dans le fichier
|
||
fourni avec l’application et vous permettra de le mettre à jour simplement votre fichier local
|
||
(via un <code>vim -d</code>) ;</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Détecter des changements dans les fichiers <code>MO</code> (traduction) et de déclencher dans ce cas un
|
||
rechargement du serveur web pour prise en compte ;</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Option : de compiler une version locale à jour de la documentation ;</li>
|
||
</ul>
|
||
<p>Une fois l’application mise à jour, prêté attention aux nouveautés et point de vigilances décrite
|
||
dans la section suivante.</p></section><section class="print-page" id="upgrade-2_4_1-to-3_0_0"><h1 id="upgrade-2_4_1-to-3_0_0-mise-a-jour-241-300">Mise à jour 2.4.1 -> 3.0.0</h1>
|
||
<p>Cette mise à jour majeure apporte de nombreuses nouveautés auxquelles il est important de prêter
|
||
attention. Cette section ne parlera pas particulièrement de ces nouveautés, mais vous pouvez
|
||
consulter le fichier
|
||
<a href="https://gitlab.easter-eggs.com/ee/ldapsaisie/-/raw/master/debian/ldapsaisie.NEWS">debian/ldapsaisie.NEWS</a>
|
||
pour cela. Cette section listera en outre les points de vigilances à avoir et les adaptations à
|
||
apporter sur votre configuration et votre code personnalisé.</p>
|
||
<h2 id="upgrade-2_4_1-to-3_0_0-fichier-configincphp">Fichier config.inc.php</h2>
|
||
<ul>
|
||
<li>ajout du paramètre <code>ConsoleTable</code> avec pour valeur par défaut sous Debian
|
||
<code>/usr/share/php/Console/Table.php</code></li>
|
||
</ul>
|
||
<ul>
|
||
<li>ajout du paramètre <code>public_root_url</code> avec pour valeur par défaut sous Debian <code>/ldapsaisie</code></li>
|
||
</ul>
|
||
<ul>
|
||
<li>paramètre <code>$GLOBALS['defaultCSSfiles']</code> : il est nécessaire de modifier les URLs des fichiers
|
||
listés : seul le nom du fichier doit rester, sa localisation sera détectée automatiquement. Par
|
||
exemple, <code>$GLOBALS['defaultCSSfiles'] = array('../light-blue.css');</code> devient
|
||
<code>$GLOBALS['defaultCSSfiles'] = array('light-blue.css');</code>.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>les paramètres <code>authObjectType</code>, <code>authObjectFilter</code> et <code>authObjectTypeAttrPwd</code> sont remplacés par
|
||
le tablau <code>LSobjects</code> dans le paramètre <code>LSauth</code>.</p>
|
||
<p>Par exemple:</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'authObjectType' => 'LSpeople',
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a>'authObjectFilter' => '(|(uid=%{user})(mail=%{user}))',
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a>'authObjectTypeAttrPwd' => 'userPassword',
|
||
</code></pre></div>
|
||
<p>Devient:</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a>'LSauth' => array (
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a> 'LSobjects' => array(
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a> 'LSpeople' => array(
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a> 'filter' => '(|(uid=%{user})(mail=%{user}))',
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a> 'password_attribute' => 'userPassword',
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a> ),
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a> ),
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-1-8" id="__codelineno-1-8" name="__codelineno-1-8"></a> [...]
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-1-9" id="__codelineno-1-9" name="__codelineno-1-9"></a>),
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Une erreur de frappe historique a été corrigé dans le nom de la variable
|
||
<code>$GLOBALS['defaultJSscripts']</code>, à savoir un <em>"R"</em> manquant.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Les fichiers Javascript utilisés par défaut par l'application ne sont désormais plus listés dans
|
||
la variable <code>$GLOBALS['defaultJSscripts']</code>. Seul doit y demeurer vos propres fichiers. Voici la
|
||
liste des fichiers concernés et qui n'ont plus à être inclus via ce paramètre :<p>- <code>mootools-core.js</code>
|
||
- <code>mootools-more.js</code>
|
||
- <code>functions.js</code>
|
||
- <code>LSdefault.js</code>
|
||
- <code>LSinfosBox.js</code></p>
|
||
</li>
|
||
</ul>
|
||
<h2 id="upgrade-2_4_1-to-3_0_0-fichiers-css">Fichiers CSS</h2>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Les fichiers <code>light-*.css</code> ont été retravaillés pour tous <em>hériter</em> du fichier <code>light-blue.css</code>
|
||
qui défini les couleurs de l'interface au travers des variables. Ainsi, il est très simple
|
||
d'ajuster ce thème à vos couleurs. Si cela vous intéresse, vous pouvez prendre exemple sur les
|
||
autres fichiers <code>light-*.css</code>.</p>
|
||
<p>Au passage, ce thème a été retravaillé pour prendre en compte la mise en forme d'un maximum de
|
||
composants de l'application tout en profitant du côté responsive de l'interface apporter par
|
||
cette mise à jour. Si vous avez un thème personnalisé, il est conseillé de regarder si celui-ci
|
||
ne pourrait pas tirer partie du fichier <code>light-blue.css</code> en le surchargeant. À minima, vous
|
||
pouvez analyser les évolutions de ce fichier pour identifier les modifications intéressantes à
|
||
reporter sur votre thème personnel.</p>
|
||
</div>
|
||
<ul>
|
||
<li>Si vous utilisez un des fichiers <code>light-*.css</code> autre que le fichier <code>light-blue.css</code>, vous devez
|
||
désormais également charger ce dernier en premier.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>corriger les URL des images : <code>url(../../images/default/find.png)</code> devient <code>url(../image/find)</code>.
|
||
Pour identifier les fichiers CSS concernés, vous pouvez utiliser les commandes suivantes :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-2-1" id="__codelineno-2-1" name="__codelineno-2-1"></a>grep<span class="w"> </span>-Er<span class="w"> </span><span class="s1">'url\(.*images'</span><span class="w"> </span>/etc/ldapsaisie/local/css
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-2-2" id="__codelineno-2-2" name="__codelineno-2-2"></a>grep<span class="w"> </span>-Er<span class="w"> </span><span class="s1">'url\(.*\.(png|gif|jpg)'</span><span class="w"> </span>/etc/ldapsaisie/local/css
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>modification CSS page <code>fatal_error</code> (fichier <code>base.css</code>) : <code>#fatal_error</code> devient <code>#error</code></li>
|
||
</ul>
|
||
<h2 id="upgrade-2_4_1-to-3_0_0-fichiers-php">Fichiers PHP</h2>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSsession :: redirect()</code> devient <code>LSurl :: redirect()</code>. Pour identifier les fichiers CSS
|
||
concernés, vous pouvez utiliser la commande suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-3-1" id="__codelineno-3-1" name="__codelineno-3-1"></a>grep<span class="w"> </span>-Er<span class="w"> </span><span class="s1">'LSsession *:: *redirect *\('</span><span class="w"> </span>/etc/ldapsaisie/local/
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>Les méthodes de gestion des Javascript et CSS additionels ont été migrées de la classe <code>LSsession</code>
|
||
vers la classe <code>LStemplate</code> :</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSsession :: addJSscript()</code> devient <code>LStemplate :: addJSscript()</code>.</p>
|
||
<p>Par ailleurs le paramètre <code>$path</code> disparait et la méthode <code>addLibJSscript</code> a été ajoutée pour
|
||
permettre spécifiquement l'inclusion des fichiers Javascript des librairies. Voici quelques
|
||
exemples d'utilisation et leur équivalent à présent:</p>
|
||
<ul>
|
||
<li><code>LSsession :: addJSscript('../../local/includes/js/LSformElement_eetelephone.js');</code>
|
||
devient <code>LStemplate :: addJSscript('LSformElement_eetelephone.js');</code></li>
|
||
</ul>
|
||
<ul>
|
||
<li><code>LSsession :: addJSscript('../../local/includes/js/LSformElement_eetelephone.js');</code>
|
||
devient <code>LStemplate :: addJSscript('LSformElement_eetelephone.js');</code></li>
|
||
</ul>
|
||
<ul>
|
||
<li><code>LSsession :: addJSscript('click-to-dial_view.js', 'local/includes/js/');</code> devient
|
||
<code>LStemplate :: addJSscript('click-to-dial_view.js');</code></li>
|
||
</ul>
|
||
<ul>
|
||
<li><code>LSsession :: addJSscript('Picker.js',LS_LIB_DIR.'arian-mootools-datepicker/');</code>
|
||
devient <code>LStemplate :: addLibJSscript('arian-mootools-datepicker/Picker.js');</code></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li><code>LSsession :: addJSconfigParam()</code> devient <code>LStemplate :: addJSconfigParam()</code>.</li>
|
||
</ul>
|
||
<ul>
|
||
<li><code>LSsession :: addHelpInfos()</code> devient <code>LStemplate :: addHelpInfo()</code>.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSsession :: addCssFile()</code> devient <code>LStemplate :: addCssFile()</code>.</p>
|
||
<p>Par ailleurs le paramètre <code>$path</code> disparait et la méthode <code>addLibCssFile</code> à été ajoutée pour
|
||
permettre spécifiquement l'inclusion des fichiers CSS des librairies. Voici quelques exemples
|
||
d'utilisation et leur équivalent à présent:</p>
|
||
<ul>
|
||
<li><code>LSsession :: addCssFile('test.css', '../../local/css/');</code> devient
|
||
<code>LStemplate :: addCssFile('test.css');</code>. Doit donc être conservé, que le nom du fichier CSS,
|
||
pas de chemin vers celui-ci.</li>
|
||
</ul>
|
||
<ul>
|
||
<li><code>LSsession :: addCssFile('datepicker_vista.css',LS_LIB_DIR.'arian-mootools-datepicker/datepicker_vista/');</code>
|
||
devient
|
||
<code>LStemplate :: addLibCssFile('arian-mootools-datepicker/datepicker_vista/datepicker_vista.css');</code></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<p>Pour identifier les fichiers concernés, vous pouvez utiliser les commandes suivantes :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-4-1" id="__codelineno-4-1" name="__codelineno-4-1"></a>grep<span class="w"> </span>-Er<span class="w"> </span><span class="s1">'LSsession *:: *(addJSscript|addLibJSscript|addJSconfigParam|addHelpInfos|addCssFile|addLibCssFile) *\('</span><span class="w"> </span>/etc/ldapsaisie/local/
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-4-2" id="__codelineno-4-2" name="__codelineno-4-2"></a>grep<span class="w"> </span>-Er<span class="w"> </span><span class="s1">'(LSsession|LStemplate) *:: *addJSscript\(.*local'</span><span class="w"> </span>/etc/ldapsaisie/local/
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-4-3" id="__codelineno-4-3" name="__codelineno-4-3"></a>grep<span class="w"> </span>-Er<span class="w"> </span><span class="s1">'(LSsession|LStemplate) *:: *addJSscript\(.*\.\.\/'</span><span class="w"> </span>/etc/ldapsaisie/local/
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-4-4" id="__codelineno-4-4" name="__codelineno-4-4"></a>grep<span class="w"> </span>-Er<span class="w"> </span><span class="s1">'(LSsession|LStemplate) *:: *addCssFile\(.*local'</span><span class="w"> </span>/etc/ldapsaisie/local/
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-4-5" id="__codelineno-4-5" name="__codelineno-4-5"></a>grep<span class="w"> </span>-Er<span class="w"> </span><span class="s1">'(LSsession|LStemplate) *:: *addCssFile\(.*\.\.\/'</span><span class="w"> </span>/etc/ldapsaisie/local/
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSlog</code> vs <code>LSdebug</code> : L’utilisation de <code>LSdebug</code> est dépriorisée en faveur de <code>LSlog</code>. Ce dernier
|
||
ajoute désormais la notion de <em>logger</em>, permettant d’identifier la source des logs. Ce mécanisme
|
||
permet la configuration d’un niveau de log spécifique pour un <em>logger</em> donné, ainsi que la mise en
|
||
place de filtres au niveau des <em>handers</em> pour ne logger par exemple que certains <em>loggers</em>, ou à
|
||
l’inverse en exclure d’autres.</p>
|
||
<ul>
|
||
<li>Pour vos classes personnalisées : si celles-ci héritent d’une classe standard, il est fort
|
||
probable qu’il soit possible d’utiliser des méthodes fournies par cette classe pour logguer
|
||
au travers un <em>logger</em> dédié (voir les méthodes <code>log_debug</code>, <code>log_info</code>, …). À défaut, il est
|
||
possible d’utiliser la classe <code>LSlog_staticLoggerClass</code> qui facilite l’implémentation.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>Pour vos <a href="#conf-configuration-des-lsaddons">LSaddons</a> : il est conseillé d’utiliser un
|
||
<em>logger</em> <code>LSaddon_[addon]</code> dédié. Le <em>logger</em> peut facilement être récupéré de la manière
|
||
suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-5-1" id="__codelineno-5-1" name="__codelineno-5-1"></a><span class="x">LSlog :: get_logger("LSaddon_[addon]")</span>
|
||
</code></pre></div>
|
||
<p>Cette méthode retourne une référence au <em>logger</em> et il est possible d’appeler directement une
|
||
méthode de log, par exemple :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-6-1" id="__codelineno-6-1" name="__codelineno-6-1"></a><span class="x">LSlog :: get_logger("LSaddon_[addon]") -> debug("message");</span>
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h2 id="upgrade-2_4_1-to-3_0_0-fichiers-templates">Fichiers templates :</h2>
|
||
<h3 id="upgrade-2_4_1-to-3_0_0-changement-de-linclusion-des-templates">Changement de l’inclusion des templates</h3>
|
||
<ul>
|
||
<li>
|
||
<p>Le cas des fichiers <code>top.tpl</code> et <code>bottom.tpl</code></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-7-1" id="__codelineno-7-1" name="__codelineno-7-1"></a>{include file='ls:top.tpl'}
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-7-2" id="__codelineno-7-2" name="__codelineno-7-2"></a>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-7-3" id="__codelineno-7-3" name="__codelineno-7-3"></a>[...]
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-7-4" id="__codelineno-7-4" name="__codelineno-7-4"></a>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-7-5" id="__codelineno-7-5" name="__codelineno-7-5"></a>{include file='ls:bottom.tpl'}
|
||
</code></pre></div>
|
||
<p>devient :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-8-1" id="__codelineno-8-1" name="__codelineno-8-1"></a>{extends file='ls:base_connected.tpl'}
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-8-2" id="__codelineno-8-2" name="__codelineno-8-2"></a>{block name="content"}
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-8-3" id="__codelineno-8-3" name="__codelineno-8-3"></a>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-8-4" id="__codelineno-8-4" name="__codelineno-8-4"></a>[...]
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-8-5" id="__codelineno-8-5" name="__codelineno-8-5"></a>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-8-6" id="__codelineno-8-6" name="__codelineno-8-6"></a>{/block}
|
||
</code></pre></div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Pages à l’état connecté uniquement (incluant le menu, l’entête…).</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>Fichiers avec entête HTML :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-9-1" id="__codelineno-9-1" name="__codelineno-9-1"></a><span class="p"><</span><span class="nt">html</span><span class="p">></span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-9-2" id="__codelineno-9-2" name="__codelineno-9-2"></a> <span class="p"><</span><span class="nt">head</span><span class="p">></span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-9-3" id="__codelineno-9-3" name="__codelineno-9-3"></a> [...]
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-9-4" id="__codelineno-9-4" name="__codelineno-9-4"></a> <span class="p"></</span><span class="nt">head</span><span class="p">></span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-9-5" id="__codelineno-9-5" name="__codelineno-9-5"></a> <span class="p"><</span><span class="nt">body</span><span class="p">></span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-9-6" id="__codelineno-9-6" name="__codelineno-9-6"></a> [...]
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-9-7" id="__codelineno-9-7" name="__codelineno-9-7"></a> <span class="p"></</span><span class="nt">body</span><span class="p">></span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-9-8" id="__codelineno-9-8" name="__codelineno-9-8"></a><span class="p"></</span><span class="nt">html</span><span class="p">></span>
|
||
</code></pre></div>
|
||
<p>devient :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-10-1" id="__codelineno-10-1" name="__codelineno-10-1"></a>{extends file='ls:base.tpl'}
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-10-2" id="__codelineno-10-2" name="__codelineno-10-2"></a>{block name="body"}
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-10-3" id="__codelineno-10-3" name="__codelineno-10-3"></a>[...]
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-10-4" id="__codelineno-10-4" name="__codelineno-10-4"></a>{/block}
|
||
</code></pre></div>
|
||
<p>Au besoin, si vous avez besoin :</p>
|
||
<ul>
|
||
<li>
|
||
<p>de remplacer les fichiers CSS chargés par défaut (<code>base.css</code> par exemple) : ajouter le block
|
||
<code>css</code> :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-11-1" id="__codelineno-11-1" name="__codelineno-11-1"></a>{block name="css"}
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-11-2" id="__codelineno-11-2" name="__codelineno-11-2"></a> <link rel="stylesheet" type="text/css" href="{css name='custom.css'}" media="screen" title="Normal" />
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-11-3" id="__codelineno-11-3" name="__codelineno-11-3"></a> {include file='ls:css.tpl'}
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-11-4" id="__codelineno-11-4" name="__codelineno-11-4"></a>{/block}
|
||
</code></pre></div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Ce block contient tous les CSS, y compris ceux gérés par <code>LSsession :: addCssFile()</code>.
|
||
Pensez à ajouter <code>{include file='ls:css.tpl'}</code> pour conserver ces derniers.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>d’ajouter des infos dans <code><head></code> : ajouter le block <code>head</code> (vide par défaut) :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-12-1" id="__codelineno-12-1" name="__codelineno-12-1"></a>{block name="head"}
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-12-2" id="__codelineno-12-2" name="__codelineno-12-2"></a>[...]
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-12-3" id="__codelineno-12-3" name="__codelineno-12-3"></a>{/block}
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>d’ajouter des fichiers Javascript personnalisés : ajouter le block <code>js</code> (vide par défaut):</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-13-1" id="__codelineno-13-1" name="__codelineno-13-1"></a>{block name="js"}
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-13-2" id="__codelineno-13-2" name="__codelineno-13-2"></a>[...]
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-13-3" id="__codelineno-13-3" name="__codelineno-13-3"></a>{/block}
|
||
</code></pre></div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Ce block sera ajouté <em>APRÈS</em> les autres fichiers Javascript chargés (ceux par défaut et ceux
|
||
ajoutés via <code>LSsession :: addJSscript()</code>.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>Autres fichiers remplacés :</p>
|
||
<ul>
|
||
<li><code>blank.tpl</code> remplacé par <code>base.tpl</code></li>
|
||
<li><code>empty.tpl</code> remplacé par <code>base_connected.tpl</code></li>
|
||
<li><code>accueil.tpl</code> remplacé par <code>homepage.tpl</code></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<p>Pour identifier les fichiers concernés, vous pouvez utiliser la commande suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-14-1" id="__codelineno-14-1" name="__codelineno-14-1"></a>grep<span class="w"> </span>-Er<span class="w"> </span><span class="s1">'(accueil|blank|empty|top|bottom)\.tpl'</span><span class="w"> </span>/etc/ldapsaisie/local/
|
||
</code></pre></div>
|
||
<h3 id="upgrade-2_4_1-to-3_0_0-fichiers-templates-fournis-par-defaut">Fichiers templates fournis par défaut :</h3>
|
||
<p>Vérifier les modifications des fichiers templates fourni avec l’application et que vous auriez
|
||
personnalisé. Pour cela, vous pouvez utiliser la commande suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-15-1" id="__codelineno-15-1" name="__codelineno-15-1"></a><span class="k">for</span><span class="w"> </span>i<span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="k">$(</span><span class="w"> </span>ls<span class="w"> </span>/etc/ldapsaisie/local/templates/*<span class="w"> </span><span class="k">)</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-15-2" id="__codelineno-15-2" name="__codelineno-15-2"></a><span class="k">do</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-15-3" id="__codelineno-15-3" name="__codelineno-15-3"></a><span class="w"> </span><span class="nv">default_file</span><span class="o">=</span><span class="s2">"/usr/share/ldapsaisie/templates/default/</span><span class="k">$(</span><span class="w"> </span>basename<span class="w"> </span><span class="s2">"</span><span class="nv">$i</span><span class="s2">"</span><span class="w"> </span><span class="k">)</span><span class="s2">"</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-15-4" id="__codelineno-15-4" name="__codelineno-15-4"></a><span class="w"> </span><span class="o">[</span><span class="w"> </span>!<span class="w"> </span>-e<span class="w"> </span><span class="s2">"</span><span class="nv">$default_file</span><span class="s2">"</span><span class="w"> </span><span class="o">]</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="k">continue</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-15-5" id="__codelineno-15-5" name="__codelineno-15-5"></a><span class="w"> </span>vi<span class="w"> </span>-d<span class="w"> </span><span class="nv">$default_file</span><span class="w"> </span><span class="nv">$i</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-15-6" id="__codelineno-15-6" name="__codelineno-15-6"></a><span class="k">done</span>
|
||
</code></pre></div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Une attention particulière doit être porté aux fichiers <code>login.tpl</code> et <code>recoverpassword.tpl</code> qui
|
||
ont particulièrement changés.</p>
|
||
</div>
|
||
<h3 id="upgrade-2_4_1-to-3_0_0-corriger-les-url-des-images">Corriger les URL des images :</h3>
|
||
<p><code>../../images/default/find.png</code> devient <code>../image/find</code></p>
|
||
<p>Pour identifier les fichiers concernés, vous pouvez utiliser les commandes suivantes :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-16-1" id="__codelineno-16-1" name="__codelineno-16-1"></a>grep<span class="w"> </span>-Er<span class="w"> </span><span class="s1">'images'</span><span class="w"> </span>/etc/ldapsaisie/local/templates
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-16-2" id="__codelineno-16-2" name="__codelineno-16-2"></a>grep<span class="w"> </span>-Er<span class="w"> </span><span class="s1">'\.(png|gif|jpg)'</span><span class="w"> </span>/etc/ldapsaisie/local/templates
|
||
</code></pre></div>
|
||
<h3 id="upgrade-2_4_1-to-3_0_0-le-cas-de-variable-de-template-lssession_css-et-lssession_js">Le cas de variable de template <code>{$LSsession_css}</code> et <code>{$LSsession_js}</code> :</h3>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Ceci est déjà géré si vous étendez bien vos templates du fichier <code>base.tpl</code> (pour les pages
|
||
non-connectées) ou <code>base_connected.tpl</code> (pour les pages connectées).</p>
|
||
</div>
|
||
<ul>
|
||
<li><code>{$LSsession_css}</code> doit être remplacé par <code>{include file='ls:css.tpl'}</code></li>
|
||
</ul>
|
||
<ul>
|
||
<li><code>{$LSsession_js}</code> doit être remplacé par <code>{include file='ls:js.tpl'}</code></li>
|
||
</ul>
|
||
<h2 id="upgrade-2_4_1-to-3_0_0-tous-les-fichiers-modification-des-urls">Tous les fichiers : Modification des URLs</h2>
|
||
<ul>
|
||
<li>
|
||
<p><code>view.php</code> :</p>
|
||
<ul>
|
||
<li>page recherche : <code>view.php?LSobject=LSpeople</code> devient <code>object/LSpeople</code></li>
|
||
</ul>
|
||
<ul>
|
||
<li>page d'un objet : <code>view.php?LSobject=LSpeople&dn=$dn</code> devient <code>object/LSpeople/$dn</code></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li><code>addon_view.php</code> : <code>addon_view.php?LSaddon=ee&view=copyContract</code> devient <code>addon/ee/copyContract</code></li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>index_ajax.php</code> :</p>
|
||
<ul>
|
||
<li>
|
||
<p>Pour les méthodes Ajax de classes :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-17-1" id="__codelineno-17-1" name="__codelineno-17-1"></a><span class="kd">var</span><span class="w"> </span><span class="nx">data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-17-2" id="__codelineno-17-2" name="__codelineno-17-2"></a><span class="w"> </span><span class="nx">template</span><span class="o">:</span><span class="w"> </span><span class="s1">'LSformElement_eetelephone'</span><span class="p">,</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-17-3" id="__codelineno-17-3" name="__codelineno-17-3"></a><span class="w"> </span><span class="nx">action</span><span class="o">:</span><span class="w"> </span><span class="s1">'make_call'</span><span class="p">,</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-17-4" id="__codelineno-17-4" name="__codelineno-17-4"></a><span class="w"> </span><span class="nx">telephoneNumber</span><span class="o">:</span><span class="w"> </span><span class="nx">tel</span><span class="p">,</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-17-5" id="__codelineno-17-5" name="__codelineno-17-5"></a><span class="w"> </span><span class="nx">name</span><span class="o">:</span><span class="w"> </span><span class="nx">name</span><span class="p">,</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-17-6" id="__codelineno-17-6" name="__codelineno-17-6"></a><span class="p">};</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-17-7" id="__codelineno-17-7" name="__codelineno-17-7"></a><span class="ow">new</span><span class="w"> </span><span class="nx">Request</span><span class="p">({</span><span class="nx">url</span><span class="o">:</span><span class="w"> </span><span class="s1">'index_ajax.php'</span><span class="p">,</span><span class="w"> </span><span class="nx">data</span><span class="o">:</span><span class="w"> </span><span class="nx">data</span><span class="p">,</span><span class="w"> </span><span class="nx">onSuccess</span><span class="o">:</span><span class="w"> </span><span class="p">...});</span>
|
||
</code></pre></div>
|
||
<p>Devient :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-18-1" id="__codelineno-18-1" name="__codelineno-18-1"></a>var data = {
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-18-2" id="__codelineno-18-2" name="__codelineno-18-2"></a> telephoneNumber: tel,
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-18-3" id="__codelineno-18-3" name="__codelineno-18-3"></a> name: name,
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-18-4" id="__codelineno-18-4" name="__codelineno-18-4"></a>};
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-18-5" id="__codelineno-18-5" name="__codelineno-18-5"></a>new Request({url: 'ajax/class/LSformElement_eetelephone/make_call', data: data, onSuccess: ...});
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>Pour les méthodes Ajax d'addon :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-19-1" id="__codelineno-19-1" name="__codelineno-19-1"></a><span class="kd">var</span><span class="w"> </span><span class="nx">data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-19-2" id="__codelineno-19-2" name="__codelineno-19-2"></a><span class="w"> </span><span class="nx">addon</span><span class="o">:</span><span class="w"> </span><span class="s1">'asterisk'</span><span class="p">,</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-19-3" id="__codelineno-19-3" name="__codelineno-19-3"></a><span class="w"> </span><span class="nx">action</span><span class="o">:</span><span class="w"> </span><span class="s1">'LSasterisk_make_call'</span><span class="p">,</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-19-4" id="__codelineno-19-4" name="__codelineno-19-4"></a><span class="w"> </span><span class="nx">telephoneNumber</span><span class="o">:</span><span class="w"> </span><span class="nx">tel</span><span class="p">,</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-19-5" id="__codelineno-19-5" name="__codelineno-19-5"></a><span class="w"> </span><span class="nx">name</span><span class="o">:</span><span class="w"> </span><span class="nx">name</span><span class="p">,</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-19-6" id="__codelineno-19-6" name="__codelineno-19-6"></a><span class="w"> </span><span class="nx">nocache</span><span class="o">:</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nb">Date</span><span class="p">().</span><span class="nx">getTime</span><span class="p">()</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-19-7" id="__codelineno-19-7" name="__codelineno-19-7"></a><span class="p">};</span>
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-19-8" id="__codelineno-19-8" name="__codelineno-19-8"></a><span class="ow">new</span><span class="w"> </span><span class="nx">Request</span><span class="p">({</span><span class="nx">url</span><span class="o">:</span><span class="w"> </span><span class="s1">'index_ajax.php'</span><span class="p">,</span><span class="w"> </span><span class="nx">data</span><span class="o">:</span><span class="w"> </span><span class="nx">data</span><span class="p">,</span><span class="w"> </span><span class="nx">onSuccess</span><span class="o">:</span><span class="w"> </span><span class="p">...});</span>
|
||
</code></pre></div>
|
||
<p>Devient :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-20-1" id="__codelineno-20-1" name="__codelineno-20-1"></a>var data = {
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-20-2" id="__codelineno-20-2" name="__codelineno-20-2"></a> telephoneNumber: tel,
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-20-3" id="__codelineno-20-3" name="__codelineno-20-3"></a> name: name,
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-20-4" id="__codelineno-20-4" name="__codelineno-20-4"></a> nocache: new Date().getTime()
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-20-5" id="__codelineno-20-5" name="__codelineno-20-5"></a>};
|
||
<a href="#upgrade-2_4_1-to-3_0_0-__codelineno-20-6" id="__codelineno-20-6" name="__codelineno-20-6"></a>new Request({url: 'ajax/addon/asterisk/LSasterisk_make_call', data: data, onSuccess: ...});
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li><code>global_search.php</code> : <code>global_search.php?refresh</code> devient <code>search?refresh</code></li>
|
||
</ul>
|
||
<ul>
|
||
<li><code>index.php</code> : <code>index.php?LSsession_recoverPassword</code> devient <code>index?LSsession_recoverPassword</code></li>
|
||
</ul>
|
||
<ul>
|
||
<li><code>create.php</code> : <code>create.php?LSobject=LSpeople</code> devient <code>object/LSpeople/create</code></li>
|
||
</ul>
|
||
<ul>
|
||
<li><code>modify.php</code> : <code>modify.php?LSobject=LSpeople&dn=$dn</code> devient <code>object/LSpeople/$dn/modify</code></li>
|
||
</ul>
|
||
<ul>
|
||
<li><code>import.php</code> : <code>import.php?LSobject=LSpeople</code> devient <code>object/LSpeople/import</code></li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>remove.php</code> : <code>remove.php?LSobject=LSpeople&dn=$dn</code> devient <code>object/LSpeople/$dn/remove</code></p>
|
||
<p>Avec validation : <code>remove.php?LSobject=LSpeople&dn=$dn&valid</code> devient
|
||
<code>object/LSpeople/$dn/remove?valid</code></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li><code>select.php</code> : <code>select.php?LSobject=LSpeople</code> devient <code>object/LSpeople/select</code></li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>custom_action.php</code> :
|
||
<code>custom_action.php?LSobject=LSpeople&dn=$dn&customAction=$customAction</code>
|
||
devient <code>object/LSpeople/$dn/customAction/$customAction</code></p>
|
||
<p>Avec validation :
|
||
<code>custom_action.php?LSobject=LSpeople&dn=$dn&customAction=$customAction&valid</code>
|
||
devient <code>object/LSpeople/$dn/customAction/$customAction?valid</code></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>custom_search_action.php</code> :
|
||
<code>custom_search_action.php?LSobject=LSpeople&customAction=$customAction</code>
|
||
devient <code>object/LSpeople/customAction/$customAction</code></p>
|
||
<p>Avec validation :
|
||
<code>custom_search_action.php?LSobject=LSpeople&customAction=$customAction&valid</code>
|
||
devient <code>object/LSpeople/customAction/$customAction?valid</code></p>
|
||
</li>
|
||
</ul>
|
||
<p>Pour identifier les fichiers concernés, vous pouvez utiliser la commande suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#upgrade-2_4_1-to-3_0_0-__codelineno-21-1" id="__codelineno-21-1" name="__codelineno-21-1"></a>grep<span class="w"> </span>-Er<span class="w"> </span><span class="s1">'(index|global_search|view|select|create|modify|import|remove|index_ajax|custom_action|custom_search_action|addon_view)\.php'</span><span class="w"> </span>/etc/ldapsaisie/local/
|
||
</code></pre></div></section><h1 class="nav-section-title-end">Ended: Mise à jour</h1><h1 class="nav-section-title">Configuration</h1><section class="print-page" id="conf"><h1 id="conf-configuration">Configuration</h1>
|
||
<p>La configuration du projet est située principalement dans le dossier <code>conf/</code>. Les exceptions seront
|
||
détaillées par la suite.</p>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">Warning</p>
|
||
<p>Toute la configuration du projet se fait par l'intermédiaire de fichiers définissant des
|
||
variables PHP dont les valeurs sont utilisées par le programme. Ceci signifie que la syntaxe de
|
||
ces fichiers doit être valide avec l'interpréteur PHP utilisé.</p>
|
||
</div></section><h2 class="nav-section-title">Configuration globale</h2><section class="print-page" id="conf-global"><h1 id="conf-global-configuration-globale">Configuration globale</h1>
|
||
<p>La plus grande partie de la configuration globale se trouve dans le fichier <code>config.inc.php</code>.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-global-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>// Variables globales
|
||
<a href="#conf-global-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a>$GLOBALS['LSconfig'] = array(
|
||
<a href="#conf-global-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> // Variables globales
|
||
<a href="#conf-global-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a>);
|
||
<a href="#conf-global-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a>
|
||
<a href="#conf-global-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a>// Variables et constantes indépendantes
|
||
<a href="#conf-global-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a>$var1 = 'val1'
|
||
<a href="#conf-global-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a>$var2 = 'val2'
|
||
<a href="#conf-global-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a>...
|
||
<a href="#conf-global-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a>define('CONST1','val1')
|
||
<a href="#conf-global-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a>define('CONST2','val2')
|
||
<a href="#conf-global-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a>...
|
||
</code></pre></div>
|
||
<h2 id="conf-global-variables-globales">Variables globales</h2>
|
||
<ul>
|
||
<li>
|
||
<p><code>NetLDAP2</code></p>
|
||
<p>Chemin vers la librairie <a href="http://pear.php.net/">PEAR</a>
|
||
<a href="http://pear.php.net/package/Net_LDAP2">Net_LDAP2</a>.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-global-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a>/usr/share/php/Net/LDAP2.php
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>Smarty</code></p>
|
||
<p>Chemin vers le moteur de template <a href="http://www.smarty.net/">Smarty</a>.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-global-__codelineno-2-1" id="__codelineno-2-1" name="__codelineno-2-1"></a>/usr/share/php/smarty/libs/Smarty.class.php
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>public_root_url</code></p>
|
||
<p>URL publique de la racine web de l'application. Il peut s'agir d'une URL relative bien qu'une URL
|
||
absolue soit préférable, notament pour éviter l'auto-détection de celle-ci lorsque nécessaire
|
||
(lien dans un e-mail par exemple. Par défaut : <code>/</code>.)</p>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Il est indispensable que ce paramètre soit configuré en adéquation avec votre environement
|
||
pour que l'application fonctionne correctement (notament en cas en cas de déploiement dans un
|
||
sous-dossier ou encore dans le cadre d'un accès à l'application au travers un
|
||
<em>reverse-proxy</em>).</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>lang</code></p>
|
||
<p>Paramètre utilisé pour l'internationalisation : code de la langue (<code>fr_FR</code> ou <code>en_US</code>)</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>encoding</code></p>
|
||
<p>Encodage de caractère (<code>UTF8</code>)</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>ldap_servers</code></p>
|
||
<p>Configuration des serveurs LDAP.
|
||
<a href="#conf-global-ldap-configuration-des-serveurs-ldap">Voir section concernée</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<h3 id="conf-global-preferences-globales">Préférences globales</h3>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Les variables globales suivantes ont une action globale, mais non-prioritaire sur le
|
||
comportement de l'application. Il peux être redéfini pour chacun des serveurs LDAP.</p>
|
||
</div>
|
||
<ul>
|
||
<li>
|
||
<p><code>cacheLSprofiles</code></p>
|
||
<p>Activation/Désactivation de la mise en cache des profils des utilisateurs connectés
|
||
(<a href="#conf-global-ldap-lsprofile-profils-dutilisateurs">LSprofiles</a>).</p>
|
||
<p>Valeurs possibles : <code>True</code> ou <code>False</code></p>
|
||
<p>Valeur recommandée : <code>True</code></p>
|
||
<p>Valeur par défaut : <code>False</code></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>cacheSubDn</code></p>
|
||
<p>Activation/Désactivation de la mise en cache des niveaux de connexion
|
||
(<a href="#conf-global-ldap-subdn-sous-niveaux-de-connexion">subDn</a>) dans l'annuaire.</p>
|
||
<p>Valeurs possibles : <code>True</code> ou <code>False</code></p>
|
||
<p>Valeur recommandée : <code>True</code></p>
|
||
<p>Valeur par défaut : <code>False</code></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>cacheSearch</code></p>
|
||
<p>Activation/Désactivation de la mise en cache du résultat des recherches dans l'annuaire.</p>
|
||
<p>Valeurs possibles : <code>True</code> ou <code>False</code></p>
|
||
<p>Valeur recommandée : <code>True</code></p>
|
||
<p>Valeur par défaut : <code>False</code></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>globalSearch</code></p>
|
||
<p>Activation/Désactivation de la recherche globale dans l'annuaire.</p>
|
||
<p>Valeurs possibles : <code>True</code> ou <code>False</code></p>
|
||
<p>Valeur par défaut : <code>True</code></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>keepLSsessionActive</code></p>
|
||
<p>Activation/Désactivation du maintient de la LSsession active.</p>
|
||
<p>Valeurs possibles : <code>True</code> ou <code>False</code></p>
|
||
<p>Valeur par défaut : <code>False</code></p>
|
||
</li>
|
||
</ul>
|
||
<h2 id="conf-global-variables-et-constantes-independantes">Variables et constantes indépendantes</h2>
|
||
<ul>
|
||
<li>
|
||
<p><code>LS_THEME</code></p>
|
||
<p>Constante déterminant le nom du theme utilisé.</p>
|
||
<p>Valeur par défaut : <em>default</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LS_TEMPLATES_DIR</code></p>
|
||
<p>Constante déterminant le chemin du dossier des templates.</p>
|
||
<p>Valeur par défaut : <em>templates</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LS_IMAGES_DIR</code></p>
|
||
<p>Constante déterminant le chemin du dossier des images.</p>
|
||
<p>Valeur par défaut : <em>images</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LS_CSS_DIR</code></p>
|
||
<p>Constante déterminant le chemin du dossier des CSS.</p>
|
||
<p>Valeur par défaut : <em>css</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSdebug</code></p>
|
||
<p>Variable booléenne déterminant si le débogage à l'écran est activé.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>$GLOBALS['LSlog']</code></p>
|
||
<p>Variable permettant de configurer la journalisation de l'application.
|
||
<a href="#conf-global-lslog-configuration-de-la-journalisation">Voir section concernée</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>NB_LSOBJECT_LIST</code></p>
|
||
<p>Constante déterminant le nombre d'objet affichés par page de résultat de recherche.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>NB_LSOBJECT_LIST_SELECT</code></p>
|
||
<p>Constante déterminant le nombre d'objet affichés par page de résultat de recherche dans une
|
||
fenêtre <em>LSselect</em>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>$GLOBALS['NB_LSOBJECT_LIST_CHOICES']</code></p>
|
||
<p>Variable permettant de configurer la liste des choix proposés à l'utilisateur pour le nombre
|
||
maximum d'objets affichés par page de résultat de recherche.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>MAX_SEND_FILE_SIZE</code></p>
|
||
<p>Constante déterminant la taille maximale d'un fichier envoyé à travers les formulaires.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>$GLOBALS['defaultJSscripts']</code></p>
|
||
<p>Tableau déterminant les fichiers Javascript à charger sur toute les pages.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>$GLOBALS['defaultCSSfiles']</code></p>
|
||
<p>Tableau déterminant les fichiers CSS à charger sur toute les pages. Ces fichiers seront chargés
|
||
dans l'ordre et en dernier permettant de surcharger tous paramètres de style.</p>
|
||
</li>
|
||
</ul></section><h3 class="nav-section-title">Connexion LDAP</h3><section class="print-page" id="conf-global-ldap"><h1 id="conf-global-ldap-configuration-des-serveurs-ldap">Configuration des serveurs LDAP</h1>
|
||
<p>Cette section décrit le tableau de configuration des différents serveurs LDAP utilisés par
|
||
l'application. Ce tableau contient lui même un tableau par serveur LDAP.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-global-ldap-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="x">$GLOBALS['LSconfig'] = array(</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="x"> ...</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="x"> 'ldap_servers' => array(</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="x"> array (</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="x"> 'name' => [nom de l'annuaire],</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="x"> 'ldap_config'=> array(</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="x"> // Définition des paramètres de connexion à l'annuaire</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="x"> ),</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="x"> 'useUserCredentials' => [boolean],</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="x"> 'useAuthzProxyControl' => [boolean],</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="x"> 'LSauth' => array (</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="x"> 'method' => [LSauth method],</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a><span class="x"> 'api_method' => [LSauth method],</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a><span class="x"> 'LSobjects' => array(</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a><span class="x"> '[object type 1]',</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a><span class="x"> '[object type 2]' => array(</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a><span class="x"> 'filter' => '[LDAP filter]',</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a><span class="x"> 'filter_function' => [callable],</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a><span class="x"> 'password_attribute' => '[attribute name]',</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a><span class="x"> 'web_access' => [booléen],</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a><span class="x"> 'api_access' => [booléen],</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-22" id="__codelineno-0-22" name="__codelineno-0-22"></a><span class="x"> )</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-23" id="__codelineno-0-23" name="__codelineno-0-23"></a><span class="x"> )</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-24" id="__codelineno-0-24" name="__codelineno-0-24"></a><span class="x"> ),</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-25" id="__codelineno-0-25" name="__codelineno-0-25"></a><span class="x"> 'LSprofiles' => array (</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-26" id="__codelineno-0-26" name="__codelineno-0-26"></a><span class="x"> // Définition des LSprofiles</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-27" id="__codelineno-0-27" name="__codelineno-0-27"></a><span class="x"> ),</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-28" id="__codelineno-0-28" name="__codelineno-0-28"></a><span class="x"> 'cacheLSprofiles' => [boolean],</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-29" id="__codelineno-0-29" name="__codelineno-0-29"></a><span class="x"> 'cacheSearch' => [boolean],</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-30" id="__codelineno-0-30" name="__codelineno-0-30"></a><span class="x"> 'globalSearch' => [boolean],</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-31" id="__codelineno-0-31" name="__codelineno-0-31"></a><span class="x"> 'LSaccess' => array (</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-32" id="__codelineno-0-32" name="__codelineno-0-32"></a><span class="x"> [Type LSobject 1],</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-33" id="__codelineno-0-33" name="__codelineno-0-33"></a><span class="x"> [Type LSobject 2],</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-34" id="__codelineno-0-34" name="__codelineno-0-34"></a><span class="x"> ...</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-35" id="__codelineno-0-35" name="__codelineno-0-35"></a><span class="x"> ),</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-36" id="__codelineno-0-36" name="__codelineno-0-36"></a><span class="x"> 'subDn' => array(</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-37" id="__codelineno-0-37" name="__codelineno-0-37"></a><span class="x"> // Définition des sous-niveaux de l'annuaire</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-38" id="__codelineno-0-38" name="__codelineno-0-38"></a><span class="x"> ),</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-39" id="__codelineno-0-39" name="__codelineno-0-39"></a><span class="x"> 'subDnLabel' => [nom des sous-niveaux],</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-40" id="__codelineno-0-40" name="__codelineno-0-40"></a><span class="x"> 'recoverPassword' => array(</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-41" id="__codelineno-0-41" name="__codelineno-0-41"></a><span class="x"> // Définition des paramètres de configuration de la récupération de mot de passe</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-42" id="__codelineno-0-42" name="__codelineno-0-42"></a><span class="x"> ),</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-43" id="__codelineno-0-43" name="__codelineno-0-43"></a><span class="x"> 'defaultView' => [view],</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-44" id="__codelineno-0-44" name="__codelineno-0-44"></a><span class="x"> 'emailSender' => [email],</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-45" id="__codelineno-0-45" name="__codelineno-0-45"></a><span class="x"> 'keepLSsessionActive' => [booléen]</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-46" id="__codelineno-0-46" name="__codelineno-0-46"></a><span class="x"> )</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-47" id="__codelineno-0-47" name="__codelineno-0-47"></a><span class="x"> ...</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-48" id="__codelineno-0-48" name="__codelineno-0-48"></a><span class="x">);</span>
|
||
<a href="#conf-global-ldap-__codelineno-0-49" id="__codelineno-0-49" name="__codelineno-0-49"></a><span class="x">...</span>
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>name</code></p>
|
||
<p>Le nom d'affichage de ce serveur Ldap (utilisé lorsque plusieurs serveur LDAP sont déclarés).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>ldap_config</code></p>
|
||
<p>Informations de connexion au serveur LDAP. Ces informations sont structurées selon les attentes de
|
||
la librairie <a href="http://pear.php.net/package/Net_LDAP2">Net_LDAP2</a>.
|
||
<a href="http://pear.php.net/manual/fr/package.networking.net-ldap.connecting.php">Plus d'informations</a></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>useUserCredentials</code></p>
|
||
<p>Booléen définissant si il faut utiliser les identifiants de l'utilisateur pour se connecter à
|
||
l'annuaire (<em>false</em> par défaut). Si cette option est activée, la connexion à l'annuaire LDAP sera
|
||
établie avec la configuration fournie dans le paramètre <em>ldap_config</em> en écrasant les informations
|
||
de connexion (<em>binddn</em> et <em>bindpwd</em>) par ceux de l'utilisateur. Si l'utilisateur n'est pas encore
|
||
connecté, la connexion sera étalie sans modifier la configuration fournie.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>useAuthzProxyControl</code></p>
|
||
<p>Booléen définissant si, lorsqu'on utilise les identifiants de l'utilisateur pour se connecter à
|
||
l'annuaire, il faut utiliser une authentification via <em>proxy authorization</em>. Dans ce cas, les
|
||
identifiants de l'utilisateur ne seront pas, à proprement parlé, utilisés pour se connecter à
|
||
l'annuaire, mais une demande de <em>proxy authorization</em> en tant que l'utilisateur connecté sera
|
||
faites à l'aide des identifiants de l'application. Ce mode nécessite une configuration
|
||
particulière au niveau de l'annuaire pour autoriser le compte de l'application à faire des
|
||
demandes de <em>proxy authorization</em> en tant que les autres utilisateurs de l'annuaire.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSprofiles</code></p>
|
||
<p>Définition des profils d'utilisateurs se connectant à l'annuaire.
|
||
<a href="#conf-global-ldap-lsprofile-profils-dutilisateurs">Voir la section concernée</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSauth</code></p>
|
||
<p>Ce tableau défini les paramètres d'authentification à l'application.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>method</code></p>
|
||
<p>Nom de la méthode d'authentification
|
||
<a href="#conf-lsauthmethod-configuration-des-lsauthmethods">LSauthMethod</a>. Exemple : pour
|
||
utiliser la classe <code>LSauthMethod_HTTP</code>, la valeur de ce paramètre sera <code>HTTP</code>.
|
||
<em>Paramètre facultatif, méthode par défaut : <code>basic</code>.</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>api_method</code></p>
|
||
<p>Nom de la méthode d'authentification
|
||
<a href="#conf-lsauthmethod-configuration-des-lsauthmethods">LSauthMethod</a> à utilisée lors
|
||
d'une connexion à l'API. Exemple : pour utiliser la classe <code>LSauthMethod_HTTP</code>, la valeur
|
||
de ce paramètre sera <code>HTTP</code>. <em>Paramètre facultatif, méthode par défaut : <code>HTTP</code>.</em></p>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">Warning</p>
|
||
<p>Toutes les <a href="#conf-lsauthmethod-configuration-des-lsauthmethods">LSauthMethod</a> ne
|
||
supportent pas forcément le mode API.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSobjects</code></p>
|
||
<p>Tableau listant les types <a href="#conf-lsobject-configuration-lsobject">LSobjects</a> pouvant se
|
||
connecter à l'application. Les valeurs de ce tableau peuvent être un nom de type d'objet ou bien
|
||
tableau détaillant les paramètres de connexion de ce type d'objet.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>filter</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> du filtre de recherche de l'utilisateur à sa
|
||
connexion. Ce format sera composé avec l'identifiant fourni par l'utilisateur. Cela peut par
|
||
exemple permettre à l'utilisateur de se connecter en fournissant son login ou son email comme
|
||
identifiant. Exemple de valeur : <code>(|(uid=%{user})(mail=%{user}))</code>.
|
||
<em>Paramètre facultatif, filtre par défaut composé à l'aide de l'attribut RDN.</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>filter_function</code></p>
|
||
<p><em>Callable</em> (au sens PHP) utilisé pour filtrer les utilisateurs trouvés dans l'annuaire à
|
||
partir des autres paramètres : cette fonction, si elle est définie, sera appelée pour chaque
|
||
utilisateur trouvé, avec pour unique paramètre, une référence à l'objet LDAP correspondant
|
||
(<code>LSldapObject</code>). Cette méthode devra alors retourner <code>true</code> ou <code>false</code> pour respectivement
|
||
autoriser ou interdire l'accès à l'application à l'utilisateur.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Si un utilisateur est exclus par cette méthode et qu'aucun autre utilisateur correspondant
|
||
n'a été trouvé dans l'annuaire, une page d'erreur sera affichée et indiquera que l'accès à
|
||
l'application est refusée.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>password_attribute</code></p>
|
||
<p>Nom de l'attribut stockant le mot de passe de ce type
|
||
d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a>.
|
||
<em>Paramètre facultatif, valeur par défaut : <code>userPassword</code>.</em></p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>C'est cet attribut de l'utilisateur qui sera modifié par la fonctionnalité de récupération
|
||
de mot de passe.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>web_access</code></p>
|
||
<p>Permet de définir si ce type d'objet à le droit d'utiliser l'interface web (facultatif, par
|
||
défaut : <code>True</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>api_access</code></p>
|
||
<p>Permet de définir si ce type d'objet à le droit d'utiliser l'API (facultatif, par défaut :
|
||
<code>False</code>).</p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>allow_multi_match</code></p>
|
||
<p>Booléen permettant de définir si un doublon d'identifiant utilisateur est autorisé. Si c'est le
|
||
cas et lorsqu'un identifiant fourni par l'utilisateur a sa connexion a permi de trouver plus
|
||
d'un utilisateur possible correspondant, l'application tentera de déterminer lequel de ces
|
||
utilisateurs correspond à la tentative d'authentification. La méthodologie employée dépendra de
|
||
la <a href="#conf-lsauthmethod-configuration-des-lsauthmethods">LSauthMethod</a> configurée. Par
|
||
exemple, la <a href="#conf-lsauthmethod-configuration-des-lsauthmethods">LSauthMethod</a> <code>basic</code>
|
||
tentera de s'identifier avec le mot de passe. Dans tous cas, si cette méthode n'a pas permis
|
||
d'identifier un seul utilisateur, l'authentification échoura. <em>Paramètre facultatif, valeur par
|
||
défaut : <code>False</code>.</em></p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>cacheLSprofiles</code></p>
|
||
<p>Activation/Désactivation de la mise en cache des <a href="#conf-global-ldap-lsprofile-profils-dutilisateurs">LSprofiles</a>
|
||
des utilisateurs connectés à ce serveur.</p>
|
||
<p>Valeur par défaut : <em>valeur de la variable globale du même nom</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>cacheSearch</code></p>
|
||
<p>Activation/Désactivation de la mise en cache du résultat des recherches sur ce serveur.</p>
|
||
<p>Valeur par défaut : <em>valeur de la variable globale du même nom</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>globalSearch</code></p>
|
||
<p>Activation/Désactivation de la recherche globale sur ce serveur en particulier. Par défaut, la
|
||
valeur du paramètre global <code>globalSearch</code> est utilisée.</p>
|
||
<p>Valeur par défaut : <em>valeur de la variable globale du même nom</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSaccess</code> <a name="LSaccess"></a></p>
|
||
<p>Définition des types d'<a href="#conf-lsobject-configuration-lsobject">LSobjects</a> devant
|
||
apparaître dans le menu de l'interface.</p>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Ce paramètre n'est utilisé que pour les annuaires n'ayant pas de sous-niveaux
|
||
(<a href="#conf-global-ldap-subdn-sous-niveaux-de-connexion">subDn</a>).</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>subDn</code></p>
|
||
<p>Définition des sous-niveaux de connexion à l'annuaire.
|
||
<a href="#conf-global-ldap-subdn-sous-niveaux-de-connexion">Voir section concernée</a>.</p>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Ce paramètre remplace le paramètre <a href="#conf-global-ldap-LSaccess">LSaccess</a> dans le cas d'un annuaire
|
||
multi-niveaux.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>subDnLabel</code></p>
|
||
<p>Définition du label utilisé pour qualifier les sous-niveaux de connexion.</p>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Ce paramètre est utile uniquement dans le cas d'un annuaire multi-niveaux.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>recoverPassword</code></p>
|
||
<p>Définition des paramètres de la récupération de mot de passe.
|
||
<a href="#conf-global-ldap-recoverpassword-recuperation-de-mot-de-passe">Voir la section concernée</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>defaultView</code></p>
|
||
<p>Définition de la vue par défaut de l'application. Par défaut, une page blanche est affichée et il
|
||
est possible de définir à l'aide de ce paramètre la vue qui s'affichera. Ce paramètre peut prendre
|
||
comme valeur :</p>
|
||
<ul>
|
||
<li><code>SELF</code> pour la vue <em>Mon compte</em></li>
|
||
</ul>
|
||
<ul>
|
||
<li>Le nom d'un <a href="#conf-lsobject-configuration-lsobject">LSobject</a> pour afficher la liste de
|
||
ce type d'objet</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Le nom d'une vue d'un <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> au format
|
||
<code>[addon]::[viewId]</code> pour afficher cette vue</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>emailSender</code></p>
|
||
<p>Adresse mail utilisée par LdapSaisie pour envoyer des e-mails en relation avec cet annuaire. Cette
|
||
adresse est celle utilisée par défaut. L'adresse utilisée peut également être configurée dans le
|
||
contexte de configuration du module devant envoyer des e-mails.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>keepLSsessionActive</code></p>
|
||
<p>Activation/Désactivation du maintient de la LSsession active.</p>
|
||
<p>Valeurs possibles : <code>True</code> ou <code>False</code></p>
|
||
<p>Valeur par défaut : <em>valeur de la variable globale du même nom</em></p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-global-ldap-lsprofile"><h1 id="conf-global-ldap-lsprofile-profils-dutilisateurs-lsprofile">Profils d'utilisateurs (LSprofile)</h1>
|
||
<p>Cette section décrit la manière dont sont définis les profils d'utilisateurs se connectant à
|
||
l'interface appelés <em>LSprofile</em>. Il est possible d'attribuer un profil à l'utilisateur connecté sur
|
||
tout ou partie de l'annuaire LDAP.</p>
|
||
<h2 id="conf-global-ldap-lsprofile-profils-dutilisateurs-par-defaut">Profils d'utilisateurs par défaut</h2>
|
||
<p>Il existe des profils d'utilisateurs par défaut, non liée à la configuration de l'application:</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>user</code></p>
|
||
<p>Tous les utilisateurs connectés à l'utilisateur. Ce <em>LSprofile</em> est valide sur l'ensemble de
|
||
l'annuaire.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>self</code></p>
|
||
<p>L'utilisateur connecté sur son objet correspondant dans l'annuaire. Ce <em>LSprofile</em> est utile pour
|
||
donner des droits à l'utilisateur sur lui-même.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>nom du type de l'objet connecté</code></p>
|
||
<p>Un <em>LSprofile</em> du nom du type d'objet utilisateur connecté est automatiquement ajouté à
|
||
l'utilisateur. Ainsi, si l'utilisateur connecté est un
|
||
<a href="#conf-lsobject-configuration-lsobject">LSobject</a> <code>LSpeople</code> par exemple, il aura le
|
||
<em>LSprofile</em> <code>LSpeople</code> sur tous l'annuaire. Ce <em>LSprofile</em> est utile pour donner des droits à tous
|
||
un type d'objets pouvant se connecter à l'application (par exemple, tous les utilisateurs
|
||
applicatifs).</p>
|
||
</li>
|
||
</ul>
|
||
<h2 id="conf-global-ldap-lsprofile-profils-dutilisateurs-personalises">Profils d'utilisateurs personalisés</h2>
|
||
<p>Il est possible de définir autant de profils d'utilisateurs que l'on souhaite. Pour chaque profil
|
||
d'utilisateur personnalisé, il faudra définir dans quelles parties de l'annuaire ce profil existe
|
||
(Exemple : les admistrateurs de groupes existent uniquement dans la branche de l'annuaire stockant
|
||
les groupes). Enfin pour chaque partie de l'annuaire, il faudra définir la manière d'identifier si
|
||
l'utilisateur qui se connecte appartient à ce profil.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-global-ldap-lsprofile-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'LSprofile' => array (
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> [nom d'un LSprofile] => array (
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> [label] => [label du LSprofile],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> [basedn] => [dn utilisateur],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> [autre basedn] => array (
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> [dn d'un utilisateur] => NULL,
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> [autre dn] => array ( // via un listage de l'attribut d'un objet
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> 'attr' => [nom de l'attribut clé de l'objet],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> 'attr_value' => [format de la valeur de l'attribut clé],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> 'LSobject' => [nom du type LSobject de l'objet]
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> )
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> ),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> 'LSobjects' => array ( // via une liste d'objet sur lequel l'utilisateur a des pouvoirs
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a> [nom du LSobject] => array (
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a> 'attr' => [nom de l'attribut clé],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a> 'attr_value' => [format de la valeur de l'attribut clé],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a> // ou
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a> 'filter' => [format du filtre de recherche],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a>
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a> 'basedn' => [basedn de recherche],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a> 'params' => [configuration de la recherche]
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-22" id="__codelineno-0-22" name="__codelineno-0-22"></a> ),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-23" id="__codelineno-0-23" name="__codelineno-0-23"></a> [nom quelconque] => array (
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-24" id="__codelineno-0-24" name="__codelineno-0-24"></a> 'filters' => array(
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-25" id="__codelineno-0-25" name="__codelineno-0-25"></a> array(
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-26" id="__codelineno-0-26" name="__codelineno-0-26"></a> 'LSobject' => [nom du LSobject],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-27" id="__codelineno-0-27" name="__codelineno-0-27"></a> 'attr' => [nom de l'attribut clé],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-28" id="__codelineno-0-28" name="__codelineno-0-28"></a> 'attr_value' => [format de la valeur de l'attribut clé],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-29" id="__codelineno-0-29" name="__codelineno-0-29"></a> // ou
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-30" id="__codelineno-0-30" name="__codelineno-0-30"></a> 'filter' => [format du filtre de recherche],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-31" id="__codelineno-0-31" name="__codelineno-0-31"></a>
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-32" id="__codelineno-0-32" name="__codelineno-0-32"></a> 'basedn' => [basedn de recherche],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-33" id="__codelineno-0-33" name="__codelineno-0-33"></a> 'params' => [configuration de la recherche]
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-34" id="__codelineno-0-34" name="__codelineno-0-34"></a> ),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-35" id="__codelineno-0-35" name="__codelineno-0-35"></a> ),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-36" id="__codelineno-0-36" name="__codelineno-0-36"></a> ),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-37" id="__codelineno-0-37" name="__codelineno-0-37"></a> ...
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-38" id="__codelineno-0-38" name="__codelineno-0-38"></a> )
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-39" id="__codelineno-0-39" name="__codelineno-0-39"></a> ),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-40" id="__codelineno-0-40" name="__codelineno-0-40"></a> ...
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-41" id="__codelineno-0-41" name="__codelineno-0-41"></a>),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-0-42" id="__codelineno-0-42" name="__codelineno-0-42"></a>...
|
||
</code></pre></div>
|
||
<p>Le paramètre <code>LSprofiles</code> est un tableau associatif contenant, en valeur clé, le nom d'un
|
||
<em>LSprofile</em> et en valeur associée, la configuration nécessaire pour déterminer si l'utilisateur
|
||
connecté appartient à ce LSprofile pour tout ou partie de l'annuaire.</p>
|
||
<p>Dans chaque configuration de <em>LSprofile</em>, il est possible d'identifier l'appartenance ou non de
|
||
l'utilisateur connecté de deux manières :</p>
|
||
<ul>
|
||
<li>
|
||
<p>Pour une branche de l'annuaire donnée (<em>basedn</em>) : en listant les utilisateurs appartenant à ce
|
||
<em>LSprofile</em> pour tous les objets de la branche. Il sera possible de lister les utilisateurs dont
|
||
on connait le <em>DN</em> ou de lister les utilisateurs appartenant à une liste stockée dans l'annuaire
|
||
(par exemple la liste des membres d'un groupe).</p>
|
||
<ul>
|
||
<li>
|
||
<p>Liste des DNs d'utilisateurs :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-global-ldap-lsprofile-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a>'LSprofile' => array (
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a> [nom du LSprofile] => array (
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a> [basedn] => [dn utilisateur],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a> // ou si plusieurs DNs
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a> [autre basedn] => array (
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a> [dn d'un utilisateur] => NULL,
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a> [dn d'un utilisateur 2] => NULL
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-1-8" id="__codelineno-1-8" name="__codelineno-1-8"></a> ),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-1-9" id="__codelineno-1-9" name="__codelineno-1-9"></a> ...
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-1-10" id="__codelineno-1-10" name="__codelineno-1-10"></a> ),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-1-11" id="__codelineno-1-11" name="__codelineno-1-11"></a> ...
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-1-12" id="__codelineno-1-12" name="__codelineno-1-12"></a>),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-1-13" id="__codelineno-1-13" name="__codelineno-1-13"></a>...
|
||
</code></pre></div>
|
||
<p>Explication : Pour un <em>LSprofile</em> et un <em>basedn</em> donnés, on définit l'utilisateur appartenant au
|
||
<em>LSprofile</em> en donnant son <em>DN</em>. Si on souhaite lister plusieurs utilisateurs, on utilise un
|
||
tableau associatif dans lequel les clés sont les <em>DNs</em> des utilisateurs et les valeurs associées
|
||
sont toutes <em>NULL</em>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>Liste d'utilisateurs stockée dans l'annuaire :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-global-ldap-lsprofile-__codelineno-2-1" id="__codelineno-2-1" name="__codelineno-2-1"></a>'LSprofile' => array (
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-2-2" id="__codelineno-2-2" name="__codelineno-2-2"></a> [nom du LSprofile] => array (
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-2-3" id="__codelineno-2-3" name="__codelineno-2-3"></a> [basedn] => array (
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-2-4" id="__codelineno-2-4" name="__codelineno-2-4"></a> [DN d'un object] => array (
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-2-5" id="__codelineno-2-5" name="__codelineno-2-5"></a> 'attr' => [nom de l'attribut clé de l'objet],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-2-6" id="__codelineno-2-6" name="__codelineno-2-6"></a> 'attr_value' => [format de la valeur de l'attribut clé],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-2-7" id="__codelineno-2-7" name="__codelineno-2-7"></a> 'LSobject' => [nom du type LSobject de l'objet]
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-2-8" id="__codelineno-2-8" name="__codelineno-2-8"></a> )
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-2-9" id="__codelineno-2-9" name="__codelineno-2-9"></a> ),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-2-10" id="__codelineno-2-10" name="__codelineno-2-10"></a> ...
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-2-11" id="__codelineno-2-11" name="__codelineno-2-11"></a>),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-2-12" id="__codelineno-2-12" name="__codelineno-2-12"></a>...
|
||
</code></pre></div>
|
||
<p>Explication : Pour un <em>LSprofile</em> et un <em>basedn</em> donnés, on liste les utilisateurs du
|
||
<em>LSprofile</em> référencés dans l'attribut <code>attr</code> de l'object de type <code>LSobject</code> et selon le format
|
||
de valeur décrit dans <code>attr_value</code>.</p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>Pour un type de <em>LSobject</em> donné : en listant les objets pour lesquels l'utilisateur aura les
|
||
droits du LSprofile. Il sera possible, à travers une recherche paramétrable dans l'annuaire, de
|
||
lister les objets pour lesquels l'utilisateur appartiendra au <em>LSprofile</em>.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-global-ldap-lsprofile-__codelineno-3-1" id="__codelineno-3-1" name="__codelineno-3-1"></a>'LSprofile' => array (
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-2" id="__codelineno-3-2" name="__codelineno-3-2"></a> [nom d'un LSprofile] => array (
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-3" id="__codelineno-3-3" name="__codelineno-3-3"></a> 'LSobjects' => array ( // via un liste d'objet pour lequel l'utilisateur
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-4" id="__codelineno-3-4" name="__codelineno-3-4"></a> // appartient au LSprofile
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-5" id="__codelineno-3-5" name="__codelineno-3-5"></a> [nom du LSobject] => array (
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-6" id="__codelineno-3-6" name="__codelineno-3-6"></a> 'attr' => [nom de l'attribut clé],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-7" id="__codelineno-3-7" name="__codelineno-3-7"></a> 'attr_value' => [format de la valeur de l'attribut clé],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-8" id="__codelineno-3-8" name="__codelineno-3-8"></a> // or
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-9" id="__codelineno-3-9" name="__codelineno-3-9"></a> 'filter' => [format du filtre de recherche],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-10" id="__codelineno-3-10" name="__codelineno-3-10"></a>
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-11" id="__codelineno-3-11" name="__codelineno-3-11"></a> 'basedn' => [format du basedn de recherche],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-12" id="__codelineno-3-12" name="__codelineno-3-12"></a> 'params' => [configuration de la recherche]
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-13" id="__codelineno-3-13" name="__codelineno-3-13"></a> ),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-14" id="__codelineno-3-14" name="__codelineno-3-14"></a> array (
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-15" id="__codelineno-3-15" name="__codelineno-3-15"></a> 'filters' => array(
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-16" id="__codelineno-3-16" name="__codelineno-3-16"></a> array(
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-17" id="__codelineno-3-17" name="__codelineno-3-17"></a> 'LSobject' => [nom du LSobject],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-18" id="__codelineno-3-18" name="__codelineno-3-18"></a> 'attr' => [nom de l'attribut clé],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-19" id="__codelineno-3-19" name="__codelineno-3-19"></a> 'attr_value' => [format de la valeur de l'attribut clé],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-20" id="__codelineno-3-20" name="__codelineno-3-20"></a> // ou
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-21" id="__codelineno-3-21" name="__codelineno-3-21"></a> 'filter' => [format du filtre de recherche],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-22" id="__codelineno-3-22" name="__codelineno-3-22"></a>
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-23" id="__codelineno-3-23" name="__codelineno-3-23"></a> 'basedn' => [format du basedn de recherche],
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-24" id="__codelineno-3-24" name="__codelineno-3-24"></a> 'params' => [configuration de la recherche]
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-25" id="__codelineno-3-25" name="__codelineno-3-25"></a> ),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-26" id="__codelineno-3-26" name="__codelineno-3-26"></a> ),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-27" id="__codelineno-3-27" name="__codelineno-3-27"></a> ),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-28" id="__codelineno-3-28" name="__codelineno-3-28"></a> ...
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-29" id="__codelineno-3-29" name="__codelineno-3-29"></a> )
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-30" id="__codelineno-3-30" name="__codelineno-3-30"></a> ),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-31" id="__codelineno-3-31" name="__codelineno-3-31"></a> ...
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-32" id="__codelineno-3-32" name="__codelineno-3-32"></a>),
|
||
<a href="#conf-global-ldap-lsprofile-__codelineno-3-33" id="__codelineno-3-33" name="__codelineno-3-33"></a>...
|
||
</code></pre></div>
|
||
<p>Explications : Dans la configuration d'un <em>LSprofile</em>, la valeur clé <em>LSobjects</em> signifie qu'on
|
||
est dans un cas de la délégation de droits sur des types d'LSobject. Dans ce tableau associatif,
|
||
il est possible de définir un ou plusieurs types de LSobject pour lesquels on délègue des droits
|
||
via des recherches simples ou enchaînées. Le fonctionnement simple consiste à partir de l'objet de
|
||
l'utilisateur et à générer un filtre et une base de recherche sur un type de LSobject. Le
|
||
fonctionnement enchainée consiste à faire un première recherche à partir de l'objet de
|
||
l'utilisateur puis à recommencer à partir des objets trouvés en construisant une liste de filtres
|
||
de recherche pour chaque objet qui seront combinés via l'opérateur booléen <em>ou</em>. Dans le cadre
|
||
d'un fonctionnement enchainée, la base de recherche est toujours générer à partir de l'objet de
|
||
l'utilisateur connecté.</p>
|
||
<p>Pour configurer une délégation de type simple on mettra le nom du LSobject dans la clé du tableau
|
||
et dans la valeur un tableau définissant la recherche. Il est possible de ne pas utiliser la clé
|
||
du tableau comme nom du LSobject grâce à la clé de configuration <em>LSobject</em>.</p>
|
||
<p>Pour configurer une délégation de type enchaîné on pourra utiliser n'importe quelle valeur unique
|
||
pour la clé du tableau et pour la valeur un tableau contenant une unique clé <em>filters</em>. La valeur
|
||
associée à cette clé est celle d'une délégation de type simple où la clé <em>LSobject</em> est devenue
|
||
obligatoire.</p>
|
||
<p>Cette configuration contient les paramètres d'une ou plusieurs recherches dans l'annuaire en
|
||
considérant que l'utilisateur connecté aura les droits du LSprofile sur les objets retournés. Les
|
||
paramètres de la recherche sont :</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSobject</code></p>
|
||
<p>C'est le nom du LSobject recherché. <em>(Paramètre facultatif pour
|
||
une délégation de type simple)</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>attr</code></p>
|
||
<p>Nom de l'attribut des LSobjets contenant une valeur clé qui
|
||
permettra d'identifier l'utilisateur comme ayant droit.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>attr_value</code></p>
|
||
<p>Le format de la valeur clé prise par l'attribut <code>attr</code>. Ce format est composé à partir des
|
||
données de l'objet de l'utilisateur connecté. Voir le paragraphe
|
||
<a href="#conf-global-lsformat-format-parametrable">Format paramètrable</a> pour plus d'informations sur
|
||
l'écriture du format.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>filter</code></p>
|
||
<p>Ce paramètre remplace les paramètres <code>attr</code> et <code>attr_value</code>. Il est possible ici d'écrire
|
||
directement le format paramètrable du filtre recherche dans l'annuaire. Ce filtre sera
|
||
automatiquement agrémenté des conditions sur l'attribut <em>objectclass</em>. Voir le paragraphe
|
||
<a href="#conf-global-lsformat-format-parametrable">Format paramètrable</a> pour plus d'informations sur
|
||
l'écriture du format.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>basedn</code></p>
|
||
<p>C'est le format paramétrable du <em>basedn</em> de la recherche généré à partir de l'utilisateur
|
||
connecté. Il est possible ainsi de la limiter sur les LSojects d'une branche précise de
|
||
l'annuaire. Voir le paragraphe <a href="#conf-global-lsformat-format-parametrable">Format paramètrable</a> pour
|
||
plus d'informations sur l'écriture du format. <em>(Paramètre facultatif)</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>params</code></p>
|
||
<p>C'est un tableau associatif contenant les paramètres étendus de la recherche. Voir le paragraphe
|
||
<a href="#conf-global-ldap_search_params-parametres-etendus-des-recherches-dans-lannuaire">Paramètres étendus des recherches dans l'annuaire</a>
|
||
pour plus de détails. <em>(Paramètre facultatif)</em></p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<p>Par ailleurs, il est possible d'attribuer un label plus explicite à chaque <em>LSprofile</em> à l'aide de
|
||
la clé <code>label</code>. Ce label sera utilisé pour faire référence au <em>LSprofile</em> lorsque nécéssaire.
|
||
<em>(Paramètre facultatif)</em></p></section><section class="print-page" id="conf-global-ldap-subdn"><h1 id="conf-global-ldap-subdn-sous-niveaux-de-connexion">Sous-niveaux de connexion</h1>
|
||
<p>Cette section décrit la manière de définir des sous-niveaux de connexion à l'annuaire (<em>subDn</em>). Le
|
||
concept de sous-niveau de connexion sert à déclarer les niveaux logiques de l'annuaire. Par exemple,
|
||
dans un annuaire dans lequel sont stockés des objets concernant plusieurs organisations et que
|
||
celles-ci se distinguent grâce à la présence d'une séparation dans l'arbre, il sera alors possible
|
||
de définir des sous-niveaux de connexion pour chacune des organisations.</p>
|
||
<p><strong>Exemple d'arborescence d'annuaire utilisant le concept de sous-niveaux correspondant à des sociétés :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-global-ldap-subdn-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>|- o=ls
|
||
<a href="#conf-global-ldap-subdn-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a>| |- ou=companies
|
||
<a href="#conf-global-ldap-subdn-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a>| | |- ou=company1
|
||
<a href="#conf-global-ldap-subdn-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a>| | | |- ou=people
|
||
<a href="#conf-global-ldap-subdn-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a>| | | |- ou=groups
|
||
<a href="#conf-global-ldap-subdn-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a>| | |- ou=company2
|
||
<a href="#conf-global-ldap-subdn-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a>| | | |- ou=people
|
||
<a href="#conf-global-ldap-subdn-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a>| | | |- ou=groups
|
||
<a href="#conf-global-ldap-subdn-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a>| |- ou=people
|
||
<a href="#conf-global-ldap-subdn-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a>| |- ou=groups
|
||
</code></pre></div>
|
||
<p>Explications : Il est possible dans cet exemple de définir des sous-niveaux de connexion
|
||
correspondants aux sociétés. Dans chacune de ces sociétés, on retrouve les <em>OU</em> correspondant au
|
||
type d'<em>LSobjets</em>. Lors de la connexion à l'interface, l'utilisateur devra choisir dans quel
|
||
sous-niveau de l'annuaire il souhaite se connecter. Une fois connecté, l'utilisateur manipulera
|
||
uniquement les objets du sous-niveau de l'annuaire dans lequel il se trouve. Il lui sera également
|
||
possible de changer de sous-niveau de connexion à travers l'interface : une liste déroulante est
|
||
disponible pour cela dans le menu.</p>
|
||
<p>Il existe deux manières de déclarer des sous-niveaux de connexion à l'annuaire :</p>
|
||
<ul>
|
||
<li>En déclarant manuellement un <em>subDn</em> de l'annuaire et en lui donnant un nom.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>En listant les <em>LSobjets</em> d'un type précis et en utilisant leurs données pour constituer le nom
|
||
des sous-niveaux. Cette liste est constituée en effectuant une recherche dans l'annuaire. Il est
|
||
possible de définir un <em>basedn</em> particulier pour cette recherche.</li>
|
||
</ul>
|
||
<p>Pour chacune de ces méthodes on définira également les types d'<em>LSobjets</em> qui sont présents dans
|
||
cette branche de l'annuaire.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-global-ldap-subdn-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a>'subDn' => array(
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a> // Déclaration manuelle
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a> '[Nom du sous-niveau]' => array(
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a> 'dn' => '[basedn du sous-niveau]',
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a> 'nologin' => true, // Désactive la connection dans ce subDn
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a> 'LSobjects' => array( // Liste des types d'LSobjets présents dans le sous-niveau
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a> [LSobject1],
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-8" id="__codelineno-1-8" name="__codelineno-1-8"></a> [LSobject2],
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-9" id="__codelineno-1-9" name="__codelineno-1-9"></a> ...
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-10" id="__codelineno-1-10" name="__codelineno-1-10"></a> )
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-11" id="__codelineno-1-11" name="__codelineno-1-11"></a> ),
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-12" id="__codelineno-1-12" name="__codelineno-1-12"></a> // Liste de LSobjets
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-13" id="__codelineno-1-13" name="__codelineno-1-13"></a> 'LSobject' => array(
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-14" id="__codelineno-1-14" name="__codelineno-1-14"></a> '[type d'LSobject]' => array( // le type d'LSobjet à lister
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-15" id="__codelineno-1-15" name="__codelineno-1-15"></a> 'basedn' => '[basedn]', // Le basedn de la recherche
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-16" id="__codelineno-1-16" name="__codelineno-1-16"></a> 'displayValue' => '[format]', // Format du nom des sous-niveaux
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-17" id="__codelineno-1-17" name="__codelineno-1-17"></a> 'nologin' => true, // Désactive la connection dans ces subDn
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-18" id="__codelineno-1-18" name="__codelineno-1-18"></a> 'onlyAccessible' => True, // Pour que seul les LSobjet accessible à l'utilisateur soit listé
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-19" id="__codelineno-1-19" name="__codelineno-1-19"></a> 'LSobjects' => array( // Liste des types d'LSobjets présents dans les sous-niveaux
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-20" id="__codelineno-1-20" name="__codelineno-1-20"></a> [LSobject1],
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-21" id="__codelineno-1-21" name="__codelineno-1-21"></a> [LSobject2],
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-22" id="__codelineno-1-22" name="__codelineno-1-22"></a> ...
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-23" id="__codelineno-1-23" name="__codelineno-1-23"></a> )
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-24" id="__codelineno-1-24" name="__codelineno-1-24"></a> )
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-25" id="__codelineno-1-25" name="__codelineno-1-25"></a> )
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-26" id="__codelineno-1-26" name="__codelineno-1-26"></a>),
|
||
<a href="#conf-global-ldap-subdn-__codelineno-1-27" id="__codelineno-1-27" name="__codelineno-1-27"></a>...
|
||
</code></pre></div></section><section class="print-page" id="conf-global-ldap-recoverpassword"><h1 id="conf-global-ldap-recoverpassword-recuperation-de-mot-de-passe">Récupération de mot de passe</h1>
|
||
<p>Cette section décrit la manière de configurer la récupération de mot de passe par les utilisateurs.
|
||
Le mécanisme de récupération de mot de passe fonctionne en deux parties :</p>
|
||
<ul>
|
||
<li>
|
||
<p>Dans un premier lieu, l'utilisateur ayant perdu son mot de passe accède à l'interface de
|
||
récupération à partir de la page de connexion. L'interface lui demande de saisir son identifiant
|
||
et éventuellement de sélectionner le serveur LDAP concerné. Une fois ces informations saisies, une
|
||
recherche de l'utilisateur est effectuée dans l'annuaire et si celui-ci est trouvé, la valeur de
|
||
l'attribut <code>recoveryHashAttr</code> de l'objet est alors redéfinie avec une valeur aléatoire.</p>
|
||
<p>Un mail est ensuite envoyé à l'utilisateur en utilisant la première valeur de l'attribut
|
||
<code>mailAttr</code> comme adresse. Ce mail est formé à partir des paramètres du tableau associatif
|
||
<code>recoveryHashMail</code>.
|
||
Celui-ci doit contenir le sujet du mail dans <code>subject</code> et le corps du message dans <code>msg</code>. Ces deux
|
||
informations sont des <a href="#conf-global-lsformat-format-parametrable">formats paramètrables</a> composés avec,
|
||
comme valeur clé, l'URL de retour à laquelle l'utilisateur devra se rendre pour accèder à la
|
||
seconde étape de la récupération de son mot de passe.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>L'utilisateur doit donc se rendre sur l'interface par l'intermédiaire de l'URL qui lui aura été
|
||
fournie dans le mail de l'étape précédente. Cette URL contient la valeur de l'attribut
|
||
<code>recoveryHashAttr</code> précédement définie. A partir de cette information, une recherche est effectuée
|
||
dans l'annuaire pour retrouver l'utilisateur correspondant.</p>
|
||
<p>Si l'utilisateur est retrouvé, un nouveau mot de passe lui est généré en utilisant les paramètres
|
||
de configuration éventuellement définis dans la configuration HTML de l'attribut "mot de passe".
|
||
Pour avoir plus d'information sur ces paramètres, consulter la documentation du type d'attribut
|
||
HTML
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-lsattr_html_password"><em>LSattr_html_password</em></a>.
|
||
L'attribut <code>recoveryHashAttr</code> est quant à lui supprimé.</p>
|
||
<p>Ensuite, un mail est composé à partir des paramètres du tableau associatif <code>newPasswordMail</code> et
|
||
est envoyé à l'utilisateur. Ce tableau doit contenir le sujet du mail dans <code>subject</code> et le corps
|
||
du message dans <code>msg</code>. Ces deux informations sont des
|
||
<a href="#conf-global-lsformat-format-parametrable">formats paramètrables</a> composés avec, comme valeur clé, le
|
||
nouveau mot de passe de l'utilisateur.</p>
|
||
</li>
|
||
</ul>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-global-ldap-recoverpassword-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'recoverPassword' => array(
|
||
<a href="#conf-global-ldap-recoverpassword-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'mailAttr' => '[attribut mail]',
|
||
<a href="#conf-global-ldap-recoverpassword-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> 'recoveryHashAttr' => '[attribut hash]',
|
||
<a href="#conf-global-ldap-recoverpassword-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> 'recoveryEmailSender' => '[adresse mail utilisée par LdapSaisie pour l'envoi des mails]',
|
||
<a href="#conf-global-ldap-recoverpassword-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> 'recoveryHashMail' => array( // 1er mail : avec l'URL pour l'accès à la 2nde partie
|
||
<a href="#conf-global-ldap-recoverpassword-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> 'subject' => '[sujet du mail]',
|
||
<a href="#conf-global-ldap-recoverpassword-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> 'msg' => "[message contenant le mot clé %{url}]"
|
||
<a href="#conf-global-ldap-recoverpassword-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> ),
|
||
<a href="#conf-global-ldap-recoverpassword-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> 'newPasswordMail' => array( // 2nd mail : avec le mot de passe
|
||
<a href="#conf-global-ldap-recoverpassword-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> 'subject' => '[sujet du mail]',
|
||
<a href="#conf-global-ldap-recoverpassword-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> 'msg' => "[message contenant le mot clé %{mdp}]"
|
||
<a href="#conf-global-ldap-recoverpassword-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> )
|
||
<a href="#conf-global-ldap-recoverpassword-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a>),
|
||
<a href="#conf-global-ldap-recoverpassword-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a>...
|
||
</code></pre></div></section><h1 class="nav-section-title-end">Ended: Connexion LDAP</h1><section class="print-page" id="conf-global-lslog"><h1 id="conf-global-lslog-configuration-de-la-journalisation-lslog">Configuration de la journalisation (LSlog)</h1>
|
||
<p>Cette section décrit le tableau de configuration de la journalisation de l'application.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-global-lslog-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="x">$GLOBALS['LSlog'] = array(</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="x"> 'enable' => [booléen],</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="x"> 'level' => '[niveau]',</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="x"> 'handlers' => array(</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="x"> '[handler 1]',</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="x"> array (</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="x"> 'handler' => [handler 2],</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="x"> 'enabled' => [booléen],</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="x"> 'level' => '[niveau]',</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="x"> 'loggers' => array('logger1', [...]),</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="x"> 'excluded_loggers' => array('logger2', [...]),</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="x"> 'format' => '[LSformat]',</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a><span class="x"> 'cli_format' => '[LSformat]',</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a><span class="x"> 'datetime_prefix' => [booléen],</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a><span class="x"> 'datetime_format' => '[format date()]',</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a><span class="x"> // Autres paramètres propre à ce handler</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a><span class="x"> [...]</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a><span class="x"> ),</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a><span class="x"> [...]</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a><span class="x"> ),</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a><span class="x"> 'loggers' => array (</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-22" id="__codelineno-0-22" name="__codelineno-0-22"></a><span class="x"> 'logger1' => array (</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-23" id="__codelineno-0-23" name="__codelineno-0-23"></a><span class="x"> 'level' => 'DEBUG',</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-24" id="__codelineno-0-24" name="__codelineno-0-24"></a><span class="x"> ),</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-25" id="__codelineno-0-25" name="__codelineno-0-25"></a><span class="x"> 'logger2' => array (</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-26" id="__codelineno-0-26" name="__codelineno-0-26"></a><span class="x"> 'enabled' => false,</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-27" id="__codelineno-0-27" name="__codelineno-0-27"></a><span class="x"> ),</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-28" id="__codelineno-0-28" name="__codelineno-0-28"></a><span class="x"> [...]</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-29" id="__codelineno-0-29" name="__codelineno-0-29"></a><span class="x"> );</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-30" id="__codelineno-0-30" name="__codelineno-0-30"></a><span class="x">);</span>
|
||
<a href="#conf-global-lslog-__codelineno-0-31" id="__codelineno-0-31" name="__codelineno-0-31"></a><span class="x">...</span>
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>enable</code></p>
|
||
<p>Booléen permatant d'activer ou désactiver complètement la journalisation. Par défaut : <code>False</code></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>level</code></p>
|
||
<p>Ce paramètre défini le niveau minimum de la journalisation : tous les messages des niveaux
|
||
inférieurs ne seront pas inclus dans le journal de l'application. Les niveaux de journalisation
|
||
gérés par l'application sont (dans l'ordre du plus petit au plus grand) :</p>
|
||
<ul>
|
||
<li><code>TRACE</code></li>
|
||
<li><code>DEBUG</code></li>
|
||
<li><code>INFO</code></li>
|
||
<li><code>WARNING</code></li>
|
||
<li><code>ERROR</code></li>
|
||
<li><code>FATAL</code></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>handlers</code></p>
|
||
<p>Tableau permettant de configurer les <em>handlers</em> de la journalisation. Chaque <em>handler</em> gère les
|
||
messages journalisés d'une manière qui lui est propre.</p>
|
||
<p>Plusieurs <em>handlers</em> peuvent être configurés en même temps (y compris plusieurs <em>handlers</em> du même
|
||
type).</p>
|
||
<p>Ce tableau peut contenir simplement le nom du type de <em>handler</em> à utiliser ou bien des tableaux
|
||
configurant un à un chacun des <em>handlers</em>. Dans ce second cas, la structure de la configuration
|
||
d'un <em>handler</em> est la suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-global-lslog-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a><span class="x">array(</span>
|
||
<a href="#conf-global-lslog-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a><span class="x"> 'handler' => [type],</span>
|
||
<a href="#conf-global-lslog-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a><span class="x"> 'level' => '[niveau]',</span>
|
||
<a href="#conf-global-lslog-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a><span class="x"> 'loggers' => array('logger1', [...]),</span>
|
||
<a href="#conf-global-lslog-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a><span class="x"> 'excluded_loggers' => array('logger2', [...]),</span>
|
||
<a href="#conf-global-lslog-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a><span class="x"> 'format' => '[LSformat]',</span>
|
||
<a href="#conf-global-lslog-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a><span class="x"> 'cli_format' => '[LSformat]',</span>
|
||
<a href="#conf-global-lslog-__codelineno-1-8" id="__codelineno-1-8" name="__codelineno-1-8"></a><span class="x"> 'datetime_prefix' => [booléen],</span>
|
||
<a href="#conf-global-lslog-__codelineno-1-9" id="__codelineno-1-9" name="__codelineno-1-9"></a><span class="x"> 'datetime_format' => '[format date()]',</span>
|
||
<a href="#conf-global-lslog-__codelineno-1-10" id="__codelineno-1-10" name="__codelineno-1-10"></a><span class="x"> // Autres paramètres propre à ce handler</span>
|
||
<a href="#conf-global-lslog-__codelineno-1-11" id="__codelineno-1-11" name="__codelineno-1-11"></a><span class="x"> [...]</span>
|
||
<a href="#conf-global-lslog-__codelineno-1-12" id="__codelineno-1-12" name="__codelineno-1-12"></a><span class="x">)</span>
|
||
<a href="#conf-global-lslog-__codelineno-1-13" id="__codelineno-1-13" name="__codelineno-1-13"></a><span class="x">...</span>
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>handler</code></p>
|
||
<p>Type du <em>handler</em> (voir ci-dessous).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>level</code></p>
|
||
<p>Ce paramètre défini le niveau minimum de la journalisation spécifique à cet <em>handler</em>. Si ce
|
||
paramètre est omis, le niveau global sera utilisé. Les valeurs possibles de ce paramètre sont
|
||
les mêmes que pour le paramètre <code>$GLOBALS['LSlog']['level']</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>enabled</code></p>
|
||
<p>Booléen permettant d'activer ou désactiver cet <em>handler</em> (paramètre facultatif, par défaut :
|
||
<code>True</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>loggers</code></p>
|
||
<p>Liste exhautive des composants dont les messages doivent être traités par ce handler (paramètre
|
||
facultatif, par défaut : tous les composants).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>excluded_loggers</code></p>
|
||
<p>Liste exhautive des composants dont les messages ne doivent pas être traités par ce handler
|
||
(paramètre facultatif, par défaut : aucun composant).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>format</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> des messages de cet journalisé par ce handler. Ce
|
||
format est composé à partir des informations décritent ci-dessous. Par défaut :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-global-lslog-__codelineno-2-1" id="__codelineno-2-1" name="__codelineno-2-1"></a>%{requesturi} - %{remoteaddr} - %{ldapservername} - %{authuser} - %{logger} - %{level} - %{message}
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>level</code></p>
|
||
<p>Le niveau du message.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>message</code></p>
|
||
<p>Le message.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>logger</code></p>
|
||
<p>Le composant ayant déchenché cette journalisation.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>clibinpath</code></p>
|
||
<p>Le nom du script ayant déclenché cette jounalisation (uniquement en cas d'exécution en ligne
|
||
de commande).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>requesturi</code></p>
|
||
<p>L'URL de la page courante (uniquement dans un contexte Web).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>remoteaddr</code></p>
|
||
<p>L'adresse IP du client (uniquement dans un contexte Web).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>ldapservername</code></p>
|
||
<p>Le nom du serveur LDAP courant.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>authuser</code></p>
|
||
<p>Le DN de l'utilisateur connecté (uniquement dans un contexte Web).</p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>cli_format</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> des messages de cet journalisé par ce handler dans
|
||
le cas d'une exécution en ligne de commande. Ce format est composé à partir des même
|
||
informations que le paramètre <code>format</code> (voir ci-dessus). Par défaut :
|
||
</p><div class="highlight"><pre><span></span><code><a href="#conf-global-lslog-__codelineno-3-1" id="__codelineno-3-1" name="__codelineno-3-1"></a>%{clibinpath} - %{logger} - %{level} - %{message}
|
||
</code></pre></div><p></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>datetime_format</code></p>
|
||
<p>Booléen permettant de définir si le message doit être préfixé de la date et heure courante. La
|
||
valeur par défaut dépends de l'handler (en règle général, toujours actif sauf lorsque le canal
|
||
de journalisation l'ajoute déjà).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>datetime_format</code></p>
|
||
<p>Format de la date et heure lorsque celle-ci est ajoutée en préfixe du message (voir paramètre
|
||
<code>datetime_format</code>). Le format correspond à celui attendu par la function <code>date()</code> de
|
||
<a href="http://www.php.net/">PHP</a>. Consultez la <a href="http://php.net/date">documentation officielle</a> pour
|
||
plus de détails (Par défaut : <code>Y/m/d H:i:s</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<p>Il existe plusieurs types d'<em>handlers</em> gérés par l'application :</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>file</code></p>
|
||
<p>Journalisation dans un simple fichier texte. Le chemin du fichier peut être configuré via le
|
||
paramètre <code>path</code>. Si ce paramètre est omis, le chemin du fichier par défaut est soit la
|
||
valeur de la variable <code>$GLOBALS['LSlog']['filename']</code> (pour la rétro-compatibilité avec les
|
||
anciennes versions d'LdapSaisie) ou à défaut : <code>tmp/LS.log</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>syslog</code></p>
|
||
<p>Journalisation via le service <em>syslog</em>. Il est possible de configurer une priorité
|
||
systématique pour les messages journalisés. À défaut, la priorité sera déterminée
|
||
automatiquement en fonction du niveau du message. Les valeurs
|
||
possibles de ce paramètre sont : <code>EMERG, ALERT, CRITICAL,ERROR, WARNING, NOTICE, INFO, DEBUG</code></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>system</code></p>
|
||
<p>Journalisation via le gestionnaire d'erreurs PHP. Cet <em>handler</em> utilise la fonction
|
||
<a href="http://www.php.net/">PHP</a> <code>error_log</code>. Pour plus d'informations sur comment configurer le
|
||
gestionnaire d'erreurs PHP, consulter la
|
||
<a href="https://www.php.net/error_log">documentation officielle</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>email</code></p>
|
||
<p>Journalisation via l'envoi d'un email : chaque message journalisé déclenchera l'envoi d'un email
|
||
au destinataire configuré. L'adresse email du destinataire peut-être configurée via le paramètre
|
||
<code>recipient</code>.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Il est conseillé d'utiliser ce type d'<em>handler</em> avec un niveau minimum de journalisation
|
||
important (<code>FATAL</code> recommandé) pour ne pas déclencher un nombre trop important d'envois
|
||
d'emails.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>loggers</code></p>
|
||
<p>Tableau permettant de configurer la journalisation composant par composant. Chaque composant peut
|
||
avoir son propre <code>logger</code> ce qui permet alors, par exemple, de configurer le niveau de log
|
||
spécifiquement pour ce composant.</p>
|
||
<p>Le nom des composant correspond en général au nom de la classe PHP correspondante, ou bien encore
|
||
le nom d'une commande (lors d'une exécution en ligne de commande).</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Par défaut, le nom du composant ayant déclenché un message journalisé est affiché juste avant
|
||
le niveau de log.</p>
|
||
</div>
|
||
<ul>
|
||
<li>
|
||
<p><code>enabled</code></p>
|
||
<p>Booléen permettant de désactiver complètement les logs du composant (par défaut: <code>True</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>level</code></p>
|
||
<p>Niveau de log spécifique pour ce composant (par défaut: le niveau de log global).</p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-global-lsformat"><h1 id="conf-global-lsformat-format-parametrable-lsfomat">Format paramétrable (LSfomat)</h1>
|
||
<p>Un <em>format paramétrable</em> est une chaîne de caractères contenant des mots clés formés comme dans
|
||
l'exemple suivant :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-global-lsformat-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>%{[nom du mot clé][:A][:B][! ou _][~][%]}
|
||
</code></pre></div>
|
||
<p>Le nom du mot clé peut contenir des lettres de "a" à "z", de "A" à "Z" et des chiffres de 0 à 9. Ces
|
||
mots clés seront remplacés par les valeurs passées en paramètres et liées au contexte d'utilisation.
|
||
Les paramètres <em>:A</em> et <em>:B</em> permettent d'extraire une partie de la chaîne complète avant la
|
||
substitution.</p>
|
||
<p>Le paramètre <code>A</code> correspond, lorsque <code>B</code> n'est pas défini, au nombre maximum de caractères à
|
||
extraire de la chaîne de substitution. <em>A</em> doit être un entier dont le signe influ, comme expliqué
|
||
ci-dessous :</p>
|
||
<ul>
|
||
<li>Si <code>A</code> est positif, les <code>A</code> premiers caractères de la chaîne de substitution seront extraits.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Si <code>A</code> est négatif, les <code>|A|</code> derniers caractères de la chaîne de substitution seront extraits.</li>
|
||
</ul>
|
||
<p>Lorsque le paramètre <code>B</code> est défini, <code>A</code> correspond au rang du premier caractère à partir duquel la
|
||
chaîne de substitution sera découpée et <code>B</code> le nombre maximum de caractères à extraire. Le signe de
|
||
<code>B</code> influera comme expliqué dans le premier cas. Si <code>B</code> vaut zéro, la totalité de la longeur de la
|
||
chaîne sera retournée en tenant compte de <code>A</code> pour le rang du premier caractère.</p>
|
||
<p>Il existe par ailleurs des paramètres permettant de modifier la valeur de substitution avant son
|
||
utilisation :</p>
|
||
<ul>
|
||
<li>Les paramètres <em>!</em> ou <em>_</em> permettre respectivement de forcer la mise en majuscule ou en minuscule ;</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Le paramètre <em>~</em> permet de forcer la suppression des accents ;</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Le paramètre <em>%</em> permet de protéger les caractères éligibles en entités HTML.</li>
|
||
</ul>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Lorsque qu'une seule valeur clé est disponible pour la substitution, le nom du mot clé n'importe
|
||
pas. Tous les mots clés trouvés dans le format seront remplacés par cette seule valeur.</p>
|
||
</div></section><section class="print-page" id="conf-global-ldap_search_params"><h1 id="conf-global-ldap_search_params-parametres-etendus-des-recherches-dans-lannuaire">Paramètres étendus des recherches dans l'annuaire</h1>
|
||
<p>Les paramètres des recherches sont ceux supportés par
|
||
<a href="http://pear.php.net/package/Net_LDAP2">Net_LDAP2</a>. Ces paramètres sont passés sous la forme d'un
|
||
tableau associatif. Les paramètres supportés sont détaillés ci-dessous :</p>
|
||
<table>
|
||
<thead>
|
||
<tr class="header">
|
||
<th>Nom</th>
|
||
<th>Description</th>
|
||
<th>Valeur par défaut</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="odd">
|
||
<td><code>scope</code></td>
|
||
<td><p>Définition de l'étendue de la recherche :</p>
|
||
<ul>
|
||
<li><p><code>base</code> - Sur une entrée seulement</p></li>
|
||
<li><p><code>one</code> - Sur les entrées imédiatement contenu par le <code>basedn</code> de la recherche</p></li>
|
||
<li><p><code>sub</code> - Sur l'arbre entier</p></li>
|
||
</ul></td>
|
||
<td><code>sub</code></td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>sizelimit</code></td>
|
||
<td>Le nombre maximum d'entrées retournées par la recherche.</td>
|
||
<td><code>0</code> (illimité)</td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>timelimit</code></td>
|
||
<td>Le délai d'attente maximum de la réponse du serveur en secondes.</td>
|
||
<td><code>0</code> (illimité)</td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>attrsonly</code></td>
|
||
<td>Si <em>vrai</em>, seuls les noms des atttributs seront retournés.</td>
|
||
<td><code>false</code></td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>attributes</code></td>
|
||
<td>Tableau contenant les noms des attributs que les entrées retournées peuvent contenir et que l'on souhaite récupérer.</td>
|
||
<td><code>array()</code>(tous)</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>Pour plus d'information sur le sujet, vous pouvez consulter la documentation officiel du projet
|
||
<a href="http://pear.php.net/package/Net_LDAP2">Net_LDAP2</a>.</p></section><h1 class="nav-section-title-end">Ended: Configuration globale</h1><h2 class="nav-section-title">Objets de l'annuaire</h2><section class="print-page" id="conf-lsobject"><h1 id="conf-lsobject-configuration-lsobject">Configuration LSobject</h1>
|
||
<p>Cette partie décrit la manière de configurer les différents types de LSobjets manipulés par
|
||
LdapSaisie.</p>
|
||
<p>La configuration des LSobjects est stockée dans le dossier <code>/conf/LSobjects</code>. Dans ce dossier, on
|
||
retrouve un fichier par type d'LSobject, nommé de la manière suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>config.LSobjects.[nom du type d'LSobject].php
|
||
</code></pre></div>
|
||
<p>Ce fichier contient la déclaration de la configuration du type d'LSobject qui est stocké dans la
|
||
variable globale <code>$GLOBALS['LSobjects']['[nom du type d'LSobject]']</code>.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a><span class="x">$GLOBALS['LSobjects']['[nom du type d'LSobject]'] = array (</span>
|
||
<a href="#conf-lsobject-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a><span class="x"> 'objectclass' => array(</span>
|
||
<a href="#conf-lsobject-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a><span class="x"> 'objetclass1',</span>
|
||
<a href="#conf-lsobject-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a><span class="x"> 'objetclass2',</span>
|
||
<a href="#conf-lsobject-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a><span class="x"> ...</span>
|
||
<a href="#conf-lsobject-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a><span class="x"> 'filter' => '[filtre LDAP]',</span>
|
||
<a href="#conf-lsobject-__codelineno-1-8" id="__codelineno-1-8" name="__codelineno-1-8"></a>
|
||
<a href="#conf-lsobject-__codelineno-1-9" id="__codelineno-1-9" name="__codelineno-1-9"></a><span class="x"> 'rdn' => 'attr1',</span>
|
||
<a href="#conf-lsobject-__codelineno-1-10" id="__codelineno-1-10" name="__codelineno-1-10"></a>
|
||
<a href="#conf-lsobject-__codelineno-1-11" id="__codelineno-1-11" name="__codelineno-1-11"></a><span class="x"> 'LSaddons' => [LSaddon(s)],</span>
|
||
<a href="#conf-lsobject-__codelineno-1-12" id="__codelineno-1-12" name="__codelineno-1-12"></a>
|
||
<a href="#conf-lsobject-__codelineno-1-13" id="__codelineno-1-13" name="__codelineno-1-13"></a><span class="x"> 'container_dn' => 'ou=people',</span>
|
||
<a href="#conf-lsobject-__codelineno-1-14" id="__codelineno-1-14" name="__codelineno-1-14"></a><span class="x"> 'generate_container_dn' => '[callable]',</span>
|
||
<a href="#conf-lsobject-__codelineno-1-15" id="__codelineno-1-15" name="__codelineno-1-15"></a><span class="x"> 'container_auto_create' => array(</span>
|
||
<a href="#conf-lsobject-__codelineno-1-16" id="__codelineno-1-16" name="__codelineno-1-16"></a><span class="x"> // Information des configurations pour la création du conteneur du type d'LSobjet</span>
|
||
<a href="#conf-lsobject-__codelineno-1-17" id="__codelineno-1-17" name="__codelineno-1-17"></a><span class="x"> // lors de la création nouveau subDn</span>
|
||
<a href="#conf-lsobject-__codelineno-1-18" id="__codelineno-1-18" name="__codelineno-1-18"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-__codelineno-1-19" id="__codelineno-1-19" name="__codelineno-1-19"></a>
|
||
<a href="#conf-lsobject-__codelineno-1-20" id="__codelineno-1-20" name="__codelineno-1-20"></a><span class="x"> 'disable_creation' => [boolean]',</span>
|
||
<a href="#conf-lsobject-__codelineno-1-21" id="__codelineno-1-21" name="__codelineno-1-21"></a>
|
||
<a href="#conf-lsobject-__codelineno-1-22" id="__codelineno-1-22" name="__codelineno-1-22"></a><span class="x"> 'before_modify' => 'function1',</span>
|
||
<a href="#conf-lsobject-__codelineno-1-23" id="__codelineno-1-23" name="__codelineno-1-23"></a><span class="x"> 'after_modify' => 'function2',</span>
|
||
<a href="#conf-lsobject-__codelineno-1-24" id="__codelineno-1-24" name="__codelineno-1-24"></a><span class="x"> 'after_create' => 'function3',</span>
|
||
<a href="#conf-lsobject-__codelineno-1-25" id="__codelineno-1-25" name="__codelineno-1-25"></a><span class="x"> 'after_delete' => 'function4',</span>
|
||
<a href="#conf-lsobject-__codelineno-1-26" id="__codelineno-1-26" name="__codelineno-1-26"></a>
|
||
<a href="#conf-lsobject-__codelineno-1-27" id="__codelineno-1-27" name="__codelineno-1-27"></a><span class="x"> 'label' => 'objet1',</span>
|
||
<a href="#conf-lsobject-__codelineno-1-28" id="__codelineno-1-28" name="__codelineno-1-28"></a><span class="x"> 'display_name_format' => '[format]',</span>
|
||
<a href="#conf-lsobject-__codelineno-1-29" id="__codelineno-1-29" name="__codelineno-1-29"></a><span class="x"> 'displayAttrName' => '[booleen]',</span>
|
||
<a href="#conf-lsobject-__codelineno-1-30" id="__codelineno-1-30" name="__codelineno-1-30"></a>
|
||
<a href="#conf-lsobject-__codelineno-1-31" id="__codelineno-1-31" name="__codelineno-1-31"></a><span class="x"> //Custom Actions</span>
|
||
<a href="#conf-lsobject-__codelineno-1-32" id="__codelineno-1-32" name="__codelineno-1-32"></a><span class="x"> 'customActions' => array (</span>
|
||
<a href="#conf-lsobject-__codelineno-1-33" id="__codelineno-1-33" name="__codelineno-1-33"></a><span class="x"> // Configuration des customActions pour ce type d'objet</span>
|
||
<a href="#conf-lsobject-__codelineno-1-34" id="__codelineno-1-34" name="__codelineno-1-34"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-__codelineno-1-35" id="__codelineno-1-35" name="__codelineno-1-35"></a>
|
||
<a href="#conf-lsobject-__codelineno-1-36" id="__codelineno-1-36" name="__codelineno-1-36"></a><span class="x"> // LSrelation</span>
|
||
<a href="#conf-lsobject-__codelineno-1-37" id="__codelineno-1-37" name="__codelineno-1-37"></a><span class="x"> 'LSrelation' => array(</span>
|
||
<a href="#conf-lsobject-__codelineno-1-38" id="__codelineno-1-38" name="__codelineno-1-38"></a><span class="x"> // Configuration des LSrelations entre ce type d'objet et les autres</span>
|
||
<a href="#conf-lsobject-__codelineno-1-39" id="__codelineno-1-39" name="__codelineno-1-39"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-__codelineno-1-40" id="__codelineno-1-40" name="__codelineno-1-40"></a>
|
||
<a href="#conf-lsobject-__codelineno-1-41" id="__codelineno-1-41" name="__codelineno-1-41"></a><span class="x"> // LSform</span>
|
||
<a href="#conf-lsobject-__codelineno-1-42" id="__codelineno-1-42" name="__codelineno-1-42"></a><span class="x"> 'LSform' => array (</span>
|
||
<a href="#conf-lsobject-__codelineno-1-43" id="__codelineno-1-43" name="__codelineno-1-43"></a><span class="x"> // Configuration des formulaires de l'objet</span>
|
||
<a href="#conf-lsobject-__codelineno-1-44" id="__codelineno-1-44" name="__codelineno-1-44"></a><span class="x"> ), // fin LSform</span>
|
||
<a href="#conf-lsobject-__codelineno-1-45" id="__codelineno-1-45" name="__codelineno-1-45"></a>
|
||
<a href="#conf-lsobject-__codelineno-1-46" id="__codelineno-1-46" name="__codelineno-1-46"></a><span class="x"> // LSsearch</span>
|
||
<a href="#conf-lsobject-__codelineno-1-47" id="__codelineno-1-47" name="__codelineno-1-47"></a><span class="x"> 'LSsearch' => array (</span>
|
||
<a href="#conf-lsobject-__codelineno-1-48" id="__codelineno-1-48" name="__codelineno-1-48"></a><span class="x"> // Configuration des recherches de l'objet</span>
|
||
<a href="#conf-lsobject-__codelineno-1-49" id="__codelineno-1-49" name="__codelineno-1-49"></a><span class="x"> ), // fin LSsearch</span>
|
||
<a href="#conf-lsobject-__codelineno-1-50" id="__codelineno-1-50" name="__codelineno-1-50"></a>
|
||
<a href="#conf-lsobject-__codelineno-1-51" id="__codelineno-1-51" name="__codelineno-1-51"></a><span class="x"> 'globalSearch' => [booleen],</span>
|
||
<a href="#conf-lsobject-__codelineno-1-52" id="__codelineno-1-52" name="__codelineno-1-52"></a><span class="x"> 'globalSearch_extraDisplayedColumns' => [booleen],</span>
|
||
<a href="#conf-lsobject-__codelineno-1-53" id="__codelineno-1-53" name="__codelineno-1-53"></a>
|
||
<a href="#conf-lsobject-__codelineno-1-54" id="__codelineno-1-54" name="__codelineno-1-54"></a><span class="x"> // ioFormat</span>
|
||
<a href="#conf-lsobject-__codelineno-1-55" id="__codelineno-1-55" name="__codelineno-1-55"></a><span class="x"> 'ioFormat' => array (</span>
|
||
<a href="#conf-lsobject-__codelineno-1-56" id="__codelineno-1-56" name="__codelineno-1-56"></a><span class="x"> // Configuration des formats d'import/export de l'objet</span>
|
||
<a href="#conf-lsobject-__codelineno-1-57" id="__codelineno-1-57" name="__codelineno-1-57"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-__codelineno-1-58" id="__codelineno-1-58" name="__codelineno-1-58"></a>
|
||
<a href="#conf-lsobject-__codelineno-1-59" id="__codelineno-1-59" name="__codelineno-1-59"></a><span class="x"> // Attributs</span>
|
||
<a href="#conf-lsobject-__codelineno-1-60" id="__codelineno-1-60" name="__codelineno-1-60"></a><span class="x"> 'attrs' => array (</span>
|
||
<a href="#conf-lsobject-__codelineno-1-61" id="__codelineno-1-61" name="__codelineno-1-61"></a><span class="x"> // Configuration des attributs du type d'LSobjet</span>
|
||
<a href="#conf-lsobject-__codelineno-1-62" id="__codelineno-1-62" name="__codelineno-1-62"></a><span class="x"> )</span>
|
||
<a href="#conf-lsobject-__codelineno-1-63" id="__codelineno-1-63" name="__codelineno-1-63"></a><span class="x">);</span>
|
||
<a href="#conf-lsobject-__codelineno-1-64" id="__codelineno-1-64" name="__codelineno-1-64"></a><span class="x">...</span>
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>objectclass</code></p>
|
||
<p>La liste des <em>objectclass</em> des objets.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>filter</code></p>
|
||
<p>Filtre de recherche LDAP applicable à tout les objets de ce type et qui sera utilisé lors de
|
||
chaque recherche de ce type d'objet.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>rdn</code></p>
|
||
<p>Nom de l'attribut correspondant au <em>RDN</em> des objets LDAP.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSaddons</code></p>
|
||
<p>LSaddon(s) dont le type d'objet dépend. Ce peut être un tableau de chaînes de caractères ou une
|
||
simpe chaîne de caractères correspondant au(x) nom(s) du/des LSaddon(s) en dépendance.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>container_dn</code></p>
|
||
<p>Elément pour construire le <em>basedn</em> de stockage de ce type d'objet. Par exemple, si le <em>basedn</em> de
|
||
l'annuaire est <code>o=ls</code> et que les objets <em>utilisateurs</em> sont stockés dans la branche de l'annuaire
|
||
<code>ou=people,o=ls</code>, alors <code>container_dn</code> devra valoir <code>ou=people</code>.</p>
|
||
<p>Lorsque l'annuaire possède des <a href="#conf-global-ldap-subdn-sous-niveaux-de-connexion">subDn</a>, les
|
||
objets seront cherchés dans le <em>basedn</em> résultant de la concaténation du paramètre <code>container_dn</code>,
|
||
d'une virgule et du <em>basedn</em> correspondant au
|
||
<a href="#conf-global-ldap-subdn-sous-niveaux-de-connexion">subDn</a> courant.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>generate_container_dn</code></p>
|
||
<p><em>Callable</em> (au sens PHP), utilisé pour générer la valeur du paramètre <code>container_dn</code>
|
||
dynamiquement. Ce <em>callable</em> prend en paramètre l'objet LSobject à
|
||
créer et retourne la valeur du paramètre <code>container_dn</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>container_auto_create</code></p>
|
||
<p>Tableau associatif contenant les paramètres de configuration nécessaires à la création des
|
||
<code>container_dn</code> dans les nouveaux objets utilisés comme
|
||
<a href="#conf-global-ldap-subdn-sous-niveaux-de-connexion">subDn</a>.
|
||
<a href="#conf-lsobject-container_auto_create-creation-automatique-du-conteneur-des-lsobjets-dans-un-subdn">Voir la section concernée</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>disable_creation</code></p>
|
||
<p>Booléen permetant de desactiver la creation de ce type d'objet de manière globale.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>before_modify</code></p>
|
||
<p>Chaîne de caractères (ou tableau de chaine de caractères) correspondant au nom d'une ou plusieurs
|
||
fonctions qui seront exécutées avant la modification d'un objet.
|
||
<a href="#conf-lsobject-triggers-declencheurs_1">Voir la section concernée</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>after_modify</code></p>
|
||
<p>Chaîne de caractères (ou tableau de chaine de caractères) correspondant au nom d'une ou plusieurs
|
||
fonctions qui seront exécutées après la modification d'un objet.
|
||
<a href="#conf-lsobject-triggers-declencheurs_1">Voir la section concernée</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>after_create</code></p>
|
||
<p>Chaîne de caractères (ou tableau de chaine de caractères) correspondant au nom d'une ou plusieurs
|
||
fonctions qui seront exécutées après la création d'un objet.
|
||
<a href="#conf-lsobject-triggers-declencheurs_1">Voir la section concernée</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>after_delete</code></p>
|
||
<p>Chaîne de caractères (ou tableau de chaine de caractères) correspondant au nom d'une ou plusieurs
|
||
fonctions qui seront exécutées après la suppression d'un objet.
|
||
<a href="#conf-lsobject-triggers-declencheurs_1">Voir la section concernée</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>label</code></p>
|
||
<p>Nom générique au pluriel qualifiant le type d'objet. Exemple : <em>Utilisateurs</em>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>display_name_format</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">Format paramètrable</a> du nom des objets composés à
|
||
partir des valeurs d'affichage des attributs de l'objet.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>displayAttrName</code></p>
|
||
<p>Booléen définissant si le nom des attributs doit être affiché en préfixe de leur message d'aide
|
||
(paramètre <code>help_info</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>customActions</code></p>
|
||
<p>Tableau associatif contenant les paramètres de configuration des
|
||
<a href="#conf-lsobject-customactions-customactions">customActions</a>.
|
||
<a href="#conf-lsobject-customactions-customactions">Voir la section concernée</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSrelation</code></p>
|
||
<p>Tableau associatif contenant les paramètres de configuration des
|
||
<a href="#conf-lsobject-lsrelation-lsrelation">LSrelations</a>. <a href="#conf-lsobject-lsrelation-lsrelation">Voir la section concernée</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSform</code></p>
|
||
<p>Tableau associatif contenant les paramètres de configuration des <a href="#conf-lsobject-lsform-lsform">LSforms</a> des
|
||
LSobjects. <a href="#conf-lsobject-lsform-lsform">Voir la section concernée</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSsearch</code></p>
|
||
<p>Tableau associatif contenant les paramètres de configuration des recherches de
|
||
LSobject de ce type dans l'annuaire.
|
||
<a href="#conf-lsobject-lssearch-lssearch">Voir la section concernée</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>globalSearch</code></p>
|
||
<p>Inclure ou non ce type d'objet dans le résultat des recherches globales (Par défaut : <code>True</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>globalSearch_extraDisplayedColumns</code></p>
|
||
<p>Afficher ou non les colonnes supplémentaires pour ce type d'objet dans le résultat des recherches
|
||
globales (Par défaut : <code>True</code>). Pour plus de détails les colonnes supplémentaires,
|
||
<a href="#conf-lsobject-lssearch-lssearch">voir la section dédiée</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>ioFormat</code></p>
|
||
<p>Tableau associatif contenant les paramètres de configuration des formats de fichiers
|
||
d'import/export de ce type d'LSobject.
|
||
<a href="#conf-lsobject-ioformat-ioformat">Voir la section concernée</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>attrs</code></p>
|
||
<p>Tableau associatif contenant les paramètres de configuration des attributs des objets.
|
||
<a href="#conf-lsobject-lsattribute-configuration-des-attributs">Voir la section concernée</a>.</p>
|
||
</li>
|
||
</ul></section><h3 class="nav-section-title">Attributs</h3><section class="print-page" id="conf-lsobject-lsattribute"><h1 id="conf-lsobject-lsattribute-configuration-des-attributs">Configuration des attributs</h1>
|
||
<p>Cette section décrit les options de configuration des attributs des
|
||
<a href="#conf-lsobject-configuration-lsobject">LSobjects</a>. Les attributs sont définis dans le tableau
|
||
associatif <code>attrs</code> de la configuration des <a href="#conf-lsobject-configuration-lsobject">LSobjects</a>. Dans ce
|
||
tableau, les clé les noms des attributs et les valeurs liés sont la configuration des attributs.</p>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">Warning</p>
|
||
<p>Contrairement à ce qui existe dans le standard LDAP, les noms des attributs sont sensibles à la
|
||
casse. Il faut que le nom des attributs dans LdapSaisie soient scrupuleusement les mêmes que
|
||
ceux retourné par <a href="http://pear.php.net/package/Net_LDAP2">Net_LDAP2</a></p>
|
||
</div>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'attrs' => array (
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> /* ----------- start -----------*/
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> 'attr1' => array (
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> 'label' => '[label de l'attr1',
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> 'displayAttrName' => '[booleen]',
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> 'help_info' => '[Message d'aide sur l'attribut attr1]',
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> 'help_info_in_view' => '[booleen]',
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> 'ldap_type' => 'ldaptype1',
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> 'ldap_options' => array(
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> // Options LDAP liées au type LDAP de l'attribut
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> 'html_type' => 'htmltype1',
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> 'html_options' => array(
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a> // Options HTML liées au type HTML de l'attribut
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a> 'no_value_label' => '[No set value label]',
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a> 'multiple' => 0,
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a> 'required' => 1,
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a> 'generate_function' => 'fonction1',
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a> 'generate_value_format' => '[LSformat]',
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a> 'default_value' => 'valeur1',
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-22" id="__codelineno-0-22" name="__codelineno-0-22"></a> 'check_data' => array (
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-23" id="__codelineno-0-23" name="__codelineno-0-23"></a> // Régle de vérification syntaxique des données saisies
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-24" id="__codelineno-0-24" name="__codelineno-0-24"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-25" id="__codelineno-0-25" name="__codelineno-0-25"></a> 'validation' => array (
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-26" id="__codelineno-0-26" name="__codelineno-0-26"></a> // Règle de vérification d'intégrité des données saisies
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-27" id="__codelineno-0-27" name="__codelineno-0-27"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-28" id="__codelineno-0-28" name="__codelineno-0-28"></a> 'rights' => array(
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-29" id="__codelineno-0-29" name="__codelineno-0-29"></a> 'LSprofile1' => 'droit1',
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-30" id="__codelineno-0-30" name="__codelineno-0-30"></a> 'LSprofile2' => 'droit2',
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-31" id="__codelineno-0-31" name="__codelineno-0-31"></a> ...
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-32" id="__codelineno-0-32" name="__codelineno-0-32"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-33" id="__codelineno-0-33" name="__codelineno-0-33"></a> 'view' => 1,
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-34" id="__codelineno-0-34" name="__codelineno-0-34"></a> 'form' => array (
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-35" id="__codelineno-0-35" name="__codelineno-0-35"></a> 'create' => 1,
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-36" id="__codelineno-0-36" name="__codelineno-0-36"></a> 'modify' => 0,
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-37" id="__codelineno-0-37" name="__codelineno-0-37"></a> ...
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-38" id="__codelineno-0-38" name="__codelineno-0-38"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-39" id="__codelineno-0-39" name="__codelineno-0-39"></a> 'dependAttrs' => array(
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-40" id="__codelineno-0-40" name="__codelineno-0-40"></a> // Attributs en dépendance
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-41" id="__codelineno-0-41" name="__codelineno-0-41"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-42" id="__codelineno-0-42" name="__codelineno-0-42"></a> 'onDisplay' => 'fonction2'
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-43" id="__codelineno-0-43" name="__codelineno-0-43"></a>
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-44" id="__codelineno-0-44" name="__codelineno-0-44"></a> 'before_modify' => 'function1',
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-45" id="__codelineno-0-45" name="__codelineno-0-45"></a> 'after_modify' => 'function2'
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-46" id="__codelineno-0-46" name="__codelineno-0-46"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-47" id="__codelineno-0-47" name="__codelineno-0-47"></a> /* ----------- end -----------*/
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-48" id="__codelineno-0-48" name="__codelineno-0-48"></a> ...
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-49" id="__codelineno-0-49" name="__codelineno-0-49"></a>);
|
||
<a href="#conf-lsobject-lsattribute-__codelineno-0-50" id="__codelineno-0-50" name="__codelineno-0-50"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>label</code></p>
|
||
<p>Le label de l'attribut.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>displayAttrName</code></p>
|
||
<p>Booléen définissant si le nom de l'attribut doit être affiché en préfixe du message d'aide
|
||
(paramètre <code>help_info</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>help_info</code></p>
|
||
<p>Message d'aide qui sera affiché dans une bulle d'aide à côté du nom de l'attribut dans les
|
||
formulaires.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>help_info_in_view</code></p>
|
||
<p>Booléen définissant si le message d'aide doit être affiché sur la vue de visualisation de l'objet.</p>
|
||
<p>Valeurs possibles : <em>0</em> ou <em>1</em></p>
|
||
<p>Valeur par défaut : <em>0</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>ldap_type</code></p>
|
||
<p>Le type LDAP de l'attribut (facultatif, par défaut:
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_ascii-lsattr_ldap_ascii">LSattr_ldap_ascii</a>).
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-configuration-des-attributs-ldap">Voir la section concernée.</a></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>ldap_options</code></p>
|
||
<p>Tableau associatif contenant les paramètres de configuration du type LDAP de l'attribut.
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-configuration-des-attributs-ldap">Voir la section concernée.</a></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>html_type</code></p>
|
||
<p>Le type HTML de l'attribut (facultatif, par défaut:
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-lsattr_html_text">LSattr_html_text</a>).
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-configuration-des-attributs-html">Voir la section concernée.</a></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>html_options</code></p>
|
||
<p>Tableau associatif contenant les paramètres de configuration du type HTML de l'attribut.
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-configuration-des-attributs-html">Voir la section concernée.</a></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>no_value_label</code></p>
|
||
<p>Label affiché lorsque l'attribut n'a pas de valeur (facultatif).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>multiple</code></p>
|
||
<p>Booléen définissant si cet attribut peut stocker plusieurs valeurs.</p>
|
||
<p>Valeurs possibles : <em>0</em> ou <em>1</em></p>
|
||
<p>Valeur par défaut : <em>0</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>required</code></p>
|
||
<p>Booléen définissant si cet attribut doit obligatoirement être défini.</p>
|
||
<p>Valeurs possibles : <em>0</em> ou <em>1</em></p>
|
||
<p>Valeur par défaut : <em>0</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>generate_function</code></p>
|
||
<p>Nom de la fonction permettant de générer la valeur de l'attribut. Cette fonction sera éxecutée, en
|
||
passant en premier paramètre, l'objet <a href="#conf-lsobject-configuration-lsobject">LSobject</a> courant.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>generate_value_format</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> permettant la génération de l'attribut.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Cette méthode de génération est utilisée uniquement si aucune fonction de génération de la
|
||
valeur n'est définie (paramètre <code>generate_function</code>).</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>default_value</code></p>
|
||
<p>Valeur par défaut de l'attribut.</p>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">Warning</p>
|
||
<p>Il doit s'agir de la valeur telque retournée par le formulaire web. Ainsi, par exemple dans le
|
||
cas d'un attribut booléen, les valeurs possibles sont <code>yes</code> ou <code>no</code>.</p>
|
||
</div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Cette valeur est également utilisée dans le cadre de la génération automatique de la valeur de
|
||
l'attribut si aucune autre méthode n'est disponible (via une fonction ou un
|
||
<a href="#conf-global-lsformat-format-parametrable">LSformat</a>).</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>check_data</code></p>
|
||
<p>Tableau associatif contenant les règles de vérification syntaxique des données de l'attribut.
|
||
<a href="#conf-lsobject-lsattribute-check_data-configuration-des-regles-de-verification-syntaxique">Voir la section concernée.</a></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>validation</code></p>
|
||
<p>Tableau associatif contenant les règles de vérification d'intégrité des données de l'attribut.
|
||
<a href="#conf-lsobject-lsattribute-validation-configuration-des-regles-de-verification-dintegrite">Voir la section concernée.</a></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>rights</code></p>
|
||
<p>Tableau associatif dont les clés sont les noms des
|
||
<a href="#conf-global-ldap-lsprofile-profils-dutilisateurs">LSprofiles</a> ayant des droits sur cet
|
||
attribut et les valeurs associées sont les droits correspondants. La valeur des droits d'un
|
||
<a href="#conf-global-ldap-lsprofile-profils-dutilisateurs">LSprofile</a> peut être <code>r</code> pour le droit de
|
||
lecture ou <code>w</code> pour le droit de lecture-écriture. Par défaut, un
|
||
<a href="#conf-global-ldap-lsprofile-profils-dutilisateurs">LSprofile</a> n'a aucun droit.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>view</code></p>
|
||
<p>Booléen définissant si l'attribut est, ou non, affiché lors de la visualisation des objets du type
|
||
courant.</p>
|
||
<p>Valeurs possibles : <em>0</em> ou <em>1</em></p>
|
||
<p>Valeur par défaut : <em>0</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>form</code></p>
|
||
<p>Tableau associatif dont les clés sont les noms des <a href="#conf-lsobject-lsform-lsform">LSforms</a> et les valeurs
|
||
associées la définition de l'affichage dans ce <a href="#conf-lsobject-lsform-lsform">LSform</a>. Si cette valeur vaut
|
||
<code>0</code>, alors l'attribut sera lecture-seule et si cette valeur vaut <code>1</code>, cet attribut sera affiché
|
||
en lecture-écriture.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>dependAttrs</code></p>
|
||
<p>Tableau associatif listant les attributs dépendants de celui-ci. Les attributs listés ici seront
|
||
regénérés lors de chaque modification de l'attribut courant. Cette génération sera effectuée avec
|
||
la fonction définie dans le paramètre <code>generate_function</code> de l'attribut.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>onDisplay</code></p>
|
||
<p>Nom ou liste de nom des fonctions retournant les valeurs d'affichages de l'attribut. Si c'est une
|
||
liste, chacune des fonctions seront executée les unes après les autres. Ces fonctions seront
|
||
éxecutées, en passant en premier paramètre, le tableau des valeurs de l'objet.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>before_modify</code></p>
|
||
<p>Chaîne de caractères (ou tableau de chaine de caractères) correspondant au nom d'une ou plusieurs
|
||
fonctions qui seront exécutées avant toutes modifications de la valeur de l'attribut.
|
||
<a href="#conf-lsobject-lsattribute-triggers-declencheurs">Voir la section concernée</a></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>after_modify</code></p>
|
||
<p>Chaîne de caractères (ou tableau de chaine de caractères) correspondant au nom d'une ou plusieurs
|
||
fonctions qui seront exécutées après toutes modifications de la valeur de l'attribut.
|
||
<a href="#conf-lsobject-lsattribute-triggers-declencheurs">Voir la section concernée</a></p>
|
||
</li>
|
||
</ul></section><h4 class="nav-section-title">Types d'attribut LDAP (LSattr_ldap)</h4><section class="print-page" id="conf-lsobject-lsattribute-lsattr_ldap"><h1 id="conf-lsobject-lsattribute-lsattr_ldap-configuration-des-attributs-ldap-lsattr_ldap">Configuration des attributs LDAP (LSattr_ldap)</h1>
|
||
<p>Cette section décrit les options propres à chacun des types d'attributs LDAP supportés par
|
||
LdapSaisie.</p></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_ascii"><h1 id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_ascii-lsattr_ldap_ascii">LSattr_ldap_ascii</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est une chaine de caractère. Ce
|
||
type est le type par défaut.</p></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_boolean"><h1 id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_boolean-lsattr_ldap_boolean">LSattr_ldap_boolean</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est une booléen. On attend ici par
|
||
booléen, tout attribut ne pouvant prendre que deux valeurs pré-définies correspond pour l'un à <em>Oui</em>
|
||
et l'autre à <em>Non</em></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_boolean-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'ldap_options' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_boolean-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'true_value' => '[valeur correspondant à Vrai]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_boolean-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> 'false_value' => '[valeur correspondant à Faux]'
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_boolean-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_boolean-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>true_value</code></p>
|
||
<p>La valeur de l'attribut correspondant à <em>Vrai</em>. (Par défaut : <code>TRUE</code>)</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>false_value</code></p>
|
||
<p>La valeur de l'attribut correspondant à <code>False</code>. (Par défaut : <code>FALSE</code>)</p>
|
||
</li>
|
||
</ul>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Les valeurs possibles pour le paramètre <code>default_value</code> sont <code>yes</code> et <code>no</code>.</p>
|
||
</div></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_compositevaluetojson"><h1 id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_compositevaluetojson-lsattr_ldap_compositevaluetojson">LSattr_ldap_compositeValueToJSON</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs composites dont les valeurs respectent le format
|
||
suivant : <code>[key1=value1][key2=value2][...]</code></p>
|
||
<p>Ce type d'attribut LDAP sera utilisé pour convertir la valeur en son équivalent <code>JSON</code> pour pouvoir
|
||
être traité à l'aide du type d' attribut HTML
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-lsattr_html_jsoncompositeattribute">LSattr_html_jsonCompositeAttribute</a>.</p></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_date"><h1 id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_date-lsattr_ldap_date">LSattr_ldap_date</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est une date.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Au sein d'LdapSaisie, les dates manipulées au travers ce type d'attribut LDAP, sont au format
|
||
<em>timestamp</em>. Il s'agit donc de nombres entiers correpondants au nombre de secondes depuis le 1
|
||
janvier 1970.</p>
|
||
<p>Le type d'attribut HTML utilisé conjointement avec ce type d'attribut LDAP devra être prévu pour
|
||
recevoir et fournir des dates au format <em>timestamp</em>, comme c'est le cas pour le <a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_date-lsattr_html_date">type d'attribut
|
||
HTML <em>date</em></a>.</p>
|
||
</div>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_date-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'ldap_options' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_date-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'timestamp' => [Booléen], // Si la date est stockée au format timestamp
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_date-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> 'formats' => array(
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_date-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> '[Format de stockage principal]', // Par défaut : "YmdHisO"
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_date-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> '[Formats de stockage alternatifs]', // Par défaut : "YmdHis.vO" & "YmdHis.uO"
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_date-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> [...]
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_date-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_date-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> 'timezone' => '[Fuseau horaire]', // Default : "UTC"
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_date-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_date-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>timestamp</code></p>
|
||
<p>Booléen définissant si la date est stockée sous la forme d'un timestamp Unix (nombre de secondes
|
||
depuis le 1er janvier 1970 à 00:00:00 UTC).</p>
|
||
<p>Si <code>timestamp</code> est vrai, LdapSaisie ne tient pas compte du paramètre format.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>formats</code></p>
|
||
<p>Formats de stockage de la date dans l'annuaire. Ces formats sont composés à partir des motifs clés
|
||
gérés par la fonction <code>date()</code> de PHP. Pour plus d'information, consulter
|
||
<a href="http://www.php.net/date">la documentation officielle</a>. Plusieurs formats peuvent être définis,
|
||
mais en cas de stockage d'une nouvelle valeur, se sera le premier format défini qui sera utilisé.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>La valeur par défaut est <em>["YmdHisO", "YmdHis.vO", "YmdHis.uO"]</em>, correspondant à la syntaxe
|
||
<code>Generalized Time</code> (sans et avec les milli-secondes ou micro-secondes) telle que définie dans
|
||
la <a href="https://tools.ietf.org/html/rfc4517">RFC4517</a>.
|
||
Exemples : <code>20091206230506Z</code> <em>(=2009/12/06 23:05:66 UTC)</em>, <code>20190613143537+0200</code>
|
||
<em>(=2019/06/13 14:35:37 UTC+0200)</em> ou <code>20230818121005.307+0200</code>
|
||
<em>(=2023/08/18 12:10:05.307 UTC+0200)</em>.</p>
|
||
</div>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">Warning</p>
|
||
<p>Si vous exploitez un attribut stockant une date incluant les milli-secondes ou les
|
||
micro-secondes, ce type d'attribut LDAP sera capable de gérer l'interpratation des valeurs
|
||
stockées, en outre le type d'attribut
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_date-lsattr_html_date">LSattr_html_date</a>, s'appuyant sur les
|
||
méthodes standards <code>strftime()</code> et <code>strptime()</code>, ne permettra pas aujourd'hui leur saisie et
|
||
affichage.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>timezone</code></p>
|
||
<p>Fuseau horaire de stockage des dates dans l'annuaire LDAP. Les valeurs possibles sont documentées
|
||
dans <a href="https://www.php.net/timezones">la documentation officielle de PHP</a>. (Par défaut : <code>UTC</code>)</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_image"><h1 id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_image-lsattr_ldap_image">LSattr_ldap_image</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est une image. Pour le moment,
|
||
aucun traitement particulier n'est appliqué pour le stockage.</p></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_naivedate"><h1 id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_naivedate-lsattr_ldap_naivedate">LSattr_ldap_naiveDate</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est une date dont la <em>timezone</em>
|
||
doit être ignorée. Côté LDAP, les dates seront stockées au format UTC étant donnée que la syntaxe
|
||
LDAP exige une <em>timezone</em>, cependant celle-ci sera complètement ignorée. Ce type peut-être utilisé
|
||
à la place du type <a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_date-lsattr_ldap_date">LSattr_ldap_date</a>.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_naivedate-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'ldap_options' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_naivedate-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'format' => '[Format de stockage]', // Default : "%Y%m%d%H%M%SZ"
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_naivedate-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_naivedate-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>format</code></p>
|
||
<p>Format de stockage de la date dans l'annuaire. Ce format est composé à partir des motifs clés
|
||
gérés par la fonction <code>strftime()</code> de PHP. Pour plus d'information, consulter
|
||
<a href="http://www.php.net/strftime">la documentation officielle</a>.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>La valeur par défaut est <em>%Y%m%d%H%M%SZ</em>, correspondant à la syntaxe <code>Generalized Time</code> (sans
|
||
les micro-secondes) telle que définie dans la <a href="https://tools.ietf.org/html/rfc4517">RFC4517</a>.
|
||
Exemple : <code>20091206230506Z</code> <em>(=2009/12/06 23:05:66 UTC)</em>.</p>
|
||
</div>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_numeric"><h1 id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_numeric-lsattr_ldap_numeric">LSattr_ldap_numeric</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est un nombre. Pour le moment,
|
||
aucun traitement particulier est n'appliqué pour le stockage.</p></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_password"><h1 id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_password-lsattr_ldap_password">LSattr_ldap_password</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est un mot de passe.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_password-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'ldap_options' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_password-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'encode' => '[Type d'encodage du mot de passe]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_password-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> 'encode_function' => '[Nom de la fonction d'encodage]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_password-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> 'verify_function' => '[Nom de la fonction de vérification]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_password-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> 'no_random_crypt_salt' => '[Booléen]', // Désactivation de l'utilisation d'une salt aléatoire
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_password-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> 'wildcardPassword' => '[mot de passe(s) en clair]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_password-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> 'encodedWildcardPassword' => '[mot de passe(s) encodé(s)]'
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_password-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_password-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>encode</code></p>
|
||
<p>Nom du type d'encodage du mot de passe utilisé. Les types d'encodages supportés sont les
|
||
suivants :</p>
|
||
<ul>
|
||
<li><code>argon2</code> (ou <code>argon2i</code>, PHP >= 7.2)</li>
|
||
<li><code>argon2id</code> (PHP >= 7.3)</li>
|
||
<li><code>md5crypt</code></li>
|
||
<li><code>crypt</code></li>
|
||
<li><code>ext_des</code></li>
|
||
<li><code>blowfish</code></li>
|
||
<li><code>sha</code></li>
|
||
<li><code>sha256</code></li>
|
||
<li><code>sha512</code></li>
|
||
<li><code>ssha</code></li>
|
||
<li><code>ssha256</code></li>
|
||
<li><code>ssha512</code></li>
|
||
<li><code>smd5</code></li>
|
||
<li><code>md5</code></li>
|
||
<li><code>clear</code></li>
|
||
</ul>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Valeur par défaut : <code>md5crypt</code></p>
|
||
</div>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Si le type d'encodage est inconnu, ou qu'il n'est pas supporté par le serveur web, un message
|
||
d'erreur alertera l'utilisateur et le mot de passe sera stocké en clair.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>encode_function</code></p>
|
||
<p>Nom d'une function qui sera utilisée afin d'encoder le mot de passe. Cette fonction recevra deux
|
||
paramètres : le <code>LSldapObject</code> et le mot de passe en clair.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>verify_function</code></p>
|
||
<p>Nom d'une function qui sera utilisée afin de valider un mot de passe soumis par l'utilisateur par
|
||
rapport à celui stocké dans l'annuaire. Cette fonction recevra trois paramètres : le
|
||
<code>LSldapObject</code>,le mot de passe en clair et le mot de passe hashé. Si ce paramètre est omis et que
|
||
le paramètre <code>encode_function</code> est défini, le mot de passe à tester sera encodé à nouveau à l'aide
|
||
de la fonction <code>encode_function</code> et le résultat sera comparé avec le mot de passe stocké dans
|
||
l'annuaire.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>no_random_crypt_salt</code></p>
|
||
<p>Désactivation de l'utilisation d'une salt générée aléatoirement au profit de l'utilisation des
|
||
deux premiers caractères du mot de passe. Ce paramètre impacte uniquement le type de cryptage
|
||
<code>crypt</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>wildcardPassword</code></p>
|
||
<p>Mot de passe (ou tableau de mot de passe) qui sera ajouté systématiquement, en plus du mot de
|
||
passe choisi. Il sera encodé de la même manière que pour le mot de passe choisi avant
|
||
enregistrement.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>encodedWildcardPassword</code></p>
|
||
<p>Mot de passe (ou tableau de mot de passe) qui sera ajouté systématiquement, en plus du mot de
|
||
passe choisi. Contrairement à la directive <code>wildcardPassword</code>, le mot de passe ne sera pas encodé
|
||
avant enregistrement.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Cette directive peut cohabiter avec sa cousine <code>wildcardPassword</code>. Les mot de passes contenus
|
||
dans les deux directives seront alors ajoutés.</p>
|
||
</div>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_postaladdress"><h1 id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_postaladdress-lsattr_ldap_postaladdress">LSattr_ldap_postaladdress</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est construite sur le modèle de
|
||
l'attribut standard <em>postalAddress</em>, c'est à dire dont les lignes sont séparées à l'aide du
|
||
caractère de délimiteur <code>$</code>.</p>
|
||
<p>Lors de la lecture des valeurs de ce type d'attribut dans l'annuaire, les caractères <code>$</code> seront
|
||
remplacés par des caractères <code>\n</code> et, à l'inverse, lors de l'écriture des valeurs de ce type
|
||
d'attribut dans l'annuaire, les caractères <code>\n</code> seront remplacés par des caractères <code>$</code>.</p></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory"><h1 id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-lsattr_ldap_pwdhistory">LSattr_ldap_pwdHistory</h1>
|
||
<p>Ce type est utilisé pour la gestion de l'attribut standard <em>pwdHistory</em>. Cet attribut, accessible en
|
||
lecture uniquement, stocke dans un format prédéfini l'historique des mots de passe d'une utilisateur
|
||
avec pour chaque entrée :</p>
|
||
<ul>
|
||
<li>la date et heure de l'ajout du mot de passe dans l'historique</li>
|
||
<li>l'OID de la syntaxe du mot de passe</li>
|
||
<li>la longueur du mot de passe</li>
|
||
<li>le mot de passe (hâché)</li>
|
||
</ul>
|
||
<p>Ce type d'attribut LDAP permettra de convertir la valeur en son équivalent <code>JSON</code> pour pouvoir être
|
||
traité à l'aide du type d'attribut HTML
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-lsattr_html_jsoncompositeattribute">LSattr_html_jsonCompositeAttribute</a>.</p>
|
||
<p><strong>Exemple de valeur de l'attribut pwdHistory :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>20201202144718Z#1.3.6.1.4.1.1466.115.121.1.40#105#{SSHA512}XDSiR6Sh6W7gyVIk6Rr2OUv8rNPr+0rHF99d9lcirE/TnnEdkjkncIi5iPubErL5lpfgh8gXLgSfmqvmFcMqXLToC25xIqyk
|
||
</code></pre></div>
|
||
<p><strong>Exemple de valeur tranformée :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a>{"time":1606920438,"syntaxOID":"1.3.6.1.4.1.1466.115.121.1.40","length":105,"hashed_password":"{SSHA512}XDSiR6Sh6W7gyVIk6Rr2OUv8rNPr+0rHF99d9lcirE/TnnEdkjkncIi5iPubErL5lpfgh8gXLgSfmqvmFcMqXLToC25xIqyk"}
|
||
</code></pre></div>
|
||
<p><strong>Exemple de configuration complète de l'attribut :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-1" id="__codelineno-2-1" name="__codelineno-2-1"></a>'pwdHistory' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-2" id="__codelineno-2-2" name="__codelineno-2-2"></a> 'label' => 'Passwords in history',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-3" id="__codelineno-2-3" name="__codelineno-2-3"></a> 'ldap_type' => 'pwdHistory',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-4" id="__codelineno-2-4" name="__codelineno-2-4"></a> 'html_type' => 'jsonCompositeAttribute',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-5" id="__codelineno-2-5" name="__codelineno-2-5"></a> 'html_options' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-6" id="__codelineno-2-6" name="__codelineno-2-6"></a> 'components' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-7" id="__codelineno-2-7" name="__codelineno-2-7"></a> 'time' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-8" id="__codelineno-2-8" name="__codelineno-2-8"></a> 'label' => 'Date added to history',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-9" id="__codelineno-2-9" name="__codelineno-2-9"></a> 'type' => 'text',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-10" id="__codelineno-2-10" name="__codelineno-2-10"></a> 'required' => true,
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-11" id="__codelineno-2-11" name="__codelineno-2-11"></a> 'multiple' => false,
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-12" id="__codelineno-2-12" name="__codelineno-2-12"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-13" id="__codelineno-2-13" name="__codelineno-2-13"></a> 'syntaxOID' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-14" id="__codelineno-2-14" name="__codelineno-2-14"></a> 'label' => 'Syntax OID',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-15" id="__codelineno-2-15" name="__codelineno-2-15"></a> 'type' => 'text',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-16" id="__codelineno-2-16" name="__codelineno-2-16"></a> 'required' => true,
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-17" id="__codelineno-2-17" name="__codelineno-2-17"></a> 'multiple' => false,
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-18" id="__codelineno-2-18" name="__codelineno-2-18"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-19" id="__codelineno-2-19" name="__codelineno-2-19"></a> 'length' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-20" id="__codelineno-2-20" name="__codelineno-2-20"></a> 'label' => 'Length',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-21" id="__codelineno-2-21" name="__codelineno-2-21"></a> 'type' => 'text',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-22" id="__codelineno-2-22" name="__codelineno-2-22"></a> 'required' => true,
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-23" id="__codelineno-2-23" name="__codelineno-2-23"></a> 'multiple' => false,
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-24" id="__codelineno-2-24" name="__codelineno-2-24"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-25" id="__codelineno-2-25" name="__codelineno-2-25"></a> 'hashed_password' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-26" id="__codelineno-2-26" name="__codelineno-2-26"></a> 'label' => 'Hashed password',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-27" id="__codelineno-2-27" name="__codelineno-2-27"></a> 'type' => 'text',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-28" id="__codelineno-2-28" name="__codelineno-2-28"></a> 'required' => true,
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-29" id="__codelineno-2-29" name="__codelineno-2-29"></a> 'multiple' => false,
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-30" id="__codelineno-2-30" name="__codelineno-2-30"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-31" id="__codelineno-2-31" name="__codelineno-2-31"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-32" id="__codelineno-2-32" name="__codelineno-2-32"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-33" id="__codelineno-2-33" name="__codelineno-2-33"></a> 'no_value_label' => 'History is empty.',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-34" id="__codelineno-2-34" name="__codelineno-2-34"></a> 'multiple' => 1,
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-35" id="__codelineno-2-35" name="__codelineno-2-35"></a> 'rights' => array(
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-36" id="__codelineno-2-36" name="__codelineno-2-36"></a> 'admin' => 'r',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-37" id="__codelineno-2-37" name="__codelineno-2-37"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-38" id="__codelineno-2-38" name="__codelineno-2-38"></a> 'view' => 1,
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_pwdhistory-__codelineno-2-39" id="__codelineno-2-39" name="__codelineno-2-39"></a>),
|
||
</code></pre></div>
|
||
<p>La date et heure de l'ajout du mot de passe dans l'historique est convertie dans un format lisible.
|
||
Par défaut, ce format est <code>AAAA/MM/JJ HH:MM:SS</code>, mais il peut aussi est personnalisé via le
|
||
paramètre <code>date_format</code>. Ce format est composé à partir des motifs clés gérés par la fonction
|
||
<code>date()</code> de PHP. Pour plus d'information, consulter
|
||
<a href="http://www.php.net/date">la documentation officielle</a>.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>La valeur par défaut est <em>YmdHisO</em>, correspondant à la syntaxe <code>Generalized Time</code> telle que
|
||
définie dans la <a href="https://tools.ietf.org/html/rfc4517">RFC4517</a> et prévu par le
|
||
<a href="http://tools.ietf.org/id/draft-behera-ldap-password-policy-10.txt">Draft-behera-ldap-password-policy</a>
|
||
spécifiant cet attribut standard.</p>
|
||
</div></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_sambaacctflags"><h1 id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_sambaacctflags-lsattr_ldap_sambaacctflags">LSattr_ldap_sambaAcctFlags</h1>
|
||
<p>Ce type est prévu pour gérer l'attribut <em>sambaAcctFlags</em> du schéma Samba, qui au travers d'une seule
|
||
et unique valeur, respectant un format prévu, liste l'ensemble des drapeaux actifs d'un compte
|
||
Samba. Il transforme l'unique valeur de l'attribut LDAP en une liste de drapeaux actuellement
|
||
activés sur le compte. Il est conçu pour être utilisé conjointement avec le type d'attribut HTML
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_sambaacctflags-lsattr_html_sambaacctflags">LSattr_html_sambaAcctFlags</a>.</p></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_shadowexpire"><h1 id="conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_shadowexpire-lsattr_ldap_shadowexpire">LSattr_ldap_shadowExpire</h1>
|
||
<p>Ce type est prévu pour gérer l'attribut <code>shadowExpire</code> du schéma POSIX, qui une stocke une date sous
|
||
la forme d'un entier correspondant au nombre de jours depuis le premier 1er 1970. Il est prévu pour
|
||
être utilisé conjointement avec le type d'attribut HTML
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_date-lsattr_html_date">LSattr_html_date</a>.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Malgrés son nom, ce type d'attribut LDAP peux être utilisé pour d'autres attributs stockant ce
|
||
même format de date, tel-que l'attribut <code>shadowLastChange</code>.</p>
|
||
</div></section><h1 class="nav-section-title-end">Ended: Types d'attribut LDAP (LSattr_ldap)</h1><h4 class="nav-section-title">Types d'attribut HTML (LSattr_html)</h4><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html"><h1 id="conf-lsobject-lsattribute-lsattr_html-configuration-des-attributs-html-lsattr_html">Configuration des attributs HTML (LSattr_html)</h1>
|
||
<p>Cette section décrit les options propres à chacun des types d'attributs HTML supportés par
|
||
LdapSaisie.</p></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_boolean"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_boolean-lsattr_html_boolean">LSattr_html_boolean</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est un booléen.</p>
|
||
<p>La valeur retournée est l'une des chaînes de caractères suivantes :</p>
|
||
<ul>
|
||
<li><code>yes</code> pour <em>Vrai</em></li>
|
||
</ul>
|
||
<ul>
|
||
<li><code>no</code> pour <code>False</code></li>
|
||
</ul>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_boolean-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'html_options' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_boolean-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'true_label' => '[label]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_boolean-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> 'false_label' => '[label]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_boolean-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_boolean-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>true_label</code></p>
|
||
<p>Label affiché pour désigner la valeur <code>True</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>false_label</code></p>
|
||
<p>Label affiché pour désigner la valeur <code>False</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Pour le moment, les attributs à valeurs multiples ne sont pas gérés.</p>
|
||
</div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Pour maîtriser les valeurs stockées dans l'annuaire, il faut coupler ce type d'attribut HTML
|
||
avec le type d'attribut LDAP <a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_boolean-lsattr_ldap_boolean">boolean</a></p>
|
||
</div>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>La définition de la valeur par défaut d'un attribut utilisant ce type HTML (paramètre
|
||
<code>default_value</code>), doit se faire à l'aide des valeurs <code>yes</code> ou <code>no</code>.</p>
|
||
</div></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_date"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_date-lsattr_html_date">LSattr_html_date</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est une date. L'outil de sélection
|
||
de date <a href="http://mootools.net/forge/p/mootools_datepicker">MooTools-DatePicker</a> est utilisé pour la
|
||
sélection graphique de la date et de l'heure.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_date-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'html_options' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_date-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'format' => '[Format d'affichage de la date]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_date-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> 'time' => '[Booleen pour le choix ou non de l heure]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_date-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> 'manual' => '[Booleen pour l edition manuelle ou non]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_date-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> 'showNowButton' => '[Booleen]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_date-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> 'showTodayButton' => '[Booleen]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_date-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> 'style' => '[Nom du style utilise]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_date-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> 'special_values' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_date-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> '[value]' => '[label]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_date-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> [...]
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_date-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_date-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_date-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>format</code></p>
|
||
<p>Format d'affichage de la date dans le champ de saisie. Ce format est composé à partir des motifs
|
||
clés suivants :</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Mot clé</th>
|
||
<th>Valeur de substitution</th>
|
||
<th>Exemple de valeur</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>%a</code></td>
|
||
<td>Nom abrégé du jour de la semaine</td>
|
||
<td>De Sun à Sat</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%A</code></td>
|
||
<td>Nom complet du jour de la semaine</td>
|
||
<td>De Sunday à Saturday</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%b</code></td>
|
||
<td>Nom du mois, abrégé, suivant la locale</td>
|
||
<td>De Jan à Dec</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%B</code></td>
|
||
<td>Nom complet du mois, suivant la locale</td>
|
||
<td>De January à December</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%c</code></td>
|
||
<td>Date et heure préférées, basées sur la locale</td>
|
||
<td>Exemple : Tue Feb 5 00:45:10 2009 pour le 5 Février 2009 à 12:45:10 AM</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%d</code></td>
|
||
<td>Jour du mois en numérique, sur 2 chiffres (avec le zéro initial)</td>
|
||
<td>De 01 à 31</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%e</code></td>
|
||
<td>Jour du mois, avec un espace précédant le premier chiffre. L'implémentation Windows est différente, voyez après pour plus d'informations.</td>
|
||
<td>De 1 à 31</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%H</code></td>
|
||
<td>L'heure, sur 2 chiffres, au format 24 heures</td>
|
||
<td>De 00 à 23</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%I</code></td>
|
||
<td>Heure, sur 2 chiffres, au format 12 heures</td>
|
||
<td>De 01 à 12</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%j</code></td>
|
||
<td>Jour de l'année, sur 3 chiffres avec un zéro initial</td>
|
||
<td>001 à 366</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%m</code></td>
|
||
<td>Mois, sur 2 chiffres</td>
|
||
<td>De 01 (pour Janvier) à 12 (pour Décembre)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%M</code></td>
|
||
<td>Minute, sur 2 chiffres</td>
|
||
<td>De 00 à 59</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%p</code></td>
|
||
<td>'AM' ou 'PM', en majuscule, basé sur l'heure fournie</td>
|
||
<td>Exemple : AM pour 00:31, PM pour 22:23</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%s</code></td>
|
||
<td>Timestamp de l'époque Unix (identique à la fonction time())</td>
|
||
<td>Exemple : 305815200 pour le 10 Septembre 1979 08:40:00 AM</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%S</code></td>
|
||
<td>Seconde, sur 2 chiffres</td>
|
||
<td>De 00 à 59</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%T</code></td>
|
||
<td>Identique à "%H:%M:%S" Exemple : 21:34:17 pour 09:34:17 PM</td>
|
||
<td></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%U</code></td>
|
||
<td>Numéro de la semaine de l'année donnée, en commençant par le premier Lundi comme première semaine</td>
|
||
<td>13 (pour la 13ème semaine pleine de l'année)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%w</code></td>
|
||
<td>Représentation numérique du jour de la semaine</td>
|
||
<td>De 0 (pour Dimanche) à 6 (pour Samedi)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%y</code></td>
|
||
<td>L'année, sur 2 chiffres</td>
|
||
<td>Exemple : 09 pour 2009, 79 pour 1979</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%Y</code></td>
|
||
<td>L'année, sur 4 chiffres</td>
|
||
<td>Exemple : 2038</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%z</code></td>
|
||
<td>Soit le décalage horaire depuis UTC, ou son abréviation (suivant le système d'exploitation)</td>
|
||
<td>Exemple : -0500 ou EST pour l'heure de l'Est</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%Z</code></td>
|
||
<td>Le décalage horaire ou son abréviation NON fournie par %z (suivant le système d'exploitation)</td>
|
||
<td>Exemple : -0500 ou EST pour l'heure de l'Est</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>%%</code></td>
|
||
<td>Le caractère de pourcentage ("%")</td>
|
||
<td>---</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>La valeur par défaut est <em>%d/%m/%Y, %T</em>. Exemple : <em>23/04/2009, 23:03:04</em></p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>time</code></p>
|
||
<p>Booléen définissant si l'outil de sélection permetra ou non le choix de l'heure en plus de la date</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>manual</code></p>
|
||
<p>Booléen autorisant ou non l'édition manuelle du champs. Si ce paramètre vaut <code>False</code>, la sélection
|
||
se fera uniquement à l'aide de l'outil graphique</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>showNowButton</code></p>
|
||
<p>Booléen définissant si le bouton <em>Maintenant</em> est affiché ou non. Par défaut, il est affiché.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>showTodayButton</code></p>
|
||
<p>Booléen définissant si le bouton <em>Aujourd'hui</em> est affiché ou non. Par défaut, il est affiché.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>style</code></p>
|
||
<p>Nom du style d'affichage de l'outil de sélection. Les valeurs possibles sont par défaut :</p>
|
||
<ul>
|
||
<li><code>default</code></li>
|
||
<li><code>dashboard</code></li>
|
||
<li><code>vista</code></li>
|
||
<li><code>jqui</code></li>
|
||
</ul>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>La création de nouveau thème est possible. Pour plus d'information, consulter
|
||
<a href="http://mootools.net/forge/p/mootools_datepicker">l'aide de l'outil de sélection de date</a>.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>special_values</code></p>
|
||
<p>Tableau listant les valeurs spéciales que peut prendre l'attribut. Dans ce tableau associatif, la
|
||
clé doit correspondre à la valeur de l'attribut (telle que fournie par
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_date-lsattr_ldap_date">l'attribut LDAP</a>) et la valeur associée au
|
||
label associé.</p>
|
||
<p>Ces valeurs spéciales seront proposées à l'utilisateur sous la forme de cases à cocher dans le
|
||
formulaire. Elles peuvent permettre par exemple de données une signification particulière au zéro
|
||
pour un attribut LDAP stockant un <em>timestamp</em>.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_image"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_image-lsattr_html_image">LSattr_html_image</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est une image. Pour le moment, les
|
||
attributs à valeurs multiples ne sont pas gérés.</p></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-lsattr_html_jsoncompositeattribute">LSattr_html_jsonCompositeAttribute</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont les valeurs sont des dictionnaires de valeurs
|
||
encodées aux formats <em>JSON</em>.</p>
|
||
<p>Exemple de valeur gérée :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="p">{</span><span class="nt">"component1"</span><span class="p">:</span><span class="w"> </span><span class="s2">"value1"</span><span class="p">,</span><span class="w"> </span><span class="nt">"component2"</span><span class="p">:</span><span class="w"> </span><span class="s2">"value2"</span><span class="p">,</span><span class="w"> </span><span class="nt">"component3"</span><span class="p">:</span><span class="w"> </span><span class="s2">"value3"</span><span class="p">}</span>
|
||
</code></pre></div>
|
||
<p>Le principe est que ces dictionnaires contienent plusieurs composants référencés par leur clé et
|
||
stockant une valeur dont le type peut être un texte libre ou bien être issue d'une liste déroulante
|
||
configurable selon le même principe que le type d'attribut
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-lsattr_html_select_list">LSattr_html_select_list</a>.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a>'html_options' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a> 'components' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a> '[clé composant 1]' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a> 'label' => '[Label du composant]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a> 'help_info' => '[Message d'aide sur le composant]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a> 'type' => '[Type de la valeur stocké]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a> 'required' => [Booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-8" id="__codelineno-1-8" name="__codelineno-1-8"></a> 'multiple' => [Booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-9" id="__codelineno-1-9" name="__codelineno-1-9"></a> 'check_data' => => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-10" id="__codelineno-1-10" name="__codelineno-1-10"></a> // Régle de vérification syntaxique des données saisies
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-11" id="__codelineno-1-11" name="__codelineno-1-11"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-12" id="__codelineno-1-12" name="__codelineno-1-12"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-13" id="__codelineno-1-13" name="__codelineno-1-13"></a> '[clé composant 2]' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-14" id="__codelineno-1-14" name="__codelineno-1-14"></a> 'label' => '[Label du composant 2]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-15" id="__codelineno-1-15" name="__codelineno-1-15"></a> 'type' => 'select_list',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-16" id="__codelineno-1-16" name="__codelineno-1-16"></a> 'required' => [Booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-17" id="__codelineno-1-17" name="__codelineno-1-17"></a> 'options' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-18" id="__codelineno-1-18" name="__codelineno-1-18"></a> [Configuration équivalente à un attribut LSattr_html_select_list]
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-19" id="__codelineno-1-19" name="__codelineno-1-19"></a> )
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-20" id="__codelineno-1-20" name="__codelineno-1-20"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-21" id="__codelineno-1-21" name="__codelineno-1-21"></a> [...]
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-22" id="__codelineno-1-22" name="__codelineno-1-22"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-23" id="__codelineno-1-23" name="__codelineno-1-23"></a> 'fullWidth' => [booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-24" id="__codelineno-1-24" name="__codelineno-1-24"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-__codelineno-1-25" id="__codelineno-1-25" name="__codelineno-1-25"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>components</code></p>
|
||
<p>Tableau associatif obligatoire contenant en valeur clé, l'identifiant des composants,
|
||
correspondant à la clé dans le dictionnaire <em>JSON</em>, et en valeurs associés, la configuration du
|
||
composant.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>label</code></p>
|
||
<p>Le label du composant.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>help_info</code></p>
|
||
<p>Message d'aide sur le composant (affiché uniquement en mode édition).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>type</code></p>
|
||
<p>Le type de valeur du composant. Les types possibles sont <code>text</code> ou <code>select_list</code> pour
|
||
respectivement soit une valeur saisie librement, soit une valeur sélectionnée parmis une liste
|
||
déroulante.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>options</code></p>
|
||
<p>Dans le cadre d'un composant de type <code>select_list</code>, cela correspond à la configuration de la
|
||
liste déroulante. Cette configuration utilise la même syntaxe de configuration que celle du type
|
||
d'attribut <a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-lsattr_html_select_list">LSattr_html_select_list</a> et son
|
||
paramètre <code>html_options</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>multiple</code></p>
|
||
<p>Booléen définissant si ce composant peut stocker plusieurs valeurs (Par défaut : <code>False</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>required</code></p>
|
||
<p>Booléen définissant si ce composant doit obligatoirement être défini (Par défaut : <code>False</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>check_data</code></p>
|
||
<p>Tableau associatif contenant les règles de vérification syntaxique des données du composant. Ces
|
||
règles sont configurables de la même manière que les celles des valeurs attributs.
|
||
<a href="#conf-lsobject-lsattribute-check_data-configuration-des-regles-de-verification-syntaxique">Voir la section concernée.</a></p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>fullWidth</code></p>
|
||
<p>Booléen permettant de définir si l'affichage dans le formulaire doit se faire sur toute la largeur
|
||
disponible de la page (Par défaut : <code>False</code>).</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_labeledvalue"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_labeledvalue-lsattr_html_labeledvalue">LSattr_html_labeledValue</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est prefixé d'un <code>label</code> et qui
|
||
respecte le format suivant : <code>[label]valeur</code>.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_labeledvalue-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'html_options' => array(
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_labeledvalue-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'labels' => array ( // Liste des labels possible
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_labeledvalue-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> 'label1' => 'Libellé label1',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_labeledvalue-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> 'label2' => 'Libellé label2',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_labeledvalue-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> [...]
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_labeledvalue-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_labeledvalue-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> 'translate_labels' => [booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_labeledvalue-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_labeledvalue-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>labels</code></p>
|
||
<p>Tableau associatif obligatoire contenant en valeur clé, le <code>label</code> utilisé dans la valeur stockée
|
||
et en valeur associée, le valeur d'affichage du <code>label</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>translate_labels</code></p>
|
||
<p>Booléen permettant d'activer/désactiver la traduction des labels (Par défaut : <code>True</code>).</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_mail"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_mail-lsattr_html_mail">LSattr_html_mail</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est une adresse e-mail. En plus
|
||
d'un affichage adapté, il offre la possibilité d'envoyer des mails directement depuis l'interface de
|
||
l'application.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_mail-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'html_options' => array(
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_mail-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'disableMailSending' => [booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_mail-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_mail-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>disableMailSending</code></p>
|
||
<p>Désactive l'envoi de mail depuis l'interface pour cet attribut.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Ceci ne désactive pas pour autant le lien HTML de type <em>mailto:</em>. Pour cela, utilisez plutôt
|
||
le type d'attribut HTML <a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-lsattr_html_text">text</a>.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Ce type d'attribut HTML est dérivé du type <a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-lsattr_html_text">text</a>. Il
|
||
profite donc de toutes les fonctionnalités d'un champ de ce type (autogénération, ...).</p>
|
||
</div></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_maildir"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_maildir-lsattr_html_maildir">LSattr_html_maildir</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est le chemin d'une maildir.
|
||
Typiquement, ce type attribut HTML est utile dans le cas de l'attribut <em>mailbox</em> utilisé par
|
||
maildrop pour stocker le chemin des boites mails. Ce type d'attribut offre la possibilité de gérér
|
||
un niveau de l'attribut et à travers les déclencheurs gérés par LdapSaisie la création, la
|
||
modification et ou la suppression de la boite mails.
|
||
Le <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a>
|
||
<a href="#conf-lsaddon-lsaddon_maildir-lsaddon_maildir">maildir</a> est utilisé pour manipuler la boite
|
||
mail à distance.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Actuellement, cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> ne gérant que l'accès via FTP
|
||
au serveur distant, l'API d'accès via FTP est attaquée directement.</p>
|
||
</div>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_maildir-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'html_options' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_maildir-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'LSform' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_maildir-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> '[LSform1]' => [booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_maildir-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> '[LSform2]' => [booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_maildir-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> ...
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_maildir-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_maildir-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> 'remoteRootPathRegex' => "[Expression régulière pour matcher le dossier à créer]",
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_maildir-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> 'archiveNameFormat' => "[LSformat du chemin/nom du fichier une fois archiver]"
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_maildir-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_maildir-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSform</code></p>
|
||
<p>Tableau associatif obligatoire contenant en valeur clé le nom des <a href="#conf-lsobject-lsform-lsform">LSforms</a>
|
||
dans lesquels la fonctionnalité de modification de la boite mail sera présente. Les valeurs
|
||
attachées sont des booléens définissant si la modification est active par défaut.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>remoteRootPathRegex</code></p>
|
||
<p>Expression régulière (compatible Perl) facultative dont le but est de <em>matcher</em> dans la valeur
|
||
complète du chemin distant de la <em>maildir</em>, le chemin de la <em>maildir</em> à créer une fois connecté
|
||
sur le serveur.</p>
|
||
<p>Exemple : Si le chemin complet de la <em>maildir</em> est <code>/home/vmail/user</code>, mais que l'utilisateur FTP
|
||
lorsqu'il se connecte arrive directement dans <code>/home/vmail</code>, et faut définir le paramètre
|
||
<code>remoteRootPathRegex</code> de la manière suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_maildir-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a>/^\/home\/vmail\/([^\/]*)\/+$/
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>archiveNameFormat</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> du nom du dossier de la <em>maildir</em> une
|
||
fois archivée. Si ce format est défini, le dossier ne sera pas supprimé mais déplacé ou rénommé.
|
||
Le format sera construit avec pour seul mot clé, le nom de l'ancien dossier. Exemple : Si le
|
||
dossier de la maildir est <code>/home/vmail/user</code> et le paramètre <code>archiveNameFormat</code> vaut
|
||
<code>%{old}.bckp</code>, le dossier sera renommé en <code>/home/vmail/user.bckp</code>.</p>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Ce format est interprété après application de la routine liée au paramètre
|
||
<code>remoteRootPathRegex</code>. Ainsi, dans l'exemple précédent, si le paramètre <code>remoteRootPathRegex</code>
|
||
tronquait uniquement le nom du dossier final, c'est à dire <code>user</code>, le format une fois
|
||
interprété donnerai <code>user.bckp</code>.</p>
|
||
</div>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_mailquota"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_mailquota-lsattr_html_mailquota">LSattr_html_mailQuota</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est le quota d'une boite mail. Le
|
||
format de la valeur générée correspondant au format attendu par le serveur de mail
|
||
<a href="http://www.courier-mta.org/">Courier</a>] par défaut. Exemple : <em>50000000S</em> correspond à un quota de
|
||
50Mio.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_mailquota-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'html_options' => array(
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_mailquota-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'suffix' => '[suffix]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_mailquota-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> )
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_mailquota-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_mailquota-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>suffix</code></p>
|
||
<p>Chaine de caractères suffixant la valeur du quota (Par défaut : <code>S</code>).</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_password"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-lsattr_html_password">LSattr_html_password</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est un mot de passe.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'html_options' => array(
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'isLoginPassword' => [booleen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> 'generationTool' => [booleen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> 'autoGenerate' => [booleen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> 'length' => [nombre de caractères],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> 'chars' => array ( // Caractères que peut contenir le mot de passe
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> array( // Liste caractère avec un nombre mininum d'apparition supérieur à 1
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> 'nb' => [nb caractères],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> 'chars' => '[liste de caractères possibles]'
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> '[autre liste de caractères possibles]', // Liste caractère avec un nombre
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> // d'apparitions égal à 1
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> ...
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a> 'use_pwgen' => [booléen], // Utiliser pwgen pour la génération du mot de passe
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a> 'pwgen_path' => "/path/to/pwgen",
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a> 'pwgen_opts' => "[options à passer à pwgen]",
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a> 'verify' => [booléen], // Activation de l'outil de vérification du mot de passe
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a> 'viewHash' => [booléen], // Activation de l'outil de visualisation du mot de passe haché
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a> 'confirmChange' => [booléen], // Activation de la confirmation en cas de changement du mot de passe
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a> 'confirmChangeQuestion' => "[LSformat]", // LSformat de la question de confirmation du changement du mot de passe
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-22" id="__codelineno-0-22" name="__codelineno-0-22"></a> 'mail' => array( // Configuration de l'envoi du mot de passe par mail
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-23" id="__codelineno-0-23" name="__codelineno-0-23"></a> 'subject' => "[LSformat du sujet du mail]",
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-24" id="__codelineno-0-24" name="__codelineno-0-24"></a> 'msg' => "[LSformat du message du mail]",
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-25" id="__codelineno-0-25" name="__codelineno-0-25"></a> 'mail_attr' => 'mail', // Attribut mail de l'objet
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-26" id="__codelineno-0-26" name="__codelineno-0-26"></a> 'get_mail_attr_function' => '[function]', // Fonction retournant l'attribut mail de l'objet
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-27" id="__codelineno-0-27" name="__codelineno-0-27"></a> 'send' => 1, // Activation par défaut de l'envoi du mot de passe
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-28" id="__codelineno-0-28" name="__codelineno-0-28"></a> 'ask' => 1, // Laisser le choix à l'utilisateur
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-29" id="__codelineno-0-29" name="__codelineno-0-29"></a> 'canEdit' => 1, // Activation de l'édition du LSformat du message par l'utilisateur
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-30" id="__codelineno-0-30" name="__codelineno-0-30"></a> 'checkDomain' => false, // Désactivation de la vérification du domaine de l'adresse email
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-31" id="__codelineno-0-31" name="__codelineno-0-31"></a> 'domain' => '[nom de domaine]', // Nom de domaine obligatoire lors de la validation de l'adresse email
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-32" id="__codelineno-0-32" name="__codelineno-0-32"></a> )
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-33" id="__codelineno-0-33" name="__codelineno-0-33"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_password-__codelineno-0-34" id="__codelineno-0-34" name="__codelineno-0-34"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>isLoginPassword</code></p>
|
||
<p>Booléen définissant si le mot de passe est celui utilisé par l'utilisateur pour se logguer à
|
||
l'annuaire LDAP. Si c'est le cas, pour vérifier si le mot de passe correspond avec un autre, une
|
||
tentative de connexion de l'utilisateur à l'annuaire sera faite. (Par défaut : <code>False</code>)</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>generationTool</code></p>
|
||
<p>Booléen définissant si l'outil de génération de mot de passe est activé.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>autoGenerate</code></p>
|
||
<p>Active la génération automatique du mot de passe lorsque l'attribut n'a encore aucune valeur de
|
||
définie. Il faut également que l'outil de génération soit activé (<code>generationTool</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>length</code></p>
|
||
<p>Nombre de caractères que devront contenir les mots de passe générés.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>chars</code></p>
|
||
<p>Tableau contenant une liste de listes de caractères possibles pour composer le mot de passe. Dans
|
||
chacune de ces listes, au moins un caractère sera utilisé dans le nouveau mot de passe. Il est
|
||
possible de définir un nombre supérieur de caractères d'une liste devant apparaître dans les mots
|
||
de passe générés en spécifiant un tableau associatif dont la clé <em>nb</em> associra le nombre entier de
|
||
caractères et la clé <em>chars</em> la liste de caractères. Une liste de caractères est un chaîne.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>use_pwgen</code></p>
|
||
<p>Booléen définissant si la commande <code>pwgen</code> doit être utilisé pour générer le mot de passe.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>pwgen_path</code></p>
|
||
<p>Chemin d'accès au binaire <code>pwgen</code>. (Par défaut : <code>pwgen</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>pwgen_opts</code></p>
|
||
<p>Options à passer à la commande <code>pwgen</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>verify</code></p>
|
||
<p>Booléen définissant si l'outil de vérification du mot de passe est activé. Si celui-ci est activé,
|
||
l'utilisateur pourra entrer un mot de passe dans le champ et cliquer sur un bouton qui lancera une
|
||
procédure de vérification du mot de passe via un test de connexion à l'annuaire.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>viewHash</code></p>
|
||
<p>Booléen définissant si l'utilisateur aura accès à la fonctionnalité de visualisation du mot de
|
||
passe haché.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>confirmInput</code></p>
|
||
<p>Booléen définissant si un second champ mot de passe sera affiché dans le formulaire pour que
|
||
l'utilisateur confirme la saisie du nouveau mot de passe.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>confirmInputError</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> du message d'erreur affiché à
|
||
l'utilisateur si le mot de passe saisie dans le champs de confirmation ne correspond pas au
|
||
nouveau mot de passe. <em>Paramètre facultatif.</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>confirmChange</code></p>
|
||
<p>Booléen définissant si l'utilisateur devra confirmer le changement de ce mot de passe. Lorsque
|
||
cette fonctionnalité est activée, l'utilisateur verra apparaître une popup de confirmation à la
|
||
validation du formulaire s'il a saisi un nouveau mot de passe.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>confirmChangeQuestion</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> de la question posée à l'utilisateur
|
||
en cas de changement du mot de passe et si la fonctionnalité est activée. Il sera composé à l'aide
|
||
du <em>label</em> de l'attribut. <em>Paramètre facultatif.</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>clearView</code></p>
|
||
<p>Booléen définissant si l'utilisateur pourra voir le mot de passe en clair par défaut (y comris en
|
||
mode visualisation uniquement).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>clearEdit</code></p>
|
||
<p>Booléen définissant si l'utilisateur éditera le mot de passe au travers un champs HTML de type
|
||
<em>text</em> et donc lisible ou au travers un champs HTML de type <em>password</em>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>mail</code></p>
|
||
<p>Paramètres de configuration de l'envoi par mail du mot de passe à l'utilisateur. Lorsque cet outil
|
||
est activé, lors de la modification/création du mot de passe, l'utilisateur pourra recevoir un
|
||
mail lui spécifiant son nouveau mot de passe.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>send</code></p>
|
||
<p>Booléen définissant si l'envoi du mot de passe est activé par défaut.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>ask</code></p>
|
||
<p>Booléen définissant si on laisse le choix à l'utilisateur d'activer ou non l'envoi du mot de
|
||
passe par mail.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>canEdit</code></p>
|
||
<p>Booléen définissant si on laisse la possibilité à l'utilisateur d'éditer le
|
||
<a href="#conf-global-lsformat-format-parametrable">LSformat</a> du message et du sujet.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>subject</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> du sujet du mail. Ce format sera
|
||
composé avec la valeur du nouveau mot de passe de l'utilisateur.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>msg</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> du message du mail. Ce format sera
|
||
composé avec les informations de l'object LDAP, y compris le mot clé <em>%{password}</em> correspondant
|
||
à la valeur du nouveau mot de passe de l'utilisateur.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>mail_attr</code></p>
|
||
<p>Le nom de l'attribut listant les mails possibles de l'utilisateur. Par défaut, la première
|
||
valeur de l'attribut sera utilisée comme adresse mail destinatrice. Cet attribut peut également
|
||
être un tableau de plusieurs noms d'attributs. Dans ce cas, la première valeur correcte sera
|
||
retenue. Si <code>canEdit</code> est activé, l'utilisateur pourra choisir l'adresse mail destinatrice parmi
|
||
la liste des valeurs de l'attribut.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>get_mail_attr_function</code></p>
|
||
<p>Nom de la fonction (ou <code>callable</code> au sens PHP) qui sera utilisé pour récupérer le nom de
|
||
l'attribut listant les mails possibles de l'utilisateur. Cette fonction prendra en paramètre,
|
||
l'objet <code>LSformElement</code> courant et devra retourner une valeur équivalente au paramètre de
|
||
configuration <code>mail_attr</code>. Si ce paramètre est défini, il prévalera toujours sur le paramètre
|
||
<code>mail_attr</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>bcc</code></p>
|
||
<p>Mettre en <em>BCC</em> un mail systématiquement (ou plusieurs en les séparant par des virgules).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>headers</code></p>
|
||
<p>Un tableau de type clé/valeur ou la clé est le nom d'un header à ajouter au mail et la valeur
|
||
est la valeur de l'header en question.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>checkDomain</code></p>
|
||
<p>Booléen définissant si le domaine de l'adresse mail doit être validée. *Paramètre facultatif,
|
||
par défaut: <code>True</code></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>domain</code></p>
|
||
<p>Nom de domaine obligatoire lors de la validation de l'adresse mail. Ce paramètre peut être une
|
||
simple chaine correspondant au domaine ou un tableau listant plusieurs domaines valides.
|
||
<em>Paramètre facultatif, par défaut tous les domaines sont acceptés.</em></p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_postaladdress"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_postaladdress-lsattr_html_postaladdress">LSattr_html_postaladdress</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs du type de l'attribut standard <em>postalAddress</em>.
|
||
Ce type d'attribut permet d'afficher, en plus de l'adresse, un lien composé à partir d'informations
|
||
de l'objet permettant par exemple d'afficher un lien vers une carte géocalisant l'adresse postale.</p>
|
||
<p>Par défaut, le lien ajouté sera un lien de recherche de l'adresse postale générée à partir de la
|
||
valeur de l'attribut (en remplaçant les retours à la ligne (<code>\n</code>) par des espaces) via le service
|
||
<a href="http://nominatim.openstreetmap.org/">Nominatim d'OpenStreetMap</a>.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Dans le cadre du fonctionnement par défaut et pour maîtriser les valeurs stockées dans
|
||
l'annuaire, il faut coupler ce type d'attribut HTML avec le type d'attribut LDAP
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_postaladdress-lsattr_ldap_postaladdress">postaladdress</a></p>
|
||
</div>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_postaladdress-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'html_options' => array(
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_postaladdress-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'map_url_pattern_format' => '[LSformat]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_postaladdress-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> 'map_url_pattern_generate_function' => '[callable]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_postaladdress-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> 'map_url_format' => '[LSformat]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_postaladdress-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_postaladdress-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>map_url_pattern_format</code></p>
|
||
<p>Ce <a href="#conf-global-lsformat-format-parametrable">LSformat</a> doit permettre de générer la valeur
|
||
de l'adresse postale qui sera insérée dans l'URL du lien ajouté dans l'interface.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>map_url_pattern_generate_function</code></p>
|
||
<p>Ce paramètre permet de définir une fonction qui sera utilisée à la place du paramètre
|
||
<code>map_url_pattern_format</code> pour générer la valeur de l'adresse postale qui sera insérée dans l'URL
|
||
du lien ajouté dans l'interface. Cette fonction prendra en paramètre l'objet <em>LSformElement</em>
|
||
courant et devra retourner une chaîne de caractères correspondant à l'adresse postale à insérer
|
||
dans le lien de l'interface. Par défaut, la fonction
|
||
<code>LSformElement_postaladdress__generate_pattern</code> est utilisée.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>map_url_format</code></p>
|
||
<p>Ce <a href="#conf-global-lsformat-format-parametrable">LSformat</a> doit permettre de générer l'URL du
|
||
lien ajouté dans l'interface. Il sera composé avec les informations de l'objet LDAP, y compris le
|
||
mot clé <code>%{pattern}</code> correspondant à la valeur de l'adresse postale générée à l'aide des
|
||
paramètres précédents. Par défaut, la format suivant sera utilisé :
|
||
<code>http://nominatim.openstreetmap.org/search.php?q=%{pattern}</code></p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_pre"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_pre-lsattr_html_pre">LSattr_html_pre</h1>
|
||
<p>Ce type est dérivé du type <a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_textarea-lsattr_html_textarea">LSattr_html_textarea</a> et
|
||
permet simplement que lors de l'affichage de la valeur, celle-ci soit affichée en respectant les
|
||
retours à la ligne et en utilisant une police de caractères <code>monospace</code>. Cela reproduit l'affichage
|
||
d'une balise HTML <code>pre</code>.</p></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_rss"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_rss-lsattr_html_rss">LSattr_html_rss</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est l'URL d'un flux RSS. Il propose
|
||
directement dans l'interface, la possibilité d'accèder au flux RSS.</p>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Ce type d'attribut HTML est dérivé du type <a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-lsattr_html_text">text</a>. Il
|
||
profite donc de toutes les fonctionnalités d'un champ de ce type (autogénération, ...).</p>
|
||
</div></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_sambaacctflags"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_sambaacctflags-lsattr_html_sambaacctflags">LSattr_html_sambaAcctFlags</h1>
|
||
<p>Ce type est prévu pour gérer l'attribut <em>sambaAcctFlags</em> du schéma Samba, qui au travers d'une seule
|
||
et unique valeur, respectant un format prévu, liste l'ensemble des drapeaux actifs d'un compte
|
||
Samba. Il est conçu pour être utilisé conjointement avec le type d'attribut LDAP
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_sambaacctflags-lsattr_ldap_sambaAcctFlags">LSattr_ldap_sambaAcctFlags</a>.</p>
|
||
<p>Pour définir la valeur par défaut de cet attribut, il faut définir paramètre <code>default_value</code> comme
|
||
un tableau des drapeaux telque prévu par Samba :</p>
|
||
<p>- <code>U</code></p>
|
||
<div class="highlight"><pre><span></span><code>Compte utilisateur standard
|
||
</code></pre></div>
|
||
<p>- <code>W</code></p>
|
||
<div class="highlight"><pre><span></span><code>Compte de poste de travail approuvé
|
||
</code></pre></div>
|
||
<p>- <code>S</code></p>
|
||
<div class="highlight"><pre><span></span><code>Compte de serveur approuvé
|
||
</code></pre></div>
|
||
<p>- <code>I</code></p>
|
||
<div class="highlight"><pre><span></span><code>Compte de domaine approuvé
|
||
</code></pre></div>
|
||
<p>- <code>M</code></p>
|
||
<div class="highlight"><pre><span></span><code>Compte de connexion Majority Node Set (MNS)
|
||
</code></pre></div>
|
||
<p>- <code>H</code></p>
|
||
<div class="highlight"><pre><span></span><code>Dossier personnel requis
|
||
</code></pre></div>
|
||
<p>- <code>N</code></p>
|
||
<div class="highlight"><pre><span></span><code>Compte sans mot de passe
|
||
</code></pre></div>
|
||
<p>- <code>X</code></p>
|
||
<div class="highlight"><pre><span></span><code>Le mot de passe n'expire jamais
|
||
</code></pre></div>
|
||
<p>- <code>D</code></p>
|
||
<div class="highlight"><pre><span></span><code>Compte désactivé
|
||
</code></pre></div>
|
||
<p>- <code>T</code></p>
|
||
<div class="highlight"><pre><span></span><code>Copie temporaire d'un autre compte
|
||
</code></pre></div>
|
||
<p>- <code>L</code></p>
|
||
<div class="highlight"><pre><span></span><code>Compte automatiquement bloqué
|
||
</code></pre></div>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_sambaacctflags-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a> Exemple de valeur par défaut...
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_sambaacctflags-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a>'default_value' => array('U', 'X'),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_sambaacctflags-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a>...
|
||
</code></pre></div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Ce type d'attribut est implémenté en dérivant le type <em>LSattr_html_select_box</em> dont les valeurs
|
||
possibles sont pré-configurées (paramètre <code>possible_values</code>). Même si cela n'est pas forcément
|
||
utiles, les autres paramètres du type parent restent utilisables.</p>
|
||
</div></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_box"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_box-lsattr_html_select_box">LSattr_html_select_box</h1>
|
||
<p>Ce type est identique au type <em>LSattr_html_select_list</em> excepté qu'il utilise en lieu et place d'une
|
||
balise HTML <code>select</code>, plusieurs balises HTML <code>input</code> de type <code>checkbox</code> en cas de valeurs multiples
|
||
ou de type <code>radio</code> en cas de valeur unique. Les paramètres de configuration de la classe
|
||
<em>LSattr_html_select_list</em> sont tous hérités et fonctionnent donc de la même manière. Par ailleurs,
|
||
ce type dispose également de paramètres qui lui sont propre (voir ci-dessous).</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_box-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'html_options' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_box-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'inline' => [Booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_box-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_box-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>inline</code></p>
|
||
<p>Booléen définissant si les valeurs possibles doivent être affichées sur une même ligne ou non
|
||
(Faux par défaut).</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-lsattr_html_select_list">LSattr_html_select_list</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont les valeurs font partie d'une liste statique
|
||
ou dynamique. Il est possible de lister des valeurs statiques et également des références à d'autres
|
||
<a href="#conf-configuration-lsobject">LSobjects</a>. La référence à un objet correspond à une
|
||
valeur clé, référente à un objet précis, qui peut être soit la valeur d'un de ses attributs, soit
|
||
son <em>DN</em>.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'html_options' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'possible_values' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> '[LSformat de la valeur clé]' => '[LSformat du nom d'affichage]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> ...
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> 'OTHER_OBJECT' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> 'object_type' => '[Type d'LSobject]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> 'display_name_format' => '[LSformat du nom d'affichage des LSobjects]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> 'value_attribute' => '[Nom de l'attribut clé]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> 'values_attribute' => '[Nom de l'attribut clé multi-valeur]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> 'filter' => '[Filtre de recherche des LSobject]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> 'scope' => '[Scope de la recherche]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> 'basedn' => '[Basedn de la recherche]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> 'onlyAccessible' => '[Booléen]'
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a> 'OTHER_ATTRIBUTE' => '[attr]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a> // Or :
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a> 'OTHER_ATTRIBUTE' => array(
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a> '[attr1]' => '[label1]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a> '[attr2]' => '[label2]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a> [...]
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-22" id="__codelineno-0-22" name="__codelineno-0-22"></a> // Or :
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-23" id="__codelineno-0-23" name="__codelineno-0-23"></a> 'OTHER_ATTRIBUTE' => array(
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-24" id="__codelineno-0-24" name="__codelineno-0-24"></a> 'attr' => [attr],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-25" id="__codelineno-0-25" name="__codelineno-0-25"></a> 'json_component_key' => '[Composant JSON clé]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-26" id="__codelineno-0-26" name="__codelineno-0-26"></a> 'json_component_label' => '[Composant JSON label]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-27" id="__codelineno-0-27" name="__codelineno-0-27"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-28" id="__codelineno-0-28" name="__codelineno-0-28"></a> array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-29" id="__codelineno-0-29" name="__codelineno-0-29"></a> 'label' => '[LSformat du nom du groupe de valeurs]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-30" id="__codelineno-0-30" name="__codelineno-0-30"></a> 'possible_values' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-31" id="__codelineno-0-31" name="__codelineno-0-31"></a> '[LSformat de la valeur clé]' => '[LSformat du nom d'affichage]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-32" id="__codelineno-0-32" name="__codelineno-0-32"></a> ...
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-33" id="__codelineno-0-33" name="__codelineno-0-33"></a> 'OTHER_OBJECT' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-34" id="__codelineno-0-34" name="__codelineno-0-34"></a> ...
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-35" id="__codelineno-0-35" name="__codelineno-0-35"></a> )
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-36" id="__codelineno-0-36" name="__codelineno-0-36"></a> )
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-37" id="__codelineno-0-37" name="__codelineno-0-37"></a> )
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-38" id="__codelineno-0-38" name="__codelineno-0-38"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-39" id="__codelineno-0-39" name="__codelineno-0-39"></a> 'get_possible_values' => [callable],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-40" id="__codelineno-0-40" name="__codelineno-0-40"></a> 'translate_labels' => [booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-41" id="__codelineno-0-41" name="__codelineno-0-41"></a> 'sort' => [Booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-42" id="__codelineno-0-42" name="__codelineno-0-42"></a> 'sortDirection' => '[ASC|DESC]'
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-43" id="__codelineno-0-43" name="__codelineno-0-43"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_list-__codelineno-0-44" id="__codelineno-0-44" name="__codelineno-0-44"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>possible_values</code></p>
|
||
<p>Tableau associatif obligatoire contenant en valeur clé le
|
||
<a href="#conf-global-lsformat-format-parametrable">LSformat</a> des valeurs clés prisent par
|
||
l'attribut et en valeurs associées, le <a href="#conf-global-lsformat-format-parametrable">LSformat</a>
|
||
des noms d'affichage de ces valeurs. Ces <a href="#conf-global-lsformat-format-parametrable">LSformats</a>
|
||
sont composés à partir des valeurs de l'objet courant (attributs, dn, ...).</p>
|
||
<p>Si la valeur clé est égale à <code>OTHER_OBJECT</code>, une liste
|
||
d'<a href="#conf-configuration-lsobject">LSobject</a> sera insérée dans la liste des valeurs
|
||
possibles. La valeur associée est alors un tableau associatif dont les valeurs clés sont les noms
|
||
des paramètres de configuration de la recherche de ces
|
||
<a href="#conf-configuration-lsobject">LSobjects</a> et les valeurs associées, les valeurs des
|
||
paramètres.</p>
|
||
<p>Il est possible de regrouper des valeurs de l'attribut en plaçant leur déclaration dans un
|
||
sous-tableau. Ce sous-tableau devra contenir la clé <code>label</code> dont la valeur associé sera le
|
||
<a href="#conf-global-lsformat-format-parametrable">LSformat</a> du nom du groupe de valeurs. Ce
|
||
<a href="#conf-global-lsformat-format-parametrable">LSformat</a> est composé à partir des valeurs de
|
||
l'objet courant (attributs, dn, ...). Une seconde clé <code>possible_values</code> regroupera les valeurs
|
||
possibles du groupe. Comme pour le tableau principal, la clé <code>OTHER_OBJECT</code> permet d'imcorporer
|
||
une liste d'<a href="#conf-configuration-lsobject">LSobject</a>.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>object_type</code></p>
|
||
<p>Nom du type d'<a href="#conf-configuration-lsobject">LSobject</a> en référence.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>display_name_format</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> du nom d'affichage des objets lors
|
||
de leur sélection.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>value_attribute</code></p>
|
||
<p>Nom de l'attribut des <a href="#conf-configuration-lsobject">LSobjects</a> en référence servant
|
||
de valeur clé et permettant de les identifier (Exemple : <code>dn</code> ou <code>uid</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>values_attribute</code></p>
|
||
<p>Nom de l'attribut des <a href="#conf-configuration-lsobject">LSobjects</a> en référence servant
|
||
de catalogue de valeurs. Dans ce mode, la valeur n'a pas de label et est affichée directement
|
||
dans l'interface. Ce paramètre peut-être utilisé en complément ou non du paramètre
|
||
<code>value_attribute</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>filter</code></p>
|
||
<p>Filtre falcultatif de la recherche des LSobjets. Il sera dans tous les cas agrémenté des valeurs
|
||
des <em>objectclass</em> du type d'<a href="#conf-configuration-lsobject">LSobject</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>scope</code></p>
|
||
<p>Scope falcultatif de la recherche des LSobjets.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>basedn</code></p>
|
||
<p>Basedn falcultatif de la recherche des LSobjets.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>onlyAccessible</code></p>
|
||
<p>Booléen falcultatif définissant si seul les LSobjets auxquels l'utilisateur connecté à accès
|
||
doivent être considérés comme sélectionnables (Faux par défaut).</p>
|
||
</li>
|
||
</ul>
|
||
<p>Si la valeur clé est égale à <code>OTHER_ATTRIBTE</code>, une liste de valeur possible sera composée à l'aide
|
||
des valeurs d'un (ou plusieurs) autre attribut de l'objet courant. La valeur associée peut être
|
||
alors :</p>
|
||
<ul>
|
||
<li>soit le nom d'un attribut dont les valeurs seront utilisées comme valeurs possibles (la valeur
|
||
affichée est égale à la valeur stockée).</li>
|
||
</ul>
|
||
<ul>
|
||
<li>soit un tableau associatif dont les valeurs clés sont les noms des attributs dont les valeurs
|
||
seront utilisés comme valeurs possibles et dont les valeurs associés seront les labels sous
|
||
lesquels ces valeurs seront regroupées (la valeur affichée est égale à la valeur stockée).</li>
|
||
</ul>
|
||
<ul>
|
||
<li>soit un tableau associatif référençant un attribut sous la clé <code>attr</code> dont les valeurs seront
|
||
utilisées comme valeurs possibles. Cet attribut peut-être du type
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_jsoncompositeattribute-lsattr_html_jsoncompositeattribute">LSattr_html_jsonCompositeAttribute</a>.
|
||
Il sera alors possible d'utiliser les valeurs d'un composant en particulier en le référençant à
|
||
l'aide de la clé <code>json_component_key</code>. Il est également possible de référencer un autre
|
||
composant à l'aide de la clé <code>json_component_label</code> et dont les valeurs seront utilisées comme
|
||
valeurs affichées lors de la sélection. À défaut, les valeurs affichées seront identiques à
|
||
celles stockées.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>get_possible_values</code></p>
|
||
<p>Paramètre permettant de spécifier un <em>callable</em> qui sera utilisé pour lister les valeurs possibles
|
||
de l'attribut. Il recevra en paramètres les informations suivantes:</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>$options</code></p>
|
||
<p>Les options HTML de l'attribut.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>$name</code></p>
|
||
<p>Le nom de l'attribut.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>&$ldapObject</code></p>
|
||
<p>Une référence à l'objet <code>LSldapObject</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<p>La valeur de retour attendue est un tableau associatif des valeurs possibles de l'attribut avec la
|
||
valeur que prendra l'attribut en tant que clé et le label correspondant en tant que valeur. Tout
|
||
autre retour sera considéré comme un échec et déclenchera une erreur.</p>
|
||
<p>Il est également possible de regrouper des valeurs possibles de l'attribut: pour cela, le tableau
|
||
retourné devra lui-même contenir un tableau associatif contenant la label traduit du groupe sous
|
||
la clé <code>label</code> et les valeurs possibles du groupe sous la clé <code>possible_values</code>.</p>
|
||
<p>Les valeurs retournées pourront être combinées avec les autres valeurs possibles configurées de
|
||
l'attribut. La prise en charge du tri des valeurs possibles est assurée par la fonction appelante
|
||
sauf dans le cas des sous-groupes de valeurs possibles. Dans ce cas, la méthode
|
||
<code>LSattr_html_select_list :: _sort()</code> pourra être utilisée pour trier les valeurs du sous-groupe :
|
||
cette méthode accepte en paramètre une référence du tableau des valeurs possibles ainsi que les
|
||
options HTML de l'attribut.</p>
|
||
<p>Si la traduction des labels des valeurs possibles de l'attribut est activées (voir ci-dessous),
|
||
celle-ci doit être prise en charge par la fonction configurée.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>translate_labels</code></p>
|
||
<p>Booléen permettant d'activer/désactiver la traduction des labels (Par défaut : <code>True</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>sort</code></p>
|
||
<p>Booléen définissant si les valeurs possibles doivent être triées ou non (Vrai par défaut). Le trie
|
||
est effectué sur les libellés des valeurs possibles.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>sortDirection</code></p>
|
||
<p>Mot clé déterminant le sens du trie des valeurs possibles.</p>
|
||
<p>Valeurs possibles : <code>ASC</code> ou <code>DESC</code> (<code>ASC</code> par défaut).</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object-lsattr_html_select_object">LSattr_html_select_object</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont les valeurs sont des références à d'autres
|
||
<a href="#conf-configuration-lsobject">LSobjects</a>. Chaque référence à un objet correspond à une
|
||
valeur prise par l'attribut. Les valeurs clés référant à un
|
||
<a href="#conf-configuration-lsobject">LSobject</a> sont soit la valeur d'un de leurs attributs,
|
||
soit leur <em>DN</em>.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'html_options' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> selectable_object => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> 'object_type' => '[Type d'LSobject selectionnable]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> 'display_name_format' => '[LSformat du nom d'affichage des LSobjects]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> 'value_attribute' => '[Nom de l'attribut clé des LSobjects]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> 'filter' => '[Filtre de recherche]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> 'onlyAccessible' => '[Booléen]'
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> [...]
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> 'ordered' => [Booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> 'sort' => [Booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a> 'sortDirection' => '[ASC|DESC]'
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_select_object-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>selectable_object</code></p>
|
||
<p>Tableau dont chaque valeur correspond à un tableau associatif spécifiant un type
|
||
d'<a href="#conf-configuration-lsobject">LSobject</a> sélectionnable. Pour chaque type d'objet
|
||
sélectionnable, les paramètres suivants doivent être renseignés :</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>object_type</code></p>
|
||
<p>Nom du type d'<a href="#conf-configuration-lsobject">LSobject</a> en référence
|
||
<em>(Paramètre obligatoire)</em>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>display_name_format</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> du nom d'affichage des objets lors
|
||
de leur sélection <em>(Paramètre facultatif)</em>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>value_attribute</code></p>
|
||
<p>Nom de l'attribut des <a href="#conf-configuration-lsobject">LSobjects</a> en référence servant
|
||
de valeur clé et permettant de les identifier <em>(Paramètre obligatoire, exemples : <code>dn</code> ou <code>uid</code>)</em>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>filter</code></p>
|
||
<p>Filtre de recherche qui sera ajouter au filtre par défaut lors de la sélection des objets
|
||
<em>(Paramètre facultatif)</em>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>onlyAccessible</code></p>
|
||
<p>Booléen définissant si seul les LSobjets auxquels l'utilisateur connecté à accès doivent être
|
||
considérés comme sélectionnables <em>(Paramètre facultatif, par défaut: <code>False</code>)</em>.</p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>ordered</code></p>
|
||
<p>Booléen définissant si la liste des objets choisis doit être ordonnable ou non <em>(Paramètre
|
||
facultatif, par défaut: <code>False</code>)</em>. Cela aura pour effet d'activer une fonctionnalité dynamique de
|
||
l'interface permettant de remonter ou descendre dans la liste les objets choisis.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Cette fonctionnalité désactive automatiquement le trie des objets à l'affichage.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>sort</code></p>
|
||
<p>Booléen définissant si la liste des objets choisis doit être triée ou non <em>(Paramètre facultatif,
|
||
par défaut: <code>True</code>)</em>. Le trie est effectué sur les libellés des objets choisis.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>sortDirection</code></p>
|
||
<p>Mot clé déterminant le sens du trie des objets choisis.</p>
|
||
<p>Valeurs possibles : <code>ASC</code> ou <code>DESC</code> (<code>ASC</code> par défaut).</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_ssh_key"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_ssh_key-lsattr_html_ssh_key">LSattr_html_ssh_key</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est une clef publique SSH. Il
|
||
permet dans l'interface, d'avoir un affichage adapté à ce type de donnée.</p></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_tel"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_tel-lsattr_html_tel">LSattr_html_tel</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est un numéro de téléphone. Lors de
|
||
l'affichage, un lien hypertexte avec une URI de type <code>tel:~~</code> est affiché.</p>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Ce type d'attribut HTML est dérivé du type <a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-lsattr_html_text">text</a>. Il
|
||
profite donc de toutes les fonctionnalités d'un champ de ce type (autogénération, ...).</p>
|
||
</div></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_text"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-lsattr_html_text">LSattr_html_text</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est une chaîne de caractères devant
|
||
être affichée dans un champ <em>input</em> HTML de type <em>text</em>.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'html_options' => array(
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'generate_value_format' => '[LSformat pour la génération de la valeur]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> 'autoGenerateOnCreate' => [booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> 'autoGenerateOnModify' => [booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> 'withoutAccent' => [booleen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> 'replaceSpaces' => "[chaîne de remplacement]",
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> 'upperCase' => [booleen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> 'lowerCase' => [booleen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a>
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> // Autocomplétion
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> 'autocomplete' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> 'object_type' => '[Type d'LSobject]', // facultatif (voir ci-dessous)
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> 'value_attributes' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a> '[attr1]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a> '[attr2]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a> [...]
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a> 'filter' => '[filtre LDAP]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a> 'basedn' => '[base DN spécifique]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a> 'scope' => '[scope de recherche]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a> 'displayFormat' => '[LSformat]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-22" id="__codelineno-0-22" name="__codelineno-0-22"></a> 'onlyAccessible' => [booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-23" id="__codelineno-0-23" name="__codelineno-0-23"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-24" id="__codelineno-0-24" name="__codelineno-0-24"></a>
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-25" id="__codelineno-0-25" name="__codelineno-0-25"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-__codelineno-0-26" id="__codelineno-0-26" name="__codelineno-0-26"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>generate_value_format</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> de la valeur utilisée pour la
|
||
génération automatique de celle-ci à partir des informations saisies dans le formulaire. Les
|
||
valeurs clefs du format sont les noms des attributs de l'objet. Seuls les attributs affichés au
|
||
moins en lecture seule dans le formulaire peuvent être utilisés dans le format. Une seule valeur
|
||
par attribut sera utilisée pour la génération : celle du premier champ (dans l'ordre d'apparition
|
||
dans le formulaire).</p>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Seuls les éléments du formulaire de type HTML <em>input</em>, <em>select</em> ou <em>textarea</em> peuvent être
|
||
utilisés.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>autoGenerateOnCreate</code></p>
|
||
<p>Activation de la génération automatique lorsque celui-ci est vide au moment du chargement du
|
||
formulaire (par défaut : <code>False</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>autoGenerateOnModify</code></p>
|
||
<p>Activation de la génération automatique lors de chaque modification de la valeur des champs du
|
||
formulaire lié (par défaut : <code>False</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>withoutAccent</code></p>
|
||
<p>Activation de la suppression des accents dans la chaîne de caractères générée automatiquement
|
||
(par défaut : <code>False</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>withoutAccent</code></p>
|
||
<p>Activation du remplacement des accents dans la chaîne de caractères générée automatiquement. La
|
||
valeur de remplacement est celle du paramètre (par défaut : <code>False</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>upperCase</code></p>
|
||
<p>Activation de la mise en majuscule de la valeur générée automatiquement (par défaut : <code>False</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>lowerCase</code></p>
|
||
<p>Activation de la mise en minuscule de la valeur générée automatiquement (par défaut : <code>False</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>autocomplete</code></p>
|
||
<p>Paramètrage de l'autocomplétion des valeurs saisies : on paramètre ici la recherche des valeurs
|
||
possibles de l'attribut dans l'annuaire qui peut se faire :</p>
|
||
<ul>
|
||
<li>Sur la base d'un type d'<a href="#conf-configuration-lsobject">LSobject</a> donné :
|
||
l'autocomplétion se fera alors comme n'importe quelle recherche d'un type d'objet donné.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Sur la base d'une recherche brute dans l'annuaire : l'autocomplétion se fera alors au travers
|
||
une recherche brute dans l'annuaire sur n'importe quels objets ayant un des attributs spécifiés
|
||
dans le paramètre <code>value_attributes</code> correspondant.</li>
|
||
</ul>
|
||
<p>Les paramètres associés à ces deux cas de figure sont décrits ci-dessous :</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>object_type</code></p>
|
||
<p>Le type d'<a href="#conf-configuration-lsobject">LSobject</a> recherché.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>value_attributes</code></p>
|
||
<p>Le(s) nom de l'attribut stockant les valeurs possibles recherchées. Il peut s'agir d'une chaîne
|
||
de caractères ou d'un tableau s'il y a plusieurs attributs.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>pattern_filter</code></p>
|
||
<p>Le <a href="#conf-global-lsformat-format-parametrable">LSformat</a> du filtre de recherche à partir
|
||
du mot clé recherché. Ce paramètre est facultatif et utile que dans le cas d'une recherche sans
|
||
type d'<a href="#conf-configuration-lsobject">LSobject</a> précis. S'il est défini, ce
|
||
<a href="#conf-global-lsformat-format-parametrable">LSformat</a> sera composé à l'aide du mot clé
|
||
recherché. À défaut, le filtre de recherche sera composé à l'aide des différents
|
||
<code>value_attributes</code> configurés.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>filter</code></p>
|
||
<p>Un filtre de recherche facultatif venant en plus de celui calculé automatiquement à partir du
|
||
mot clé de recherche.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>basedn</code></p>
|
||
<p>Le <em>basedn</em> de la recherche. <em>Paramètre facultatif.</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>scope</code></p>
|
||
<p>Le <em>scope</em> de la recherche. <em>Paramètre facultatif, par défaut : <code>sub</code>.</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>display_name_format</code></p>
|
||
<p>Le <a href="#conf-global-lsformat-format-parametrable">LSformat</a> d'affichage des objets trouvés.
|
||
Ce paramètre est facultatif et par défaut, il s'agira du format d'affichage propre au type
|
||
d'<a href="#conf-configuration-lsobject">LSobject</a> (si défini) et à défaut, la valeur
|
||
possible trouvée sera affichée. Si est configuré, ce
|
||
<a href="#conf-global-lsformat-format-parametrable">LSformat</a> sera composé à l'aide des valeurs
|
||
brutes des attributs des objets correspondants avec en plus la valeur possible trouvée dans le
|
||
mot clé <code>value</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>only_accessible</code></p>
|
||
<p>Booléen falcultatif définissant si seul les
|
||
<a href="#conf-configuration-lsobject">LSobjects</a> auxquels l'utilisateur connecté à accès
|
||
doivent être considérés comme sélectionnables (Faux par défaut). Ce paramètre n'est appliqué que
|
||
dans le cas d'une recherche pour un type d'<a href="#conf-configuration-lsobject">LSobject</a>
|
||
donné.</p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_textarea"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_textarea-lsattr_html_textarea">LSattr_html_textarea</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est une chaine de caractères trop
|
||
longue pour être saisie dans un champs HTML <em>imput</em> de type <em>text</em> et est plus adapté à un champ
|
||
HTML <em>textarea</em>.</p></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_url"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_url-lsattr_html_url">LSattr_html_url</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est une URL. Il propose directement
|
||
dans l'interface, la possibilité d'accèder au site ou encore de l'ajouter dans ses favoris
|
||
(lorsque le navigateur le supporte).</p>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Ce type d'attribut HTML est dérivé du type <a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-lsattr_html_text">text</a>. Il
|
||
profite donc de toutes les fonctionnalités d'un champ de ce type (autogénération, ...).</p>
|
||
</div></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_valuewithunit"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_valuewithunit-lsattr_html_valuewithunit">LSattr_html_valueWithUnit</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est un entier auxquel un facteur
|
||
peut s'appliquer (par exemple : <code>Kilo, Méga, ...</code>).</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_valuewithunit-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'html_options' => array(
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_valuewithunit-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'units' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_valuewithunit-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> '[facteur1]' => '[label unit1]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_valuewithunit-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> '[facteur2]' => '[label unit2]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_valuewithunit-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> [...]
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_valuewithunit-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_valuewithunit-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> 'translate_labels' => [booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_valuewithunit-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> 'nb_decimals' => [number of decimals],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_valuewithunit-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> 'dec_point' => '[decimals point]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_valuewithunit-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> 'thousands_sep' => '[thousands separator]',
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_valuewithunit-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> 'store_integer' => [booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_valuewithunit-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> 'round_down' => [booléen],
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_valuewithunit-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> )
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_valuewithunit-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_valuewithunit-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>units</code></p>
|
||
<p>Tableau associatif dont la clé est un entier correspondant au facteur et la valeur est le label de
|
||
l'unité. (Par exemple : <code>1 => Octet, 1024 => Kilo-octet, ...</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>translate_labels</code></p>
|
||
<p>Booléen permettant d'activer/désactiver la traduction des labels (Par défaut : <code>True</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>nb_decimals</code></p>
|
||
<p>Le nombre de décimals à afficher en cas de nombre non-entier (Par défaut : <code>2</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>dec_point</code></p>
|
||
<p>Le caractère à utiliser comme séparateur de décimal (Par défaut, une virgule).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>thousands_sep</code></p>
|
||
<p>Le caractère à utiliser comme séparateur de milliers (Par défaut, un espace).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>store_integer</code></p>
|
||
<p>Booléen permettant d'activer/désactiver le stockage de valeurs entières (Par défaut : <code>True</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>round_down</code></p>
|
||
<p>Booléen permettant d'arrondir à l'entier inférieur (et non à l'entier supérieur par défaut) en cas
|
||
de stockage de valeurs entières.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_wysiwyg"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_wysiwyg-lsattr_html_wysiwyg">LSattr_html_wysiwyg</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est du code HTML et dont l'édition
|
||
doit être fait à l'aide d'un éditeur <em>WYSIWYG</em>. La librairie <a href="https://www.tinymce.com">TinyMCE</a>
|
||
est utilisée pour cela.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_wysiwyg-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'html_options' => array(
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_wysiwyg-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'extra_options' => array (
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_wysiwyg-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> [Options à passer à TinyMCE]
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_wysiwyg-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_wysiwyg-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a>),
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_wysiwyg-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>extra_options</code></p>
|
||
<p>Ce paramètre permet de passer des options à <a href="https://www.tinymce.com">TinyMCE</a> pour personnaliser
|
||
son comportement. Par exemple, il est possible d'utiliser le paramètre <code>valid_styles</code> pour définir
|
||
quels styles CSS sont autorisés. Pour plus d'informations, consultez la documentation de
|
||
<a href="https://www.tinymce.com">TinyMCE</a> .</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_xmpp"><h1 id="conf-lsobject-lsattribute-lsattr_html-lsattr_html_xmpp-lsattr_html_xmpp">LSattr_html_xmpp</h1>
|
||
<p>Ce type est utilisé pour la gestion des attributs dont la valeur est une adresse XMPP. Il propose
|
||
directement dans l'interface, la possibilité de lancer une fenêtre de dialogue avec l'interlocuteur
|
||
de son client XMPP préféré.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Cette fonctionnalité n'est supporté uniquement par les navigateurs web supportant les URI de
|
||
type <code>xmpp://</code>.</p>
|
||
</div>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Ce type d'attribut HTML est dérivé du type <a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_text-lsattr_html_text">text</a>. Il
|
||
profite donc de toutes les fonctionnalités d'un champ de ce type (autogénération, ...).</p>
|
||
</div></section><h1 class="nav-section-title-end">Ended: Types d'attribut HTML (LSattr_html)</h1><h4 class="nav-section-title">Règles de vérification syntaxique (LSformRule)</h4><section class="print-page" id="conf-lsobject-lsattribute-check_data"><h1 id="conf-lsobject-lsattribute-check_data-configuration-des-regles-de-verification-syntaxique">Configuration des règles de vérification syntaxique</h1>
|
||
<p>Cette section décrit la manière de configuer des règles de vérification syntaxique sur les données
|
||
des attributs. Ces règles seront utilisées pour vérifier que les valeurs saisies par un utilisateur
|
||
dans un formulaire sont correctes.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-check_data-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'check_data' => array (
|
||
<a href="#conf-lsobject-lsattribute-check_data-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> '[regle1]' => array(
|
||
<a href="#conf-lsobject-lsattribute-check_data-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> 'msg' => "[Message d'erreur]",
|
||
<a href="#conf-lsobject-lsattribute-check_data-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> 'params' => array(
|
||
<a href="#conf-lsobject-lsattribute-check_data-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> // Paramètres de la règle
|
||
<a href="#conf-lsobject-lsattribute-check_data-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> )
|
||
<a href="#conf-lsobject-lsattribute-check_data-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-check_data-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> ...
|
||
<a href="#conf-lsobject-lsattribute-check_data-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a>),
|
||
<a href="#conf-lsobject-lsattribute-check_data-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a>...
|
||
</code></pre></div>
|
||
<p>Le paramètre <code>check_data</code> est un tableau associatif dont les clés sont les noms des règles de
|
||
vérification syntaxique actives et les valeurs associées sont des tableaux associatifs contenant les
|
||
paramètres des règles.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>msg</code></p>
|
||
<p>Le message d'erreur à afficher lors que la règle n'est pas respectée (optionnel).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>params</code></p>
|
||
<p>Tableau associatif contenant les paramètres de la règle. Les paramètres possibles sont propres à
|
||
chaque type de règle. Les clès sont les noms des paramètres et les valeurs associés, les valeurs
|
||
des paramètres.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-alphanumeric"><h1 id="conf-lsobject-lsattribute-check_data-alphanumeric-alphanumeric">alphanumeric</h1>
|
||
<p>Cette règle vérifie que la valeur est une chaîne de caractères composée uniquement de lettres
|
||
non-accuentées, en minuscule ou en majuscule et/ou de chiffres.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>withAccents</code></p>
|
||
<p>Si le paramètre est à <em>true</em>, les lettres accentuées seront acceptées.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-callable"><h1 id="conf-lsobject-lsattribute-check_data-callable-callable">callable</h1>
|
||
<p>Cette règle vérifie que la valeur saisie est correcte en utilisant une fonction personnalisée. Cette
|
||
fonction devra prendre en paramètres la valeur à valider, le tableau des paramètres de la règle
|
||
ainsi qu'un pointeur sur l'objet <em>LSformElement</em>. Sur la base de ses informations, elle devra
|
||
valider la valeur et retourner <code>True</code> si la valeur est valide et <code>False</code> sinon.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>callable</code></p>
|
||
<p>Le nom de la fonction (ou tout autre <code>callable</code> au sens PHP) de validation.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-date"><h1 id="conf-lsobject-lsattribute-check_data-date-date">date</h1>
|
||
<p>Cette règle vérifie que la valeur saisie est bien une date et qu'elle respecte un format précis.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>format</code></p>
|
||
<p>Format de la date à respecter. Ce format doit être compatible avec la fonction <code>strftime()</code> de
|
||
PHP. <a href="http://www.php.net/strftime">Voir la documentation de la fonction</a></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>special_values</code></p>
|
||
<p>Tableau listant les valeurs spéciales que peut prendre l'attribut. Dans ce tableau, seules les
|
||
valeurs sont utilisées et les clés n'ont pas d'importance. Ces valeurs spéciales n'auront pas
|
||
forcément besoin de respecter le format attendu.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-differentpassword"><h1 id="conf-lsobject-lsattribute-check_data-differentpassword-differentpassword">differentPassword</h1>
|
||
<p>Cette règle vérifie que la valeur saisie ne correspond pas à un des mots de passe stockés dans
|
||
d'autres attributs du même objet.</p>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Les autres attributs doivent utiliser le type d'attribut <em>LDAP</em>
|
||
<a href="#conf-lsobject-lsattribute-lsattr_ldap-lsattr_ldap_password-lsattr_ldap_password">LSattr_ldap_password</a>.</p>
|
||
</div>
|
||
<ul>
|
||
<li>
|
||
<p><code>otherPasswordAttributes</code></p>
|
||
<p>La liste des autres attributs dont les mots de passe doivent être différent.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-email"><h1 id="conf-lsobject-lsattribute-check_data-email-email">email</h1>
|
||
<p>Cette règle vérifie que la valeur saisie est bien une adresse e-mail. Il est possible de vérifier si
|
||
elle appartient bien à un domaine en particulier ou encore de vérifier si le domaine existe et qu'il
|
||
possède un serveur de mail(MX).</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>domain</code></p>
|
||
<p>Nom de domaine obligatoire. Ce paramètre peut être une simple chaine correspondant au domaine ou
|
||
un tableau listant plusieurs domaines possibles.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>checkDomain</code></p>
|
||
<p>Booléen définissant si le domaine de l'adresse mail doit être validée.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-filesize"><h1 id="conf-lsobject-lsattribute-check_data-filesize-filesize">filesize</h1>
|
||
<p>Cette règle vérifie que la valeur est un fichier dont la taille en octets respecte les limites
|
||
passées en paramètre.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>minSize</code></p>
|
||
<p>Taille minimum.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>maxSize</code></p>
|
||
<p>Taille maximum.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-imagefile"><h1 id="conf-lsobject-lsattribute-check_data-imagefile-imagefile">imagefile</h1>
|
||
<p>Cette règle vérifie que la valeur est bien un fichier et que le type mime de celui-ci est bien une
|
||
image. Cette règle utilise la règle mimetype en spécifiant si l'utilisateur ne le fait pas que le
|
||
type mime doit respecter la regex suivante : <code>/image\/.*/</code></p>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Cette règle est une simple interface à la règle mimetype, il est donc possible de passer
|
||
d'autres paramètres propres à ce type.</p>
|
||
</div></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-imagesize"><h1 id="conf-lsobject-lsattribute-check_data-imagesize-imagesize">imagesize</h1>
|
||
<p>Cette règle vérifie que la valeur est une image dont la taille en pixels respecte les limites
|
||
passées en paramètre.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>minWidth</code></p>
|
||
<p>Largeur minimum.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>maxWitdh</code></p>
|
||
<p>Largeur maximum.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>minHeight</code></p>
|
||
<p>Hauteur minimum.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>maxHeight</code></p>
|
||
<p>Hauteur maximum.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-inarray"><h1 id="conf-lsobject-lsattribute-check_data-inarray-inarray">inarray</h1>
|
||
<p>Cette règle vérifie que la valeur saisie fait partie d'une liste de valeurs autorisées
|
||
(ou interdites).</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>possible_values</code></p>
|
||
<p>Tableau listant les valeurs autorisées.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>reverse</code></p>
|
||
<p>Booléen permettant d'inverser la logique de validation : si <code>reverse</code> est vrai, la valeur testée
|
||
sera acceptée si elle ne fait pas partie des valeurs possibles (Paramètre facultatif, par défaut :
|
||
<code>False</code>).</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-integer"><h1 id="conf-lsobject-lsattribute-check_data-integer-integer">integer</h1>
|
||
<p>Cette règle vérifie que la valeur saisie est un entier. Les paramètres permettent de spécifier
|
||
éventuellement si la valeur doit être positive ou négative et également de borner les valeurs
|
||
valides.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>positive</code></p>
|
||
<p>Booléen définissant si la valeur doit être positive.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>negative</code></p>
|
||
<p>Booléen définissant si la valeur doit être negative.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>min</code></p>
|
||
<p>Valeur minimale (supérieur ou égale).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>max</code></p>
|
||
<p>Valeur maximale (inférieur ou égale).</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-ldapsearchuri"><h1 id="conf-lsobject-lsattribute-check_data-ldapsearchuri-ldapsearchuri">ldapSearchURI</h1>
|
||
<p>Cette règle vérifie que la valeur est une URI de recherche LDAP valide, c'est à dire, par exemple,
|
||
<code>ldaps://ldap.example.com:636/o=example?attr1,attr2?one?(gidNumber=100)</code></p>
|
||
<p>Cette vérification commence par découper la valeur à l'aide du sépérateur <code>?</code> et elle s'assure
|
||
ensuite :</p>
|
||
<ul>
|
||
<li>Que la première partie est bien une URI LDAP valide. Si l'hôte LDAP est spécifié, elle s'assure
|
||
qu'il soit une adresse IP ou un nom de domaine valide. Si le port LDAP est spécifié, elle s'assure
|
||
également qu'il soit correct et que l'hôte est également bien spécifié.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Si la base de recherche est spécifiée, elle s'assure qu'elle soit compatible avec la racine de
|
||
l'annuaire connecté.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Si un ou plusieurs attributs sont spécifiés, elle les vérifie un à un afin de vérifier qu'il
|
||
s'agit de nom d'attribut valide.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Que le scope de recherche soit bien spécifié et valide.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Si le filtre de recherche est spécifié, elle vérifie qu'il soit valide.</li>
|
||
</ul>
|
||
<p><strong>Paramêtres de configuration :</strong></p>
|
||
<ul>
|
||
<li>
|
||
<p><code>check_resolving_ldap_host</code></p>
|
||
<p>Si l'hôte du serveur LDAP est spécifié et qu'il s'agit d'un nom de domaine valide, un tentative de
|
||
résolution DNS sera également faite (optionnel, par défaut : <code>True</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>host_required</code></p>
|
||
<p>Booléen détermintant si une erreur est relevée en cas d'absence de l'hôte LDAP. (optionnel,
|
||
par défaut : <code>False</code>)</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>basedn_required</code></p>
|
||
<p>Booléen détermintant si une erreur est relevée en cas d'absence de base de recherche. (optionnel,
|
||
par défaut : <code>False</code>)</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>scope_required</code></p>
|
||
<p>Booléen détermintant si une erreur est relevée en cas d'absence de portée de recherche.
|
||
(optionnel, par défaut : <code>True</code>)</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>attr_required</code></p>
|
||
<p>Booléen détermintant si une erreur est relevée en cas d'absence d'attribut recherché. (optionnel,
|
||
par défaut : <code>False</code>)</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>max_attrs_count</code></p>
|
||
<p>Nombre maximum d'attribut recherchés. (optionnel, par défaut : pas de limite)</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>filter_required</code></p>
|
||
<p>Booléen détermintant si une erreur est relevée en cas d'absence de filtre de recherche.
|
||
(optionnel, par défaut : <code>False</code>)</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-lettersonly"><h1 id="conf-lsobject-lsattribute-check_data-lettersonly-lettersonly">lettersonly</h1>
|
||
<p>Cette règle vérifie que la valeur est une chaîne de caractères composée uniquement de lettres
|
||
non-accuentées, en minuscule ou en majuscule.</p></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-maxlength"><h1 id="conf-lsobject-lsattribute-check_data-maxlength-maxlength">maxlength</h1>
|
||
<p>Cette règle vérifie que la valeur saisie est une chaine de caractères dont la longueur est inférieur
|
||
ou égale à la valeur passées en paramètre.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>limit</code></p>
|
||
<p>Limite supérieur (ou égale) de la longueur de la chaîne de caratères.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-mimetype"><h1 id="conf-lsobject-lsattribute-check_data-mimetype-mimetype">mimetype</h1>
|
||
<p>Cette règle vérifie que la valeur est bien un fichier et que le type mime de celui-ci est correct.
|
||
Il est possible de vérifier si le type mime fait partie d'une liste ou encore s'il valide une
|
||
expression régulière.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>mimeType</code></p>
|
||
<p>Type mime obligatoire. Ce paramètre peut être une simple chaine correspondant au type mime ou un
|
||
tableau listant plusieurs possibilités.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>mimeTypeRegEx</code></p>
|
||
<p>Expression régulière que doit respecter le type mime.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-minlength"><h1 id="conf-lsobject-lsattribute-check_data-minlength-minlength">minlength</h1>
|
||
<p>Cette règle vérifie que la valeur saisie est une chaine de caractères dont la longueur est supérieur
|
||
ou égale à la valeur passée en paramètre.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>limit</code></p>
|
||
<p>Limite inférieure (ou égale) de la longueur de la chaîne de caratères.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-nonzero"><h1 id="conf-lsobject-lsattribute-check_data-nonzero-nonzero">nonzero</h1>
|
||
<p>Cette régle vérifie que la valeur est une valeur numérique non nulle.</p></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-nopunctuation"><h1 id="conf-lsobject-lsattribute-check_data-nopunctuation-nopunctuation">nopunctuation</h1>
|
||
<p>Cette régle vérifie que la valeur est une chaîne de caractères ne contenant pas de signe de
|
||
ponctuation. Les caractères suivants sont actuellement exclus :
|
||
<code>( ) . \ / \ * \ ^ \ ? # ! @ $ % + = , " ' > < ~ [ ] { }</code></p></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-numberofvalues"><h1 id="conf-lsobject-lsattribute-check_data-numberofvalues-numberofvalues">numberOfValues</h1>
|
||
<p>Cette règle vérifie que le nombre de valeurs de l'attribut est comprise entre les limites passées en
|
||
paramètre.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>min</code></p>
|
||
<p>Nombre minimum de valeurs (paramètre optionnel).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>max</code></p>
|
||
<p>Nombre maximum de valeurs (paramètre optionnel).</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-numeric"><h1 id="conf-lsobject-lsattribute-check_data-numeric-numeric">numeric</h1>
|
||
<p>Cette régle vérifie que la valeur est une valeur numérique.</p></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-password"><h1 id="conf-lsobject-lsattribute-check_data-password-password">password</h1>
|
||
<p>Cette règle vérifie que la valeur est un mot de passe respectant la politique de sécurité définie
|
||
par les paramètres de la règle.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>minlength</code></p>
|
||
<p>Longueur minimale du mot de passe.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>maxlength</code></p>
|
||
<p>Longueur maximale du mot de passe.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>prohibitedValues</code></p>
|
||
<p>Tableau de valeurs interdites.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>regex</code></p>
|
||
<p>Expression(s) régulière(s) que doit respecter le mot de passe. Ce paramètre peut être une
|
||
expression régulière au format <a href="http://php.net/pcre.pattern">PCRE</a> ou un tableau d'expressions
|
||
régulières.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>minValidRegex</code></p>
|
||
<p>Le nombre minimum d'expression régulière qui doivent être validées pour que le mot de passe soit
|
||
considéré comme correct. Ce paramètre est optionnel, par défaut, toutes les expressions régulières
|
||
doivent être validées.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-rangelength"><h1 id="conf-lsobject-lsattribute-check_data-rangelength-rangelength">rangelength</h1>
|
||
<p>Cette règle vérifie que la valeur saisie est une chaine de caractères dont la longueur est comprise
|
||
entre deux valeurs passées en paramètre.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>limits</code></p>
|
||
<p>Tableau contenant deux valeurs, la première étant la limite inférieure ou égale et la seconde la
|
||
limite supérieure ou égale.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-regex"><h1 id="conf-lsobject-lsattribute-check_data-regex-regex">regex</h1>
|
||
<p>Cette règle vérifie que la valeur saisie respecte bien l'expression régulière passée en paramètre.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>regex</code></p>
|
||
<p>L'expression régulière devant être respectée. Cette expression régulière doit être au format
|
||
<a href="http://php.net/pcre.pattern">PCRE</a>.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-required"><h1 id="conf-lsobject-lsattribute-check_data-required-required">required</h1>
|
||
<p>Cette régle vérifie que la valeur n'est pas une chaîne de caractères de longueur nulle.</p></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-ssh_pub_key"><h1 id="conf-lsobject-lsattribute-check_data-ssh_pub_key-ssh_pub_key">ssh_pub_key</h1>
|
||
<p>Cette règle vérifie que la valeur est une clé publique SSH.</p>
|
||
<p>Cette vérification utilise tout d'abord une expression régulière pour valider la forme syntaxique de
|
||
la clé publique (<code>ssh-[type] [clé au format base64] [commentaire]</code>) puis tente de décoder la partie
|
||
en base64 de la clé pour vérifier qu'il s'agit bien d'une chaine de caractères.</p></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-telephonenumber"><h1 id="conf-lsobject-lsattribute-check_data-telephonenumber-telephonenumber">telephonenumber</h1>
|
||
<p>Cette régle vérifie que la valeur est un numéro de téléphone français. Celui-ci doit respecter
|
||
l'expression regulière suivante : <code>/^(01|02|03|04|05|06|08|09)[0-9]{8}$/</code></p></section><section class="print-page" id="conf-lsobject-lsattribute-check_data-zxcvbn"><h1 id="conf-lsobject-lsattribute-check_data-zxcvbn-zxcvbn">zxcvbn</h1>
|
||
<p>Cette règle vérifie la sécurité d'un mot de passe en utilisant la librairie
|
||
<a href="https://github.com/bjeavons/zxcvbn-php">ZxcvbnPhp</a>. Cette librairie s'appuie sur un ensemble de
|
||
vérifications permettant de déterminer à quel point le mot de passe choisi est commun, prévisible
|
||
et plus globalement, estime en combien de temps il pourra être cassé par une personne malveillante.
|
||
Sur la base de l'analyse du mot de passe saisi, des conseils seront donnés à l'utilisateur pour le
|
||
guider dans le choix d'un mot de passe sûre.</p>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">Warning</p>
|
||
<p>La librairie <code>ZxcvbnPhp</code> n'est compatible qu'avec PHP 7 et supérieur.</p>
|
||
</div>
|
||
<ul>
|
||
<li>
|
||
<p><code>minScore</code></p>
|
||
<p>Le score minimal pour que le mot de passe soit accepté. Il doit s'agir d'un entier cimpris entre 0
|
||
(le plus faible) et 4 (le plus sécurisé). Paramètre facultatif valant 4 par défaut.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>userDataAttrs</code></p>
|
||
<p>Liste d'attributs de l'objet dont les valeurs seront passées à la librairie <code>Zxcvbn</code> qui les
|
||
considérera comme associés à l'utilisateur. Ainsi, par exemple, si l'utilisateur utilise son nom
|
||
de famille ou encore son prénom dans son mot de passe, la librairie pourra lui indiqué que cela ne
|
||
le protège que peut des attaques ciblées. Paramètre facultatif, mais il est fortement conseillé de
|
||
renseigner un maximum d'attributs contenant des informations personnelles relatives à l'utilisteur.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>showWarning</code></p>
|
||
<p>Booléen définissant si les messages d'alertes retournés par la librairie <code>Zxcvbn</code> doivent être
|
||
affichés à l'utilisateur. Paramètre facultatif et vrai par défaut.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>showSuggestions</code></p>
|
||
<p>Booléen définissant si les messages de suggestions retournés par la librairie <code>Zxcvbn</code> doivent
|
||
être affichés à l'utilisateur. Paramètre facultatif et vrai par défaut.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>zxcvbn_autoload_path</code></p>
|
||
<p>Le chemin vers le fichier de chargement automatique des classes de la librairie <em>ZxcvbnPhp</em>. Ce
|
||
paramètre est facultatif et vaut par défaut <code>Zxcvbn/autoload.php</code>, ce qui est adapté si vous
|
||
utiliser le paquet Debian <code>php-zxcvbn</code> disponible sur le dépôt Debian du projet LdapSaisie.</p>
|
||
</li>
|
||
</ul></section><h1 class="nav-section-title-end">Ended: Règles de vérification syntaxique (LSformRule)</h1><section class="print-page" id="conf-lsobject-lsattribute-validation"><h1 id="conf-lsobject-lsattribute-validation-configuration-des-regles-de-verification-dintegrite">Configuration des règles de vérification d'intégrité</h1>
|
||
<p>Cette section décrit la manière de configurer des règles de vérification d'intégrité sur les données
|
||
des attributs. Il est possible de valider la valeur de l'attribut par l'intermédiraire de la
|
||
vérification de résultat d'une recherche paramètrable dans l'annuaire ou encore d'appeler une
|
||
fonction de votre choix pour effectuer la vérification voulue.</p>
|
||
<h2 id="conf-lsobject-lsattribute-validation-validation-par-lanalyse-du-resultat-dune-recherche-dans-lannuaire">Validation par l'analyse du résultat d'une recherche dans l'annuaire</h2>
|
||
<p>Une telle règle permet de vérifier si les valeurs des attributs n'entrent pas en conflit avec
|
||
d'autres objets de l'annuaire. Ce test peut également permetre de vérifier si les valeurs devant
|
||
faire référence à d'autres objets de l'annuaire sont correctes.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-validation-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>'validation' => array (
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> ...
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> array(
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> 'msg' => "[LSformat du message d'erreur]",
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> 'filter' => '[LSformat du filtre de la recherche]',
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> 'object_type' => '[Type d'LSobject recherché]',
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> 'basedn' => '[BaseDn de la recherche]',
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> 'scope' => '[Scope de la recherche]',
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> 'result' => '[Résultat positif de la recherche]',
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> 'except_current_object' => '[Exclure l'objet courant]'
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> ...
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a>),
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>msg</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> du message d'erreur à afficher lorsque la
|
||
validation échoue. Ce format est construit avec les valeurs du
|
||
<a href="#conf-lsobject-configuration-lsobject">LSobject</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>filter</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> du filtre de la recherche. Ce format peut
|
||
être construit avec toutes les valeurs du LSobject (attributs, DN, ...) et également avec la
|
||
valeur à valider en utilisant pour mot clé <code>%{val}</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>object_type</code></p>
|
||
<p>Le nom du type d'LSobject recherché. Si un type est spécifié, le filtre de la recherche sera une
|
||
combinaison de celui du paramètre <code>filter</code> et du filtre composé à partir des <em>objectClass</em> du type
|
||
d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a>. <em>Paramètre facultatif.</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>basedn</code></p>
|
||
<p>Le <em>basedn</em> de la recherche <em>(Paramètre facultatif, par défaut : racine de l'annuaire)</em>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>scope</code></p>
|
||
<p>Le <em>scope</em> de la recherche <em>(Paramètre facultatif, par défaut : <code>sub</code>)</em>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>result</code></p>
|
||
<p>Le résultat de la recherche : si <code>result</code> vaut zéro, la recherche ne devra retourner aucun objet
|
||
pour que la validation soit réussie. Sinon, la recherche devra retourner au moins un objet.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>except_current_object</code></p>
|
||
<p>Booléen définissant si l'objet courrant doit être exclu du résultat de la recherche. Ce paramètre
|
||
n'est évalué quand cas de création (formulaire <code>create</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<h2 id="conf-lsobject-lsattribute-validation-validation-par-lexecution-dune-fonction">Validation par l'exécution d'une fonction</h2>
|
||
<p>Il est possible d'effectuer la validation de l'attribut par l'exécution d'une fonction de votre
|
||
choix. Il lui sera passé en paramètre une référence à l'objet <code>LSldapObject</code> courant. Si la fonction
|
||
ne retourne pas <em>true</em>, la validation échouera.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-validation-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a>'validation' => array (
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a> ..
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a> array(
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a> 'msg' => "[LSformat du message d'erreur]",
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a> 'function' => '[Nom de la fonction de validation]'
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a> ),
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a> ...
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-1-8" id="__codelineno-1-8" name="__codelineno-1-8"></a>),
|
||
<a href="#conf-lsobject-lsattribute-validation-__codelineno-1-9" id="__codelineno-1-9" name="__codelineno-1-9"></a>...
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>msg</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> du message d'erreur à afficher lorsque la
|
||
validation échoue. Ce format est construit avec les valeurs du
|
||
<a href="#conf-lsobject-configuration-lsobject">LSobject</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>function</code></p>
|
||
<p>Le nom de la fonction à exécuter. Si cette fonction n'existe pas, un message d'erreur sera affiché
|
||
et la validation échouera.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsattribute-triggers"><h1 id="conf-lsobject-lsattribute-triggers-declencheurs">Déclencheurs</h1>
|
||
<p>Cette section décrit la manière de paramétrer des déclencheurs afin que LdapSaisie exécute durant
|
||
ses processus, et à des moments bien précis des traitements d'un
|
||
<a href="#conf-lsobject-lsattribute-configuration-des-attributs">LSattributes</a>, des fonctions que vous pourrez développer vous
|
||
même. De plus, le résultat de l'exécution de vos fonctions pourra influer sur le déroulement des
|
||
processus.</p>
|
||
<p>Actuellement, les évènements suivant sont gérés :</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Nom</th>
|
||
<th>Description</th>
|
||
<th>Bloquant</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>before_create</code></td>
|
||
<td>Avant la création du LSobject, lorsque l'attribut a au moins une valeur.</td>
|
||
<td>Oui</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>after_create</code></td>
|
||
<td>Après la création du LSobject, lorsque l'attribut a au moins une valeur.</td>
|
||
<td>Non</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>before_modify</code></td>
|
||
<td>Avant la modification de la valeur de l'attribut.</td>
|
||
<td>Oui</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>after_modify</code></td>
|
||
<td>Après la modification de la valeur de l'attribut.</td>
|
||
<td>Non</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>before_delete</code></td>
|
||
<td>Avant la suppression du LSobject contenant l'attribut.</td>
|
||
<td>Oui</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>after_delete</code></td>
|
||
<td>Après la suppression du LSobject contenant l'attribut.</td>
|
||
<td>Non</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Si un événement est dit <em>bloquant</em>, lors de l'exécution des actions liées, si une des fonctions
|
||
retourne <code>false</code>, le processus s'arrêtera.</p>
|
||
</div>
|
||
<h2 id="conf-lsobject-lsattribute-triggers-configuration">Configuration</h2>
|
||
<p>La configuration des déclencheurs se fait dans la définition des
|
||
<a href="#conf-lsobject-lsattribute-configuration-des-attributs">LSattributes</a>. Par exemple, pour définir les fonctions à
|
||
exécuter après la modification de la valeur de l'attribut <em>mail</em> du type de
|
||
<a href="#conf-lsobject-configuration-lsobject">LSobject</a> <em>LSpeople</em>, c'est à dire lors de leur évenement
|
||
<code>after_modify</code>, il faut définir la variable suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-triggers-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>$GLOBALS['LSobjects']['LSpeople']['attrs']['mail']['after_modify']
|
||
</code></pre></div>
|
||
<p>Cette variable peut contenir soit une chaine de caractères correspondant au nom de la fonction à
|
||
exécuter, soit un tableau de chaînes de caractères correspondant aux noms des fonctions à exécuter.</p>
|
||
<h2 id="conf-lsobject-lsattribute-triggers-ecriture-dune-fonction">Écriture d'une fonction</h2>
|
||
<p>Une fonction exécuté par un déclencheur d'un LSattribute se déclare de la manière suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsattribute-triggers-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a><span class="x">/*</span>
|
||
<a href="#conf-lsobject-lsattribute-triggers-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a><span class="x"> * Ma fonction à exécuter lors de l'évènement [event]</span>
|
||
<a href="#conf-lsobject-lsattribute-triggers-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a><span class="x"> *</span>
|
||
<a href="#conf-lsobject-lsattribute-triggers-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a><span class="x"> * Paramètre :</span>
|
||
<a href="#conf-lsobject-lsattribute-triggers-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a><span class="x"> * - $object : Le LSobject contenant le LSattribute sur lequel l'évenement</span>
|
||
<a href="#conf-lsobject-lsattribute-triggers-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a><span class="x"> * survient</span>
|
||
<a href="#conf-lsobject-lsattribute-triggers-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a><span class="x"> *</span>
|
||
<a href="#conf-lsobject-lsattribute-triggers-__codelineno-1-8" id="__codelineno-1-8" name="__codelineno-1-8"></a><span class="x"> * Valeurs retournées :</span>
|
||
<a href="#conf-lsobject-lsattribute-triggers-__codelineno-1-9" id="__codelineno-1-9" name="__codelineno-1-9"></a><span class="x"> * - True : Tout s'est bien passé</span>
|
||
<a href="#conf-lsobject-lsattribute-triggers-__codelineno-1-10" id="__codelineno-1-10" name="__codelineno-1-10"></a><span class="x"> * - False : Une erreur est survenue ou la fonction souhaite bloquer le</span>
|
||
<a href="#conf-lsobject-lsattribute-triggers-__codelineno-1-11" id="__codelineno-1-11" name="__codelineno-1-11"></a><span class="x"> * processus lors d'un évènement bloquant.</span>
|
||
<a href="#conf-lsobject-lsattribute-triggers-__codelineno-1-12" id="__codelineno-1-12" name="__codelineno-1-12"></a><span class="x"> */</span>
|
||
<a href="#conf-lsobject-lsattribute-triggers-__codelineno-1-13" id="__codelineno-1-13" name="__codelineno-1-13"></a><span class="x">function maFonction ($object) {</span>
|
||
<a href="#conf-lsobject-lsattribute-triggers-__codelineno-1-14" id="__codelineno-1-14" name="__codelineno-1-14"></a>
|
||
<a href="#conf-lsobject-lsattribute-triggers-__codelineno-1-15" id="__codelineno-1-15" name="__codelineno-1-15"></a><span class="x"> // Actions</span>
|
||
<a href="#conf-lsobject-lsattribute-triggers-__codelineno-1-16" id="__codelineno-1-16" name="__codelineno-1-16"></a>
|
||
<a href="#conf-lsobject-lsattribute-triggers-__codelineno-1-17" id="__codelineno-1-17" name="__codelineno-1-17"></a><span class="x">}</span>
|
||
</code></pre></div>
|
||
<p>Cette fonction doit prendre pour seul paramètre, le LSobject contenant le LSattribute sur lequel
|
||
l'évenement survient et doit retourner soit <code>True</code> si tout s'est bien passé, soit <code>False</code> en cas de
|
||
problème. Dans le cas d'un événement bloquant, si la fonction retourne <code>False</code>, le processus est
|
||
arrêté.</p></section><h1 class="nav-section-title-end">Ended: Attributs</h1><section class="print-page" id="conf-lsobject-container_auto_create"><h1 id="conf-lsobject-container_auto_create-creation-automatique-du-conteneur-des-lsobjets-dans-un-subdn">Création automatique du conteneur des LSobjets dans un subDn</h1>
|
||
<p>Cette section décrit la manière de configurer la création automatique des conteneurs des LSobjets.
|
||
Si le <em>basedn</em> correspondant à la branche de stockage des <a href="#conf-lsobject-configuration-lsobject">LSobjects</a>
|
||
n'existe pas, LdapSaisie tentera de le créer à partir de la configuration de la variable
|
||
<code>$GLOBALS['LSobjects']['[nom du type d'LSobject]']['container_auto_create']</code>.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-container_auto_create-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>$GLOBALS['LSobjects']['[nom du type d'LSobject]']['container_auto_create'] = array (
|
||
<a href="#conf-lsobject-container_auto_create-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'objectclass' => array(
|
||
<a href="#conf-lsobject-container_auto_create-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> 'objectclass1',
|
||
<a href="#conf-lsobject-container_auto_create-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> 'objectclass2',
|
||
<a href="#conf-lsobject-container_auto_create-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> ...
|
||
<a href="#conf-lsobject-container_auto_create-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> ),
|
||
<a href="#conf-lsobject-container_auto_create-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> 'attrs' => array(
|
||
<a href="#conf-lsobject-container_auto_create-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> 'attr1' => 'val1',
|
||
<a href="#conf-lsobject-container_auto_create-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> 'attr2' => array(
|
||
<a href="#conf-lsobject-container_auto_create-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> 'val2',
|
||
<a href="#conf-lsobject-container_auto_create-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> 'val3',
|
||
<a href="#conf-lsobject-container_auto_create-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> ...
|
||
<a href="#conf-lsobject-container_auto_create-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> ),
|
||
<a href="#conf-lsobject-container_auto_create-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a> ...
|
||
<a href="#conf-lsobject-container_auto_create-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a> )
|
||
<a href="#conf-lsobject-container_auto_create-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a>);
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>objectclass</code></p>
|
||
<p>La liste des <em>objectclass</em> de l'objet conteneur.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>attrs</code></p>
|
||
<p>Un tableau associatif dont les clés sont les noms des attributs de l'objet conteneur à définir et
|
||
dont les valeurs associées sont la/les valeur(s) de ces attributs.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-triggers"><h1 id="conf-lsobject-triggers-declencheurs">Déclencheurs</h1>
|
||
<p>Cette section décrit la manière de paramétrer des déclencheurs afin que LdapSaisie exécute durant
|
||
ses processus, et à des moments bien précis des traitements d'un
|
||
<a href="#conf-lsobject-configuration-lsobject">LSobject</a>, des fonctions que vous pourrez développer vous même. De
|
||
plus, le résultat de l'exécution de vos fonctions pourra influer sur le déroulement des processus.</p>
|
||
<p>Actuellement, les évenements suivant sont gérés :</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Nom</th>
|
||
<th>Description</th>
|
||
<th>Bloquant</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>before_create</code></td>
|
||
<td>Avant la création du LSobject.</td>
|
||
<td>Oui</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>after_create</code></td>
|
||
<td>Après la création du LSobject.</td>
|
||
<td>Non</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>before_modify</code></td>
|
||
<td>Avant la modification du LSobject</td>
|
||
<td>Oui</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>after_modify</code></td>
|
||
<td>Après la modification du LSobject</td>
|
||
<td>Non</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>before_rename</code></td>
|
||
<td>Avant de renommer le LSobject</td>
|
||
<td>Oui</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>after_rename</code></td>
|
||
<td>Après avoir renommé le LSobject</td>
|
||
<td>Non</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>before_delete</code></td>
|
||
<td>Avant la suppression du LSobject</td>
|
||
<td>Oui</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>after_delete</code></td>
|
||
<td>Après la suppression du LSobject</td>
|
||
<td>Non</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Si un événement est dit <em>bloquant</em>, lors de l'exécution des actions liées, si une des fonctions
|
||
retourne <code>false</code>, le processus s'arrêtera.</p>
|
||
</div>
|
||
<h2 id="conf-lsobject-triggers-configuration">Configuration</h2>
|
||
<p>La configuration des déclencheurs se fait dans la définition des types
|
||
d'<a href="#conf-lsobject-configuration-lsobject">LSobjects</a>. Par exemple, pour définir les fonctions à exécuter
|
||
après la modification des LSobjects de type <em>LSpeople</em>, c'est à dire lors de leur évènement
|
||
<code>after_modify</code>, il faut définir la variable suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-triggers-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="x">$GLOBALS['LSobjects']['[nom du type d'LSobject]']['after_modify']</span>
|
||
</code></pre></div>
|
||
<p>Cette variable peut contenir soit une chaine de caractères correspondant au nom de la fonction à
|
||
exécuter, soit un tableau de chaînes de caractères correspondant aux noms des fonctions à exécuter.</p>
|
||
<h2 id="conf-lsobject-triggers-ecriture-dune-fonction">Écriture d'une fonction</h2>
|
||
<p>Une fonction exécuté par un déclencheur d'un LSobject se déclare de la manière suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-triggers-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a><span class="x">/*</span>
|
||
<a href="#conf-lsobject-triggers-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a><span class="x"> * Ma fonction à exécuter lors de l'evenement [event]</span>
|
||
<a href="#conf-lsobject-triggers-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a><span class="x"> *</span>
|
||
<a href="#conf-lsobject-triggers-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a><span class="x"> * Paramètre :</span>
|
||
<a href="#conf-lsobject-triggers-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a><span class="x"> * - $object : Le LSobject sur lequel l'évènement survient</span>
|
||
<a href="#conf-lsobject-triggers-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a><span class="x"> *</span>
|
||
<a href="#conf-lsobject-triggers-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a><span class="x"> * Valeurs retournées :</span>
|
||
<a href="#conf-lsobject-triggers-__codelineno-1-8" id="__codelineno-1-8" name="__codelineno-1-8"></a><span class="x"> * - True : Tout s'est bien passé</span>
|
||
<a href="#conf-lsobject-triggers-__codelineno-1-9" id="__codelineno-1-9" name="__codelineno-1-9"></a><span class="x"> * - False : Une erreur est survenue ou la fonction souhaite bloquer le</span>
|
||
<a href="#conf-lsobject-triggers-__codelineno-1-10" id="__codelineno-1-10" name="__codelineno-1-10"></a><span class="x"> * processus lors d'un évènement bloquant.</span>
|
||
<a href="#conf-lsobject-triggers-__codelineno-1-11" id="__codelineno-1-11" name="__codelineno-1-11"></a><span class="x"> */</span>
|
||
<a href="#conf-lsobject-triggers-__codelineno-1-12" id="__codelineno-1-12" name="__codelineno-1-12"></a><span class="x">function maFonction ($object) {</span>
|
||
<a href="#conf-lsobject-triggers-__codelineno-1-13" id="__codelineno-1-13" name="__codelineno-1-13"></a>
|
||
<a href="#conf-lsobject-triggers-__codelineno-1-14" id="__codelineno-1-14" name="__codelineno-1-14"></a><span class="x"> // Actions</span>
|
||
<a href="#conf-lsobject-triggers-__codelineno-1-15" id="__codelineno-1-15" name="__codelineno-1-15"></a>
|
||
<a href="#conf-lsobject-triggers-__codelineno-1-16" id="__codelineno-1-16" name="__codelineno-1-16"></a><span class="x">}</span>
|
||
</code></pre></div>
|
||
<p>Cette fonction doit prendre pour seul paramètre, le LSobject sur lequel l'évènement survient et doit
|
||
retourner soit <code>True</code> si tout s'est bien passé, soit <code>False</code> en cas de problème. Dans le cas d'un
|
||
événement bloquant, si la fonction retourne <code>False</code>, le processus est arrêté.</p></section><section class="print-page" id="conf-lsobject-customactions"><h1 id="conf-lsobject-customactions-actions-personnalisees-customactions">Actions personnalisées (customActions)</h1>
|
||
<p>Cette section décrit la manière de configurer les actions personnalisées exécutables sur les
|
||
<a href="#conf-lsobject-configuration-lsobject">LSobjects</a> appelées <em>customActions</em>.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-customactions-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>$GLOBALS['LSobjects']['[nom du type d'LSobject]']['customActions'] = array (
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'action1' => array(
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> 'label' => '[label l'action]',
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> 'hideLabel' => '[booléen]',
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> 'helpInfo' => '[label d'aide]',
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> 'icon' => '[nom de l'icône de l'action]',
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> 'function' => '[fonction à exécuter]',
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> 'question_format' => '[LSformat de la question de confirmation]',
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> 'onSuccessMsgFormat' => '[LSformat du message à afficher en cas de succès de l'action]',
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> 'disableOnSuccessMsg' => '[booléen]',
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> 'noConfirmation' => '[booléen]',
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> 'redirectToObjectList' => '[booléen]',
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> 'noRedirect' => '[booléen]',
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a> 'rights' => array(
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a> 'LSprofile1',
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a> 'LSprofile2',
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a> ...
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a> )
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a> )
|
||
<a href="#conf-lsobject-customactions-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a>);
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>label</code></p>
|
||
<p>Le label de l'action.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>hideLabel</code></p>
|
||
<p>Cache le label dans le bouton de l'action.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>helpInfo</code></p>
|
||
<p>Le label du message d'aide qui sera affiché au survole du bouton de l'action.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>icon</code></p>
|
||
<p>Nom de l'îcone à afficher dans le bouton de l'action. Ce nom correspond au nom du fichier de
|
||
l'image (sans l'extention) qui devra se trouver dans le dossier
|
||
<code>src/images/[nom du theme d'images]/</code> ou dans le dossier <code>src/local/images</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>function</code></p>
|
||
<p>Le nom de la fonction à exécuter qui implémente l'action personnalisée Cette fonction prendra en
|
||
seule paramètre le <a href="#conf-lsobject-configuration-lsobject">LSobject</a> sur lequel l'action devra être
|
||
exécutée et retournera <code>True</code> en cas de succès ou <code>False</code> en cas d'échec d'exécution de la fonction.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>question_format</code></p>
|
||
<p>Le <a href="#conf-global-lsformat-format-parametrable">LSformat</a> de la question de confirmation
|
||
d'exécution de l'action. Ce <a href="#conf-global-lsformat-format-parametrable">LSformat</a> sera composé à
|
||
l'aide du nom de l'objet.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>onSuccessMsgFormat</code></p>
|
||
<p>Le <a href="#conf-global-lsformat-format-parametrable">LSformat</a> du message à afficher en cas de succès
|
||
d'exécution de l'action. Ce <a href="#conf-global-lsformat-format-parametrable">LSformat</a> sera composé à
|
||
l'aide du nom de l'objet.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>disableOnSuccessMsg</code></p>
|
||
<p>Booléen permetant de désactiver le message afficher en cas de succès d'exécution de l'action.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>noConfirmation</code></p>
|
||
<p>Booléen permetant de désactiver la confirmation de l'exécution de l'action.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>redirectToObjectList</code></p>
|
||
<p>Booléen permetant de rediriger l'utilisateur vers la liste des objets plutôt que sur la fiche de
|
||
l'objet après l'execution de l'action.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>noRedirect</code></p>
|
||
<p>Booléen permetant de désactiver la redirection de l'utilisateur après l'execution de l'action.
|
||
Cela permet à la fonction de définir son propre fichier de template de retour et donc d'afficher
|
||
une page personnalisable.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>rights</code></p>
|
||
<p>Tableau contenant la liste des noms des
|
||
<a href="#conf-global-ldap-lsprofile-profils-dutilisateurs">LSprofiles</a> ayant le droit d'exécuter cette
|
||
action.</p>
|
||
</li>
|
||
</ul>
|
||
<h2 id="conf-lsobject-customactions-ecriture-dune-fonction-implementant-une-customaction">Écriture d'une fonction implémentant une customAction</h2>
|
||
<p>Une fonction implémentant une <em>customAction</em> se déclare de la manière suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-customactions-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a>/*
|
||
<a href="#conf-lsobject-customactions-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a> * Ma fonction implémentant ma customAction
|
||
<a href="#conf-lsobject-customactions-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a> *
|
||
<a href="#conf-lsobject-customactions-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a> * Paramètre :
|
||
<a href="#conf-lsobject-customactions-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a> * - $object : Le LSobject sur lequel mon action doit être exécutée
|
||
<a href="#conf-lsobject-customactions-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a> *
|
||
<a href="#conf-lsobject-customactions-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a> * Valeurs retournées :
|
||
<a href="#conf-lsobject-customactions-__codelineno-1-8" id="__codelineno-1-8" name="__codelineno-1-8"></a> * - True : Tout s'est bien passé
|
||
<a href="#conf-lsobject-customactions-__codelineno-1-9" id="__codelineno-1-9" name="__codelineno-1-9"></a> * - False : Une erreur est survenue
|
||
<a href="#conf-lsobject-customactions-__codelineno-1-10" id="__codelineno-1-10" name="__codelineno-1-10"></a> */
|
||
<a href="#conf-lsobject-customactions-__codelineno-1-11" id="__codelineno-1-11" name="__codelineno-1-11"></a>function maFonction ($object) {
|
||
<a href="#conf-lsobject-customactions-__codelineno-1-12" id="__codelineno-1-12" name="__codelineno-1-12"></a>
|
||
<a href="#conf-lsobject-customactions-__codelineno-1-13" id="__codelineno-1-13" name="__codelineno-1-13"></a> // Actions
|
||
<a href="#conf-lsobject-customactions-__codelineno-1-14" id="__codelineno-1-14" name="__codelineno-1-14"></a>
|
||
<a href="#conf-lsobject-customactions-__codelineno-1-15" id="__codelineno-1-15" name="__codelineno-1-15"></a>}
|
||
</code></pre></div>
|
||
<p>Cette fonction doit prendre pour seul paramètre, le <a href="#conf-lsobject-configuration-lsobject">LSobject</a> sur
|
||
lequel l'action personnalisée doit être exécutée et doit retourner soit <code>True</code> si tout s'est bien
|
||
passé, soit <code>False</code> en cas de problème.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Ces fonctions sont le plus couramment définies au sein d'
|
||
<a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a>.</p>
|
||
</div></section><section class="print-page" id="conf-lsobject-lsrelation"><h1 id="conf-lsobject-lsrelation-les-relations-entre-les-objets-de-lannuire-lsrelation">Les relations entre les objets de l'annuire (LSrelation)</h1>
|
||
<p>Cette section décrit la manière de configurer les relations entre les
|
||
<a href="#conf-lsobject-configuration-lsobject">LSobjects</a> appelées <em>LSrelation</em>.</p>
|
||
<p>Dans le cadre d'une liaison dîte <em>simple</em>, c'est à dire une liaison au travers la valeur d'un
|
||
attribut qui fera directement référence à un autre objet (<em>DN</em> ou la première valeur d'un attribut
|
||
de référence), pourra être configurée simplement en spécifiant l'attribut de liaison et le type de
|
||
valeur qu'il contient. Dans le cas d'une liaison plus complexe, il sera possible de développer vous
|
||
même des méthodes de mise en relation.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsrelation-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="x">$GLOBALS['LSobjects']['[nom du type d'LSobject]']['LSrelation'] = array (</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="x"> 'relation1' => array(</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="x"> 'label' => '[label de la relation]',</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="x"> 'emptyText' => "[texte affiché si aucune relation avec d'autres objets</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="x"> n'existe pour l'objet courant]",</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="x"> 'LSobject' => '[le type d'LSobjet en relation]',</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="x"> 'display_name_format' => '[LSformat du nom d'affichage des LSobjet en relation]',</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="x"> 'canEdit_attribute' => '[nom d'attribut]',</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="x"> // Liaison simple</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="x"> 'linkAttribute' => '[attribut de liaison]',</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="x"> 'linkAttributeValue' => '[valeur de l'attribut de liaison]',</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a><span class="x"> 'linkAttributeOtherValues' => array('[autres valeurs possible de l'attribut de liaison]', [...]),</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a><span class="x"> // Liaison complexe</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a><span class="x"> 'list_function' => '[méthode1]',</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a><span class="x"> 'getkeyvalue_function' => '[methode2]',</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a><span class="x"> 'update_function' => '[methode3]',</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a><span class="x"> 'remove_function' => '[methode4]',</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a><span class="x"> 'rename_function' => '[methode5]',</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a><span class="x"> 'canEdit_function' => '[methode6]',</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-22" id="__codelineno-0-22" name="__codelineno-0-22"></a>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-23" id="__codelineno-0-23" name="__codelineno-0-23"></a><span class="x"> 'rights' => array(</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-24" id="__codelineno-0-24" name="__codelineno-0-24"></a><span class="x"> 'LSprofile1' => 'r',</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-25" id="__codelineno-0-25" name="__codelineno-0-25"></a><span class="x"> 'LSprofile2' => 'w',</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-26" id="__codelineno-0-26" name="__codelineno-0-26"></a><span class="x"> ...</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-27" id="__codelineno-0-27" name="__codelineno-0-27"></a><span class="x"> )</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-28" id="__codelineno-0-28" name="__codelineno-0-28"></a><span class="x"> )</span>
|
||
<a href="#conf-lsobject-lsrelation-__codelineno-0-29" id="__codelineno-0-29" name="__codelineno-0-29"></a><span class="x">);</span>
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>label</code></p>
|
||
<p>Le label de la relation.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>emptyText</code></p>
|
||
<p>Le texte à afficher pour décrire le fait que l'objet courant n'a aucune relation d'établie avec
|
||
d'autres <a href="#conf-lsobject-configuration-lsobject">LSobjects</a>. Exemple (au sujet d'un utilisateur) :
|
||
<em>N'appartient à aucun groupe.</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSobject</code></p>
|
||
<p>Le type d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a> en relation avec le type courant.
|
||
<em>(Facultatif en cas de liaison complexe)</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>display_name_format</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> du nom d'affichage des objets en relation.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>canEdit_attribute</code></p>
|
||
<p>Le nom de l'attibut du type d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a> en relation devant être
|
||
éditable par l'utilisateur pour que celui-ci puisse modifier la relation. Dans le cadre d'une
|
||
relation simple, celui-ci peut, si nécessaire, être différent du paramètre <code>linkAttribute</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>linkAttribute</code></p>
|
||
<p>Dans le cadre d'une relation simple, il s'agit de l'attribut de liaison du type
|
||
d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a> en relation avec le type courant, c'est à dire
|
||
l'attribut dans lequel on retrouve une valeur en relation avec l'objet courant.
|
||
<em>(Facultatif en cas de liaison complexe)</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>linkAttributeValue</code></p>
|
||
<p>Dans le cadre d'une relation simple, il s'agit du type de valeur prisent par l'attribut de liaison
|
||
du type d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a> en relation avec le type courant. Il peut
|
||
s'agir du mot clé <code>dn</code> si l'attribut de liaison contient le <em>DN</em> de l'objet courant ou bien le nom
|
||
d'un attribut du type d'objet courant dont la première valeur sera stockée par l'attribut de
|
||
liaison. <em>(Facultatif en cas de liaison complexe)</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>linkAttributeOtherValues</code></p>
|
||
<p>Dans le cadre d'une relation simple, il s'agit d'autres types de valeur possiblement prisent par
|
||
l'attribut en plus de celui défini par le paramètre <code>linkAttributeValue</code>. Ce paramètre ne sert
|
||
qu'a détecter des liaisons établies à l'aide de valeurs autres que celle relative au paramètre
|
||
<code>linkAttributeValue</code> : en cas de nouvelle liaison, c'est la valeur associée à ce dernier qui sera
|
||
utilisée pour établir la liaison. <em>(Facultatif en cas de liaison complexe)</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>list_function</code></p>
|
||
<p>La méthode de la classe du type d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a> en relation,
|
||
permettant de lister les objets de ce type en relation avec l'objet courant.
|
||
<em>(Facultatif en cas de liaison simple)</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>getkeyvalue_function</code></p>
|
||
<p>La méthode de la classe du type d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a> en relation,
|
||
permettant d'obtenir la valeur clé à stocker pour établir la relation entre l'objet courant et
|
||
d'autres objets du type concerné. <em>(Facultatif en cas de liaison simple)</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>update_function</code></p>
|
||
<p>La méthode de la classe du type d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a> en relation,
|
||
permettant de mettre à jour les relations existantes entre l'objet courant et les objets du type
|
||
concerné. Cette liste d'objets en relation est établie par l'utilisateur à travers l'interface.
|
||
<em>(Facultatif en cas de liaison simple)</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>remove_function</code></p>
|
||
<p>La méthode de la classe du type d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a> en relation
|
||
permettant de supprimer une relation existante entre l'objet courant et un objet du type concerné.
|
||
<em>(Facultatif en cas de liaison simple)</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>rename_function</code></p>
|
||
<p>La méthode de la classe du type d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a> en relation
|
||
permettant d'effectuer les actions nécessaires lorsque l'objet courant est renommé dans le but
|
||
de maintenir les valeurs clés permettant d'établir les relations entre l'objet courant et les
|
||
objets en relation avec lui. <em>(Facultatif en cas de liaison simple)</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>canEdit_function</code></p>
|
||
<p>La méthode de la classe du type d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a> en relation
|
||
permettant de vérifier que l'utilisateur à le droit de modifier la relation avec un objet
|
||
en particulier. <em>(Facultatif en cas de liaison simple)</em></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>rights</code></p>
|
||
<p>Tableau associatif dont les clés sont les noms des
|
||
<a href="#conf-global-ldap-lsprofile-profils-dutilisateurs">LSprofiles</a> ayant des droits sur cette
|
||
relation et dont les valeurs associées sont les droits correspondants. La valeur des droits d'un
|
||
<a href="#conf-global-ldap-lsprofile-profils-dutilisateurs">LSprofile</a> peut être <code>r</code> pour le droit de
|
||
lecture ou <code>w</code> pour le droit de lecture-écriture.Par défaut, un
|
||
<a href="#conf-global-ldap-lsprofile-profils-dutilisateurs">LSprofile</a> n'a aucun droit.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lsform"><h1 id="conf-lsobject-lsform-les-formulaires-lsform">Les formulaires (LSform)</h1>
|
||
<p>Cette section décrit la manière de paramétrer les formulaires d'LdapSaisie pour un type
|
||
<a href="#conf-lsobject-configuration-lsobject">LSobject</a> donné. Pour chaque type
|
||
d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a>, il faut configurer plusieurs formulaires
|
||
correspondant aux vues gérées par LdapSaisie (création, modification, ...). Les formulaires se
|
||
configurent par plusieurs biais :</p>
|
||
<ul>
|
||
<li>Via la configuration des attributs : La configuration des attributs détermine la présence ou non
|
||
des attributs dans les formulaires. Elle permet également de définir si on souhaite bloquer leur
|
||
présence en lecture seulement.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Via les droits de l'utilisateur connecté sur les attributs de l'objet à éditer : en fonction des
|
||
droits de l'utilisateur sur un attribut, celui-ci apparaîtra en lecture-écriture ou en lecture
|
||
uniquement voir pas du tout.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>Via la configuration au niveau de chaque type d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a> : il
|
||
y est possible de définir le comportement globale du formulaire comme la validation via Ajax ou
|
||
encore la disposition logique des attributs dans le formulaire.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsform-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>$GLOBALS['LSobjects']['[nom du type d'LSobject]']['LSform'] = array (
|
||
<a href="#conf-lsobject-lsform-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> 'ajaxSubmit' => [booléen],
|
||
<a href="#conf-lsobject-lsform-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> 'layout' => array (
|
||
<a href="#conf-lsobject-lsform-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> // Configuration de la disposition logique des attributs
|
||
<a href="#conf-lsobject-lsform-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> ),
|
||
<a href="#conf-lsobject-lsform-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> 'dataEntryForm' => array (
|
||
<a href="#conf-lsobject-lsform-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> // Configuration des masques de saisie
|
||
<a href="#conf-lsobject-lsform-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> )
|
||
<a href="#conf-lsobject-lsform-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a>
|
||
<a href="#conf-lsobject-lsform-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a>);
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>ajaxSubmit</code></p>
|
||
<p>Booléen définissant si le formulaire sera envoyé via une requête Ajax plutôt qu'à travers un
|
||
rafraîchissement de la page. Par défaut : <code>True</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>layout</code></p>
|
||
<p>Tableau contenant la configuration de l'affichage du formulaire : il est possible de définir la
|
||
disposition des attributs dans le formulaire en les regroupant dans des onglets et en les
|
||
faisant apparaître dans un ordre logique.
|
||
<a href="#conf-lsobject-lsform-configuration-de-laffichage">Voir la section concernée.</a></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>dataEntryForm</code></p>
|
||
<p>Tableau contenant la configuration des masques de saisie : il est possible de définir des
|
||
masques de saisie pour faire en sorte que lors de la création d'un objet, seul un certain nombre
|
||
d'élements soit demandé à l'utilisateur.
|
||
<a href="#conf-lsobject-lsform-configuration-des-masques-de-saisie">Voir la section concernée.</a></p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<h2 id="conf-lsobject-lsform-configuration-de-laffichage">Configuration de l'affichage</h2>
|
||
<p>La configuration des <em>layout</em> se situe dans la configuration des
|
||
<a href="#conf-lsobject-configuration-lsobject">LSobjects</a>, dans la variable <code>layout</code>
|
||
(<code>$GLOBALS['LSobjects']['[nom du type d'LSobject]']['LSform']['layout']</code>). Cette variable est un
|
||
tableau associatif dont la clé est l'identifiant de l'onglet et dont la valeur associée est la
|
||
configuration de l'onglet.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsform-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a><span class="x">$GLOBALS['LSobjects']['[nom du type d'LSobject]']['LSform']['layout'] = array (</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a><span class="x"> 'onglet1' => array(</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a><span class="x"> 'label' => '[label de l'onglet]',</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a><span class="x"> 'img' => 1, // Valeur possible 1 ou 0</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a><span class="x"> 'args' => array (</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a><span class="x"> 'arg1',</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a><span class="x"> 'arg2',</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-1-8" id="__codelineno-1-8" name="__codelineno-1-8"></a><span class="x"> ...</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-1-9" id="__codelineno-1-9" name="__codelineno-1-9"></a><span class="x"> )</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-1-10" id="__codelineno-1-10" name="__codelineno-1-10"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-1-11" id="__codelineno-1-11" name="__codelineno-1-11"></a><span class="x"> ...</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-1-12" id="__codelineno-1-12" name="__codelineno-1-12"></a><span class="x">);</span>
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>label</code></p>
|
||
<p>Le label de l'onglet.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>img</code></p>
|
||
<p>Affiche ou non l'image d'un éventuel attribut de type HTML
|
||
<a href="#conf-lsobject-lsattribute-lsattr_html-lsattr_html_image-lsattr_html_image">LSattr_html_image</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>args</code></p>
|
||
<p>Tableau associatif contenant une liste ordonnée des attributs qui apparaîtront dans l'onglet.</p>
|
||
</li>
|
||
</ul>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Lorsqu'un <em>layout</em> est défini, celui-ci est <em>"suivi à la lettre"</em> pour l'affichage du
|
||
<a href="#conf-lsobject-lsform-lsform">LSform</a>. Ainsi, si un attribut est défini dans la configuration de l'objet comme
|
||
présent dans le <a href="#conf-lsobject-lsform-lsform">LSform</a> courant, mais que celui-ci n'est pas présent dans le <em>layout</em>,
|
||
il ne sera pas du tout affiché.</p>
|
||
</div>
|
||
<h3 id="conf-lsobject-lsform-configuration-des-masques-de-saisie">Configuration des masques de saisie</h3>
|
||
<p>La configuration des masques de saisie (<em>dataEntryForm</em>) se situe dans la configuration des
|
||
<a href="#conf-lsobject-configuration-lsobject">LSobjects</a>, dans la variable <code>dataEntryForm</code>
|
||
(<code>$GLOBALS['LSobjects']['[nom du type d'LSobject]']['LSform']['dataEntryForm']</code>). Cette variable est
|
||
un tableau associatif dont la clé est l'identifiant du masque de saisie et dont la valeur associée
|
||
est sa configuration.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lsform-__codelineno-2-1" id="__codelineno-2-1" name="__codelineno-2-1"></a><span class="x">$GLOBALS['LSobjects']['[nom du type d'LSobject]']['LSform']['dataEntryForm'] = array (</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-2" id="__codelineno-2-2" name="__codelineno-2-2"></a><span class="x"> 'masque1' => array(</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-3" id="__codelineno-2-3" name="__codelineno-2-3"></a><span class="x"> 'label' => '[label du masque de saisie]',</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-4" id="__codelineno-2-4" name="__codelineno-2-4"></a><span class="x"> 'disabledLayout' => [booleen],</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-5" id="__codelineno-2-5" name="__codelineno-2-5"></a><span class="x"> 'displayedElements' => array (</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-6" id="__codelineno-2-6" name="__codelineno-2-6"></a><span class="x"> 'attr1',</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-7" id="__codelineno-2-7" name="__codelineno-2-7"></a><span class="x"> 'attr2',</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-8" id="__codelineno-2-8" name="__codelineno-2-8"></a><span class="x"> ...</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-9" id="__codelineno-2-9" name="__codelineno-2-9"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-10" id="__codelineno-2-10" name="__codelineno-2-10"></a><span class="x"> 'defaultValues' => array (</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-11" id="__codelineno-2-11" name="__codelineno-2-11"></a><span class="x"> 'attr3' => [value],</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-12" id="__codelineno-2-12" name="__codelineno-2-12"></a><span class="x"> 'attr4' => [value],</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-13" id="__codelineno-2-13" name="__codelineno-2-13"></a><span class="x"> ...</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-14" id="__codelineno-2-14" name="__codelineno-2-14"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-15" id="__codelineno-2-15" name="__codelineno-2-15"></a><span class="x"> 'requiredAllAttributes' => [booleen],</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-16" id="__codelineno-2-16" name="__codelineno-2-16"></a><span class="x"> 'requiredAttributes' => array (</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-17" id="__codelineno-2-17" name="__codelineno-2-17"></a><span class="x"> 'attr1',</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-18" id="__codelineno-2-18" name="__codelineno-2-18"></a><span class="x"> 'attr2',</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-19" id="__codelineno-2-19" name="__codelineno-2-19"></a><span class="x"> ...</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-20" id="__codelineno-2-20" name="__codelineno-2-20"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-21" id="__codelineno-2-21" name="__codelineno-2-21"></a><span class="x"> 'forceGeneration' => array (</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-22" id="__codelineno-2-22" name="__codelineno-2-22"></a><span class="x"> 'attr1',</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-23" id="__codelineno-2-23" name="__codelineno-2-23"></a><span class="x"> 'attr2',</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-24" id="__codelineno-2-24" name="__codelineno-2-24"></a><span class="x"> ...</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-25" id="__codelineno-2-25" name="__codelineno-2-25"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-26" id="__codelineno-2-26" name="__codelineno-2-26"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-27" id="__codelineno-2-27" name="__codelineno-2-27"></a><span class="x"> ...</span>
|
||
<a href="#conf-lsobject-lsform-__codelineno-2-28" id="__codelineno-2-28" name="__codelineno-2-28"></a><span class="x">);</span>
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>label</code></p>
|
||
<p>Le label du masque de saisie.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>disabledLayout</code></p>
|
||
<p>Active ou non les <a href="#conf-lsobject-lsform-configuration-de-laffichage">layouts</a> pour ce masque de saisie.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>displayedElements</code></p>
|
||
<p>Tableau contenant la liste des attributs qui devront être saisie dans le masque de saisie.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>defaultValues</code></p>
|
||
<p>Tableau associatif contenant la liste des valeurs par défaut des attributs. Les valeurs multiples
|
||
sont possibles en utilisant des tableaux.</p>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Les valeurs seront vue comme des valeurs retournées par le formulaire et non comme des valeurs
|
||
des attribus LDAP eux-même. Ainsi et par exemple, un attribut traité comme un booléen dans un
|
||
formulaire pourra prendre comme valeur par défaut <code>yes</code> ou <code>no</code>.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>requiredAttributes</code></p>
|
||
<p>Tableau contenant la liste des attributs obligatoires du masque de saisie. Cette liste d'attributs
|
||
obligatoires viendra en complément de la configuration des attributs. Il est ainsi possible de
|
||
rendre des attributs obligatoires durant la saisie d'un masque tout en les laissant facultatif le
|
||
reste du temps.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>requiredAllAttributes</code></p>
|
||
<p>Si ce parametre vaut <code>True</code>, tout les attributs du masque de saisie seront tous obligatoires de la
|
||
même manière qu'avec le paramètre <code>requiredAttributes</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>forceGeneration</code></p>
|
||
<p>Tableau contenant la liste des attributs dont la génération sera forcée lors de la validation du
|
||
formation.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsobject-lssearch"><h1 id="conf-lsobject-lssearch-recherche-des-objets-dans-lannuaire-lssearch">Recherche des objets dans l'annuaire (LSsearch)</h1>
|
||
<p>Cette section décrit la manière de paramétrer les recherches dans l'annuaire pour un type
|
||
d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a> donné.</p>
|
||
<p>La configuration des <em>LSsearch</em> se situe dans la configuration des
|
||
<a href="#conf-lsobject-configuration-lsobject">LSobjects</a>, dans la variable <code>LSsearch</code>
|
||
(<code>$GLOBALS['LSobjects']['[nom du type d'LSobject]']['LSsearch']</code>).</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lssearch-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="x">$GLOBALS['LSobjects']['[nom du type d'LSobject]']['LSsearch'] = array (</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="x"> 'attrs' => array(</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="x"> 'attr1',</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="x"> 'attr2',</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="x"> ...</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="x"> 'attr3' => array(</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="x"> 'searchLSformat' => '[LSformat]',</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="x"> 'approxLSformat' => '[LSformat]',</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="x"> ...</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="x"> 'params' => array(</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a><span class="x"> // Paramètres de la recherche</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a><span class="x"> 'pattern' => '[string]',</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a><span class="x"> 'sizelimit' => [integer],</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a><span class="x"> 'recursive' => [boolean],</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a><span class="x"> 'approx' => [boolean],</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a><span class="x"> 'withoutCache' => [boolean],</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a><span class="x"> 'onlyAccessible' => [boolean],</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a><span class="x"> // Paramètres de tri</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a><span class="x"> 'sortBy' => [displayName|subDn],</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-22" id="__codelineno-0-22" name="__codelineno-0-22"></a><span class="x"> 'sortDirection' => [ASC|DESC],</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-23" id="__codelineno-0-23" name="__codelineno-0-23"></a><span class="x"> 'sortlimit' => [integer],</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-24" id="__codelineno-0-24" name="__codelineno-0-24"></a><span class="x"> // Paramètre d'affichage</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-25" id="__codelineno-0-25" name="__codelineno-0-25"></a><span class="x"> 'displayFormat' => [LSformat],</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-26" id="__codelineno-0-26" name="__codelineno-0-26"></a><span class="x"> 'nbObjectsByPage' => [integer],</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-27" id="__codelineno-0-27" name="__codelineno-0-27"></a><span class="x"> 'nbObjectsByPageChoices' => array([integer], [integer], ...),</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-28" id="__codelineno-0-28" name="__codelineno-0-28"></a><span class="x"> 'validPatternRegex' => '[regex]'</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-29" id="__codelineno-0-29" name="__codelineno-0-29"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-30" id="__codelineno-0-30" name="__codelineno-0-30"></a><span class="x"> 'predefinedFilters' => array(</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-31" id="__codelineno-0-31" name="__codelineno-0-31"></a><span class="x"> 'filter1' => 'label filter1',</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-32" id="__codelineno-0-32" name="__codelineno-0-32"></a><span class="x"> 'filter2' => 'label filter2'</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-33" id="__codelineno-0-33" name="__codelineno-0-33"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-34" id="__codelineno-0-34" name="__codelineno-0-34"></a><span class="x"> 'extraDisplayedColumns' => array(</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-35" id="__codelineno-0-35" name="__codelineno-0-35"></a><span class="x"> 'col1' => array(</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-36" id="__codelineno-0-36" name="__codelineno-0-36"></a><span class="x"> 'label' => 'label column 1',</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-37" id="__codelineno-0-37" name="__codelineno-0-37"></a><span class="x"> 'LSformat' => '[LSformat]'</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-38" id="__codelineno-0-38" name="__codelineno-0-38"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-39" id="__codelineno-0-39" name="__codelineno-0-39"></a><span class="x"> 'col2' => array(</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-40" id="__codelineno-0-40" name="__codelineno-0-40"></a><span class="x"> 'label' => 'label column 2',</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-41" id="__codelineno-0-41" name="__codelineno-0-41"></a><span class="x"> 'generateFunction' => '[fonction de génération]',</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-42" id="__codelineno-0-42" name="__codelineno-0-42"></a><span class="x"> 'additionalAttrs' => array('[attr1]', '[attr2]', ...),</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-43" id="__codelineno-0-43" name="__codelineno-0-43"></a><span class="x"> 'escape' => [booléen],</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-44" id="__codelineno-0-44" name="__codelineno-0-44"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-45" id="__codelineno-0-45" name="__codelineno-0-45"></a><span class="x"> 'col3' => array(</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-46" id="__codelineno-0-46" name="__codelineno-0-46"></a><span class="x"> 'label' => 'label column 3',</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-47" id="__codelineno-0-47" name="__codelineno-0-47"></a><span class="x"> 'LSformat' => '[LSformat]',</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-48" id="__codelineno-0-48" name="__codelineno-0-48"></a><span class="x"> 'alternativeLSformats' => array (</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-49" id="__codelineno-0-49" name="__codelineno-0-49"></a><span class="x"> '[LSformat 1]',</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-50" id="__codelineno-0-50" name="__codelineno-0-50"></a><span class="x"> '[LSformat 2]'</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-51" id="__codelineno-0-51" name="__codelineno-0-51"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-52" id="__codelineno-0-52" name="__codelineno-0-52"></a><span class="x"> 'formaterLSformat' => '[LSformat]',</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-53" id="__codelineno-0-53" name="__codelineno-0-53"></a><span class="x"> 'formaterFunction' => '[fonction de formatage]',</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-54" id="__codelineno-0-54" name="__codelineno-0-54"></a><span class="x"> 'cssStyle' => '[CSS style]',</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-55" id="__codelineno-0-55" name="__codelineno-0-55"></a><span class="x"> 'visibleTo' => array (</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-56" id="__codelineno-0-56" name="__codelineno-0-56"></a><span class="x"> '[LSprofile 1]',</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-57" id="__codelineno-0-57" name="__codelineno-0-57"></a><span class="x"> '[LSprofile 2]'</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-58" id="__codelineno-0-58" name="__codelineno-0-58"></a><span class="x"> )</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-59" id="__codelineno-0-59" name="__codelineno-0-59"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-60" id="__codelineno-0-60" name="__codelineno-0-60"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-61" id="__codelineno-0-61" name="__codelineno-0-61"></a><span class="x"> 'customActions' => array (</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-62" id="__codelineno-0-62" name="__codelineno-0-62"></a><span class="x"> // Configuration des customActions pour les recherches de ce type d'objet</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-63" id="__codelineno-0-63" name="__codelineno-0-63"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-64" id="__codelineno-0-64" name="__codelineno-0-64"></a><span class="x"> 'showSelectionBoxes' => [boolean],</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-0-65" id="__codelineno-0-65" name="__codelineno-0-65"></a><span class="x">);</span>
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>attrs</code></p>
|
||
<p>Tableau listant les attributs pouvant être utilisés dans les filtres de recherche LDAP employés
|
||
par LdapSaisie. Lorsqu'un motif de recherche est passé par l'utilisateur, LdapSaisie composera un
|
||
filtre LDAP à partir de cette liste.</p>
|
||
<p>Lors d'une recherche non-approximative, le filtre de recherche sera composé (par défaut) de la
|
||
manière suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lssearch-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a>(|(attr1=*motif*)(attr2=*motif*)...)
|
||
</code></pre></div>
|
||
<p>Lors d'une recherche approximative, le filtre de recherche sera composé (par défaut) de la manière
|
||
suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lssearch-__codelineno-2-1" id="__codelineno-2-1" name="__codelineno-2-1"></a>(|(attr1=~motif)(attr2~=motif)...)
|
||
</code></pre></div>
|
||
<p>Il est également possible de paramétrer la manière dont sera composé le filtre de recherche
|
||
attribut par attribut à l'aide des paramètres <code>searchLSformat</code> et <code>approxLSformat</code>.</p>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Ces filtres, une fois composés, sont insérés dans un autre, filtrant en plus sur les
|
||
<em>ObjectClass</em> du type d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a> de la manière suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lssearch-__codelineno-3-1" id="__codelineno-3-1" name="__codelineno-3-1"></a>(& (&(objectclass=oc1)(objectclass=oc2)) (filtre) )
|
||
</code></pre></div>
|
||
</div>
|
||
<ul>
|
||
<li>
|
||
<p><code>searchLSformat</code></p>
|
||
<p>Ce paramètre est un <a href="#conf-global-lsformat-format-parametrable">LSformat</a> permettant de définir,
|
||
attribut par attribut, comment le filtre de recherche LDAP est composé à partir d'un motif de
|
||
recherche et en cas de recherche non-approximative.</p>
|
||
<p>Ce <a href="#conf-global-lsformat-format-parametrable">LSformat</a> est composé à l'aide des éléments
|
||
<code>name</code>, le nom de l'attribut et <code>pattern</code>, le motif de recherche.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lssearch-__codelineno-4-1" id="__codelineno-4-1" name="__codelineno-4-1"></a>(%{name}=%{pattern})
|
||
</code></pre></div>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Le filtre déduit doit obligatoirement commencer par <code>(</code> et se terminer par <code>)</code>.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>approxLSformat</code></p>
|
||
<p>Ce paramètre est un <a href="#conf-global-lsformat-format-parametrable">LSformat</a> permettant de définir,
|
||
attribut par attribut, comment le filtre de recherche LDAP est composé à partir d'un motif de
|
||
recherche et en cas de recherche approximative.</p>
|
||
<p>Ce <a href="#conf-global-lsformat-format-parametrable">LSformat</a> est composé à l'aide des éléments
|
||
<code>name</code>, le nom de l'attribut et <code>pattern</code>, le motif de recherche.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lssearch-__codelineno-5-1" id="__codelineno-5-1" name="__codelineno-5-1"></a>(%{name}=~%{pattern})
|
||
</code></pre></div>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Le filtre déduit doit obligatoirement commencer par <code>(</code> et se terminer par <code>)</code>.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>params</code></p>
|
||
<p>Tableau des paramètres par défaut d'une recherche. Ce tableau contient les paramètres qui seront
|
||
utilisés pour initialisé une recherche. Ces paramètres pourront être redéfini par l'utilisateur
|
||
ou par l'application en fonction du contexte dans lequel cette recherche est effectuée.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>pattern</code></p>
|
||
<p>Mot clé de la recherche.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>sizelimit</code></p>
|
||
<p>Entier determinant le nombre maximum d'objet pouvant être retournés dans une recherche.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>recursive</code></p>
|
||
<p>Booléen déterminant si la recherche récursive est activée.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>approx</code></p>
|
||
<p>Booléen déterminant si la recherche approximative est activée.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>withoutCache</code></p>
|
||
<p>Booléen déterminant si le cache de recherche doit être utilisé.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>onlyAccessible</code></p>
|
||
<p>Booléen déterminant si seul les objets accessibles à l'utilisateur connecté doivent être
|
||
retournés par la recherche.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>sortBy</code></p>
|
||
<p>Mot clé déterminant sur quel valeur/colonne le résultat de recherche sera trié.</p>
|
||
<p>Valeurs possibles : <code>displayName</code>, <code>subDn</code> ou <code>NULL</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>sortDirection</code></p>
|
||
<p>Mot clé déterminant le sens du trie du résultat de la recherche.</p>
|
||
<p>Valeurs possibles : <code>ASC</code>, <code>DESC</code> ou <code>NULL</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>sortlimit</code></p>
|
||
<p>Entier determinant le nombre maximum d'objet pouvant être triés dans le résultat d'une
|
||
recherche.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>displayFormat</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> d'affichage du nom de l'objet dans le
|
||
résultat de la recherche.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>nbObjectsByPage</code></p>
|
||
<p>Entier déterminant le nombre d'objet maximum affichés dans une page de résultat de la recherche.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>nbObjectsByPageChoices</code></p>
|
||
<p>Tableau des choix proposés à l'utilisateur pour le nombre d'objets maximum affichés dans une
|
||
page de résultat de la recherche.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>validPatternRegex</code></p>
|
||
<p>Expression régulière de validation des mots clés de recherche pour ce type
|
||
d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a>.</p>
|
||
<p>(Par défaut : <code>/^[\w\-_\\\'\"^[]\(\){}\=\+\£\%\$\€\.\:\;\,\?\/\@]+$/iu</code>)</p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>predefinedFilters</code></p>
|
||
<p>Tableau associatif contenant des filtres prédéfinis pour la recherche. Les clés sont les filtres
|
||
au format LDAP et les valeurs sont les labels associés.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>extraDisplayedColumns</code></p>
|
||
<p>Tableau associatif contenant des colonnes supplémentaires à afficher dans les résultats de
|
||
recherche. Les clés sont les identifiants des colonnes supplémentaires et les valeurs sont leur
|
||
configuration définie à partir des paramètres suivant :</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>label</code></p>
|
||
<p>Le label de la colonne.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSformat</code></p>
|
||
<p>Le <a href="#conf-global-lsformat-format-parametrable">LSformat</a> d'affichage de la colonne. Ce format
|
||
est composé à partir des attributs des objets LDAP dans leur format brut.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>alternativeLSformats</code></p>
|
||
<p>Tableau des <a href="#conf-global-lsformat-format-parametrable">LSformats</a> alternatifs à utiliser si le
|
||
résultat du format principal est vide. Les formats définis dans cette liste sont essayés les uns
|
||
après les autres et le premier <a href="#conf-global-lsformat-format-parametrable">LSformat</a> retournant
|
||
une valeur non-vide est utilisé.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>formaterLSformat</code></p>
|
||
<p><a href="#conf-global-lsformat-format-parametrable">LSformat</a> optionnel permettant de mettre en forme le
|
||
résultat obtenu des <a href="#conf-global-lsformat-format-parametrable">LSformats</a> précédents. Ce
|
||
<a href="#conf-global-lsformat-format-parametrable">LSformat</a> ne sera utilisé que si le résultat obtenu
|
||
précédement n'est pas vide. Il est ainsi possible d'utiliser les paramètres <code>LSformat</code> et
|
||
<code>alternativeLSformats</code> afin de récupérer la valeur à afficher, puis de la mettre en forme grâce
|
||
à ce <a href="#conf-global-lsformat-format-parametrable">LSformat</a>. Ce format est composé à partir des
|
||
attributs des objets LDAP dans leur format brut et de la valeur retournés précedement accessible
|
||
via la variable <code>val</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>formaterFunction</code></p>
|
||
<p>Le nom d'une fonction optionnelle à exécuter pour mettre en forme le résultat obtenu des
|
||
<a href="#conf-global-lsformat-format-parametrable">LSformats</a> précédents. Cette fonction ne sera
|
||
appelée que si le résultat obtenu précédement n'est pas vide. La fonction prendra en paramètre
|
||
la valeur à mettre en forme et retournera la valeur mise en forme.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>generateFunction</code></p>
|
||
<p>Le nom d'une fonction qui sera utilisée pour générer la valeur d'affichage de cette colonne. La
|
||
fonction prendra en paramètre une référence de l'objet <code>LSsearchEntry</code> et retournera la valeur
|
||
de la colonne.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>additionalAttrs</code></p>
|
||
<p>Un tableau de nom d'attributs à inclure dans le resultat de la recherche LDAP. Ce tableau permet
|
||
notamment d'inclure les attributs nécessaires au bon fonctionnement de la fonction
|
||
<code>generateFunction</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>escape</code></p>
|
||
<p>Ce paramètre booléen permet de définir si, lors de l'affichage, le contenu de la colonne doit
|
||
être transformé pour protéger les caractères éligibles en entités HTML. Par défaut, ce paramètre
|
||
est <code>True</code>.</p>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">Warning</p>
|
||
<p>Cette fonctionnalité existe pour des raisons de sécurité et notamment en protection des
|
||
failles <code>XSS</code>. Si vous désactivez cette fonctionnalité, il est important de gérer la
|
||
problématique de sécurité par ailleurs.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>cssStyle</code></p>
|
||
<p>Ce paramètre permet de définir un style CSS personnalisé pour la colonne. S'il est défini, le
|
||
contenu de ce paramètre sera ajouté en tant qu'attribut <code>style</code> des balises <code>th</code> et <code>td</code> de la
|
||
colone.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>visibleTo</code></p>
|
||
<p>Ce paramètre permet de restreindre la visibilité de cette colonne aux seuls
|
||
<a href="#conf-global-ldap-lsprofile-profils-dutilisateurs">LSprofiles</a> spécifiés. S'il est omis, la
|
||
colonne sera visible pour tous.</p>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>customActions</code></p>
|
||
<p>Tableau associatif contenant les paramètres de configuration des
|
||
<a href="#conf-lsobject-lssearch-customactions">customActions</a>. <a href="#conf-lsobject-lssearch-customactions">Voir la section concernée</a>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>showSelectionBoxes</code></p>
|
||
<p>Booléen permettant de définir si les cases à cocher de sélections des objets doivent être
|
||
affichées. Lorsqu'elles sont affichées, l'utilisateur pourra sélectionner un ou plusieurs objets
|
||
dans la liste avant de déclencher une <a href="#conf-lsobject-lssearch-customsactions">customAction</a>. Dans ce cas, les DNs de ces
|
||
objets seront passés à la page d'exécution de la <a href="#conf-lsobject-lssearch-customsactions">customAction</a> via le paramètre
|
||
<code>selected</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<h2 id="conf-lsobject-lssearch-les-actions-personnalisees-customactions">Les actions personnalisées (customActions)</h2>
|
||
<p>Cette section décrit la manière de configurer les actions personnalisées exécutables sur les
|
||
recherches d'<a href="#conf-lsobject-configuration-lsobject">LSobjects</a> appelées <a href="#conf-lsobject-lssearch-customactions">customActions</a>.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lssearch-__codelineno-6-1" id="__codelineno-6-1" name="__codelineno-6-1"></a>$GLOBALS['LSobjects']['[nom du type d'LSobject]']['LSsearch']['customActions'] = array (
|
||
<a href="#conf-lsobject-lssearch-__codelineno-6-2" id="__codelineno-6-2" name="__codelineno-6-2"></a> 'action1' => array(
|
||
<a href="#conf-lsobject-lssearch-__codelineno-6-3" id="__codelineno-6-3" name="__codelineno-6-3"></a> 'label' => '[label l'action]',
|
||
<a href="#conf-lsobject-lssearch-__codelineno-6-4" id="__codelineno-6-4" name="__codelineno-6-4"></a> 'hideLabel' => '[booléen]',
|
||
<a href="#conf-lsobject-lssearch-__codelineno-6-5" id="__codelineno-6-5" name="__codelineno-6-5"></a> 'icon' => '[nom de l'icône de l'action]',
|
||
<a href="#conf-lsobject-lssearch-__codelineno-6-6" id="__codelineno-6-6" name="__codelineno-6-6"></a> 'function' => '[fonction à exécuter]',
|
||
<a href="#conf-lsobject-lssearch-__codelineno-6-7" id="__codelineno-6-7" name="__codelineno-6-7"></a> 'question_format' => '[LSformat de la question de confirmation]',
|
||
<a href="#conf-lsobject-lssearch-__codelineno-6-8" id="__codelineno-6-8" name="__codelineno-6-8"></a> 'onSuccessMsgFormat' => '[LSformat du message à afficher en cas de succès de l'action]',
|
||
<a href="#conf-lsobject-lssearch-__codelineno-6-9" id="__codelineno-6-9" name="__codelineno-6-9"></a> 'disableOnSuccessMsg' => '[booléen]',
|
||
<a href="#conf-lsobject-lssearch-__codelineno-6-10" id="__codelineno-6-10" name="__codelineno-6-10"></a> 'noConfirmation' => '[booléen]',
|
||
<a href="#conf-lsobject-lssearch-__codelineno-6-11" id="__codelineno-6-11" name="__codelineno-6-11"></a> 'redirectToObjectList' => '[booléen]',
|
||
<a href="#conf-lsobject-lssearch-__codelineno-6-12" id="__codelineno-6-12" name="__codelineno-6-12"></a> 'rights' => array(
|
||
<a href="#conf-lsobject-lssearch-__codelineno-6-13" id="__codelineno-6-13" name="__codelineno-6-13"></a> 'LSprofile1',
|
||
<a href="#conf-lsobject-lssearch-__codelineno-6-14" id="__codelineno-6-14" name="__codelineno-6-14"></a> 'LSprofile2',
|
||
<a href="#conf-lsobject-lssearch-__codelineno-6-15" id="__codelineno-6-15" name="__codelineno-6-15"></a> ...
|
||
<a href="#conf-lsobject-lssearch-__codelineno-6-16" id="__codelineno-6-16" name="__codelineno-6-16"></a> )
|
||
<a href="#conf-lsobject-lssearch-__codelineno-6-17" id="__codelineno-6-17" name="__codelineno-6-17"></a> )
|
||
<a href="#conf-lsobject-lssearch-__codelineno-6-18" id="__codelineno-6-18" name="__codelineno-6-18"></a>);
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>label</code></p>
|
||
<p>Le label de l'action.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>hideLabel</code></p>
|
||
<p>Cache le label dans le bouton de l'action.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>icon</code></p>
|
||
<p>Nom de l'îcone à afficher dans le bouton de l'action. Ce nom correspond au nom du fichier de
|
||
l'image (sans l'extention) qui devra se trouver dans le dossier
|
||
<code>/src/images/[nom du theme d'images]/</code> ou dans le dossier <code>src/local/images</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>function</code></p>
|
||
<p>Le nom de la fonction à exécuter qui implémente l'action personnalisée Cette fonction prendra en
|
||
seule paramètre l'objet <a href="#conf-lsobject-lssearch-lssearch">LSsearch</a>. sur lequel l'action devra être exécutée et
|
||
retournera <code>True</code> en cas de succès ou <code>False</code> en cas d'échec d'exécution de la fonction.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>question_format</code></p>
|
||
<p>Le <a href="#conf-global-lsformat-format-parametrable">LSformat</a> de la question de confirmation
|
||
d'exécution de l'action. Ce <a href="#conf-global-lsformat-format-parametrable">LSformat</a> sera composé à
|
||
l'aide du label de l'action.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>onSuccessMsgFormat</code></p>
|
||
<p>Le <a href="#conf-global-lsformat-format-parametrable">LSformat</a> du message à afficher en cas de succès
|
||
d'exécution de l'action. Ce <a href="#conf-global-lsformat-format-parametrable">LSformat</a> sera composé à
|
||
l'aide du label de l'action.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>disableOnSuccessMsg</code></p>
|
||
<p>Booléen permetant de désactiver le message afficher en cas de succès d'exécution de l'action.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>noConfirmation</code></p>
|
||
<p>Booléen permetant de désactiver la confirmation de l'exécution de l'action.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>redirectToObjectList</code></p>
|
||
<p>Booléen permetant de rediriger ou non l'utilisateur vers la liste des objets (Vrai par défaut).
|
||
Si l'utilisateur n'est redirigé, le template par défaut (ou celui défini durant l'éxécution de la
|
||
fonction) sera affiché.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>rights</code></p>
|
||
<p>Tableau contenant la liste des noms des <a href="#conf-global-ldap-lsprofile-profils-dutilisateurs">LSprofiles</a>
|
||
ayant le droit d'exécuter cette action.</p>
|
||
</li>
|
||
</ul>
|
||
<h3 id="conf-lsobject-lssearch-ecriture-dune-fonction-implementant-une-customaction">Écriture d'une fonction implémentant une customAction</h3>
|
||
<p>Une fonction implémentant une <em>customAction</em> se déclare de la manière suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lssearch-__codelineno-7-1" id="__codelineno-7-1" name="__codelineno-7-1"></a><span class="x">/*</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-7-2" id="__codelineno-7-2" name="__codelineno-7-2"></a><span class="x"> * Ma fonction implémentant ma customAction</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-7-3" id="__codelineno-7-3" name="__codelineno-7-3"></a><span class="x"> *</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-7-4" id="__codelineno-7-4" name="__codelineno-7-4"></a><span class="x"> * Paramètre :</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-7-5" id="__codelineno-7-5" name="__codelineno-7-5"></a><span class="x"> * - $search : L'objet LSsearch de la recherche sur lequel mon action doit être exécutée</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-7-6" id="__codelineno-7-6" name="__codelineno-7-6"></a><span class="x"> *</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-7-7" id="__codelineno-7-7" name="__codelineno-7-7"></a><span class="x"> * Valeurs retournées :</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-7-8" id="__codelineno-7-8" name="__codelineno-7-8"></a><span class="x"> * - True : Tout s'est bien passé</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-7-9" id="__codelineno-7-9" name="__codelineno-7-9"></a><span class="x"> * - False : Une erreur est survenue</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-7-10" id="__codelineno-7-10" name="__codelineno-7-10"></a><span class="x"> */</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-7-11" id="__codelineno-7-11" name="__codelineno-7-11"></a><span class="x">function maFonction ($search) {</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-7-12" id="__codelineno-7-12" name="__codelineno-7-12"></a>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-7-13" id="__codelineno-7-13" name="__codelineno-7-13"></a><span class="x"> // Actions</span>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-7-14" id="__codelineno-7-14" name="__codelineno-7-14"></a>
|
||
<a href="#conf-lsobject-lssearch-__codelineno-7-15" id="__codelineno-7-15" name="__codelineno-7-15"></a><span class="x">}</span>
|
||
</code></pre></div>
|
||
<p>Cette fonction doit prendre pour seul paramètre, l'objet <a href="#conf-lsobject-lssearch-lssearch">LSsearch</a>. sur lequel l'action
|
||
personnalisée doit être exécutée et doit retourner soit <code>True</code> si tout s'est bien passé, soit
|
||
<code>False</code> en cas de problème.</p>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>La recherche passée en paramètre n'a pas encore été exécutée. En conséquence, si vous avez
|
||
besoin d'accéder au résultat de la recherche, il est nécessaire d'exécuter au préalable :
|
||
<code>$search -> run();</code>. Cela permet en outre, de modifier les paramètres de la recherche avant de
|
||
l'exécuter. Cela peut par exemple être utile, si vous avez besoin d'accèder aux valeurs
|
||
d'attributs particuliers, d'ajouter des attributs au résultat de la recherche :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-lssearch-__codelineno-8-1" id="__codelineno-8-1" name="__codelineno-8-1"></a><span class="x">$search -> setParam('attributes',array('attr1','attr2'));</span>
|
||
</code></pre></div>
|
||
</div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Ces fonctions sont le plus couramment définies au sein
|
||
d'<a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a>.</p>
|
||
</div></section><section class="print-page" id="conf-lsobject-ioformat"><h1 id="conf-lsobject-ioformat-les-formats-dimportexport-ioformat">Les formats d'import/export (ioFormat)</h1>
|
||
<p>Cette section décrit la manière de paramétrer les formats d'import/export pour un type d'
|
||
<a href="#conf-lsobject-configuration-lsobject">LSobject</a> donné.</p>
|
||
<p>La configuration des <em>ioFormats</em> se situe dans la configuration des
|
||
<a href="#conf-lsobject-configuration-lsobject">LSobjects</a>, dans la variable <code>ioFormat</code>
|
||
(<code>$GLOBALS['LSobjects']['[nom du type d'LSobject]']['ioFormat']</code>). Cette variable est un tableau
|
||
associatif dont la clé est l'identifiant du format et dont la valeur associée est la configuration
|
||
du format.</p>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Le moteur d'importation simule la validation d'un formulaire de création du type
|
||
d'<a href="#conf-lsobject-configuration-lsobject">LSobject</a> (ou de modification en cas d'activation du mode
|
||
mise à jour uniquement, voir ci-dessous). En conséquence :</p>
|
||
<ul>
|
||
<li>seul les attributs présent dans le formulaire de création peuvent être importés.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>tous les attributs obligatoires présents dans le formulaire de création doivent être fournis
|
||
par le fichier source ou générer à partir des autres attributs.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Les valeurs des attributs issus de l'importation seront vue comme des valeurs retournées par
|
||
le formulaire et non comme des valeurs des attribus LDAP eux-même. Ainsi et par exemple, un
|
||
attribut traité comme un booléen dans un formulaire pourra prendre comme valeur par
|
||
défaut <code>yes</code> ou <code>no</code>.</li>
|
||
</ul>
|
||
</div>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-ioformat-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>$GLOBALS['LSobjects']['[nom du type d'LSobject]']['ioFormat'] = array (
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> '[ioFormat ID]' => array (
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> 'label' => '[Label du type de fichier]',
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> 'driver' => '[Pilote d'ioFormat utilisé]',
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> 'driver_options' => array([Options du pilote d'ioFormat utilisé]),
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> 'update_only' => '[Booléen]',
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> 'fields => array (
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> '[champ 1]' => '[attribut 1]',
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> '[champ 2]' => '[attribut 2]',
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> [...]
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> ),
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> 'generated_fields' => array (
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> '[attribute 3]' => '[LSformat]',
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a> '[attribute 4]' => array('[LSformat1]', '[LSformat2]', ...)
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a> '[attribute 5]' => function($attrs, $row) {
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a> return array([...]);
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a> },
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a> [...]
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a> ),
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a> 'before_import' => array('function1', 'function2'),
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a> 'after_import' => 'function3',
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-22" id="__codelineno-0-22" name="__codelineno-0-22"></a> ),
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-23" id="__codelineno-0-23" name="__codelineno-0-23"></a> [...]
|
||
<a href="#conf-lsobject-ioformat-__codelineno-0-24" id="__codelineno-0-24" name="__codelineno-0-24"></a>);
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>label</code></p>
|
||
<p>Le label du format</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>driver</code></p>
|
||
<p>Le pilote a utilisé pour ce format. Le pilote permet de gérér la lecture et l'écriture dans un
|
||
type de fichier d'import/export. Pour plus d'information sur les pilotes disponibles,
|
||
<a href="#conf-lsobject-ioformat-pilote-dioformat">Voir la section concernée.</a></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>driver_options</code></p>
|
||
<p>Tableau associatif des options du pilote utilisé pour ce format. Pour plus d'informations,
|
||
consulter la documentation du pilote utilisé.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>update_only</code></p>
|
||
<p>Booléen permettant d'activer le mode mise à jour uniquement pour ce format. Dans ce mode, les
|
||
données de l'objet LDAP correspondant seront chargées depuis l'annuaire avant toutes validations
|
||
des données fournies dans le fichier d'import, et ce, dans un formulaire de modifications et non
|
||
pas un formulaire de création autrement. Pour que cela soit possible, il est indispensable que le
|
||
DN de l'objet puisse être déduit depuis les données fournies dans le fichier d'import. Pour cela,
|
||
vous pouvez le fournir via un champ du fichier d'import associé à la clé <code>dn</code> ou à défaut il sera
|
||
généré à partir du RDN dont la valeur devra être fournie dans le fichier d'import. Vous pouvez
|
||
également le générer via le paramètre <code>generated_fields</code> (voir ci-dessous).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>fields</code></p>
|
||
<p>Tableau associatif permettant d'associer un champ du fichier source (la clé) avec attribut de
|
||
l'objet LDAP (la valeur). Il est également possible d'associé un champ avec la valeur <code>dn</code> pour
|
||
fournir le DN de l'objet en mode mise à jour uniquement (voir ci-dessus).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>generated_fields</code></p>
|
||
<p>Tableau associatif permettant de définir soit des
|
||
<a href="#conf-global-lsformat-format-parametrable">LSformats</a>, soit un <em>callable</em> (au sens PHP) pour
|
||
générer les valeurs d'attributs automatiquement. Ce tableau contient en clé, le nom de l'attribut
|
||
à générer (ou <code>dn</code> pour la génération du DN de l'objet en mode mise à jour uniquement), et en
|
||
valeur associée, un ou plusieurs <a href="#conf-global-lsformat-format-parametrable">LSformat</a> ou un
|
||
<em>callable</em> à utiliser pour générer ses valeurs.
|
||
En cas de <a href="#conf-global-lsformat-format-parametrable">LSformat</a>, ils seront composés à l'aide des
|
||
valeurs des autres attributs de l'objet. En cas d'un <em>callable</em>, il sera appeler avec en paramètre
|
||
le tableau des valeurs des autres attributs (<code>$attrs</code>), le tableau des données issues du fichier
|
||
source (<code>$row</code>) et devra retourner le tableau des valeurs générées de l'attribut ou <code>false</code> en cas
|
||
d'erreur.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>before_import</code></p>
|
||
<p>Chaîne de caractères (ou tableau de chaîne de caractères) correspondant au nom d'une ou plusieurs
|
||
fonctions qui seront exécutées avant chaque import. <a href="#conf-lsobject-ioformat-declencheurs">Voir la section concernée</a></p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>after_import</code></p>
|
||
<p>Chaîne de caractères (ou tableau de chaîne de caractères) correspondant au nom d'une ou plusieurs
|
||
fonctions qui seront exécutées après chaque import. <a href="#conf-lsobject-ioformat-declencheurs">Voir la section concernée</a></p>
|
||
</li>
|
||
</ul>
|
||
<h2 id="conf-lsobject-ioformat-pilote-dioformat">Pilote d'ioFormat</h2>
|
||
<p>Cette section décrit la manière de configurer les pilotes d'ioFormat utilisés lors des
|
||
imports/exports d'<a href="#conf-lsobject-configuration-lsobject">LSobjects</a>.</p>
|
||
<h3 id="conf-lsobject-ioformat-pilote-de-fichiers-csv">Pilote de fichiers CSV</h3>
|
||
<p>Ce pilote permet de gérer l'import/export de <a href="#conf-lsobject-configuration-lsobject">LSobject</a> à partir
|
||
d'un fichier <code>CSV</code>. Depuis la version 4 d'LdapSaisie, ce pilote utilise les fonctions standards
|
||
<code>fgetcsv()</code> et <code>fputcsv</code> fournis par PHP. Avant cela, la classe PEAR
|
||
<a href="http://pear.php.net/package/File_CSV_DataSource">File_CSV_DataSource</a> était utilisée. Par défaut,
|
||
les paramètres de lecture et d'écriture des fichiers sont : la virgule sert de délimiteur, le
|
||
caractère <code>"</code> peut être utilisé pour encadrer les valeurs des champs et la longueur maximale d'une
|
||
ligne est infini. Ces paramètres peuvent être modifiés en configurant les options du pilote.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-ioformat-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a>$GLOBALS['LSobjects']['[nom du type d'LSobject]']['ioFormat']['[ID ioFormat]']['driver_options'] = array (
|
||
<a href="#conf-lsobject-ioformat-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a> 'delimiter' => '[délimiteur]',
|
||
<a href="#conf-lsobject-ioformat-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a> 'enclosure' => '[caractère d'encadrement de texte]',
|
||
<a href="#conf-lsobject-ioformat-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a> 'length' => [longueur maximale d'une ligne],
|
||
<a href="#conf-lsobject-ioformat-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a> 'escape' => '[caractère d'échappement]',
|
||
<a href="#conf-lsobject-ioformat-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a> 'multiple_value_delimiter' => '[délimiteur]',
|
||
<a href="#conf-lsobject-ioformat-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a>);
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>delimiter</code></p>
|
||
<p>Le caractère utilisé pour délimiter les champs (Par défaut, une virgule).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>length</code></p>
|
||
<p>La longueur maximale d'une ligne du fichier. Si zéro est spécifié, la longueur d'une ligne ne sera
|
||
pas limité, mais la lecture du fichier sera ralentie. (Par défaut : <code>0</code>)</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>enclosure</code></p>
|
||
<p>Le caractère utilisé pour encadrer les valeurs des champs (Par défaut : <code>"</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>escape</code></p>
|
||
<p>Le caractère d'échappement utilisé si un des champs d'une ligne de fichier contient le caractère
|
||
utilisé pour encadrer les valeurs. (Par défaut : <code>\</code>).</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Selon la RFC4180, l'echappement du caractère utilisé pour encadrer les valeurs des champs doit
|
||
se faire en le doublant. Le caractère défini ici est une alternative à ce comportement par
|
||
défaut. Pour désactiver ce caractère d'échappement alternatif, il est possible depuis de la
|
||
version 7.4.0 de PHP de mettre ici une chaine vide.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>multiple_value_delimiter</code></p>
|
||
<p>Le caractère utilisé pour délimiter au sein d'un champs, les valeurs valeurs multiples d'un
|
||
attribut (Par défaut : <code>|</code>).</p>
|
||
</li>
|
||
</ul>
|
||
<h2 id="conf-lsobject-ioformat-declencheurs">Déclencheurs</h2>
|
||
<p>Cette section décrit la manière de paramétrer des déclencheurs afin que LdapSaisie exécute durant
|
||
ses processus, et à des moments bien précis des traitements d'un <a href="#conf-lsobject-ioformat-ioformat">ioFormat</a>, des
|
||
fonctions que vous pourrez développer vous même. De plus, le résultat de l'exécution de vos
|
||
fonctions pourra influer sur le déroulement des processus.</p>
|
||
<p>Actuellement, les évenements suivant sont gérés :</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Nom</th>
|
||
<th>Description</th>
|
||
<th>Bloquant</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>before_import</code></td>
|
||
<td>Avant l'import.</td>
|
||
<td>Oui</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>after_import</code></td>
|
||
<td>Après l'import'.</td>
|
||
<td>Non</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Si un événement est dit <em>bloquant</em>, lors de l'exécution des actions liées, si une des fonctions
|
||
retourne <code>false</code>, le processus s'arrêtera.</p>
|
||
</div>
|
||
<h3 id="conf-lsobject-ioformat-configuration">Configuration</h3>
|
||
<p>La configuration des déclencheurs se fait dans la définition des types d'<a href="#conf-lsobject-ioformat-ioformat">ioFormat</a>. Par
|
||
exemple, pour définir les fonctions à exécuter après l'import des LSobjects de type <em>LSpeople</em> avec
|
||
son LSioFormat <em>mycsv</em>, c'est à dire lors de leur évènement <code>after_import</code>, il faut définir la
|
||
variable suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-ioformat-__codelineno-2-1" id="__codelineno-2-1" name="__codelineno-2-1"></a><span class="x">$GLOBALS['LSobjects']['LSpeople']['ioFormat']['mycsv']['after_import']</span>
|
||
</code></pre></div>
|
||
<p>Cette variable peut contenir soit une chaine de caractères correspondant au nom de la fonction à
|
||
exécuter, soit un tableau de chaînes de caractères correspondant aux noms des fonctions à exécuter.
|
||
Il est également possible de mettre ici directement des
|
||
<a href="https://www.php.net/manual/fr/functions.anonymous.php">fonctions anonymes</a>.</p>
|
||
<h3 id="conf-lsobject-ioformat-ecriture-dune-fonction">Ecriture d'une fonction</h3>
|
||
<p>Une fonction exécutée par un déclencheur d'un ioFormat se déclare de la manière suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-ioformat-__codelineno-3-1" id="__codelineno-3-1" name="__codelineno-3-1"></a><span class="x">/*</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-3-2" id="__codelineno-3-2" name="__codelineno-3-2"></a><span class="x"> * Ma fonction à exécuter lors de l'evenement [event]</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-3-3" id="__codelineno-3-3" name="__codelineno-3-3"></a><span class="x"> *</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-3-4" id="__codelineno-3-4" name="__codelineno-3-4"></a><span class="x"> * Paramètres :</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-3-5" id="__codelineno-3-5" name="__codelineno-3-5"></a><span class="x"> * - $ioFormat : Le LSioFormat sur lequel l'évènement survient</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-3-6" id="__codelineno-3-6" name="__codelineno-3-6"></a><span class="x"> * - $data : Les données de contexte de l'évènement</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-3-7" id="__codelineno-3-7" name="__codelineno-3-7"></a><span class="x"> *</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-3-8" id="__codelineno-3-8" name="__codelineno-3-8"></a><span class="x"> * Valeurs retournées :</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-3-9" id="__codelineno-3-9" name="__codelineno-3-9"></a><span class="x"> * - True : Tout s'est bien passé</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-3-10" id="__codelineno-3-10" name="__codelineno-3-10"></a><span class="x"> * - False : Une erreur est survenue ou la fonction souhaite bloquer le</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-3-11" id="__codelineno-3-11" name="__codelineno-3-11"></a><span class="x"> * processus lors d'un évènement bloquant.</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-3-12" id="__codelineno-3-12" name="__codelineno-3-12"></a><span class="x"> */</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-3-13" id="__codelineno-3-13" name="__codelineno-3-13"></a><span class="x">function maFonction (&$ioFormat, &$data) {</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-3-14" id="__codelineno-3-14" name="__codelineno-3-14"></a>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-3-15" id="__codelineno-3-15" name="__codelineno-3-15"></a><span class="x"> // Actions</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-3-16" id="__codelineno-3-16" name="__codelineno-3-16"></a>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-3-17" id="__codelineno-3-17" name="__codelineno-3-17"></a><span class="x">}</span>
|
||
</code></pre></div>
|
||
<p>Cette fonction doit accepter deux paramètres, le LSioFormat sur lequel l'évènement survient et un
|
||
tableau des données contextuelles de l'évènement. Elle doit par ailleurs retourner <code>True</code> si tout
|
||
s'est bien passé ou <code>False</code> en cas de problème. Dans le cas d'un événement bloquant, si la fonction
|
||
retourne <code>False</code>, le processus est arrêté.</p>
|
||
<p>Les données contextuelles de l'évènement, passées en paramètre, pourront dépendre du contexte et de
|
||
l'évènement déclencheur, mais pour les moments, il s'agit toujours d'un tableau telque décrit
|
||
ci-dessous :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsobject-ioformat-__codelineno-4-1" id="__codelineno-4-1" name="__codelineno-4-1"></a><span class="x">array(</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-2" id="__codelineno-4-2" name="__codelineno-4-2"></a><span class="x"> 'input_file' => "[/path/of/import.file]",</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-3" id="__codelineno-4-3" name="__codelineno-4-3"></a><span class="x"> 'updateIfExists' => [boolean],</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-4" id="__codelineno-4-4" name="__codelineno-4-4"></a><span class="x"> 'justTry' => [boolean],</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-5" id="__codelineno-4-5" name="__codelineno-4-5"></a><span class="x"> 'objectsData' => array(</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-6" id="__codelineno-4-6" name="__codelineno-4-6"></a><span class="x"> [Données des objets chargés depuis le fichier d'import]</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-7" id="__codelineno-4-7" name="__codelineno-4-7"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-8" id="__codelineno-4-8" name="__codelineno-4-8"></a><span class="x"> 'return' => array(</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-9" id="__codelineno-4-9" name="__codelineno-4-9"></a><span class="x"> 'success' => [boolean],</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-10" id="__codelineno-4-10" name="__codelineno-4-10"></a><span class="x"> 'LSobject' => "[nom du type d'LSobject]",</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-11" id="__codelineno-4-11" name="__codelineno-4-11"></a><span class="x"> 'ioFormat' => "[nom du type d'ioFormat]",</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-12" id="__codelineno-4-12" name="__codelineno-4-12"></a><span class="x"> 'updateIfExists' => [boolean],</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-13" id="__codelineno-4-13" name="__codelineno-4-13"></a><span class="x"> 'justTry' => [boolean],</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-14" id="__codelineno-4-14" name="__codelineno-4-14"></a><span class="x"> 'imported' => array([objets importés]),</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-15" id="__codelineno-4-15" name="__codelineno-4-15"></a><span class="x"> 'updated' => array([objets mis à jour]),</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-16" id="__codelineno-4-16" name="__codelineno-4-16"></a><span class="x"> 'errors' => array(</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-17" id="__codelineno-4-17" name="__codelineno-4-17"></a><span class="x"> array(</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-18" id="__codelineno-4-18" name="__codelineno-4-18"></a><span class="x"> 'data' => [données de l'objet importé ayant déclenché l'erreur],</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-19" id="__codelineno-4-19" name="__codelineno-4-19"></a><span class="x"> 'errors' => array (</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-20" id="__codelineno-4-20" name="__codelineno-4-20"></a><span class="x"> 'globals' => array("Erreur 1", [...]),</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-21" id="__codelineno-4-21" name="__codelineno-4-21"></a><span class="x"> 'attrs' => array(</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-22" id="__codelineno-4-22" name="__codelineno-4-22"></a><span class="x"> 'attr1' => array("Erreur 1", [...]),</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-23" id="__codelineno-4-23" name="__codelineno-4-23"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-24" id="__codelineno-4-24" name="__codelineno-4-24"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-25" id="__codelineno-4-25" name="__codelineno-4-25"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-26" id="__codelineno-4-26" name="__codelineno-4-26"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-27" id="__codelineno-4-27" name="__codelineno-4-27"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-28" id="__codelineno-4-28" name="__codelineno-4-28"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-29" id="__codelineno-4-29" name="__codelineno-4-29"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsobject-ioformat-__codelineno-4-30" id="__codelineno-4-30" name="__codelineno-4-30"></a><span class="x">)</span>
|
||
</code></pre></div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Les clés <code>objectsData</code> et <code>return</code> sont des références. En cas de modification, cela influencera
|
||
respectivement sur les données utilisées pour l'import et sur le résultat de l'import tel
|
||
qu'affiché dans l'interface.</p>
|
||
</div></section><h1 class="nav-section-title-end">Ended: Objets de l'annuaire</h1><h2 class="nav-section-title">Configuration des addons (LSaddons)</h2><section class="print-page" id="conf-lsaddon"><h1 id="conf-lsaddon-configuration-des-lsaddons">Configuration des LSaddons</h1>
|
||
<p>Cette partie décrit la manière de configurer les différents LSaddons actuellement supportés par
|
||
LdapSaisie. Ces addons peuvent avoir un fichier de configuration et il sera alors stocké dans le
|
||
dossier <code>conf/LSaddons/</code> et potera le nom <code>config.LSaddons.[addon name].php</code>.</p></section><section class="print-page" id="conf-lsaddon-lsaddon_accesslog"><h1 id="conf-lsaddon-lsaddon_accesslog-lsaddon_accesslog">LSaddon_accesslog</h1>
|
||
<p>Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> fournit la fonction <code>showObjectAccessLogs()</code>
|
||
pouvant être utilisée comme <a href="#conf-lsobject-customactions-customactions">customActions</a> et
|
||
permettant d'afficher les logs d'accès produits par
|
||
<a href="https://www.openldap.org/doc/admin24/overlays.html#Access%20Logging">l'overlay OpenLDAP accesslog</a>
|
||
sur un objet de l'annuaire.</p>
|
||
<p>La constante <code>LS_ACCESSLOG_BASEDN</code> du fichier de configuration de l'addon
|
||
(<code>conf/LSaddons/config.LSaddons.accesslog.php</code>) permet d'indiquer le base DN de la base stockant les
|
||
logs :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>// Accesslog base DN
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a>define('LS_ACCESSLOG_BASEDN', 'cn=ldapsaisie-accesslog');
|
||
</code></pre></div>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">Warning</p>
|
||
<p>LdapSaisie se connectera à la base stockant les logs d'accès de l'annuaire avec les mêmes
|
||
paramètres de connexion que pour la base principale (excepté le base DN). Pensez à ajuster les
|
||
ACLs de la base stockant les logs d'accès pour autoriser l'utilisateur d'LdapSaisie à se
|
||
connecter et lire les informations qu'elle contient.</p>
|
||
<p><strong>Exemple d'ACL à mettre en place :</strong>
|
||
</p><div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a>to *
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a> by dn.exact=uid=ldapsaisie,ou=sysaccounts,o=ls read
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a> by * break
|
||
</code></pre></div><p></p>
|
||
</div>
|
||
<p>Ci-dessous, vous trouverez un exemple de configuration de la fonction <code>showObjectAccessLogs()</code> comme
|
||
<a href="#conf-lsobject-customactions-customactions">customActions</a> :</p>
|
||
<p><strong>Exemple d'utilisation :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-2-1" id="__codelineno-2-1" name="__codelineno-2-1"></a><span class="x">$GLOBALS['LSobjects']['LSpeople'] = array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-2-2" id="__codelineno-2-2" name="__codelineno-2-2"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-2-3" id="__codelineno-2-3" name="__codelineno-2-3"></a><span class="x"> 'customActions' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-2-4" id="__codelineno-2-4" name="__codelineno-2-4"></a><span class="x"> 'showObjectAccessLogs' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-2-5" id="__codelineno-2-5" name="__codelineno-2-5"></a><span class="x"> 'function' => 'showObjectAccessLogs',</span>
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-2-6" id="__codelineno-2-6" name="__codelineno-2-6"></a><span class="x"> 'label' => 'Show access logs',</span>
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-2-7" id="__codelineno-2-7" name="__codelineno-2-7"></a><span class="x"> 'hideLabel' => true,</span>
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-2-8" id="__codelineno-2-8" name="__codelineno-2-8"></a><span class="x"> 'noConfirmation' => true,</span>
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-2-9" id="__codelineno-2-9" name="__codelineno-2-9"></a><span class="x"> 'disableOnSuccessMsg' => true,</span>
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-2-10" id="__codelineno-2-10" name="__codelineno-2-10"></a><span class="x"> 'icon' => 'clock',</span>
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-2-11" id="__codelineno-2-11" name="__codelineno-2-11"></a><span class="x"> 'rights' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-2-12" id="__codelineno-2-12" name="__codelineno-2-12"></a><span class="x"> 'admin'</span>
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-2-13" id="__codelineno-2-13" name="__codelineno-2-13"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-2-14" id="__codelineno-2-14" name="__codelineno-2-14"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-2-15" id="__codelineno-2-15" name="__codelineno-2-15"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-2-16" id="__codelineno-2-16" name="__codelineno-2-16"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsaddon-lsaddon_accesslog-__codelineno-2-17" id="__codelineno-2-17" name="__codelineno-2-17"></a><span class="x">);</span>
|
||
</code></pre></div></section><section class="print-page" id="conf-lsaddon-lsaddon_asterisk"><h1 id="conf-lsaddon-lsaddon_asterisk-lsaddon_asterisk">LSaddon_asterisk</h1>
|
||
<p>Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> est utilisé pour gérer les fonctionnalités
|
||
spécifiques au serveur de téléphonie Asterisk. Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a>
|
||
donne accès à une fonction permettant l'encodage d'un mot de passe au format spécifique attendu par
|
||
Asterisk. Ce format est un hash MD5 d'une chaine de caractère composée du nom d'utilisateur, d'une
|
||
chaine fixe spécifiée dans la configuration d'Asterisk et du mot de passe en clair.</p></section><section class="print-page" id="conf-lsaddon-lsaddon_exportsearchresultascsv"><h1 id="conf-lsaddon-lsaddon_exportsearchresultascsv-lsaddon_exportsearchresultascsv">LSaddon_exportSearchResultAsCSV</h1>
|
||
<p>Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> fournie une fonction du même nom pouvant être
|
||
utilisée comme <a href="#conf-lsobject-lssearch-customactions_1">customActions</a> et permettant de télécharger
|
||
le résultat d'une recherche au format CSV. L'export généré reprend exactement le contenu des
|
||
colonnes du tableau du résultat de la recherche. Le DN de l'objet LDAP correspondant est également
|
||
fournis dans une colonne.</p>
|
||
<p>Des paramètres de configuration sont disponibles dans le fichier de configuration
|
||
<code>config.LSaddons.exportSearchResultAsCSV.php</code>. Ils permettent notamment de contrôller le format du
|
||
fichier CSV généré.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="x">// CSV file delimiter</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="x">define('LS_EXPORTSEARCHRESULTASCSV_DELIMITER',',');</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="x">// CSV file enclosure</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="x">define('LS_EXPORTSEARCHRESULTASCSV_ENCLOSURE','"');</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="x">// CSV file escape character (available since PHP 5.5.4)</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="x">define('LS_EXPORTSEARCHRESULTASCSV_ESCAPE_CHAR','\\');</span>
|
||
</code></pre></div>
|
||
<p>Ci-dessous, vous trouverez un exemple de configuration de la fonction <code>exportSearchResultAsCSV()</code>
|
||
comme <a href="#conf-lsobject-lssearch-customactions_1">customActions</a> :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a><span class="x">$GLOBALS['LSobjects']['LSpeople']['LSsearch'] = array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a><span class="x"> 'customActions' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a><span class="x"> 'exportSearchResultAsCSV' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a><span class="x"> 'label' => 'Export result as CSV',</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a><span class="x"> 'icon' => 'export_csv',</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a><span class="x"> 'function' => 'exportSearchResultAsCSV',</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-1-8" id="__codelineno-1-8" name="__codelineno-1-8"></a><span class="x"> 'noConfirmation' => true,</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-1-9" id="__codelineno-1-9" name="__codelineno-1-9"></a><span class="x"> 'disableOnSuccessMsg' => true,</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-1-10" id="__codelineno-1-10" name="__codelineno-1-10"></a><span class="x"> 'rights' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-1-11" id="__codelineno-1-11" name="__codelineno-1-11"></a><span class="x"> 'admin'</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-1-12" id="__codelineno-1-12" name="__codelineno-1-12"></a><span class="x"> )</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-1-13" id="__codelineno-1-13" name="__codelineno-1-13"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-1-14" id="__codelineno-1-14" name="__codelineno-1-14"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-1-15" id="__codelineno-1-15" name="__codelineno-1-15"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-__codelineno-1-16" id="__codelineno-1-16" name="__codelineno-1-16"></a><span class="x">);</span>
|
||
</code></pre></div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Le label et l'icône fournis dans cet exemple sont traduits et délivrés avec LdapSaisie.</p>
|
||
</div></section><section class="print-page" id="conf-lsaddon-lsaddon_impersonate"><h1 id="conf-lsaddon-lsaddon_impersonate-lsaddon_impersonate">LSaddon_impersonate</h1>
|
||
<p>Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> fournie une fonction du même nom pouvant être
|
||
utilisée comme <a href="#conf-lsobject-customactions-customactions">customActions</a> et permettant de se
|
||
reconnecter en tant qu'un autre utilisateur de l'annuaire.</p>
|
||
<p>Ci-dessous, vous trouverez un exemple de configuration de la fonction <code>impersonate()</code> comme
|
||
<a href="#conf-lsobject-customactions-customactions">customActions</a> :</p>
|
||
<p><strong>Exemple d'utilisation :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_impersonate-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="x">$GLOBALS['LSobjects']['LSpeople'] = array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_impersonate-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsaddon-lsaddon_impersonate-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="x"> 'customActions' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_impersonate-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="x"> 'impersonate' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_impersonate-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="x"> 'function' => 'impersonate',</span>
|
||
<a href="#conf-lsaddon-lsaddon_impersonate-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="x"> 'label' => 'Reconnect as this user',</span>
|
||
<a href="#conf-lsaddon-lsaddon_impersonate-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="x"> 'hideLabel' => True,</span>
|
||
<a href="#conf-lsaddon-lsaddon_impersonate-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="x"> 'noConfirmation' => true,</span>
|
||
<a href="#conf-lsaddon-lsaddon_impersonate-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="x"> 'disableOnSuccessMsg' => true,</span>
|
||
<a href="#conf-lsaddon-lsaddon_impersonate-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="x"> 'icon' => 'user_go',</span>
|
||
<a href="#conf-lsaddon-lsaddon_impersonate-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="x"> 'rights' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_impersonate-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="x"> 'admin'</span>
|
||
<a href="#conf-lsaddon-lsaddon_impersonate-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_impersonate-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_impersonate-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_impersonate-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsaddon-lsaddon_impersonate-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a><span class="x">);</span>
|
||
</code></pre></div></section><section class="print-page" id="conf-lsaddon-lsaddon_lsaccessrightsmatrixview"><h1 id="conf-lsaddon-lsaddon_lsaccessrightsmatrixview-lsaddon_lsaccessrightsmatrixview">LSaddon_LSaccessRightsMatrixView</h1>
|
||
<p>Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> offre une interface de visualisation des droits
|
||
d'accès des différents <a href="#conf-global-ldap-lsprofile-profils-dutilisateurs">LSprofiles</a> configurés.
|
||
Pour chaque type d'objet, la matrice des droits d'accès par attribut et par profil est affiché sous
|
||
la forme d'un tableau.</p>
|
||
<p>Le fichier de configuration permet de définir au travers la variable
|
||
<code>$GLOBALS['LSaccessRightsMatrixView_allowed_LSprofiles']</code> la liste des
|
||
<a href="#conf-global-ldap-lsprofile-profils-dutilisateurs">LSprofiles</a> autorisés à accéder à cette interface.</p></section><section class="print-page" id="conf-lsaddon-lsaddon_mail"><h1 id="conf-lsaddon-lsaddon_mail-lsaddon_mail">LSaddon_mail</h1>
|
||
<p>Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> est utilisé pour gérer l'envoi de courriels. Il
|
||
utilise pour cela les librairies <a href="http://pear.php.net/">PEAR</a> <em>Mail</em> et <em>Mail_Mime</em> qui doivent être
|
||
installés.</p>
|
||
<p>Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> offre aussi la possibilité d'envoyer des
|
||
courriels dont le contenu est construit à partir de modèles. Ces modèles sont enregistrés dans des
|
||
fichiers textes stockés (voir <code>$GLOBALS['MAIL_TEMPLATES_DIRECTORIES']</code>). Pour chaque modèle, vous
|
||
devez fournir trois fichiers portant le même nom mais avec des extensions différentes :</p>
|
||
<ul>
|
||
<li><code>template.subject</code> : le sujet du courriel. Note : seule la première ligne du fichier est utilisé
|
||
(et passée dans la fonction <code>trim()</code>)</li>
|
||
<li><code>template.html</code> : le contenu HTML du courriel</li>
|
||
<li><code>template.txt</code>: le contenu texte du courriel</li>
|
||
</ul>
|
||
<p>Ces trois fichiers sont utilisés en tant que modèle <a href="http://www.smarty.net/">Smarty</a> et seront
|
||
construit en utilisant les variables fournies dans le contexte d'envoi des courriels. À noter que le
|
||
moteur Smarty utilisé pour la génération du contenu de ces courriels n'est pas le même que celui
|
||
utilisé par LdapSaisie pour l'affichage des pages.</p>
|
||
<p>Par ailleurs, cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> fourni une vue de gestion des
|
||
modèles de courriels existants (voir <code>$GLOBALS['MAIL_TEMPLATES_EDITOR_VIEW_ACCESS']</code> pour la
|
||
configuration des accès).</p>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">Warning</p>
|
||
<p>Cette vue n'est pas conçues pour être mise entre toutes les mains. La sécurisation de modèles de
|
||
courriels étant très complexe, il est fortement recommandé de n'ouvrir l'accès à cette vue
|
||
qu'aux utilisateurs avertis et de confiances.</p>
|
||
</div>
|
||
<p>Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> doit être configuré en éditant son
|
||
fichier de configuration <code>config.LSaddons.mail.php</code>.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="x"> ***********************************************</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="x"> * Configuration du support de l'envoi de mail *</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="x"> ***********************************************</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="x"> */</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="x">// Pear :: Mail</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="x">define('PEAR_MAIL','/usr/share/php/Mail.php');</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="x">// Pear :: Mail_mime</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="x">define('PEAR_MAIL_MIME','/usr/share/php/Mail/mime.php');</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="x">/*</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a><span class="x"> * Méthode d'envoie :</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a><span class="x"> * - mail : envoie avec la méthode PHP mail()</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a><span class="x"> * - sendmail : envoie la commande sendmail du système</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a><span class="x"> * - smtp : envoie en utilisant un serveur SMTP</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a><span class="x"> */</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a><span class="x">define('MAIL_SEND_METHOD','smtp');</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a><span class="x">/*</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a><span class="x"> * Paramètres d'envoie :</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-22" id="__codelineno-0-22" name="__codelineno-0-22"></a><span class="x"> * Ces paramètres dépende de la méthode utilisé. Repporté vous à la documentation</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-23" id="__codelineno-0-23" name="__codelineno-0-23"></a><span class="x"> * de PEAR :: Mail pour plus d'information.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-24" id="__codelineno-0-24" name="__codelineno-0-24"></a><span class="x"> * Lien : http://pear.php.net/manual/en/package.mail.mail.factory.php</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-25" id="__codelineno-0-25" name="__codelineno-0-25"></a><span class="x"> * Infos :</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-26" id="__codelineno-0-26" name="__codelineno-0-26"></a><span class="x"> * List of parameter for the backends</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-27" id="__codelineno-0-27" name="__codelineno-0-27"></a><span class="x"> * mail</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-28" id="__codelineno-0-28" name="__codelineno-0-28"></a><span class="x"> * o If safe mode is disabled, $params will be passed as the fifth</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-29" id="__codelineno-0-29" name="__codelineno-0-29"></a><span class="x"> * argument to the PHP mail() function. If $params is an array,</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-30" id="__codelineno-0-30" name="__codelineno-0-30"></a><span class="x"> * its elements will be joined as a space-delimited string.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-31" id="__codelineno-0-31" name="__codelineno-0-31"></a><span class="x"> * sendmail</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-32" id="__codelineno-0-32" name="__codelineno-0-32"></a><span class="x"> * o $params["sendmail_path"] - The location of the sendmail program</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-33" id="__codelineno-0-33" name="__codelineno-0-33"></a><span class="x"> * on the filesystem. Default is /usr/bin/sendmail.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-34" id="__codelineno-0-34" name="__codelineno-0-34"></a><span class="x"> * o $params["sendmail_args"] - Additional parameters to pass to the</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-35" id="__codelineno-0-35" name="__codelineno-0-35"></a><span class="x"> * sendmail. Default is -i.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-36" id="__codelineno-0-36" name="__codelineno-0-36"></a><span class="x"> * smtp</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-37" id="__codelineno-0-37" name="__codelineno-0-37"></a><span class="x"> * o $params["host"] - The server to connect. Default is localhost.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-38" id="__codelineno-0-38" name="__codelineno-0-38"></a><span class="x"> * o $params["port"] - The port to connect. Default is 25.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-39" id="__codelineno-0-39" name="__codelineno-0-39"></a><span class="x"> * o $params["auth"] - Whether or not to use SMTP authentication.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-40" id="__codelineno-0-40" name="__codelineno-0-40"></a><span class="x"> * Default is FALSE.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-41" id="__codelineno-0-41" name="__codelineno-0-41"></a><span class="x"> * o $params["username"] - The username to use for SMTP authentication.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-42" id="__codelineno-0-42" name="__codelineno-0-42"></a><span class="x"> * o $params["password"] - The password to use for SMTP authentication.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-43" id="__codelineno-0-43" name="__codelineno-0-43"></a><span class="x"> * o $params["localhost"] - The value to give when sending EHLO or HELO.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-44" id="__codelineno-0-44" name="__codelineno-0-44"></a><span class="x"> * Default is localhost</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-45" id="__codelineno-0-45" name="__codelineno-0-45"></a><span class="x"> * o $params["timeout"] - The SMTP connection timeout.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-46" id="__codelineno-0-46" name="__codelineno-0-46"></a><span class="x"> * Default is NULL (no timeout).</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-47" id="__codelineno-0-47" name="__codelineno-0-47"></a><span class="x"> * o $params["verp"] - Whether to use VERP or not. Default is FALSE.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-48" id="__codelineno-0-48" name="__codelineno-0-48"></a><span class="x"> * o $params["debug"] - Whether to enable SMTP debug mode or not.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-49" id="__codelineno-0-49" name="__codelineno-0-49"></a><span class="x"> * Default is FALSE.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-50" id="__codelineno-0-50" name="__codelineno-0-50"></a><span class="x"> * o $params["persist"] - Indicates whether or not the SMTP connection</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-51" id="__codelineno-0-51" name="__codelineno-0-51"></a><span class="x"> * should persist over multiple calls to the send() method.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-52" id="__codelineno-0-52" name="__codelineno-0-52"></a><span class="x"> */</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-53" id="__codelineno-0-53" name="__codelineno-0-53"></a><span class="x">$GLOBALS['MAIL_SEND_PARAMS'] = NULL;</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-54" id="__codelineno-0-54" name="__codelineno-0-54"></a>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-55" id="__codelineno-0-55" name="__codelineno-0-55"></a><span class="x">/*</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-56" id="__codelineno-0-56" name="__codelineno-0-56"></a><span class="x"> * Headers :</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-57" id="__codelineno-0-57" name="__codelineno-0-57"></a><span class="x"> */</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-58" id="__codelineno-0-58" name="__codelineno-0-58"></a><span class="x">$GLOBALS['MAIL_HEARDERS = array();</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-59" id="__codelineno-0-59" name="__codelineno-0-59"></a>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-60" id="__codelineno-0-60" name="__codelineno-0-60"></a><span class="x">// Catch all sent emails</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-61" id="__codelineno-0-61" name="__codelineno-0-61"></a><span class="x">$GLOBALS['MAIL_CATCH_ALL'] = array();</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-62" id="__codelineno-0-62" name="__codelineno-0-62"></a>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-63" id="__codelineno-0-63" name="__codelineno-0-63"></a><span class="x">/**</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-64" id="__codelineno-0-64" name="__codelineno-0-64"></a><span class="x"> * Email templates</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-65" id="__codelineno-0-65" name="__codelineno-0-65"></a><span class="x"> *</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-66" id="__codelineno-0-66" name="__codelineno-0-66"></a><span class="x"> * This addon offer ability to send email by using templates. Email templates are stored in</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-67" id="__codelineno-0-67" name="__codelineno-0-67"></a><span class="x"> * full-text files in configured directories (see $GLOBALS['MAIL_TEMPLATES_DIRECTORIES']). For each</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-68" id="__codelineno-0-68" name="__codelineno-0-68"></a><span class="x"> * template, you have to provide three files with the same name but with different extensions:</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-69" id="__codelineno-0-69" name="__codelineno-0-69"></a><span class="x"> * - template.subject: the email subject. Note: only the first line is used (and stripped)</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-70" id="__codelineno-0-70" name="__codelineno-0-70"></a><span class="x"> * - template.html: the HTML content of the email</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-71" id="__codelineno-0-71" name="__codelineno-0-71"></a><span class="x"> * - template.txt: the text content of the email</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-72" id="__codelineno-0-72" name="__codelineno-0-72"></a><span class="x"> * All these files will be used as Smarty templates and will be computed using variables provided</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-73" id="__codelineno-0-73" name="__codelineno-0-73"></a><span class="x"> * in the sending context. Note that the Smarty object used to compute the template is not the same</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-74" id="__codelineno-0-74" name="__codelineno-0-74"></a><span class="x"> * as the one used by LdapSaisie to display pages.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-75" id="__codelineno-0-75" name="__codelineno-0-75"></a><span class="x"> *</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-76" id="__codelineno-0-76" name="__codelineno-0-76"></a><span class="x"> * Futhermore, this addon offer a view to list and edit existing template (see</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-77" id="__codelineno-0-77" name="__codelineno-0-77"></a><span class="x"> * $GLOBALS['MAIL_TEMPLATES_EDITOR_VIEW_ACCESS'] to configured access).</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-78" id="__codelineno-0-78" name="__codelineno-0-78"></a><span class="x"> */</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-79" id="__codelineno-0-79" name="__codelineno-0-79"></a>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-80" id="__codelineno-0-80" name="__codelineno-0-80"></a><span class="x">// List of directory paths where as stored mail templates</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-81" id="__codelineno-0-81" name="__codelineno-0-81"></a><span class="x">// Notes:</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-82" id="__codelineno-0-82" name="__codelineno-0-82"></a><span class="x">// - provided path could be absolute or relative. Relative path are relative to the root base</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-83" id="__codelineno-0-83" name="__codelineno-0-83"></a><span class="x">// sources LdapSaisie directory (commonly /usr/share/ldapsaisie or the src directory if you</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-84" id="__codelineno-0-84" name="__codelineno-0-84"></a><span class="x">// installed it from sources). On Debian installation, you can specify 'local/email_templates' to</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-85" id="__codelineno-0-85" name="__codelineno-0-85"></a><span class="x">// refer to /etc/ldapsaisie/local/email_templates directory/</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-86" id="__codelineno-0-86" name="__codelineno-0-86"></a><span class="x">// - Multiple directories could be specified, sorted so that the first ones take priority over</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-87" id="__codelineno-0-87" name="__codelineno-0-87"></a><span class="x">// the last one.</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-88" id="__codelineno-0-88" name="__codelineno-0-88"></a><span class="x">// - To allow users to edit them using the editor view, these directories must be</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-89" id="__codelineno-0-89" name="__codelineno-0-89"></a><span class="x">// writable by PHP process (commonly runed as www-data).</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-90" id="__codelineno-0-90" name="__codelineno-0-90"></a><span class="x">$GLOBALS['MAIL_TEMPLATES_DIRECTORIES'] = array('local/email_templates');</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-91" id="__codelineno-0-91" name="__codelineno-0-91"></a>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-92" id="__codelineno-0-92" name="__codelineno-0-92"></a><span class="x">// List of granted LSprofiles to access mail templates editor view</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-93" id="__codelineno-0-93" name="__codelineno-0-93"></a><span class="x">// WARNING: Sanitizing mail templates is hell... EXPOSE THIS VIEW ONLY TO TRUSTED USERS!</span>
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-0-94" id="__codelineno-0-94" name="__codelineno-0-94"></a><span class="x">$GLOBALS['MAIL_TEMPLATES_EDITOR_VIEW_ACCESS'] = array('admin');</span>
|
||
</code></pre></div>
|
||
<p>Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> offre avant tout la possibilité d'envoyer des
|
||
courriels en utilisant la fonction PHP <code>sendMail()</code> :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_mail-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a>bool sendMail(
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a> <string> $to,
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a> <string> $subject,
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a> <string> $msg,
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a> <array(string)> $headers,
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a> <array> $attachments,
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a> <string> $eol,
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-1-8" id="__codelineno-1-8" name="__codelineno-1-8"></a> <string> $encoding,
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-1-9" id="__codelineno-1-9" name="__codelineno-1-9"></a> <boolean> $html
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-1-10" id="__codelineno-1-10" name="__codelineno-1-10"></a>);
|
||
</code></pre></div>
|
||
<p>Pour l'envoi de courriels en utilisant un modèle, il faut utiliser la fonction PHP
|
||
<code>sendMailFromTemplate()</code> :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_mail-__codelineno-2-1" id="__codelineno-2-1" name="__codelineno-2-1"></a>bool sendMailFromTemplate(
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-2-2" id="__codelineno-2-2" name="__codelineno-2-2"></a> <string> $tplname,
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-2-3" id="__codelineno-2-3" name="__codelineno-2-3"></a> <string> $to,
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-2-4" id="__codelineno-2-4" name="__codelineno-2-4"></a> <array> $variables,
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-2-5" id="__codelineno-2-5" name="__codelineno-2-5"></a> <array(string)> $headers,
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-2-6" id="__codelineno-2-6" name="__codelineno-2-6"></a> <array> $attachments
|
||
<a href="#conf-lsaddon-lsaddon_mail-__codelineno-2-7" id="__codelineno-2-7" name="__codelineno-2-7"></a>);
|
||
</code></pre></div></section><section class="print-page" id="conf-lsaddon-lsaddon_maildir"><h1 id="conf-lsaddon-lsaddon_maildir-lsaddon_maildir">LSaddon_maildir</h1>
|
||
<p>Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> est utilisé pour gérer la manipulation distante
|
||
de maildir.</p>
|
||
<p><strong>FIXME</strong></p></section><section class="print-page" id="conf-lsaddon-lsaddon_mailquota"><h1 id="conf-lsaddon-lsaddon_mailquota-lsaddon_mailquota">LSaddon_mailquota</h1>
|
||
<p>Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> fournie une fonction <code>mailquota_get_usage</code>
|
||
pouvant être utilisée pour récupérer l'utilisation du quota d'une boîte mail IMAP. Pour cela,
|
||
LdapSaisie se connecte au serveur IMAP en utilisant un compte maître.</p>
|
||
<p>Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> fournie une également une fonction
|
||
<code>mailquota_show_usage</code> pouvant être utilisée comme
|
||
<a href="#conf-lsobject-customactions-customactions">customActions</a> et permettant d'afficher l'utilisation
|
||
du quota de la boîte mail correspondante via une message dynamique (<code>LSinfo</code>).</p>
|
||
<p>Des paramètres de configuration sont disponibles dans le fichier de configuration
|
||
<code>config.LSaddons.mailquota.php</code>.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="x">// IMAP Mailbox connection string LSformat (composed with LSldapObject attributes)</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="x">// See : https://php.net/imap_open (parameter $mailbox)</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="x">define('MAILQUOTA_IMAP_MAILBOX','{localhost}');</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="x">// IMAP Master user</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="x">define('MAILQUOTA_IMAP_MASTER_USER', 'ldapsaisie');</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="x">// IMAP Master user's password</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="x">define('MAILQUOTA_IMAP_MASTER_USER_PWD', 'secret');</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="x">// IMAP Master user LSformat composed with :</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="x">// * masteruser = master username (MAILQUOTA_IMAP_MASTER_USER)</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a><span class="x">// * LSldapObject attributes</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a><span class="x">define('MAILQUOTA_IMAP_MASTER_USER_FORMAT', '%{mail}*%{masteruser}');</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a><span class="x">// IMAP quota root mailbox</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a><span class="x">define('MAILQUOTA_IMAP_QUOTA_ROOT_MAILBOX', 'INBOX');</span>
|
||
</code></pre></div>
|
||
<p>Ci-dessous, vous trouverez un exemple de configuration de la fonction <code>mailquota_show_usage()</code>
|
||
comme <a href="#conf-lsobject-customactions-customactions">customActions</a> :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a><span class="x">$GLOBALS['LSobjects']['LSpeople'] = array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a><span class="x"> 'customActions' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a><span class="x"> 'showmailquotausage' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a><span class="x"> 'function' => 'mailquota_show_usage',</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a><span class="x"> 'label' => 'Show mail quota usage',</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a><span class="x"> 'noConfirmation' => true,</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-1-8" id="__codelineno-1-8" name="__codelineno-1-8"></a><span class="x"> 'disableOnSuccessMsg' => true,</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-1-9" id="__codelineno-1-9" name="__codelineno-1-9"></a><span class="x"> 'icon' => 'mail',</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-1-10" id="__codelineno-1-10" name="__codelineno-1-10"></a><span class="x"> 'rights' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-1-11" id="__codelineno-1-11" name="__codelineno-1-11"></a><span class="x"> 'admin'</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-1-12" id="__codelineno-1-12" name="__codelineno-1-12"></a><span class="x"> )</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-1-13" id="__codelineno-1-13" name="__codelineno-1-13"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-1-14" id="__codelineno-1-14" name="__codelineno-1-14"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-1-15" id="__codelineno-1-15" name="__codelineno-1-15"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-1-16" id="__codelineno-1-16" name="__codelineno-1-16"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsaddon-lsaddon_mailquota-__codelineno-1-17" id="__codelineno-1-17" name="__codelineno-1-17"></a><span class="x">);</span>
|
||
</code></pre></div></section><section class="print-page" id="conf-lsaddon-lsaddon_phpldapadmin"><h1 id="conf-lsaddon-lsaddon_phpldapadmin-lsaddon_phpldapadmin">LSaddon_phpldapadmin</h1>
|
||
<p>Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> est utilisé pour permettre un lien facile entre
|
||
le logiciel <a href="https://github.com/leenooks/phpLDAPadmin">PhpLdapAdmin</a> et LdapSaisie. Il sera possible
|
||
ainsi à partir d'un objet dans LdapSaisie de voir ce même objet dans
|
||
<a href="https://github.com/leenooks/phpLDAPadmin">PhpLdapAdmin</a>.</p>
|
||
<p>Il est necessaire de configurer l'URL de votre installation de
|
||
<a href="https://github.com/leenooks/phpLDAPadmin">PhpLdapAdmin</a> dans le fichier de configuration
|
||
<code>config.LSaddons.phpldapadmin.php</code>.</p>
|
||
<p><strong>Structure du fichier :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="x">// PhpLdapAdmin View Object URL format</span>
|
||
<a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="x">define('LS_PHPLDAPADMIN_VIEW_OBJECT_URL_FORMAT','//'.$_SERVER['SERVER_NAME'].'/phpldapadmin/cmd.php?cmd=template_engine&server_id=0&dn=%{dn}');</span>
|
||
</code></pre></div>
|
||
<p>Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> offre la possibilité d'utilisé la fonction PHP
|
||
<code>redirectToPhpLdapAdmin()</code> comme <a href="#conf-lsobject-customactions-customactions">customActions</a>.</p>
|
||
<p><strong>Exemple d'utilisation :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a><span class="x">$GLOBALS['LSobjects']['LSpeople'] = array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a><span class="x"> 'customActions' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a><span class="x"> 'redirectPhpLdapAdmin' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a><span class="x"> 'function' => 'redirectToPhpLdapAdmin',</span>
|
||
<a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a><span class="x"> 'label' => 'See in PhpLdapAdmin',</span>
|
||
<a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a><span class="x"> 'hideLabel' => True,</span>
|
||
<a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-1-8" id="__codelineno-1-8" name="__codelineno-1-8"></a><span class="x"> 'noConfirmation' => true,</span>
|
||
<a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-1-9" id="__codelineno-1-9" name="__codelineno-1-9"></a><span class="x"> 'disableOnSuccessMsg' => true,</span>
|
||
<a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-1-10" id="__codelineno-1-10" name="__codelineno-1-10"></a><span class="x"> 'icon' => 'phpldapadmin',</span>
|
||
<a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-1-11" id="__codelineno-1-11" name="__codelineno-1-11"></a><span class="x"> 'rights' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-1-12" id="__codelineno-1-12" name="__codelineno-1-12"></a><span class="x"> 'admin'</span>
|
||
<a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-1-13" id="__codelineno-1-13" name="__codelineno-1-13"></a><span class="x"> )</span>
|
||
<a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-1-14" id="__codelineno-1-14" name="__codelineno-1-14"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-1-15" id="__codelineno-1-15" name="__codelineno-1-15"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-1-16" id="__codelineno-1-16" name="__codelineno-1-16"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsaddon-lsaddon_phpldapadmin-__codelineno-1-17" id="__codelineno-1-17" name="__codelineno-1-17"></a><span class="x">);</span>
|
||
</code></pre></div></section><section class="print-page" id="conf-lsaddon-lsaddon_ppolicy"><h1 id="conf-lsaddon-lsaddon_ppolicy-lsaddon_ppolicy">LSaddon_ppolicy</h1>
|
||
<p>Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> fourni :</p>
|
||
<ul>
|
||
<li>
|
||
<p>une fonction <code>ppolicy_extraDisplayColumn_password_expiration</code> pouvant être utilisée pour la
|
||
génération d'une <em>extraDisplayedColumn</em> affichant l'état d'expiration du mot de passe des objets
|
||
d'une recherche.</p>
|
||
<p><strong>Exemple d'utilisation :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a>$GLOBALS['LSobjects']['LSpeople']['LSsearch'] = array (
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a> [...]
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> 'extraDisplayedColumns' => array (
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> [...]
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> 'password_expiration' => array (
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> 'label' => 'Password expiration',
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> 'generateFunction' => 'ppolicy_extraDisplayColumn_password_expiration',
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> 'additionalAttrs' => array('pwdChangedTime', 'pwdPolicySubentry'),
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> 'escape' => false,
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> 'cssStyle' => 'width: 14em; text-align: center;'
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> ),
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> [...]
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> ),
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a> [...]
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a>);
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>une fonction <code>ppolicy_export_search_info</code> pouvant être utilisée comme
|
||
<a href="#conf-lsobject-lssearch-customactions_1">actions personnalisées sur les recherches d'LSobjects</a>
|
||
pour exporter au format CSV les informations des politiques de mots de passe des objets retournés
|
||
par la recherche.</p>
|
||
<p><strong>Exemple d'utilisation :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a><span class="x">$GLOBALS['LSobjects']['LSpeople']['LSsearch'] = array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a><span class="x"> 'customActions' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a><span class="x"> 'exportPpolicyInfo' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a><span class="x"> 'label' => 'Export password policy info',</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a><span class="x"> 'icon' => 'export_csv',</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a><span class="x"> 'function' => 'ppolicy_export_search_info',</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-1-8" id="__codelineno-1-8" name="__codelineno-1-8"></a><span class="x"> 'noConfirmation' => true,</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-1-9" id="__codelineno-1-9" name="__codelineno-1-9"></a><span class="x"> 'disableOnSuccessMsg' => true,</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-1-10" id="__codelineno-1-10" name="__codelineno-1-10"></a><span class="x"> 'rights' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-1-11" id="__codelineno-1-11" name="__codelineno-1-11"></a><span class="x"> 'admin',</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-1-12" id="__codelineno-1-12" name="__codelineno-1-12"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-1-13" id="__codelineno-1-13" name="__codelineno-1-13"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-1-14" id="__codelineno-1-14" name="__codelineno-1-14"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-1-15" id="__codelineno-1-15" name="__codelineno-1-15"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-1-16" id="__codelineno-1-16" name="__codelineno-1-16"></a><span class="x">);</span>
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>la méthode d'API <code>exportPpolicyInfo</code> permettant d'exporter les informations des politiques de mots
|
||
de passe de tous les objets d'un type donné. Cette méthode est accessible via l'URL au format
|
||
suivant : <code>/api/1.0/exportPpolicyInfo/[object type]</code></li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>la commande CLI <code>export_ppolicy_info</code> permettant d'exporter les informations des politiques de
|
||
mots de passe de tous les objets d'un type donné.</p>
|
||
<p><strong>Utilisation :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-2-1" id="__codelineno-2-1" name="__codelineno-2-1"></a>ldapsaisie<span class="w"> </span>export_ppolicy_info<span class="w"> </span><span class="o">[</span>object<span class="w"> </span>type<span class="o">]</span><span class="w"> </span><span class="o">[</span>-o<span class="p">|</span>--output<span class="w"> </span>filepath<span class="o">]</span><span class="w"> </span><span class="o">[</span>-j<span class="p">|</span>--json<span class="w"> </span><span class="o">[</span>-p<span class="p">|</span>--pretty<span class="o">]]</span>
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<p>Des paramètres de configuration sont disponibles dans le fichier de configuration
|
||
<code>config.LSaddons.ppolicy.php</code>.</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-1" id="__codelineno-3-1" name="__codelineno-3-1"></a><span class="x">// Default password policy object DN (set to null if no default policy is configured)</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-2" id="__codelineno-3-2" name="__codelineno-3-2"></a><span class="x">define('LS_PPOLICY_DEFAULT_DN', null);</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-3" id="__codelineno-3-3" name="__codelineno-3-3"></a>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-4" id="__codelineno-3-4" name="__codelineno-3-4"></a><span class="x">// Ppolicy password warning expiration threshold (in seconds)</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-5" id="__codelineno-3-5" name="__codelineno-3-5"></a><span class="x">define('LS_PPOLICY_WARNING_EXPIRATION_THRESHOLD', 7 * 86400);</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-6" id="__codelineno-3-6" name="__codelineno-3-6"></a>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-7" id="__codelineno-3-7" name="__codelineno-3-7"></a><span class="x">// Ppolicy password critical expiration threshold (in seconds)</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-8" id="__codelineno-3-8" name="__codelineno-3-8"></a><span class="x">define('LS_PPOLICY_CRITICAL_EXPIRATION_THRESHOLD', 2 * 86400);</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-9" id="__codelineno-3-9" name="__codelineno-3-9"></a>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-10" id="__codelineno-3-10" name="__codelineno-3-10"></a><span class="x">// CSV file delimiter</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-11" id="__codelineno-3-11" name="__codelineno-3-11"></a><span class="x">define('LS_PPOLICY_CSV_DELIMITER',';');</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-12" id="__codelineno-3-12" name="__codelineno-3-12"></a>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-13" id="__codelineno-3-13" name="__codelineno-3-13"></a><span class="x">// CSV file enclosure</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-14" id="__codelineno-3-14" name="__codelineno-3-14"></a><span class="x">define('LS_PPOLICY_CSV_ENCLOSURE','"');</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-15" id="__codelineno-3-15" name="__codelineno-3-15"></a>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-16" id="__codelineno-3-16" name="__codelineno-3-16"></a><span class="x">// CSV file escape character (available since PHP 5.5.4)</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-17" id="__codelineno-3-17" name="__codelineno-3-17"></a><span class="x">define('LS_PPOLICY_CSV_ESCAPE_CHAR','\\');</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-18" id="__codelineno-3-18" name="__codelineno-3-18"></a>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-19" id="__codelineno-3-19" name="__codelineno-3-19"></a><span class="x">// List of LSprofiles who are granted to use the exportPpolicyInfo API method</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-20" id="__codelineno-3-20" name="__codelineno-3-20"></a><span class="x">$GLOBALS['LS_PPOLICY_API_GRANTED_PROFILES'] = array('admin');</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-21" id="__codelineno-3-21" name="__codelineno-3-21"></a>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-22" id="__codelineno-3-22" name="__codelineno-3-22"></a><span class="x">// List of extra attributes to include in Ppolicy info export</span>
|
||
<a href="#conf-lsaddon-lsaddon_ppolicy-__codelineno-3-23" id="__codelineno-3-23" name="__codelineno-3-23"></a><span class="x">$GLOBALS['LS_PPOLICY_INFO_EXPORT_EXTRA_ATTRS'] = array();</span>
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>LS_PPOLICY_DEFAULT_DN</code></p>
|
||
<p>Constante définissant le DN de la politique par défaut. Si aucune politique par défaut n'est
|
||
définie, ce paramètre doit valoir <code>null</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LS_PPOLICY_WARNING_EXPIRATION_THRESHOLD</code></p>
|
||
<p>Constante définissant le seuil d'alerte pour l'expiration des mots de passe (en seconde). Par
|
||
défaut : 7 jours.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LS_PPOLICY_CRITICAL_EXPIRATION_THRESHOLD</code></p>
|
||
<p>Constante définissant le seuil critique pour l'expiration des mots de passe (en seconde). Par
|
||
défaut : 2 jours.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LS_PPOLICY_CSV_DELIMITER</code></p>
|
||
<p>Constante définissant le caractère utilisé lors de la génération de l'export CSV comme séparateur
|
||
de champ. Par défaut : un point-virgule.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LS_PPOLICY_CSV_ENCLOSURE</code></p>
|
||
<p>Constante définissant le caractère utilisé lors de la génération de l'export CSV pour
|
||
l'encadrement des champs. Par défaut : un guillemet double.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LS_PPOLICY_CSV_ESCAPE_CHAR</code></p>
|
||
<p>Constante définissant le caractère utilisé lors de la génération de l'export CSV pour
|
||
l'échappement des champs. Par défaut : une barre oblique inverse.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>$GLOBALS['LS_PPOLICY_API_GRANTED_PROFILES']</code></p>
|
||
<p>Tableau global listant les <a href="#conf-global-ldap-lsprofile-profils-dutilisateurs">LSprofiles</a>
|
||
autorisés à utiliser la méthode d'API <code>exportPpolicyInfo</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>$GLOBALS['LS_PPOLICY_INFO_EXPORT_EXTRA_ATTRS']</code></p>
|
||
<p>Tableau global listant les attributs supplémentaires à inclure lors de l'export des informations
|
||
de politique de mots de passe.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsaddon-lsaddon_showsupportinfo"><h1 id="conf-lsaddon-lsaddon_showsupportinfo-lsaddon_showsupportinfo">LSaddon_showSupportInfo</h1>
|
||
<p>Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> fourni une page affichant les informations utiles
|
||
pour l'équipe assurant le support de l'application. Cette page est accessible à l'adresse
|
||
<code>addon/showSupportInfo/showMySupportInfo</code>. Elle compile (et permet de télécharger) l'ensemble des
|
||
informations utiles à l'appréciation du contexte d'accès à l'application par l'utilisateur.</p>
|
||
<p>Cette page est accessible par tous les utilisateurs connectés à l'application. Cependant, par
|
||
défaut, il n'y a aucun lien d'accès à celle-ci. Il est possible d'ajouter un lien d'accès dans le
|
||
menu et modifiant la valeur de la constante <code>SHOW_SUPPORT_INFO_IN_MENU</code> à <code>True</code>.</p>
|
||
<p>Une fonction <code>showMySupportInfo()</code> est également fournie et peut-être utilisée comme
|
||
<a href="#conf-lsobject-customactions-customactions">customActions</a>. Elle redirigera alors l'utilisateur
|
||
vers cette page. Ci-dessous, vous trouverez un exemple de configuration de la fonction
|
||
<code>showMySupportInfo()</code> comme <a href="#conf-lsobject-customactions-customactions">customActions</a> :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_showsupportinfo-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="x">$GLOBALS['LSobjects']['LSpeople'] = array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_showsupportinfo-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsaddon-lsaddon_showsupportinfo-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="x"> 'customActions' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_showsupportinfo-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="x"> 'showMySupportInfo' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_showsupportinfo-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="x"> 'function' => 'showMySupportInfo',</span>
|
||
<a href="#conf-lsaddon-lsaddon_showsupportinfo-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="x"> 'label' => 'Show my support information',</span>
|
||
<a href="#conf-lsaddon-lsaddon_showsupportinfo-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="x"> 'hideLabel' => True,</span>
|
||
<a href="#conf-lsaddon-lsaddon_showsupportinfo-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="x"> 'noConfirmation' => true,</span>
|
||
<a href="#conf-lsaddon-lsaddon_showsupportinfo-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="x"> 'disableOnSuccessMsg' => true,</span>
|
||
<a href="#conf-lsaddon-lsaddon_showsupportinfo-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="x"> 'icon' => 'terminal',</span>
|
||
<a href="#conf-lsaddon-lsaddon_showsupportinfo-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="x"> 'rights' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_showsupportinfo-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="x"> 'self'</span>
|
||
<a href="#conf-lsaddon-lsaddon_showsupportinfo-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_showsupportinfo-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_showsupportinfo-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_showsupportinfo-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsaddon-lsaddon_showsupportinfo-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a><span class="x">);</span>
|
||
</code></pre></div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Le label et l'icône fournis dans cet exemple sont traduits et délivrés avec LdapSaisie.</p>
|
||
</div></section><section class="print-page" id="conf-lsaddon-lsaddon_showtechinfo"><h1 id="conf-lsaddon-lsaddon_showtechinfo-lsaddon_showtechinfo">LSaddon_showTechInfo</h1>
|
||
<p>Cet <a href="#conf-lsaddon-configuration-des-lsaddons">LSaddon</a> fournie une fonction du même nom pouvant être
|
||
utilisée comme <a href="#conf-lsobject-customactions-customactions">customActions</a> et permettant d'afficher
|
||
les informations techniques d'un objet de l'annuaire.</p>
|
||
<p>Ci-dessous, vous trouverez un exemple de configuration de la fonction <code>showTechInfo()</code> comme
|
||
<a href="#conf-lsobject-customactions-customactions">customActions</a> :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsaddon-lsaddon_showtechinfo-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="x">$GLOBALS['LSobjects']['LSpeople'] = array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_showtechinfo-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsaddon-lsaddon_showtechinfo-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="x"> 'customActions' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_showtechinfo-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="x"> 'showTechInfo' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_showtechinfo-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="x"> 'function' => 'showTechInfo',</span>
|
||
<a href="#conf-lsaddon-lsaddon_showtechinfo-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="x"> 'label' => 'Show technical information',</span>
|
||
<a href="#conf-lsaddon-lsaddon_showtechinfo-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="x"> 'hideLabel' => True,</span>
|
||
<a href="#conf-lsaddon-lsaddon_showtechinfo-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="x"> 'noConfirmation' => true,</span>
|
||
<a href="#conf-lsaddon-lsaddon_showtechinfo-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="x"> 'disableOnSuccessMsg' => true,</span>
|
||
<a href="#conf-lsaddon-lsaddon_showtechinfo-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="x"> 'icon' => 'tech_info',</span>
|
||
<a href="#conf-lsaddon-lsaddon_showtechinfo-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="x"> 'rights' => array (</span>
|
||
<a href="#conf-lsaddon-lsaddon_showtechinfo-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="x"> 'admin'</span>
|
||
<a href="#conf-lsaddon-lsaddon_showtechinfo-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_showtechinfo-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_showtechinfo-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a><span class="x"> ),</span>
|
||
<a href="#conf-lsaddon-lsaddon_showtechinfo-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a><span class="x"> [...]</span>
|
||
<a href="#conf-lsaddon-lsaddon_showtechinfo-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a><span class="x">);</span>
|
||
</code></pre></div>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Le label et l'icône fournis dans cet exemple sont traduits et délivrés avec LdapSaisie.</p>
|
||
</div></section><h1 class="nav-section-title-end">Ended: Configuration des addons (LSaddons)</h1><h2 class="nav-section-title">Configuration des méthodes d'authentification (LSauthMethod)</h2><section class="print-page" id="conf-lsauthmethod"><h1 id="conf-lsauthmethod-configuration-des-methodes-dauthentification-lsauthmethod">Configuration des méthodes d'authentification (LSauthMethod)</h1>
|
||
<p>Cette partie décrit la manière de configurer les méthodes d'authentification d'LdapSaisie appelée
|
||
LSauthMethod). Ces librairies peuvent avoir un fichier de configuration et il sera alors stocké dans
|
||
le dossier <code>conf/LSauth/</code>.</p></section><section class="print-page" id="conf-lsauthmethod-lsauthmethod_anonymous"><h1 id="conf-lsauthmethod-lsauthmethod_anonymous-lsauthmethod_anonymous">LSauthMethod_anonymous</h1>
|
||
<p>Cette <a href="#conf-lsauthmethod-configuration-des-lsauthmethods">LSauthMethod</a> est utilisée pour gérer
|
||
l'authentification automatique des utilisateurs arrivant (équivalent à un mode anonyme). Cette
|
||
librairie doit être configurée en éditant le fichier de configuration
|
||
<code>conf/LSauth/config.LSauthMethod_anonymous.php</code> et notament en définissant la constante
|
||
<code>LSAUTHMETHOD_ANONYMOUS_USER</code> contenant le login d'un utilisateur dont les droits d'accès seront
|
||
endossés par tout les personnes utilisant LdapSaisie.</p></section><section class="print-page" id="conf-lsauthmethod-lsauthmethod_cas"><h1 id="conf-lsauthmethod-lsauthmethod_cas-lsauthmethod_cas">LSauthMethod_CAS</h1>
|
||
<p>Cette <a href="#conf-lsauthmethod-configuration-des-lsauthmethods">LSauthMethod</a> est utilisée pour gérer
|
||
l'authentification via un service SSO CAS. Cette librairie doit être configurée en éditant le
|
||
fichier de configuration <code>conf/LSauth/config.LSauthMethod_CAS.php</code>.</p>
|
||
<p><strong>Structure du fichier :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="x">/*</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="x"> *****************************************************</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="x"> * Configuration of the CAS authentification support *</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="x"> *****************************************************</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="x"> */</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="x">// phpCAS Path (http://www.ja-sig.org/wiki/display/CASC/phpCAS)</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="x">define('PHP_CAS_PATH','/usr/share/php/CAS.php');</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="x">// phpCAS Debug File</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="x">// define('PHP_CAS_DEBUG_FILE','/tmp/phpCAS.log');</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a><span class="x">// Disable logout</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a><span class="x">define('LSAUTH_CAS_DISABLE_LOGOUT',false);</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a><span class="x">// CAS Server version (used constant name know by phpCAS : CAS_VERSION_1_0 or CAS_VERSION_2_0)</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a><span class="x">define('LSAUTH_CAS_VERSION','CAS_VERSION_2_0');</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a><span class="x">// CAS Server hostname</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a><span class="x">define('LSAUTH_CAS_SERVER_HOSTNAME','cas.univ.fr');</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-22" id="__codelineno-0-22" name="__codelineno-0-22"></a><span class="x">// CAS Server port</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-23" id="__codelineno-0-23" name="__codelineno-0-23"></a><span class="x">define('LSAUTH_CAS_SERVER_PORT',443);</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-24" id="__codelineno-0-24" name="__codelineno-0-24"></a>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-25" id="__codelineno-0-25" name="__codelineno-0-25"></a><span class="x">// CAS Server URI (empty by default)</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-26" id="__codelineno-0-26" name="__codelineno-0-26"></a><span class="x">// define('LSAUTH_CAS_SERVER_URI','cas/');</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-27" id="__codelineno-0-27" name="__codelineno-0-27"></a>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-28" id="__codelineno-0-28" name="__codelineno-0-28"></a><span class="x">// No SSL validation for the CAS server</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-29" id="__codelineno-0-29" name="__codelineno-0-29"></a><span class="x">define('LSAUTH_CAS_SERVER_NO_SSL_VALIDATION',false);</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-30" id="__codelineno-0-30" name="__codelineno-0-30"></a>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-31" id="__codelineno-0-31" name="__codelineno-0-31"></a><span class="x">// CAS server SSL CA Certificate path</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_cas-__codelineno-0-32" id="__codelineno-0-32" name="__codelineno-0-32"></a><span class="x">//define('LSAUTH_CAS_SERVER_SSL_CACERT','');</span>
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>PHP_CAS_PATH</code></p>
|
||
<p>Le chemin d'accès du fichier <code>CAS.php</code> de la librairie
|
||
<a href="http://www.ja-sig.org/wiki/display/CASC/phpCAS">phpCAS</a>. Le chemin d'exemple correspond au chemin
|
||
résultant d'une installation via <a href="http://pear.php.net/">PEAR</a> sur une Debian (Lenny).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>PHP_CAS_DEBUG_FILE</code></p>
|
||
<p>Chemin du fichier de log de la librairie <a href="http://www.ja-sig.org/wiki/display/CASC/phpCAS">phpCAS</a>.
|
||
Commenter la ligne pour désactiver les logs.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSAUTH_CAS_DISABLE_LOGOUT</code></p>
|
||
<p>Booléen définissant si l'utilisateur peut se déconnecter du serveur CAS depuis l'interface.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Remarque : l'appel de l'URL de déconnexion via une requête <code>GET</code> supprimera la session PHP et
|
||
donc la session LdapSaisie sans déconnecter pour autant l'utilisateur au niveau du serveur
|
||
CAS. Cela peut donc permettre de gérer la déconnexion automatique au niveau d'LdapSaisie suite
|
||
à une déconnexion au niveau du CAS à traver le concepte de <code>Global Logout</code>.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSAUTH_CAS_VERSION</code></p>
|
||
<p>Nom de la constant <a href="http://www.ja-sig.org/wiki/display/CASC/phpCAS">phpCAS</a> permettant de définir
|
||
la version CAS du serveur. Actuellement, la librairie
|
||
<a href="http://www.ja-sig.org/wiki/display/CASC/phpCAS">phpCAS</a> ne reconnait que la constante
|
||
<code>CAS_VERSION_1_0</code> pour la version 1 de CAS ou la constante <code>CAS_VERSION_2_0</code> pour la version 2 de
|
||
CAS.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Remarque : Des tests on montrés que l'utilisation d'une compatibilité CAS version 2 peut
|
||
également fonctionner sur un version 3 du serveur CAS.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSAUTH_CAS_SERVER_HOSTNAME</code></p>
|
||
<p>Le nom d'hôte du serveur CAS.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSAUTH_CAS_SERVER_PORT</code></p>
|
||
<p>Le port d'écoute du serveur CAS.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSAUTH_CAS_SERVER_URI</code></p>
|
||
<p>Le dossier HTTP dans lequel se trouve le service CAS. Exemple : Pour un service CAS accessible via
|
||
l'URL <code>https://cas.univ.fr/cas/</code>, la constante devra valoir <code>cas/</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSAUTH_CAS_SERVER_NO_SSL_VALIDATION</code></p>
|
||
<p>Booléen permettant de désactiver la validation du certificat SSL du serveur CAS lors des requêtes
|
||
de validation des tickets CAS.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSAUTH_CAS_SERVER_SSL_CACERT</code></p>
|
||
<p>Chemin d'accès du fichier contenant le certificat SSL de la CA du serveur CAS au format PEM.
|
||
Commenter la ligne pour désactiver ce paramètre.</p>
|
||
</li>
|
||
</ul></section><section class="print-page" id="conf-lsauthmethod-lsauthmethod_http"><h1 id="conf-lsauthmethod-lsauthmethod_http-lsauthmethod_http">LSauthMethod_HTTP</h1>
|
||
<p>Cette <a href="#conf-lsauthmethod-configuration-des-lsauthmethods">LSauthMethod</a> est utilisée pour gérer
|
||
l'authentification via les variables d'environnements définies suite à une authentification,
|
||
potentiellement déléguée au serveur web.</p>
|
||
<p>Cette méthode récupère dans l'environment d'exécution PHP, le nom d'utilisateur et le mot de passe
|
||
de l'utilisateur connecté. À partir du nom d'utilisateur, une recherche dans l'annuaire sera
|
||
effectuée pour trouver l'utilisateur correspondant. L'authentification sera réussie uniquement si un
|
||
et un seul utilisateur est retourné par la recherche et si une authentification auprès de l'annuaire
|
||
LDAP réussie à l'aide du DN de l'objet LDAP trouvé et du mot de passe fourni.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>En cas d'authentification déléguée au serveur web, il est possible de désactiver la vérification
|
||
du mot de passe via le paramètre <code>LSAUTHMETHOD_HTTP_TRUST_WITHOUT_PASSWORD_CHALLENGE</code>
|
||
(voir ci-dessous).</p>
|
||
</div>
|
||
<p>Les variables d'environnements utilisées pour authentifier l'utilisateur connecté dépendent de la
|
||
méthode configurée via la constante <code>LSAUTHMETHOD_HTTP_METHOD</code> (voir ci-dessous). Si ces variables
|
||
ne sont pas disponibles, une erreur HTTP 403 sera générée pour réclamer une authentification à
|
||
l'utilisateur.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Cette <a href="#conf-lsauthmethod-configuration-des-lsauthmethods">LSauthMethod</a> supporte le mode API et il s'agit
|
||
de la méthode utilisée par défaut dans ce mode.</p>
|
||
</div>
|
||
<p>Cette librairie peut être configurée en éditant le fichier de configuration
|
||
<code>conf/LSauth/config.LSauthMethod_HTTP.php</code>.</p>
|
||
<p><strong>Structure du fichier :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsauthmethod-lsauthmethod_http-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="x">/*</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_http-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="x"> *****************************************************</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_http-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="x"> * Configuration of the HTTP authentification support *</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_http-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="x"> *****************************************************</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_http-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="x"> */</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_http-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_http-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="x">// Don't check HTTP server's login/password by LDAP authentication challenge</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_http-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="x">//define('LSAUTHMETHOD_HTTP_TRUST_WITHOUT_PASSWORD_CHALLENGE',true);</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_http-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_http-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="x">// Authentication realm (API mode only)</span>
|
||
<a href="#conf-lsauthmethod-lsauthmethod_http-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a><span class="x">//define('LSAUTHMETHOD_HTTP_API_REALM', ___('LdapSaisie API - Authentication required'));</span>
|
||
</code></pre></div>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSAUTHMETHOD_HTTP_TRUST_WITHOUT_PASSWORD_CHALLENGE</code></p>
|
||
<p>Permet de désactiver le test d'authentification auprès de l'annuaire LDAP. Pour cela, cette
|
||
constante doit être définie et valoir <code>True</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSAUTHMETHOD_HTTP_METHOD</code></p>
|
||
<p>Permet de définir la méthode utilisée par le serveur web pour passer à <a href="http://www.php.net/">PHP</a>
|
||
l'identifiant de l'utilisateur connecté et son mot de passe.</p>
|
||
<p>Cette constance peut pendre les valeurs suivantes :</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>PHP_PASS</code></p>
|
||
<p>Dans cette méthode, le serveur web défini les variables d'environnement <code>PHP_AUTH_USER</code> et
|
||
<code>PHP_AUTH_PW</code>. Cette méthode est la méthode par défaut et convient en cas d'utilisation de
|
||
<code>mod_php</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>REMOTE_USER</code></p>
|
||
<p>Dans cette méthode, le serveur web défini la variable d'environnement <code>REMOTE_USER</code>. Cette
|
||
variable ne contient que l'identifiant de l'utilisateur connecté. Cette méthode ne peut donc
|
||
être utilisée que conjointement avec l'activation du paramètre
|
||
<code>LSAUTHMETHOD_HTTP_TRUST_WITHOUT_PASSWORD_CHALLENGE</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>AUTHORIZATION</code></p>
|
||
<p>Dans cette méthode, le serveur web passe le contenu de l'entête HTTP <code>Authorization</code> dans la
|
||
variable d'environnement <code>HTTP_AUTHORIZATION</code>. Cette méthode convient en cas d'utilisation de
|
||
<a href="http://www.php.net/">PHP</a> en mode CGI ou encore via PHP-FPM.</p>
|
||
<p>Pour utiliser cette méthode, il faudra adapter la configuration du serveur web. Par exemple,
|
||
pour Apache HTTPd, vous pouvez utiliser le module <code>rewrite</code> et la règle de réécriture suivante :</p>
|
||
<div class="highlight"><pre><span></span><code><a href="#conf-lsauthmethod-lsauthmethod_http-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a>RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSAUTHMETHOD_HTTP_LOGOUT_REMOTE_URL</code></p>
|
||
<p>URL de déconnexion externe, utile par exemple dans le contexte d'une connexion via un service SSO.
|
||
L'utilisateur sera automatiquement redirigé vers cette URL après sa déconnexion effective au
|
||
niveau d'LdapSaisie.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Si cette URL de déconnexion n'est pas défini, le bouton de déconnexion sera masqué.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>LSAUTHMETHOD_HTTP_REALM</code></p>
|
||
<p>Domaine d'authentification (<code>reaml</code>) utilisé pour réclamer l'authentification de l'utilisateur
|
||
(facultatif).</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Pour que le message soit traduit, utilisez la fonction <code>___()</code> (voir exemple).</p>
|
||
</div>
|
||
</li>
|
||
</ul></section><h1 class="nav-section-title-end">Ended: Configuration des méthodes d'authentification (LSauthMethod)</h1><h1 class="nav-section-title-end">Ended: Configuration</h1><section class="print-page" id="api"><h1 id="api-api">API</h1>
|
||
<p>Depuis la version 4.0, LdapSaisie offre une API visant à permettre de faire les mêmes choses que ce
|
||
qu'il est possible d'accomplir via l'interface web. L'idée n'est bien entendue pas de se substituer
|
||
systématiquement à la possibilité de se connecter directement à l'annuaire, mais plutôt d'offrir une
|
||
API web pour l'intégration d'outil préférant ce mode d'interaction, ou encore, pour exposer des
|
||
méthodes accès aux données de l'annuaire tout en profitant des logiques métiers
|
||
implémentées/configurées dans LdapSaisie : validation syntaxique et d'unicité, règle de génération
|
||
et d'interdépendances des attributs, déclencheurs, ...</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Cette API est actuellement dans une phase de test et n'offre pas encore toutes les
|
||
fonctionnalités proposées dans l'interface web. Elle est vouée à évoluer pour intégrer petit à
|
||
petit un maximum de fonctionnalités. Des contributions à ce sujet seront plus qu'appréciée !</p>
|
||
</div>
|
||
<h2 id="api-authentification">Authentification</h2>
|
||
<p>L'authentification à l'API utilise le même composant <code>LSauth</code> que lors d'une authentification à
|
||
l'interface web, cependant, ce composant s'adapte pour prendre en compte de mode de connexion. Par
|
||
défaut, la méthode d'authentification utilisée sera
|
||
<a href="#conf-lsauthmethod-lsauthmethod_http-LSauthMethod_HTTP">LSauthMethod_HTTP</a> et permettra de se
|
||
connecter en spécifiant le nom d'utilisateur et le mot de l'utilisateur cherchant à se connecter via
|
||
une authentification basique HTTP.</p>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">Warning</p>
|
||
<p>Il est à noter que tous les types d'utilisateur ne peuvent pas forcément utiliser l'API : le
|
||
paramètre <code>api_access</code> doit être explicitement positionné à <code>True</code> dans
|
||
<a href="#conf-global-ldap-configuration-des-serveurs-ldap">la configuration du serveur LDAP</a>.</p>
|
||
</div>
|
||
<p>Une fois connecté, l'utilisateur endossera les droits associés à ses
|
||
<a href="#conf-global-ldap-lsprofile-profils-dutilisateurs">LSprofiles</a>, tout comme un utilisateur
|
||
connecté à l'interface web.</p>
|
||
<h2 id="api-methodes-exposees">Méthodes exposées</h2>
|
||
<p>Les URLs des méthodes de l'API ont été construites par mimétisme sur celle de l'interface web et
|
||
sous la racine web <code>api/</code>. Par ailleurs, un numéro de version d'API a été insérée dans chacune
|
||
d'elles afin d'anticiper toutes évolutions futures majeures nécéssitants de conserver une
|
||
rétrocompatibilité avec les anciennes versions de l'API.</p>
|
||
<p>Toutes les méthodes retournent des informations au format JSON et accepte le paramètre <code>pretty</code>
|
||
permettant d'obtenir un retour plus facilement lisible. Les chaines de caractères échangées doivent
|
||
par ailleurs être encodées en UTF-8. On trouvera par ailleurs dans le retour JSON :</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>success</code></p>
|
||
<p>Booléen précisant si l'action demandée a correctement été exécutée.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>messages</code></p>
|
||
<p>Ce tableau pourra être présent et lister les messages d'informations générées par l'action
|
||
demandée. Il s'agira des mêmes messages que ceux affichés dans l'interface web lorsque les
|
||
actions équivalentes y sont faites.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li><code>errors</code>
|
||
Ce tableau pourra être présent et lister les messages d'erreurs générées par l'action demandée.</li>
|
||
</ul>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Les messages d'informations et d'erreurs générées par l'application sont traduites dans la
|
||
langue courante qui peut être spécifiée via le paramètre <code>lang</code> accepté par toutes les méthodes
|
||
(exemple : <code>fr_FR</code> ou <code>en_US</code>).</p>
|
||
</div>
|
||
<p>Lorsqu'une méthode cible un type d'objets, voir un objet en particulier, ces informations seront
|
||
transmises dans l'URL appelée. Si le type d'objet ou l'objet demandé est introuvable, une erreur
|
||
HTTP 404 sera générée.</p>
|
||
<div class="admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>Sauf précision contraire, toutes les méthodes exposées sont accessibles uniquement via les
|
||
méthodes HTTP <code>GET</code> ou <code>POST</code>. L'accès via une autre méthode retournera une erreur 404.</p>
|
||
</div>
|
||
<ul>
|
||
<li>
|
||
<p><code>/api/1.0/object/[object type]</code></p>
|
||
<p>Cette méthode permet de rechercher/lister les informations d'un type d'objets de l'annuaire en
|
||
particulier. Le type de l'objet est précisé dans l'URL et doit être encodé en conséquence. Par
|
||
mimétisme du comportement de l'interface web, la recherche est paginée et accepte des paramètres
|
||
similaires en plus de paramètre plus appropriés à un fonctionnement programmatique :</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>filter</code></p>
|
||
<p>Permet de spécifier un filtre de recherche LDAP personnalisé. Celui-ci sera combiné avec les
|
||
paramètres propres au type d'objets recherchés et aux autres paramètres spécifiés (<code>pattern</code>
|
||
par exemple).</p>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">Warning</p>
|
||
<p>Du fait d'une limitation de la classe <code>Net_LDAP2_Filter</code> utilisée pour analyser le
|
||
filtre passé en paramètre, seuls les filtres simples du type <code>(attribut=valeur)</code> sont
|
||
acceptés ici. Pour les mêmes raisons, il est important que le filtre spécifié soit
|
||
toujours entourné de paranthèses.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>predefinedFilter</code></p>
|
||
<p>Permet de spécifier un des filtres de recherche LDAP prédéfinis dans la configuration du
|
||
type d'objet.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>pattern</code></p>
|
||
<p>Permet de spécifier un mot clé de recherche, comme proposé dans l'interface web.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>approx</code></p>
|
||
<p>Booléen permettant d'activer/désactiver la recherche approximative sur le mot clé. Les
|
||
valeurs acceptées sont <code>1</code> ou <code>0</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>basedn</code></p>
|
||
<p>Permet de spécifier une base de recherche personnalisé pour la recherche.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>subDn</code></p>
|
||
<p>Dans le cas d'un serveur LDAP configuré avec des
|
||
<a href="#conf-global-ldap-subdn-sous-niveaux-de-connexion">sous-niveaux de connexion</a>, permet de
|
||
spécifier le sous-niveau pour la recherche.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>scope</code></p>
|
||
<p>Permet de spécifier l'étendue de la recherche dans l'annuaire. Valeurs acceptées: <code>sub</code>,
|
||
<code>one</code> et <code>base</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>recursive</code></p>
|
||
<p>Booléen permettant d'activer/désactiver la recherche recursive, c'est à dire une recherche à
|
||
la racine de l'annuaire (ou du
|
||
<a href="#conf-global-ldap-subdn-sous-niveaux-de-connexion">sous-niveau de connexion</a>) avec une
|
||
étendue de recherche maximale. Les valeurs acceptées sont <code>1</code> ou <code>0</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>displayFormat</code></p>
|
||
<p>Permet de spécifier un <a href="#conf-global-lsformat-format-parametrable">LSformat</a> personnalisé
|
||
pour le nom des objets dans le résultat de recherche.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>extraDisplayedColumns</code></p>
|
||
<p>Booléen permettant d'activer le retour des colonnes personnalisées dans le résultat de
|
||
recherche. Les valeurs acceptées sont <code>1</code> ou <code>0</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>attributes</code></p>
|
||
<p>Liste des attributs supplémentaires que devra retourner la recherche.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>attributesDetails</code></p>
|
||
<p>Permet d'obtenir les détails sur les valeurs des attributs (au lieu des valeurs au format
|
||
attendu en cas de création/modification de l'objet). Seul la présence de ce paramètre suffit
|
||
à activer ce comportement, sa valeur n'a pas d'importance.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>sortBy</code></p>
|
||
<p>Permet de préciser sur quelle information le résultat de recherche doit être trié. Valeurs
|
||
acceptées : <code>displayName</code>, <code>subDn</code> ou un des noms des colonnes personnalisées.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>sortDirection</code></p>
|
||
<p>Permet de préciser l'ordre de tri du résultat de recherche. Valeurs acceptées : <code>ASC</code> (A-Z)
|
||
ou <code>DESC</code> (Z-A).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>page</code></p>
|
||
<p>Permet de préciser la page du résultat de recherche.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>nbObjectsByPage</code></p>
|
||
<p>Permet de préciser le nombre maximum d'objets retournés par page du résultat de recherche.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>all</code></p>
|
||
<p>Permet de réclamer le résultat complet de la recherche (désactivation de la pagination).
|
||
Seul la présence de ce paramètre suffit à activer ce comportement, sa valeur n'a pas
|
||
d'importance.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>as_list</code></p>
|
||
<p>Permet de réclamer un résultat de recherche dans lequel, la clé <code>objects</code> sera une liste et
|
||
non un dictionnaire. Dans ce cas, le DN de l'objet est fourni dans la clé <code>dn</code> des détails
|
||
des objets.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>withoutCache</code></p>
|
||
<p>Booléen permettant de désactiver l'utilisation du cache. Les valeurs acceptées sont <code>1</code> ou
|
||
<code>0</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>keepParamsBetweenSearches</code></p>
|
||
<p>Booléen permettant d'activer/désactiver le stockage en session des paramètres de recherche
|
||
(optionnel, par défaut : <code>False</code>). Les valeurs acceptées sont <code>1</code> ou <code>0</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<p><strong>Exemple :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#api-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a># curl -u username:secret 'https://ldapsaisie/api/1.0/object/LSpeople?extraDisplayedColumns=1&pretty'
|
||
<a href="#api-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a>{
|
||
<a href="#api-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a> "success": true,
|
||
<a href="#api-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> "objects": {
|
||
<a href="#api-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a> "uid=hmartin,ou=people,o=ls": {
|
||
<a href="#api-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> "name": "Henri MARTIN",
|
||
<a href="#api-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a> "Mail": "henri.martin@ls.com"
|
||
<a href="#api-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> },
|
||
<a href="#api-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> "uid=s.ldapsaisie,ou=people,o=ls": {
|
||
<a href="#api-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> "name": "Secretariat LdapSaisie",
|
||
<a href="#api-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> "Mail": "secretariat@ldapsaisie.biz"
|
||
<a href="#api-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> },
|
||
<a href="#api-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> "uid=ls,ou=people,o=ls": {
|
||
<a href="#api-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a> "name": "LdapSaisie",
|
||
<a href="#api-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a> "Mail": "ldap.saisie@ls.com"
|
||
<a href="#api-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a> },
|
||
<a href="#api-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a> "uid=erwpa,ou=people,o=ls": {
|
||
<a href="#api-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a> "name": "Erwan PAGE",
|
||
<a href="#api-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a> "Mail": "erwan.page@ldapsaisie.biz"
|
||
<a href="#api-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a> },
|
||
<a href="#api-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a> "uid=user2,ou=people,ou=company1,ou=companies,o=ls": {
|
||
<a href="#api-__codelineno-0-22" id="__codelineno-0-22" name="__codelineno-0-22"></a> "name": "prenom2 nom2",
|
||
<a href="#api-__codelineno-0-23" id="__codelineno-0-23" name="__codelineno-0-23"></a> "Mail": "user2@ls.com"
|
||
<a href="#api-__codelineno-0-24" id="__codelineno-0-24" name="__codelineno-0-24"></a> }
|
||
<a href="#api-__codelineno-0-25" id="__codelineno-0-25" name="__codelineno-0-25"></a> },
|
||
<a href="#api-__codelineno-0-26" id="__codelineno-0-26" name="__codelineno-0-26"></a> "total": 14,
|
||
<a href="#api-__codelineno-0-27" id="__codelineno-0-27" name="__codelineno-0-27"></a> "params": {
|
||
<a href="#api-__codelineno-0-28" id="__codelineno-0-28" name="__codelineno-0-28"></a> "keepParamsBetweenSearches": false,
|
||
<a href="#api-__codelineno-0-29" id="__codelineno-0-29" name="__codelineno-0-29"></a> "filter": null,
|
||
<a href="#api-__codelineno-0-30" id="__codelineno-0-30" name="__codelineno-0-30"></a> "pattern": null,
|
||
<a href="#api-__codelineno-0-31" id="__codelineno-0-31" name="__codelineno-0-31"></a> "predefinedFilter": false,
|
||
<a href="#api-__codelineno-0-32" id="__codelineno-0-32" name="__codelineno-0-32"></a> "basedn": null,
|
||
<a href="#api-__codelineno-0-33" id="__codelineno-0-33" name="__codelineno-0-33"></a> "scope": null,
|
||
<a href="#api-__codelineno-0-34" id="__codelineno-0-34" name="__codelineno-0-34"></a> "sizelimit": 0,
|
||
<a href="#api-__codelineno-0-35" id="__codelineno-0-35" name="__codelineno-0-35"></a> "attronly": false,
|
||
<a href="#api-__codelineno-0-36" id="__codelineno-0-36" name="__codelineno-0-36"></a> "approx": false,
|
||
<a href="#api-__codelineno-0-37" id="__codelineno-0-37" name="__codelineno-0-37"></a> "recursive": true,
|
||
<a href="#api-__codelineno-0-38" id="__codelineno-0-38" name="__codelineno-0-38"></a> "attributes": [],
|
||
<a href="#api-__codelineno-0-39" id="__codelineno-0-39" name="__codelineno-0-39"></a> "onlyAccessible": true,
|
||
<a href="#api-__codelineno-0-40" id="__codelineno-0-40" name="__codelineno-0-40"></a> "sortDirection": null,
|
||
<a href="#api-__codelineno-0-41" id="__codelineno-0-41" name="__codelineno-0-41"></a> "sortBy": null,
|
||
<a href="#api-__codelineno-0-42" id="__codelineno-0-42" name="__codelineno-0-42"></a> "sortlimit": 0,
|
||
<a href="#api-__codelineno-0-43" id="__codelineno-0-43" name="__codelineno-0-43"></a> "displayFormat": "%{cn}",
|
||
<a href="#api-__codelineno-0-44" id="__codelineno-0-44" name="__codelineno-0-44"></a> "nbObjectsByPage": 25,
|
||
<a href="#api-__codelineno-0-45" id="__codelineno-0-45" name="__codelineno-0-45"></a> "withoutCache": false,
|
||
<a href="#api-__codelineno-0-46" id="__codelineno-0-46" name="__codelineno-0-46"></a> "extraDisplayedColumns": true
|
||
<a href="#api-__codelineno-0-47" id="__codelineno-0-47" name="__codelineno-0-47"></a> },
|
||
<a href="#api-__codelineno-0-48" id="__codelineno-0-48" name="__codelineno-0-48"></a> "page": 1,
|
||
<a href="#api-__codelineno-0-49" id="__codelineno-0-49" name="__codelineno-0-49"></a> "nbPages": 3
|
||
<a href="#api-__codelineno-0-50" id="__codelineno-0-50" name="__codelineno-0-50"></a>}
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>/api/1.0/object/[object type]/[dn]</code></p>
|
||
<p>Cette méthode permet de récupérer les informations d'un objet de l'annuaire au format JSON. Le
|
||
type de l'objet et son DN sont précisés dans l'URL et doivent être encodés en conséquence. Par
|
||
défaut, les valeurs des attributs retournées sont au format tel qu'attendu en cas de
|
||
création/modification de l'objet. Il est cependant possible d'ajouter le paramètre <code>details</code>
|
||
afin d'obtenir des informations complémentaires sur les valeurs des attributs.</p>
|
||
<p><strong>Exemple :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#api-__codelineno-1-1" id="__codelineno-1-1" name="__codelineno-1-1"></a># curl -u username:secret 'https://ldapsaisie/api/1.0/object/LSpeople/uid=hmartin,ou=people,o=ls?pretty'
|
||
<a href="#api-__codelineno-1-2" id="__codelineno-1-2" name="__codelineno-1-2"></a>{
|
||
<a href="#api-__codelineno-1-3" id="__codelineno-1-3" name="__codelineno-1-3"></a> "success": true,
|
||
<a href="#api-__codelineno-1-4" id="__codelineno-1-4" name="__codelineno-1-4"></a> "dn": "uid=hmartin,ou=people,o=ls",
|
||
<a href="#api-__codelineno-1-5" id="__codelineno-1-5" name="__codelineno-1-5"></a> "type": "LSpeople",
|
||
<a href="#api-__codelineno-1-6" id="__codelineno-1-6" name="__codelineno-1-6"></a> "name": "Henri MARTIN",
|
||
<a href="#api-__codelineno-1-7" id="__codelineno-1-7" name="__codelineno-1-7"></a> "details": false,
|
||
<a href="#api-__codelineno-1-8" id="__codelineno-1-8" name="__codelineno-1-8"></a> "attributes": {
|
||
<a href="#api-__codelineno-1-9" id="__codelineno-1-9" name="__codelineno-1-9"></a> "uid": "hmartin",
|
||
<a href="#api-__codelineno-1-10" id="__codelineno-1-10" name="__codelineno-1-10"></a> "givenName": "Henri",
|
||
<a href="#api-__codelineno-1-11" id="__codelineno-1-11" name="__codelineno-1-11"></a> "sn": "MARTIN",
|
||
<a href="#api-__codelineno-1-12" id="__codelineno-1-12" name="__codelineno-1-12"></a> "cn": "Henri MARTIN",
|
||
<a href="#api-__codelineno-1-13" id="__codelineno-1-13" name="__codelineno-1-13"></a> "mail": "henri.martin@ls.com",
|
||
<a href="#api-__codelineno-1-14" id="__codelineno-1-14" name="__codelineno-1-14"></a> "personalTitle": "M.",
|
||
<a href="#api-__codelineno-1-15" id="__codelineno-1-15" name="__codelineno-1-15"></a> "description": [],
|
||
<a href="#api-__codelineno-1-16" id="__codelineno-1-16" name="__codelineno-1-16"></a> "jpegPhoto": null,
|
||
<a href="#api-__codelineno-1-17" id="__codelineno-1-17" name="__codelineno-1-17"></a> "lsGodfatherDn": [
|
||
<a href="#api-__codelineno-1-18" id="__codelineno-1-18" name="__codelineno-1-18"></a> "uid=eeggs,ou=people,o=ls"
|
||
<a href="#api-__codelineno-1-19" id="__codelineno-1-19" name="__codelineno-1-19"></a> ],
|
||
<a href="#api-__codelineno-1-20" id="__codelineno-1-20" name="__codelineno-1-20"></a> "uidNumber": "101022",
|
||
<a href="#api-__codelineno-1-21" id="__codelineno-1-21" name="__codelineno-1-21"></a> "gidNumber": "102001",
|
||
<a href="#api-__codelineno-1-22" id="__codelineno-1-22" name="__codelineno-1-22"></a> "loginShell": "no",
|
||
<a href="#api-__codelineno-1-23" id="__codelineno-1-23" name="__codelineno-1-23"></a> "homeDirectory": "\/home\/com",
|
||
<a href="#api-__codelineno-1-24" id="__codelineno-1-24" name="__codelineno-1-24"></a> "gecos": null,
|
||
<a href="#api-__codelineno-1-25" id="__codelineno-1-25" name="__codelineno-1-25"></a> "shadowExpire": null,
|
||
<a href="#api-__codelineno-1-26" id="__codelineno-1-26" name="__codelineno-1-26"></a> "shadowMax": null,
|
||
<a href="#api-__codelineno-1-27" id="__codelineno-1-27" name="__codelineno-1-27"></a> "shadowInactive": null,
|
||
<a href="#api-__codelineno-1-28" id="__codelineno-1-28" name="__codelineno-1-28"></a> "shadowLastChange": null,
|
||
<a href="#api-__codelineno-1-29" id="__codelineno-1-29" name="__codelineno-1-29"></a> "sambaSID": "S-1-5-21-2421470416-3566881284-3047381809-203044",
|
||
<a href="#api-__codelineno-1-30" id="__codelineno-1-30" name="__codelineno-1-30"></a> "sambaPrimaryGroupSID": "S-1-5-21-2421470416-3566881284-3047381809-205003",
|
||
<a href="#api-__codelineno-1-31" id="__codelineno-1-31" name="__codelineno-1-31"></a> "sambaAcctFlags": [
|
||
<a href="#api-__codelineno-1-32" id="__codelineno-1-32" name="__codelineno-1-32"></a> "U"
|
||
<a href="#api-__codelineno-1-33" id="__codelineno-1-33" name="__codelineno-1-33"></a> ],
|
||
<a href="#api-__codelineno-1-34" id="__codelineno-1-34" name="__codelineno-1-34"></a> "sambaHomeDrive": null,
|
||
<a href="#api-__codelineno-1-35" id="__codelineno-1-35" name="__codelineno-1-35"></a> "sambaHomePath": null,
|
||
<a href="#api-__codelineno-1-36" id="__codelineno-1-36" name="__codelineno-1-36"></a> "sambaProfilePath": null,
|
||
<a href="#api-__codelineno-1-37" id="__codelineno-1-37" name="__codelineno-1-37"></a> "sambaLogonScript": null,
|
||
<a href="#api-__codelineno-1-38" id="__codelineno-1-38" name="__codelineno-1-38"></a> "sambaLogonTime": null,
|
||
<a href="#api-__codelineno-1-39" id="__codelineno-1-39" name="__codelineno-1-39"></a> "sambaLogoffTime": null,
|
||
<a href="#api-__codelineno-1-40" id="__codelineno-1-40" name="__codelineno-1-40"></a> "sambaKickoffTime": null,
|
||
<a href="#api-__codelineno-1-41" id="__codelineno-1-41" name="__codelineno-1-41"></a> "sambaPwdLastSet": null,
|
||
<a href="#api-__codelineno-1-42" id="__codelineno-1-42" name="__codelineno-1-42"></a> "sambaPwdMustChange": null,
|
||
<a href="#api-__codelineno-1-43" id="__codelineno-1-43" name="__codelineno-1-43"></a> "sambaPwdCanChange": null
|
||
<a href="#api-__codelineno-1-44" id="__codelineno-1-44" name="__codelineno-1-44"></a> },
|
||
<a href="#api-__codelineno-1-45" id="__codelineno-1-45" name="__codelineno-1-45"></a> "relations": {
|
||
<a href="#api-__codelineno-1-46" id="__codelineno-1-46" name="__codelineno-1-46"></a> "groups": {
|
||
<a href="#api-__codelineno-1-47" id="__codelineno-1-47" name="__codelineno-1-47"></a> "cn=direction,ou=groups,o=ls": "direction",
|
||
<a href="#api-__codelineno-1-48" id="__codelineno-1-48" name="__codelineno-1-48"></a> "cn=secretariat,ou=groups,o=ls": "secretariat"
|
||
<a href="#api-__codelineno-1-49" id="__codelineno-1-49" name="__codelineno-1-49"></a> },
|
||
<a href="#api-__codelineno-1-50" id="__codelineno-1-50" name="__codelineno-1-50"></a> "godfather": []
|
||
<a href="#api-__codelineno-1-51" id="__codelineno-1-51" name="__codelineno-1-51"></a> }
|
||
<a href="#api-__codelineno-1-52" id="__codelineno-1-52" name="__codelineno-1-52"></a>}
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>/api/1.0/object/[object type]/create</code></p>
|
||
<p>Cette méthode permet de créer un objet dans l'annuaire. Le type de l'objet qui sera créé est
|
||
précisé dans l'URL et doit être encodé en conséquence. Les informations de l'objet doivent est
|
||
transmises au format <code>x-www-form-urlencoded</code>. Elles peuvent également être au format
|
||
<code>multipart/form-data</code>, en particulier si votre requête contient une image. Par mimétisme avec
|
||
l'interface web, seuls les attributs prévus dans le formulaire de création du type d'objet
|
||
peuvent être passées ici. De la même manière, les attributs non-spécifiés ici, pouront être
|
||
auto-générés en accord avec leur configuration et la requête sera acceptée uniquement si tous
|
||
les attributs obligatoires y sont spécifiés ou s'ils peuvent être auto-générés.</p>
|
||
<p>Le format et la syntaxe des valeurs des attributs dépends de leur type HTML. Ainsi, par exemple,
|
||
un attribut de type HTML <code>boolean</code> acceptera comme valeurs possibles <code>yes</code> ou <code>no</code>. Pour plus
|
||
de détails sur le type de valeur acceptée par un type d'attribut HTML en particulier, consultez
|
||
sa documentation. Vous pouvez également analyser le code de la méthode <code>getPostData()</code> de la
|
||
classe <a href="http://www.php.net/">PHP</a> correspondante.</p>
|
||
<p>Si l'application détecte un souci avec les informations transmises pour les attributs, un
|
||
tableau <code>fields_errors</code> sera présent dans la réponse JSON et contiendra pour chacun des
|
||
attributs problématique, un tableau des messages d'erreurs générées par l'application.</p>
|
||
<p>Si le type d'objet en prévoit, vous pouvez également utiliser un
|
||
<a href="#conf-lsobject-lsform-configuration-des-masques-de-saisie">masque de saisie</a> via le
|
||
paramètre <code>dataEntryForm</code>.</p>
|
||
<p><strong>Exemple :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#api-__codelineno-2-1" id="__codelineno-2-1" name="__codelineno-2-1"></a># curl -u username:secret 'https://ldapsaisie/api/1.0/object/LSpeople/create?pretty' -d "uid=foo.bar&personalTitle=M.&givenName=foo&sn=bar&cn=Foo Bar&mail=foo.bar@example.com&userPassword=Y0urS3cr3t&lsGodfatherDn[]=uid=admin,ou=people,o=ls&gidNumber=70000"
|
||
<a href="#api-__codelineno-2-2" id="__codelineno-2-2" name="__codelineno-2-2"></a>{
|
||
<a href="#api-__codelineno-2-3" id="__codelineno-2-3" name="__codelineno-2-3"></a> "success": true,
|
||
<a href="#api-__codelineno-2-4" id="__codelineno-2-4" name="__codelineno-2-4"></a> "type": "LSpeople",
|
||
<a href="#api-__codelineno-2-5" id="__codelineno-2-5" name="__codelineno-2-5"></a> "dn": "uid=foo.bar,ou=people,o=ls",
|
||
<a href="#api-__codelineno-2-6" id="__codelineno-2-6" name="__codelineno-2-6"></a> "name": "Foo Bar",
|
||
<a href="#api-__codelineno-2-7" id="__codelineno-2-7" name="__codelineno-2-7"></a> "messages": [
|
||
<a href="#api-__codelineno-2-8" id="__codelineno-2-8" name="__codelineno-2-8"></a> "Le mail de notification a \u00e9t\u00e9 envoy\u00e9.",
|
||
<a href="#api-__codelineno-2-9" id="__codelineno-2-9" name="__codelineno-2-9"></a> "L'objet a \u00e9t\u00e9 ajout\u00e9."
|
||
<a href="#api-__codelineno-2-10" id="__codelineno-2-10" name="__codelineno-2-10"></a> ]
|
||
<a href="#api-__codelineno-2-11" id="__codelineno-2-11" name="__codelineno-2-11"></a>}
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>/api/1.0/object/[object type]/[dn]/modify</code></p>
|
||
<p>Cette méthode permet de modifier un objet dans l'annuaire. Le type de l'objet et son DN sont
|
||
précisés dans l'URL et doivent être encodés en conséquence. Les informations de l'objet à
|
||
modifier doivent être transmises au même format que pour la méthode <code>create</code> (voir ci-dessus).
|
||
Comme pour cette dernière, seuls les attributs prévus dans le formulaire de modification du type
|
||
d'objet peuvent être passées ici et la réponse JSON pourra contenir un tableau <code>fields_errors</code>
|
||
contenant les erreurs générées par l'application au sujet des valeurs transmises pour les
|
||
attributs.</p>
|
||
<p><strong>Exemple :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#api-__codelineno-3-1" id="__codelineno-3-1" name="__codelineno-3-1"></a># curl -u username:secret 'https://ldapsaisie/api/1.0/object/LSpeople/uid=foo.bar,ou=people,o=ls/modify?pretty' -d "givenName=foo&sn=bar&cn=Foo Bar"
|
||
<a href="#api-__codelineno-3-2" id="__codelineno-3-2" name="__codelineno-3-2"></a>{
|
||
<a href="#api-__codelineno-3-3" id="__codelineno-3-3" name="__codelineno-3-3"></a> "dn": "uid=foo.bar,ou=people,o=ls",
|
||
<a href="#api-__codelineno-3-4" id="__codelineno-3-4" name="__codelineno-3-4"></a> "type": "LSpeople",
|
||
<a href="#api-__codelineno-3-5" id="__codelineno-3-5" name="__codelineno-3-5"></a> "name": "Foo Bar",
|
||
<a href="#api-__codelineno-3-6" id="__codelineno-3-6" name="__codelineno-3-6"></a> "success": true,
|
||
<a href="#api-__codelineno-3-7" id="__codelineno-3-7" name="__codelineno-3-7"></a> "messages": [
|
||
<a href="#api-__codelineno-3-8" id="__codelineno-3-8" name="__codelineno-3-8"></a> "L'objet a bien \u00e9t\u00e9 modifi\u00e9."
|
||
<a href="#api-__codelineno-3-9" id="__codelineno-3-9" name="__codelineno-3-9"></a> ]
|
||
<a href="#api-__codelineno-3-10" id="__codelineno-3-10" name="__codelineno-3-10"></a>}
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>/api/1.0/object/[object type]/[dn]/remove</code></p>
|
||
<p>Cette méthode permet de supprimer un objet dans l'annuaire. Le type de l'objet et son DN sont
|
||
précisés dans l'URL et doivent être encodés en conséquence.</p>
|
||
<p><strong>Exemple :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#api-__codelineno-4-1" id="__codelineno-4-1" name="__codelineno-4-1"></a># curl -u username:secret 'https://ldapsaisie/api/1.0/object/LSpeople/uid=foo.bar,ou=people,o=ls/remove?pretty'
|
||
<a href="#api-__codelineno-4-2" id="__codelineno-4-2" name="__codelineno-4-2"></a>{
|
||
<a href="#api-__codelineno-4-3" id="__codelineno-4-3" name="__codelineno-4-3"></a> "dn": "uid=foo.bar,ou=people,o=ls",
|
||
<a href="#api-__codelineno-4-4" id="__codelineno-4-4" name="__codelineno-4-4"></a> "type": "LSpeople",
|
||
<a href="#api-__codelineno-4-5" id="__codelineno-4-5" name="__codelineno-4-5"></a> "name": "Foo Bar",
|
||
<a href="#api-__codelineno-4-6" id="__codelineno-4-6" name="__codelineno-4-6"></a> "success": true,
|
||
<a href="#api-__codelineno-4-7" id="__codelineno-4-7" name="__codelineno-4-7"></a> "messages": [
|
||
<a href="#api-__codelineno-4-8" id="__codelineno-4-8" name="__codelineno-4-8"></a> "Foo Bar a bien \u00e9t\u00e9 supprim\u00e9."
|
||
<a href="#api-__codelineno-4-9" id="__codelineno-4-9" name="__codelineno-4-9"></a> ]
|
||
<a href="#api-__codelineno-4-10" id="__codelineno-4-10" name="__codelineno-4-10"></a>}
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>/api/1.0/object/[object type]/import</code></p>
|
||
<p>Cette méthode permet d'importer des objets d'un type en particulier à partir de données d'import
|
||
formatées selon un <a href="#conf-lsobject-ioformat-ioformat">ioFormat</a> configuré pour ce type
|
||
d'objets. Le type de l'objet est précisé dans l'URL et doit être encodé en conséquence. Par
|
||
mimétisme du comportement de l'interface web, cette méthode accepte des paramètres similaires et
|
||
s'attend à récupérer les données d'import dans le corps de la requête.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>ioFormat</code></p>
|
||
<p>Le nom de l'<a href="#conf-lsobject-ioformat-ioformat">ioFormat</a>des données d'import.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>updateIfExists</code></p>
|
||
<p>Booléen permettant d'activer/désactiver la mise à jour des données des objets s'ils existent
|
||
déjà. Si ce mode est inactif et qu'un objet des données d'import existe déjà, une erreur
|
||
sera remontée. Les valeurs acceptées sont <code>1</code> ou <code>0</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>justTry</code></p>
|
||
<p>Booléen permettant d'activer/désactiver le mode de vérification des données d'import
|
||
uniquement. Si ce mode est actif, les données d'import seront analysées pour vérifier
|
||
qu'elles sont correctes, mais l'import en lui-même ne sera pas effectué. Les valeurs
|
||
acceptées sont <code>1</code> ou <code>0</code>.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Le retour de cette méthode en mode <code>justTry</code> est identique à une exécution en mode
|
||
normal. Ce mode permet donc d'anticiper le résultat d'un import à partir d'un jeu de
|
||
données sources.</p>
|
||
</div>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">Warning</p>
|
||
<p>En mode <code>justTry</code>, seul la vérification syntaxique des données est fiable, car les
|
||
informations doublonnées au sein des données d'import ne pourront être détectées.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<p>En cas d'erreurs détectées dans les informations des objets des données d'import, le tableau
|
||
<code>errors</code> du retour de la méthode contiendra une entrée pour chaque objet en erreur sous le
|
||
format d'un dictionnaire dont la clé <code>data</code> reprendra les informations de l'objet telle que
|
||
chargé (ou générée) depuis les données sources, ainsi qu'un dictionnaire sous la clé <code>errors</code>
|
||
qui contiendra les erreurs globales concernant l'objet sous la clé <code>globals</code> et les erreurs
|
||
propres à ses attributs dans un dictionnaire sous la clé <code>attrs</code>.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Les erreurs d'importation sur un objet sont non-bloquantes : l'importation des autres objets
|
||
ne sera pas interrompue.</p>
|
||
</div>
|
||
<p><strong>Exemple :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#api-__codelineno-5-1" id="__codelineno-5-1" name="__codelineno-5-1"></a># curl -u username:secret --data-binary @/path/to/input.file 'https://ldapsaisie/api/1.0/object/LSpeople/import?ioFormat=mycsv&pretty'
|
||
<a href="#api-__codelineno-5-2" id="__codelineno-5-2" name="__codelineno-5-2"></a>{
|
||
<a href="#api-__codelineno-5-3" id="__codelineno-5-3" name="__codelineno-5-3"></a> "success": false,
|
||
<a href="#api-__codelineno-5-4" id="__codelineno-5-4" name="__codelineno-5-4"></a> "LSobject": "LSpeople",
|
||
<a href="#api-__codelineno-5-5" id="__codelineno-5-5" name="__codelineno-5-5"></a> "ioFormat": "mycsv",
|
||
<a href="#api-__codelineno-5-6" id="__codelineno-5-6" name="__codelineno-5-6"></a> "updateIfExists": false,
|
||
<a href="#api-__codelineno-5-7" id="__codelineno-5-7" name="__codelineno-5-7"></a> "justTry": false,
|
||
<a href="#api-__codelineno-5-8" id="__codelineno-5-8" name="__codelineno-5-8"></a> "imported": {
|
||
<a href="#api-__codelineno-5-9" id="__codelineno-5-9" name="__codelineno-5-9"></a> "uid=rturin,ou=people,o=ls": "M. Roger TURIN"
|
||
<a href="#api-__codelineno-5-10" id="__codelineno-5-10" name="__codelineno-5-10"></a> },
|
||
<a href="#api-__codelineno-5-11" id="__codelineno-5-11" name="__codelineno-5-11"></a> "updated": [],
|
||
<a href="#api-__codelineno-5-12" id="__codelineno-5-12" name="__codelineno-5-12"></a> "errors": [
|
||
<a href="#api-__codelineno-5-13" id="__codelineno-5-13" name="__codelineno-5-13"></a> {
|
||
<a href="#api-__codelineno-5-14" id="__codelineno-5-14" name="__codelineno-5-14"></a> "data": {
|
||
<a href="#api-__codelineno-5-15" id="__codelineno-5-15" name="__codelineno-5-15"></a> "uid": [
|
||
<a href="#api-__codelineno-5-16" id="__codelineno-5-16" name="__codelineno-5-16"></a> "lmartin"
|
||
<a href="#api-__codelineno-5-17" id="__codelineno-5-17" name="__codelineno-5-17"></a> ],
|
||
<a href="#api-__codelineno-5-18" id="__codelineno-5-18" name="__codelineno-5-18"></a> "personalTitle": [
|
||
<a href="#api-__codelineno-5-19" id="__codelineno-5-19" name="__codelineno-5-19"></a> "Mme"
|
||
<a href="#api-__codelineno-5-20" id="__codelineno-5-20" name="__codelineno-5-20"></a> ],
|
||
<a href="#api-__codelineno-5-21" id="__codelineno-5-21" name="__codelineno-5-21"></a> "givenName": [
|
||
<a href="#api-__codelineno-5-22" id="__codelineno-5-22" name="__codelineno-5-22"></a> "Ludivine"
|
||
<a href="#api-__codelineno-5-23" id="__codelineno-5-23" name="__codelineno-5-23"></a> ],
|
||
<a href="#api-__codelineno-5-24" id="__codelineno-5-24" name="__codelineno-5-24"></a> "sn": [
|
||
<a href="#api-__codelineno-5-25" id="__codelineno-5-25" name="__codelineno-5-25"></a> "MARTIN"
|
||
<a href="#api-__codelineno-5-26" id="__codelineno-5-26" name="__codelineno-5-26"></a> ],
|
||
<a href="#api-__codelineno-5-27" id="__codelineno-5-27" name="__codelineno-5-27"></a> "mail": [
|
||
<a href="#api-__codelineno-5-28" id="__codelineno-5-28" name="__codelineno-5-28"></a> "lmartin@gmail.com"
|
||
<a href="#api-__codelineno-5-29" id="__codelineno-5-29" name="__codelineno-5-29"></a> ],
|
||
<a href="#api-__codelineno-5-30" id="__codelineno-5-30" name="__codelineno-5-30"></a> "userPassword": [
|
||
<a href="#api-__codelineno-5-31" id="__codelineno-5-31" name="__codelineno-5-31"></a> "123Yh%uT"
|
||
<a href="#api-__codelineno-5-32" id="__codelineno-5-32" name="__codelineno-5-32"></a> ],
|
||
<a href="#api-__codelineno-5-33" id="__codelineno-5-33" name="__codelineno-5-33"></a> "gidNumber": [
|
||
<a href="#api-__codelineno-5-34" id="__codelineno-5-34" name="__codelineno-5-34"></a> "102009"
|
||
<a href="#api-__codelineno-5-35" id="__codelineno-5-35" name="__codelineno-5-35"></a> ],
|
||
<a href="#api-__codelineno-5-36" id="__codelineno-5-36" name="__codelineno-5-36"></a> "loginShell": [
|
||
<a href="#api-__codelineno-5-37" id="__codelineno-5-37" name="__codelineno-5-37"></a> "no"
|
||
<a href="#api-__codelineno-5-38" id="__codelineno-5-38" name="__codelineno-5-38"></a> ],
|
||
<a href="#api-__codelineno-5-39" id="__codelineno-5-39" name="__codelineno-5-39"></a> "cn": [
|
||
<a href="#api-__codelineno-5-40" id="__codelineno-5-40" name="__codelineno-5-40"></a> "Mme Ludivine MARTIN"
|
||
<a href="#api-__codelineno-5-41" id="__codelineno-5-41" name="__codelineno-5-41"></a> ]
|
||
<a href="#api-__codelineno-5-42" id="__codelineno-5-42" name="__codelineno-5-42"></a> },
|
||
<a href="#api-__codelineno-5-43" id="__codelineno-5-43" name="__codelineno-5-43"></a> "errors": {
|
||
<a href="#api-__codelineno-5-44" id="__codelineno-5-44" name="__codelineno-5-44"></a> "globals": [
|
||
<a href="#api-__codelineno-5-45" id="__codelineno-5-45" name="__codelineno-5-45"></a> "Un objet existe d\u00e9j\u00e0 dans l'annuaire LDAP avec le DN uid=lmartin,ou=people,o=ls."
|
||
<a href="#api-__codelineno-5-46" id="__codelineno-5-46" name="__codelineno-5-46"></a> ],
|
||
<a href="#api-__codelineno-5-47" id="__codelineno-5-47" name="__codelineno-5-47"></a> "attrs": []
|
||
<a href="#api-__codelineno-5-48" id="__codelineno-5-48" name="__codelineno-5-48"></a> }
|
||
<a href="#api-__codelineno-5-49" id="__codelineno-5-49" name="__codelineno-5-49"></a> }
|
||
<a href="#api-__codelineno-5-50" id="__codelineno-5-50" name="__codelineno-5-50"></a> ],
|
||
<a href="#api-__codelineno-5-51" id="__codelineno-5-51" name="__codelineno-5-51"></a> "messages": [
|
||
<a href="#api-__codelineno-5-52" id="__codelineno-5-52" name="__codelineno-5-52"></a> "Le mail de notification a \u00e9t\u00e9 envoy\u00e9."
|
||
<a href="#api-__codelineno-5-53" id="__codelineno-5-53" name="__codelineno-5-53"></a> ]
|
||
<a href="#api-__codelineno-5-54" id="__codelineno-5-54" name="__codelineno-5-54"></a>}
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>/api/1.0/object/[object type]/export</code></p>
|
||
<p>Cette méthode permet d'exporter les objets d'un type en particulier dans un
|
||
<a href="#conf-lsobject-ioformat-ioformat">ioFormat</a> configuré pour ce type d'objets. Le type de
|
||
l'objet est précisé dans l'URL et doit être encodé en conséquence.</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>ioFormat</code></p>
|
||
<p>Le nom de l'<a href="#conf-lsobject-ioformat-ioformat">ioFormat</a> .</p>
|
||
</li>
|
||
</ul>
|
||
<p>En tant normal, le retour de cette méthode sera directement le fichier d'export demandé.
|
||
Cependant, si une erreur survient, les paramètres d'export seront repris dans le retour <code>JSON</code>
|
||
de la méthode qui contiendra également les erreurs survenues.</p>
|
||
<p><strong>Exemple :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#api-__codelineno-6-1" id="__codelineno-6-1" name="__codelineno-6-1"></a># curl -u username:secret --data-binary @/path/to/input.file 'https://ldapsaisie/api/1.0/object/LSpeople/export?ioFormat=mycsv&pretty'
|
||
<a href="#api-__codelineno-6-2" id="__codelineno-6-2" name="__codelineno-6-2"></a>login;civility;firstname;name;mail;password;gid;shell
|
||
<a href="#api-__codelineno-6-3" id="__codelineno-6-3" name="__codelineno-6-3"></a>hmartin;M.;Henri;MARTIN;henri.martin@ls.com;********;102001;no
|
||
<a href="#api-__codelineno-6-4" id="__codelineno-6-4" name="__codelineno-6-4"></a>s.ldapsaisie;M.;Secretariat;LdapSaisie;secretariat@ldapsaisie.biz;********;70000;no
|
||
<a href="#api-__codelineno-6-5" id="__codelineno-6-5" name="__codelineno-6-5"></a>ls;M.;Ldap;Saisie;ldap.saisie@ls.com;********;102001;no
|
||
<a href="#api-__codelineno-6-6" id="__codelineno-6-6" name="__codelineno-6-6"></a>erwpa;M.;Erwan;PAGEARD;erwan.page@ldapsaisie.biz;********;102009;no
|
||
<a href="#api-__codelineno-6-7" id="__codelineno-6-7" name="__codelineno-6-7"></a>[...]
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>/api/1.0/object/[object type]/[dn]/relation/[relation]</code></p>
|
||
<p>Cette méthode permet de gérer les objets en relation avec un objet en particulier de l'annuaire.
|
||
Le type de l'objet, son DN et le nom de la relation sont précisés dans l'URL et doivent être
|
||
encodés en conséquence. Cette méthode accepte les paramètres <code>add</code> et <code>remove</code> permettant de
|
||
lister le ou les DN d'objet(s) à respectivement ajouter ou supprimer parmis les objets
|
||
actuellement en relation avec l'objet spécifié. Si aucun DN n'est spécifié comme devant être
|
||
ajouté ou supprimé, la méthode retournera simplement les DN des objets en relation. En cas de
|
||
modification demandée, la méthode retournera la nouvelle liste des DNs des objets en relation,
|
||
quel que soit le résultat de l'opération de mise à jour.</p>
|
||
<p><strong>Exemple :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#api-__codelineno-7-1" id="__codelineno-7-1" name="__codelineno-7-1"></a># curl -u username:secret 'https://ldapsaisie/api/1.0/object/LSpeople/uid=foo.bar,ou=people,o=ls/relation/groups?pretty&add[]=cn=ls,ou=groups,o=ls&add[]=cn=invite,ou=groups,o=ls'
|
||
<a href="#api-__codelineno-7-2" id="__codelineno-7-2" name="__codelineno-7-2"></a>{
|
||
<a href="#api-__codelineno-7-3" id="__codelineno-7-3" name="__codelineno-7-3"></a> "dn": "uid=foo.bar,ou=people,o=ls",
|
||
<a href="#api-__codelineno-7-4" id="__codelineno-7-4" name="__codelineno-7-4"></a> "type": "LSpeople",
|
||
<a href="#api-__codelineno-7-5" id="__codelineno-7-5" name="__codelineno-7-5"></a> "name": "Foo Bar",
|
||
<a href="#api-__codelineno-7-6" id="__codelineno-7-6" name="__codelineno-7-6"></a> "relation": "groups",
|
||
<a href="#api-__codelineno-7-7" id="__codelineno-7-7" name="__codelineno-7-7"></a> "success": true,
|
||
<a href="#api-__codelineno-7-8" id="__codelineno-7-8" name="__codelineno-7-8"></a> "relatedObjects": [
|
||
<a href="#api-__codelineno-7-9" id="__codelineno-7-9" name="__codelineno-7-9"></a> "cn=ls,ou=groups,o=ls",
|
||
<a href="#api-__codelineno-7-10" id="__codelineno-7-10" name="__codelineno-7-10"></a> "cn=invite,ou=groups,o=ls"
|
||
<a href="#api-__codelineno-7-11" id="__codelineno-7-11" name="__codelineno-7-11"></a> ],
|
||
<a href="#api-__codelineno-7-12" id="__codelineno-7-12" name="__codelineno-7-12"></a> "messages": [
|
||
<a href="#api-__codelineno-7-13" id="__codelineno-7-13" name="__codelineno-7-13"></a> "Objects in relation updated."
|
||
<a href="#api-__codelineno-7-14" id="__codelineno-7-14" name="__codelineno-7-14"></a> ]
|
||
<a href="#api-__codelineno-7-15" id="__codelineno-7-15" name="__codelineno-7-15"></a>}
|
||
</code></pre></div>
|
||
</li>
|
||
</ul></section><h1 class="nav-section-title">Contribution</h1><section class="print-page" id="contrib"><h1 id="contrib-contribution">Contribution</h1>
|
||
<p>Comme tout projet libre qui se respecte, les contributions à LdapSaisie sont les bienvenues. Ce
|
||
chapitre explique les possibilités de contribution.</p></section><h2 class="nav-section-title">Les addons (LSaddon)</h2><section class="print-page" id="contrib-addons"><h1 id="contrib-addons-les-addons-lsaddon">Les addons (LSaddon)</h1>
|
||
<p>Les <a href="#conf-configuration-des-lsaddons">LSaddons</a> sont utilisés pour implémenter dans LdapSaisie
|
||
des fonctionnalités spécifiques tel que :</p>
|
||
<ul>
|
||
<li>le support d'une famille d'attributs spécifiques (POSIX, Samba, SUPANN…) par le biais de méthodes
|
||
de génération de la valeur de ces attributs par exemple (paramètre <code>generate_function</code>) ;</li>
|
||
</ul>
|
||
<ul>
|
||
<li>des tâches communes et génériques (envoi de mails, connexion FTP/SSH…) ;</li>
|
||
</ul>
|
||
<ul>
|
||
<li>l'implémentation de <a href="#conf-declencheurs_1">déclencheurs</a> spécifiques à votre environnement :
|
||
création automatique du dossier client sur le serveur de fichiers de l'entreprise, création de la
|
||
boite mail de l'utilisateur… ;</li>
|
||
</ul>
|
||
<ul>
|
||
<li>l'implémentation de <a href="#contrib-addons-les-vues-personnalisees">vues personnalisées</a> proposées dans l'interface</li>
|
||
</ul>
|
||
<ul>
|
||
<li>l'implémentation d'action personnalisée sur les <a href="#conf-customactions">objets</a> (synchronisation,
|
||
archivage…) ou sur les <a href="#conf-lsobject-lssearch-customactions">résultats de recherches</a>
|
||
(export, rapport personnalisé…) ;</li>
|
||
</ul>
|
||
<h2 id="contrib-addons-structure-decriture">Structure d'écriture</h2>
|
||
<p>L'écriture d'un <a href="#conf-configuration-des-lsaddons">LSaddon</a> doit respecter une structure
|
||
suffisamment souple afin de ne pas être un frein à vos contributions, tout en permettant d'assurer
|
||
la bonne intégration de votre contribution au projet. Le code que vous écrirez sera réparti dans
|
||
deux fichiers :</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>conf/LSaddons/config.LSaddons.[addon name].php</code></p>
|
||
<p>Ce fichier contiendra la configuration de votre <a href="#conf-configuration-des-lsaddons">LSaddon</a>.
|
||
On y retrouvera la déclaration de constances et/ou variables de configuration permettant d'adapter
|
||
votre <a href="#conf-configuration-des-lsaddons">LSaddon</a> à une installation et à un environnement.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>includes/addons/LSaddons.[addon name].php</code></p>
|
||
<p>Ce fichier contiendra le code à proprement dit de votre <a href="#conf-configuration-des-lsaddons">LSaddon</a>.</p>
|
||
<p><strong>Structure du fichier includes/addons/LSaddons.[addon name].php :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#contrib-addons-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="cp"><?php</span>
|
||
<a href="#contrib-addons-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a>
|
||
<a href="#contrib-addons-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="cm">/*</span>
|
||
<a href="#contrib-addons-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="cm"> * Error messages</span>
|
||
<a href="#contrib-addons-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="cm"> */</span>
|
||
<a href="#contrib-addons-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a>
|
||
<a href="#contrib-addons-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="c1">// Support error messages</span>
|
||
<a href="#contrib-addons-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="nx">LSerror</span> <span class="o">::</span> <span class="na">defineError</span><span class="p">(</span><span class="s1">'MYADDON_SUPPORT_01'</span><span class="p">,</span>
|
||
<a href="#contrib-addons-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="nx">___</span><span class="p">(</span><span class="s2">"MYADDON Support : Unable to load %{dep}."</span><span class="p">)</span>
|
||
<a href="#contrib-addons-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a><span class="p">);</span>
|
||
<a href="#contrib-addons-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a>
|
||
<a href="#contrib-addons-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a><span class="nx">LSerror</span> <span class="o">::</span> <span class="na">defineError</span><span class="p">(</span><span class="s1">'MYADDON_SUPPORT_02'</span><span class="p">,</span>
|
||
<a href="#contrib-addons-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> <span class="nx">___</span><span class="p">(</span><span class="s2">"MYADDON Support : The constant %{const} is not defined."</span><span class="p">)</span>
|
||
<a href="#contrib-addons-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a><span class="p">);</span>
|
||
<a href="#contrib-addons-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a>
|
||
<a href="#contrib-addons-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a><span class="c1">// Other orror messages</span>
|
||
<a href="#contrib-addons-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a><span class="nx">LSerror</span> <span class="o">::</span> <span class="na">defineError</span><span class="p">(</span><span class="s1">'MYADDON_01'</span><span class="p">,</span>
|
||
<a href="#contrib-addons-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a> <span class="nx">___</span><span class="p">(</span><span class="s2">"An error : %{msg}."</span><span class="p">)</span>
|
||
<a href="#contrib-addons-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a><span class="p">);</span>
|
||
<a href="#contrib-addons-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a>
|
||
<a href="#contrib-addons-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a><span class="nx">LSerror</span> <span class="o">::</span> <span class="na">defineError</span><span class="p">(</span><span class="s1">'MYADDON_02'</span><span class="p">,</span>
|
||
<a href="#contrib-addons-__codelineno-0-22" id="__codelineno-0-22" name="__codelineno-0-22"></a> <span class="nx">___</span><span class="p">(</span><span class="s2">"An other error about %{about} : %{msg}"</span><span class="p">)</span>
|
||
<a href="#contrib-addons-__codelineno-0-23" id="__codelineno-0-23" name="__codelineno-0-23"></a><span class="p">);</span>
|
||
<a href="#contrib-addons-__codelineno-0-24" id="__codelineno-0-24" name="__codelineno-0-24"></a>
|
||
<a href="#contrib-addons-__codelineno-0-25" id="__codelineno-0-25" name="__codelineno-0-25"></a><span class="nx">LSerror</span> <span class="o">::</span> <span class="na">defineError</span><span class="p">(</span><span class="s1">'MYADDON_03'</span><span class="p">,</span>
|
||
<a href="#contrib-addons-__codelineno-0-26" id="__codelineno-0-26" name="__codelineno-0-26"></a> <span class="nx">___</span><span class="p">(</span><span class="s2">"Unknown error."</span><span class="p">)</span>
|
||
<a href="#contrib-addons-__codelineno-0-27" id="__codelineno-0-27" name="__codelineno-0-27"></a><span class="p">);</span>
|
||
<a href="#contrib-addons-__codelineno-0-28" id="__codelineno-0-28" name="__codelineno-0-28"></a>
|
||
<a href="#contrib-addons-__codelineno-0-29" id="__codelineno-0-29" name="__codelineno-0-29"></a><span class="sd">/**</span>
|
||
<a href="#contrib-addons-__codelineno-0-30" id="__codelineno-0-30" name="__codelineno-0-30"></a><span class="sd"> * Verify support of my addon by LdapSaisie</span>
|
||
<a href="#contrib-addons-__codelineno-0-31" id="__codelineno-0-31" name="__codelineno-0-31"></a><span class="sd"> *</span>
|
||
<a href="#contrib-addons-__codelineno-0-32" id="__codelineno-0-32" name="__codelineno-0-32"></a><span class="sd"> * @author My Name <my.email@example.com></span>
|
||
<a href="#contrib-addons-__codelineno-0-33" id="__codelineno-0-33" name="__codelineno-0-33"></a><span class="sd"> *</span>
|
||
<a href="#contrib-addons-__codelineno-0-34" id="__codelineno-0-34" name="__codelineno-0-34"></a><span class="sd"> * @return boolean true if my addon is totaly supported, false in other cases</span>
|
||
<a href="#contrib-addons-__codelineno-0-35" id="__codelineno-0-35" name="__codelineno-0-35"></a><span class="sd"> **/</span>
|
||
<a href="#contrib-addons-__codelineno-0-36" id="__codelineno-0-36" name="__codelineno-0-36"></a><span class="k">function</span> <span class="nf">LSaddon_myaddon_support</span><span class="p">()</span> <span class="p">{</span>
|
||
<a href="#contrib-addons-__codelineno-0-37" id="__codelineno-0-37" name="__codelineno-0-37"></a>
|
||
<a href="#contrib-addons-__codelineno-0-38" id="__codelineno-0-38" name="__codelineno-0-38"></a> <span class="nv">$retval</span><span class="o">=</span><span class="k">true</span><span class="p">;</span>
|
||
<a href="#contrib-addons-__codelineno-0-39" id="__codelineno-0-39" name="__codelineno-0-39"></a>
|
||
<a href="#contrib-addons-__codelineno-0-40" id="__codelineno-0-40" name="__codelineno-0-40"></a> <span class="c1">// Check/load dependencies</span>
|
||
<a href="#contrib-addons-__codelineno-0-41" id="__codelineno-0-41" name="__codelineno-0-41"></a> <span class="k">if</span> <span class="p">(</span> <span class="o">!</span><span class="nb">class_exists</span><span class="p">(</span><span class="s1">'mylib'</span><span class="p">)</span> <span class="p">)</span> <span class="p">{</span>
|
||
<a href="#contrib-addons-__codelineno-0-42" id="__codelineno-0-42" name="__codelineno-0-42"></a> <span class="k">if</span> <span class="p">(</span> <span class="o">!</span><span class="nx">LSsession</span><span class="o">::</span><span class="na">includeFile</span><span class="p">(</span><span class="nx">LS_LIB_DIR</span> <span class="o">.</span> <span class="s1">'class.mylib.php'</span><span class="p">)</span> <span class="p">)</span> <span class="p">{</span>
|
||
<a href="#contrib-addons-__codelineno-0-43" id="__codelineno-0-43" name="__codelineno-0-43"></a> <span class="nx">LSerror</span> <span class="o">::</span> <span class="na">addErrorCode</span><span class="p">(</span><span class="s1">'MYADDON_SUPPORT_01'</span><span class="p">,</span> <span class="s1">'mylib'</span><span class="p">);</span>
|
||
<a href="#contrib-addons-__codelineno-0-44" id="__codelineno-0-44" name="__codelineno-0-44"></a> <span class="nv">$retval</span><span class="o">=</span><span class="k">false</span><span class="p">;</span>
|
||
<a href="#contrib-addons-__codelineno-0-45" id="__codelineno-0-45" name="__codelineno-0-45"></a> <span class="p">}</span>
|
||
<a href="#contrib-addons-__codelineno-0-46" id="__codelineno-0-46" name="__codelineno-0-46"></a> <span class="p">}</span>
|
||
<a href="#contrib-addons-__codelineno-0-47" id="__codelineno-0-47" name="__codelineno-0-47"></a>
|
||
<a href="#contrib-addons-__codelineno-0-48" id="__codelineno-0-48" name="__codelineno-0-48"></a>
|
||
<a href="#contrib-addons-__codelineno-0-49" id="__codelineno-0-49" name="__codelineno-0-49"></a> <span class="nv">$MUST_DEFINE_CONST</span><span class="o">=</span> <span class="k">array</span><span class="p">(</span>
|
||
<a href="#contrib-addons-__codelineno-0-50" id="__codelineno-0-50" name="__codelineno-0-50"></a> <span class="s1">'LS_MYADDON_CONF_O1'</span><span class="p">,</span>
|
||
<a href="#contrib-addons-__codelineno-0-51" id="__codelineno-0-51" name="__codelineno-0-51"></a> <span class="s1">'LS_MYADDON_CONF_O2'</span><span class="p">,</span>
|
||
<a href="#contrib-addons-__codelineno-0-52" id="__codelineno-0-52" name="__codelineno-0-52"></a> <span class="o">...</span>
|
||
<a href="#contrib-addons-__codelineno-0-53" id="__codelineno-0-53" name="__codelineno-0-53"></a> <span class="p">);</span>
|
||
<a href="#contrib-addons-__codelineno-0-54" id="__codelineno-0-54" name="__codelineno-0-54"></a>
|
||
<a href="#contrib-addons-__codelineno-0-55" id="__codelineno-0-55" name="__codelineno-0-55"></a> <span class="k">foreach</span><span class="p">(</span><span class="nv">$MUST_DEFINE_CONST</span> <span class="k">as</span> <span class="nv">$const</span><span class="p">)</span> <span class="p">{</span>
|
||
<a href="#contrib-addons-__codelineno-0-56" id="__codelineno-0-56" name="__codelineno-0-56"></a> <span class="k">if</span> <span class="p">(</span> <span class="p">(</span><span class="o">!</span><span class="nb">defined</span><span class="p">(</span><span class="nv">$const</span><span class="p">))</span> <span class="o">||</span> <span class="p">(</span><span class="nb">constant</span><span class="p">(</span><span class="nv">$const</span><span class="p">)</span> <span class="o">==</span> <span class="s2">""</span><span class="p">))</span> <span class="p">{</span>
|
||
<a href="#contrib-addons-__codelineno-0-57" id="__codelineno-0-57" name="__codelineno-0-57"></a> <span class="nx">LSerror</span> <span class="o">::</span> <span class="na">addErrorCode</span><span class="p">(</span><span class="s1">'MYADDON_SUPPORT_02'</span><span class="p">,</span><span class="nv">$const</span><span class="p">);</span>
|
||
<a href="#contrib-addons-__codelineno-0-58" id="__codelineno-0-58" name="__codelineno-0-58"></a> <span class="nv">$retval</span><span class="o">=</span><span class="k">false</span><span class="p">;</span>
|
||
<a href="#contrib-addons-__codelineno-0-59" id="__codelineno-0-59" name="__codelineno-0-59"></a> <span class="p">}</span>
|
||
<a href="#contrib-addons-__codelineno-0-60" id="__codelineno-0-60" name="__codelineno-0-60"></a> <span class="p">}</span>
|
||
<a href="#contrib-addons-__codelineno-0-61" id="__codelineno-0-61" name="__codelineno-0-61"></a>
|
||
<a href="#contrib-addons-__codelineno-0-62" id="__codelineno-0-62" name="__codelineno-0-62"></a> <span class="k">if</span> <span class="p">(</span><span class="nv">$retval</span><span class="p">)</span> <span class="p">{</span>
|
||
<a href="#contrib-addons-__codelineno-0-63" id="__codelineno-0-63" name="__codelineno-0-63"></a> <span class="c1">// Register LSaddon view using LSsession :: registerLSaddonView()</span>
|
||
<a href="#contrib-addons-__codelineno-0-64" id="__codelineno-0-64" name="__codelineno-0-64"></a>
|
||
<a href="#contrib-addons-__codelineno-0-65" id="__codelineno-0-65" name="__codelineno-0-65"></a> <span class="k">if</span> <span class="p">(</span><span class="nb">php_sapi_name</span><span class="p">()</span> <span class="o">==</span> <span class="s1">'cli'</span><span class="p">)</span> <span class="p">{</span>
|
||
<a href="#contrib-addons-__codelineno-0-66" id="__codelineno-0-66" name="__codelineno-0-66"></a> <span class="c1">// Register LSaddon CLI command using LScli :: add_command()</span>
|
||
<a href="#contrib-addons-__codelineno-0-67" id="__codelineno-0-67" name="__codelineno-0-67"></a> <span class="p">}</span>
|
||
<a href="#contrib-addons-__codelineno-0-68" id="__codelineno-0-68" name="__codelineno-0-68"></a> <span class="p">}</span>
|
||
<a href="#contrib-addons-__codelineno-0-69" id="__codelineno-0-69" name="__codelineno-0-69"></a>
|
||
<a href="#contrib-addons-__codelineno-0-70" id="__codelineno-0-70" name="__codelineno-0-70"></a> <span class="k">return</span> <span class="nv">$retval</span><span class="p">;</span>
|
||
<a href="#contrib-addons-__codelineno-0-71" id="__codelineno-0-71" name="__codelineno-0-71"></a><span class="p">}</span>
|
||
<a href="#contrib-addons-__codelineno-0-72" id="__codelineno-0-72" name="__codelineno-0-72"></a>
|
||
<a href="#contrib-addons-__codelineno-0-73" id="__codelineno-0-73" name="__codelineno-0-73"></a><span class="sd">/**</span>
|
||
<a href="#contrib-addons-__codelineno-0-74" id="__codelineno-0-74" name="__codelineno-0-74"></a><span class="sd"> * My first function</span>
|
||
<a href="#contrib-addons-__codelineno-0-75" id="__codelineno-0-75" name="__codelineno-0-75"></a><span class="sd"> *</span>
|
||
<a href="#contrib-addons-__codelineno-0-76" id="__codelineno-0-76" name="__codelineno-0-76"></a><span class="sd"> * Description of this wonderfull function</span>
|
||
<a href="#contrib-addons-__codelineno-0-77" id="__codelineno-0-77" name="__codelineno-0-77"></a><span class="sd"> *</span>
|
||
<a href="#contrib-addons-__codelineno-0-78" id="__codelineno-0-78" name="__codelineno-0-78"></a><span class="sd"> * @author My Name <my.email@example.com></span>
|
||
<a href="#contrib-addons-__codelineno-0-79" id="__codelineno-0-79" name="__codelineno-0-79"></a><span class="sd"> *</span>
|
||
<a href="#contrib-addons-__codelineno-0-80" id="__codelineno-0-80" name="__codelineno-0-80"></a><span class="sd"> * @return [type(s) of returned values (pipe separator)] Description of the return of this function</span>
|
||
<a href="#contrib-addons-__codelineno-0-81" id="__codelineno-0-81" name="__codelineno-0-81"></a><span class="sd"> **/</span>
|
||
<a href="#contrib-addons-__codelineno-0-82" id="__codelineno-0-82" name="__codelineno-0-82"></a><span class="k">function</span> <span class="nf">myaddon_first_function</span><span class="p">(</span><span class="nv">$arg1</span><span class="p">,</span> <span class="nv">$arg2</span><span class="p">)</span> <span class="p">{</span>
|
||
<a href="#contrib-addons-__codelineno-0-83" id="__codelineno-0-83" name="__codelineno-0-83"></a> <span class="c1">// Do some stuff</span>
|
||
<a href="#contrib-addons-__codelineno-0-84" id="__codelineno-0-84" name="__codelineno-0-84"></a> <span class="k">if</span> <span class="p">(</span><span class="nx">something</span><span class="p">)</span> <span class="p">{</span>
|
||
<a href="#contrib-addons-__codelineno-0-85" id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="nx">LSerror</span> <span class="o">::</span> <span class="na">addErrorCode</span><span class="p">(</span>
|
||
<a href="#contrib-addons-__codelineno-0-86" id="__codelineno-0-86" name="__codelineno-0-86"></a> <span class="s1">'MYADDON_01'</span><span class="p">,</span>
|
||
<a href="#contrib-addons-__codelineno-0-87" id="__codelineno-0-87" name="__codelineno-0-87"></a> <span class="s1">'something went wrong'</span> <span class="c1">// Error LSformat unique argument</span>
|
||
<a href="#contrib-addons-__codelineno-0-88" id="__codelineno-0-88" name="__codelineno-0-88"></a> <span class="p">);</span>
|
||
<a href="#contrib-addons-__codelineno-0-89" id="__codelineno-0-89" name="__codelineno-0-89"></a> <span class="k">return</span> <span class="k">false</span><span class="p">;</span>
|
||
<a href="#contrib-addons-__codelineno-0-90" id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="p">}</span>
|
||
<a href="#contrib-addons-__codelineno-0-91" id="__codelineno-0-91" name="__codelineno-0-91"></a>
|
||
<a href="#contrib-addons-__codelineno-0-92" id="__codelineno-0-92" name="__codelineno-0-92"></a> <span class="k">if</span> <span class="p">(</span><span class="nx">something</span> <span class="k">else</span><span class="p">)</span> <span class="p">{</span>
|
||
<a href="#contrib-addons-__codelineno-0-93" id="__codelineno-0-93" name="__codelineno-0-93"></a> <span class="nx">LSerror</span> <span class="o">::</span> <span class="na">addErrorCode</span><span class="p">(</span>
|
||
<a href="#contrib-addons-__codelineno-0-94" id="__codelineno-0-94" name="__codelineno-0-94"></a> <span class="s1">'MYADDON_02'</span><span class="p">,</span>
|
||
<a href="#contrib-addons-__codelineno-0-95" id="__codelineno-0-95" name="__codelineno-0-95"></a> <span class="k">array</span><span class="p">(</span> <span class="c1">// Error LSformat arguments</span>
|
||
<a href="#contrib-addons-__codelineno-0-96" id="__codelineno-0-96" name="__codelineno-0-96"></a> <span class="s1">'about'</span> <span class="o">=></span> <span class="s1">'second step'</span><span class="p">,</span>
|
||
<a href="#contrib-addons-__codelineno-0-97" id="__codelineno-0-97" name="__codelineno-0-97"></a> <span class="s1">'msg'</span> <span class="o">=></span> <span class="s1">'something went wrong'</span>
|
||
<a href="#contrib-addons-__codelineno-0-98" id="__codelineno-0-98" name="__codelineno-0-98"></a> <span class="p">)</span>
|
||
<a href="#contrib-addons-__codelineno-0-99" id="__codelineno-0-99" name="__codelineno-0-99"></a> <span class="p">);</span>
|
||
<a href="#contrib-addons-__codelineno-0-100" id="__codelineno-0-100" name="__codelineno-0-100"></a> <span class="k">return</span> <span class="k">false</span><span class="p">;</span>
|
||
<a href="#contrib-addons-__codelineno-0-101" id="__codelineno-0-101" name="__codelineno-0-101"></a> <span class="p">}</span>
|
||
<a href="#contrib-addons-__codelineno-0-102" id="__codelineno-0-102" name="__codelineno-0-102"></a>
|
||
<a href="#contrib-addons-__codelineno-0-103" id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="k">if</span> <span class="p">(</span><span class="nx">still</span> <span class="nx">something</span> <span class="k">else</span><span class="p">)</span> <span class="p">{</span>
|
||
<a href="#contrib-addons-__codelineno-0-104" id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="nx">LSerror</span> <span class="o">::</span> <span class="na">addErrorCode</span><span class="p">(</span><span class="s1">'MYADDON_03'</span><span class="p">);</span> <span class="c1">// Error without argument</span>
|
||
<a href="#contrib-addons-__codelineno-0-105" id="__codelineno-0-105" name="__codelineno-0-105"></a> <span class="k">return</span> <span class="k">false</span><span class="p">;</span>
|
||
<a href="#contrib-addons-__codelineno-0-106" id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="p">}</span>
|
||
<a href="#contrib-addons-__codelineno-0-107" id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="k">return</span> <span class="k">true</span><span class="p">;</span>
|
||
<a href="#contrib-addons-__codelineno-0-108" id="__codelineno-0-108" name="__codelineno-0-108"></a><span class="p">}</span>
|
||
<a href="#contrib-addons-__codelineno-0-109" id="__codelineno-0-109" name="__codelineno-0-109"></a>
|
||
<a href="#contrib-addons-__codelineno-0-110" id="__codelineno-0-110" name="__codelineno-0-110"></a><span class="p">[</span><span class="o">...</span><span class="p">]</span>
|
||
<a href="#contrib-addons-__codelineno-0-111" id="__codelineno-0-111" name="__codelineno-0-111"></a>
|
||
<a href="#contrib-addons-__codelineno-0-112" id="__codelineno-0-112" name="__codelineno-0-112"></a><span class="c1">// Defined custom CLI commands functions only on CLI context</span>
|
||
<a href="#contrib-addons-__codelineno-0-113" id="__codelineno-0-113" name="__codelineno-0-113"></a><span class="k">if</span> <span class="p">(</span><span class="nb">php_sapi_name</span><span class="p">()</span> <span class="o">!=</span> <span class="s1">'cli'</span><span class="p">)</span>
|
||
<a href="#contrib-addons-__codelineno-0-114" id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="k">return</span> <span class="k">true</span><span class="p">;</span> <span class="c1">// Always return true to avoid some warning in log</span>
|
||
<a href="#contrib-addons-__codelineno-0-115" id="__codelineno-0-115" name="__codelineno-0-115"></a>
|
||
<a href="#contrib-addons-__codelineno-0-116" id="__codelineno-0-116" name="__codelineno-0-116"></a><span class="c1">// Defined functions handling custom CLI commands and optionnaly</span>
|
||
<a href="#contrib-addons-__codelineno-0-117" id="__codelineno-0-117" name="__codelineno-0-117"></a><span class="c1">// their arguments autocompleter functions.</span>
|
||
</code></pre></div>
|
||
</li>
|
||
</ul>
|
||
<p>Par convention, la structure de ce fichier est toujours à peu près la même:</p>
|
||
<ul>
|
||
<li>On déclare tout d'abord les messages d'erreurs qui seront potentiellement émis par notre
|
||
<a href="#conf-configuration-des-lsaddons">LSaddon</a> en commençant par les messages d'erreurs liés au
|
||
support de cet <a href="#conf-configuration-des-lsaddons">LSaddon</a>. On utilise pour cela la méthode
|
||
<code>LSerror :: defineError()</code> qui attends en premier argument, l'identifiant du message
|
||
d'erreur et en tant que second argument, le
|
||
<a href="#conf-global-lsformat-format-parametrable">LSformat</a> du message d'erreur. Par convention,
|
||
les identifiants des messages d'erreurs seront en majuscule et préfixés du nom du
|
||
<a href="#conf-configuration-des-lsaddons">LSaddon</a>.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>On déclare ensuite une fonction <code>LSaddon_[myaddon]_support</code> qui sera exécutée lors du chargement
|
||
de l'addon et qui permettra de s'assurer du support de celui-ci. Cette fonction devra retourner
|
||
<code>True</code> si c'est le cas ou <code>False</code> dans le cas contraire.</p>
|
||
<p>Cette fonction s'assura notamment :</p>
|
||
<ul>
|
||
<li>que les librairies dont l'addon dépends sont bien chargées et fonctionnelles ;</li>
|
||
<li>que ses variables et constantes de configuration sont bien définies ;</li>
|
||
<li>de déclarer <a href="#contrib-addons-les-vues-personnalisees">les vues personnalisées</a> fournies par cet
|
||
<a href="#conf-configuration-des-lsaddons">LSaddon</a> ;</li>
|
||
<li>de déclarer <a href="#contrib-addons-les-commandes-cli-personnalisees">les commandes <em>CLI</em> personnalisées</a> fournies par
|
||
cet <a href="#conf-configuration-des-lsaddons">LSaddon</a> ;</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>On déclare ensuite les fonctions, classes et éléments fournis et manipulés par l'addon.</li>
|
||
<li>
|
||
<p>Si notre addon offre des <a href="#contrib-addons-les-commandes-cli-personnalisees">commandes <em>CLI</em> personnalisées</a>, les
|
||
fonctions les implémentant ne seront définies, dans un souci de performance, que dans un contexte
|
||
ou elles seraient potentiellement appelables, c'est à dire dans un contexte d'exécution <code>CLI</code>.
|
||
Pour cela, nous utilisons communément la fonction <code>php_sapi_name</code> pour déterminer le contexte
|
||
d'exécution et si celui-ci vaut <code>cli</code>, nous stoppons l'exécution du reste du code du fichier via
|
||
un <code>return true</code>.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Il est important dans ce contexte de ne jamais retourner autre chose que <code>True</code> pour éviter
|
||
tout message d'erreur inutile dans les logs.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>On déclare, pour finir, les fonctions implémentant les
|
||
<a href="#contrib-addons-les-commandes-cli-personnalisees">commandes <em>CLI</em> personnalisées</a> et leur éventuelle fonction
|
||
gérant l'autocomplétion des arguments qu'elles acceptent.</li>
|
||
</ul></section><section class="print-page" id="contrib-addons-custom-views"><h1 id="contrib-addons-custom-views-les-vues-personnalisees">Les vues personnalisées</h1>
|
||
<p>Les <a href="#conf-configuration-des-lsaddons">LSaddons</a> peuvent fournir des vues personnalisées qui
|
||
seront accessibles à tout ou parties des utilisateurs de l'application. Ce filtrage d'accès sera
|
||
fait en utilisant les <a href="#conf-global-ldap-lsprofile-profils-dutilisateurs">LSprofiles</a> de
|
||
l'utilisateur connecté sur la
|
||
<a href="#conf-global-ldap-subdn-sous-niveaux-de-connexion">racine courante de l'annuaire LDAP</a>.</p>
|
||
<p>Pour mettre en place une telle vue personnalisée, il est nécessaire de :</p>
|
||
<ul>
|
||
<li>Déclarer cette vue dans la fonction <code>LSaddon_[addon]_support</code> de l'addon à l'aide de la méthode
|
||
<code>LSsession :: registerLSaddonView()</code> ;</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Déclarer la fonction implémentant cette vue. Cette fonction n'acceptera aucun paramètre et ne
|
||
retournera rien. Elle devra en outre s'occuper de définir son fichier template et charger les
|
||
dépendances de ce dernier (fichiers <em>CSS & JS</em>, variables...).</li>
|
||
</ul>
|
||
<p>Pour implémenter une telle vue personnalisée, vous pouvez vous inspirer de l'exemple fourni
|
||
ci-dessous ou encore des vues fournies par les autres
|
||
<a href="#conf-configuration-des-lsaddons">LSaddons</a> (par exemple, l'addon
|
||
<a href="#conf-lsaddon-lsaddon_exportsearchresultascsv-lsaddon_exportsearchresultascsv">exportSearchResultAsCSV</a>).</p>
|
||
<p><strong>Structure du fichier includes/addons/LSaddons.[addon name].php :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#contrib-addons-custom-views-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="cp"><?php</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="k">function</span> <span class="nf">LSaddon_myaddon_support</span><span class="p">()</span> <span class="p">{</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> <span class="nv">$retval</span><span class="o">=</span><span class="k">true</span><span class="p">;</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> <span class="c1">// Some check</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> <span class="k">if</span> <span class="p">(</span><span class="nv">$retval</span><span class="p">)</span> <span class="p">{</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> <span class="nv">$retval</span> <span class="o">=</span> <span class="nx">LSsession</span> <span class="o">::</span> <span class="na">registerLSaddonView</span><span class="p">(</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> <span class="s1">'myaddon'</span><span class="p">,</span> <span class="c1">// addon name</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> <span class="s1">'myaddon_view'</span><span class="p">,</span> <span class="c1">// addon view ID</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> <span class="nx">__</span><span class="p">(</span><span class="s1">'MyAddon view'</span><span class="p">),</span> <span class="c1">// addon view label</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> <span class="s1">'myaddon_view'</span><span class="p">,</span> <span class="c1">// callable (ex: function name) that implement addon view</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a> <span class="k">array</span><span class="p">(</span><span class="s1">'user'</span><span class="p">),</span> <span class="c1">// array listing allowed LSprofiles</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a> <span class="k">true</span> <span class="c1">// Show/hide this addon view in user menu</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a> <span class="p">);</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a> <span class="p">}</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a> <span class="k">return</span> <span class="nv">$retval</span><span class="p">;</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a><span class="p">}</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-22" id="__codelineno-0-22" name="__codelineno-0-22"></a><span class="p">[</span><span class="o">...</span><span class="p">]</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-23" id="__codelineno-0-23" name="__codelineno-0-23"></a>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-24" id="__codelineno-0-24" name="__codelineno-0-24"></a><span class="sd">/**</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-25" id="__codelineno-0-25" name="__codelineno-0-25"></a><span class="sd"> * My addon view handler function</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-26" id="__codelineno-0-26" name="__codelineno-0-26"></a><span class="sd"> *</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-27" id="__codelineno-0-27" name="__codelineno-0-27"></a><span class="sd"> * Description of this view</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-28" id="__codelineno-0-28" name="__codelineno-0-28"></a><span class="sd"> *</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-29" id="__codelineno-0-29" name="__codelineno-0-29"></a><span class="sd"> * @author My Name <my.email@example.com></span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-30" id="__codelineno-0-30" name="__codelineno-0-30"></a><span class="sd"> *</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-31" id="__codelineno-0-31" name="__codelineno-0-31"></a><span class="sd"> * @return void</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-32" id="__codelineno-0-32" name="__codelineno-0-32"></a><span class="sd"> **/</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-33" id="__codelineno-0-33" name="__codelineno-0-33"></a><span class="k">function</span> <span class="nf">myaddon_view</span><span class="p">()</span> <span class="p">{</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-34" id="__codelineno-0-34" name="__codelineno-0-34"></a> <span class="c1">// Do some stuff and set some template variables</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-35" id="__codelineno-0-35" name="__codelineno-0-35"></a> <span class="nv">$list</span> <span class="o">=</span> <span class="k">array</span> <span class="p">([</span><span class="o">...</span><span class="p">]);</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-36" id="__codelineno-0-36" name="__codelineno-0-36"></a> <span class="nx">LStemplate</span> <span class="o">::</span> <span class="na">assign</span><span class="p">(</span><span class="s1">'list'</span><span class="p">,</span> <span class="nv">$list</span><span class="p">);</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-37" id="__codelineno-0-37" name="__codelineno-0-37"></a>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-38" id="__codelineno-0-38" name="__codelineno-0-38"></a> <span class="c1">// Load some CSS & JS files need on this view</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-39" id="__codelineno-0-39" name="__codelineno-0-39"></a> <span class="nx">LStemplate</span> <span class="o">::</span> <span class="na">addCssFile</span><span class="p">(</span><span class="s1">'LSaddon_myadon.css'</span><span class="p">);</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-40" id="__codelineno-0-40" name="__codelineno-0-40"></a> <span class="nx">LStemplate</span> <span class="o">::</span> <span class="na">addJSscript</span><span class="p">(</span><span class="s1">'LSaddon_myadon.js'</span><span class="p">);</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-41" id="__codelineno-0-41" name="__codelineno-0-41"></a>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-42" id="__codelineno-0-42" name="__codelineno-0-42"></a> <span class="c1">// Set template file of the view</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-43" id="__codelineno-0-43" name="__codelineno-0-43"></a> <span class="nx">LSsession</span> <span class="o">::</span> <span class="na">setTemplate</span><span class="p">(</span><span class="s1">'LSaddon_myadon_view.tpl'</span><span class="p">);</span>
|
||
<a href="#contrib-addons-custom-views-__codelineno-0-44" id="__codelineno-0-44" name="__codelineno-0-44"></a><span class="p">}</span>
|
||
</code></pre></div></section><section class="print-page" id="contrib-addons-cli-commands"><h1 id="contrib-addons-cli-commands-les-commandes-cli-personnalisees">Les commandes <em>CLI</em> personnalisées</h1>
|
||
<p>Les <a href="#conf-configuration-des-lsaddons">LSaddons</a> peuvent fournir des commandes <em>CLI</em>
|
||
personnalisées qui seront accessibles via la commande <code>ldapsaisie</code> fournie avec l'application. Cela
|
||
peut, par exemple, vous permettre de rendre accessible en ligne de commandes une procédure
|
||
implémentée dans le code d'LdapSaisie et vous permettre de mettre en place une tâche planifiée
|
||
exécutant cette procédure régulièrement.</p>
|
||
<p>Pour mettre en place une telle commande <em>CLI</em> personnalisée, il est nécessaire de :</p>
|
||
<ul>
|
||
<li>Déclarer cette vue dans la fonction <code>LSaddon_[addon]_support</code> de l'addon à l'aide de la méthode
|
||
<code>LScli :: add_command()</code> ;</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Déclarer la fonction implémentant cette commande <em>CLI</em> personnalisée. Cette fonction acceptera,
|
||
en tant qu'unique paramètre, un tableau des arguments reçus lors de l'exécution de la commande et
|
||
retournera <code>True</code> ou <code>False</code> en cas de succès/d'erreur d'exécution de la commande. Cette valeur de
|
||
retour influencera le code retourné par la commande : <code>0</code> en cas de succès, <code>1</code> en cas d'erreur.</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>Bien que cela ne soit pas obligatoire, il sera également possible de déclarer une fonction
|
||
permettant l'autocomplétion des arguments acceptés par la commande.</p>
|
||
<p>Cette méthode recevra en paramètre :</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>$command_args</code></p>
|
||
<p>Un tableau des arguments déjà reçus par la commande.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>$comp_word_num</code></p>
|
||
<p>Un entier indiquant le rang de l'argument que l'autocomplétion tente de compléter. Il peut
|
||
s'agir du rang d'un paramètre déjà fourni et présent dans le tableau <code>$command_args</code> ou bien
|
||
d'un rang supérieur aux nombres d'arguments déjà fournis à la commande et dans ce cas il s'agira
|
||
d'autocompléter tous potentiels autre argument que pourrait accepter cette commande.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>$comp_word</code></p>
|
||
<p>Une chaîne de caractères correspondant à ce qu'a déjà saisi l'utilisateur de l'argument que l'on
|
||
tente d'autocompléter. Cette chaîne de caractères peut être vide ou non, en fonction de s'il
|
||
s'agit d'un nouvel argument à autocompléter ou non.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>$opts</code></p>
|
||
<p>Un tableau des potentiels arguments globaux acceptés par <em>LScli</em> dans le contexte actuel (par
|
||
exemple, <code>-d</code> ou <code>--debug</code> pour l'activation du mode debug). La réponse de cette fonction devra
|
||
inclure ces potentiels arguments si le contexte d'autocomplétion si prête (nouvel argument par
|
||
exemple).</p>
|
||
</li>
|
||
</ul>
|
||
<p>Pour finir, cette fonction devra retourner un tableau des potentielles valeurs que pourrait
|
||
prendre l'argument autocomplété. Si une unique proposition est faite à l'utilisateur, celle-ci
|
||
sera automatiquement proposée à l'utilisateur et à défaut, la liste des valeurs possibles lui
|
||
seront affichées.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Pour vous aider dans l'écrire d'une telle méthode d'autocomplétion, des méthodes statiques
|
||
sont fournies par la classe <code>LScli</code> pour les autocomplétions les plus courantes :</p>
|
||
<ul>
|
||
<li><code>LScli :: autocomplete_class_name()</code></li>
|
||
</ul>
|
||
<p>Autocomplétion du nom d'une classe PHP.</p>
|
||
<ul>
|
||
<li><code>LScli :: autocomplete_addon_name()</code></li>
|
||
</ul>
|
||
<p>Autocomplétion du nom d'un <a href="#conf-configuration-des-lsaddons">LSaddon</a>.</p>
|
||
<ul>
|
||
<li><code>LScli :: autocomplete_int()</code></li>
|
||
</ul>
|
||
<p>Autocomplétion d'un nombre entier.</p>
|
||
<ul>
|
||
<li><code>LScli :: autocomplete_LSobject_types()</code></li>
|
||
</ul>
|
||
<p>Autocomplétion du nom d'un type d'<a href="#conf-configuration-lsobject">LSobject</a>.</p>
|
||
<ul>
|
||
<li><code>LScli :: autocomplete_LSobject_dn()</code></li>
|
||
</ul>
|
||
<p>Autocomplétion du DN d'un type précis d'<a href="#conf-configuration-lsobject">LSobject</a> de
|
||
l'annuaire.</p>
|
||
<p>Par ailleurs, la méthode <code>LScli :: autocomplete_opts()</code> vous facilitera la construction de la
|
||
liste des valeurs d'autocomplétion de l'argument courant en fonction de ce qui a déjà été
|
||
saisi par l'utilisateur (paramètre <code>$comp_word</code>). Cette méthode s'occupera en l'occurrence de
|
||
filtrer parmi toutes les valeurs contextuelles possibles, celles qui correspondent au préfixe
|
||
fourni par l'utilisateur.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<p>Pour implémenter une telle commande <em>CLI</em> personnalisée, vous pouvez vous inspirer de l'exemple
|
||
fourni ci-dessous ou encore des commandes <em>CLI</em> fournies par les autres
|
||
<a href="#conf-configuration-des-lsaddons">LSaddons</a> ou classes PHP de l'application.</p>
|
||
<p><strong>Structure du fichier includes/addons/LSaddons.[addon name].php :</strong></p>
|
||
<div class="highlight"><pre><span></span><code><a href="#contrib-addons-cli-commands-__codelineno-0-1" id="__codelineno-0-1" name="__codelineno-0-1"></a><?php
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-2" id="__codelineno-0-2" name="__codelineno-0-2"></a>function LSaddon_myaddon_support() {
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-3" id="__codelineno-0-3" name="__codelineno-0-3"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-4" id="__codelineno-0-4" name="__codelineno-0-4"></a> $retval=true;
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-5" id="__codelineno-0-5" name="__codelineno-0-5"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-6" id="__codelineno-0-6" name="__codelineno-0-6"></a> // Some check
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-7" id="__codelineno-0-7" name="__codelineno-0-7"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-8" id="__codelineno-0-8" name="__codelineno-0-8"></a> if ($retval) {
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-9" id="__codelineno-0-9" name="__codelineno-0-9"></a> if (php_sapi_name() == 'cli') {
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-10" id="__codelineno-0-10" name="__codelineno-0-10"></a> LScli :: add_command(
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-11" id="__codelineno-0-11" name="__codelineno-0-11"></a> 'my_custom_cli_cmd', // The CLI command name (required)
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-12" id="__codelineno-0-12" name="__codelineno-0-12"></a> 'cli_my_custom_cli_cmd', // The CLI command handler (must be callable, required)
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-13" id="__codelineno-0-13" name="__codelineno-0-13"></a> 'My custom CLI command', // A short description of what this command does (required)
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-14" id="__codelineno-0-14" name="__codelineno-0-14"></a> '[arg1] [arg2] [...]', // A short list of commands available arguments show in usage message
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-15" id="__codelineno-0-15" name="__codelineno-0-15"></a> // (optional, default: false)
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-16" id="__codelineno-0-16" name="__codelineno-0-16"></a> 'This command permit to ...', // A long description of what this command does (optional, default:
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-17" id="__codelineno-0-17" name="__codelineno-0-17"></a> // false)
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-18" id="__codelineno-0-18" name="__codelineno-0-18"></a> true, // Permit to define if this command need connection to LDAP server
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-19" id="__codelineno-0-19" name="__codelineno-0-19"></a> // (optional, default: true)
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-20" id="__codelineno-0-20" name="__codelineno-0-20"></a> 'cli_my_custom_cli_cmd_autocompleter', // Callable of the CLI command arguments autocompleter (optional,
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-21" id="__codelineno-0-21" name="__codelineno-0-21"></a> // default: null)
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-22" id="__codelineno-0-22" name="__codelineno-0-22"></a> true // Allow override if a command already exists with the same name
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-23" id="__codelineno-0-23" name="__codelineno-0-23"></a> // (optional, default: null)
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-24" id="__codelineno-0-24" name="__codelineno-0-24"></a> );
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-25" id="__codelineno-0-25" name="__codelineno-0-25"></a> }
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-26" id="__codelineno-0-26" name="__codelineno-0-26"></a> }
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-27" id="__codelineno-0-27" name="__codelineno-0-27"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-28" id="__codelineno-0-28" name="__codelineno-0-28"></a> return $retval;
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-29" id="__codelineno-0-29" name="__codelineno-0-29"></a>}
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-30" id="__codelineno-0-30" name="__codelineno-0-30"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-31" id="__codelineno-0-31" name="__codelineno-0-31"></a>[...]
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-32" id="__codelineno-0-32" name="__codelineno-0-32"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-33" id="__codelineno-0-33" name="__codelineno-0-33"></a>// Defined CLI commands functions only on CLI context
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-34" id="__codelineno-0-34" name="__codelineno-0-34"></a>if (php_sapi_name() != 'cli')
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-35" id="__codelineno-0-35" name="__codelineno-0-35"></a> return true; // Always return true to avoid some warning in log
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-36" id="__codelineno-0-36" name="__codelineno-0-36"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-37" id="__codelineno-0-37" name="__codelineno-0-37"></a>/**
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-38" id="__codelineno-0-38" name="__codelineno-0-38"></a> * My addon CLI command my_custom_cli_cmd handler function
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-39" id="__codelineno-0-39" name="__codelineno-0-39"></a> *
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-40" id="__codelineno-0-40" name="__codelineno-0-40"></a> * Description of this CLI command.
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-41" id="__codelineno-0-41" name="__codelineno-0-41"></a> *
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-42" id="__codelineno-0-42" name="__codelineno-0-42"></a> * @param array $command_args Command arguments
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-43" id="__codelineno-0-43" name="__codelineno-0-43"></a> * - Positional arguments :
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-44" id="__codelineno-0-44" name="__codelineno-0-44"></a> * - LSobject
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-45" id="__codelineno-0-45" name="__codelineno-0-45"></a> * - dn
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-46" id="__codelineno-0-46" name="__codelineno-0-46"></a> * - Optional arguments :
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-47" id="__codelineno-0-47" name="__codelineno-0-47"></a> * - -f|--force : Force mode
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-48" id="__codelineno-0-48" name="__codelineno-0-48"></a> *
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-49" id="__codelineno-0-49" name="__codelineno-0-49"></a> * @author My Name <my.email@example.com>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-50" id="__codelineno-0-50" name="__codelineno-0-50"></a> *
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-51" id="__codelineno-0-51" name="__codelineno-0-51"></a> * @return boolean True on success, false otherwise
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-52" id="__codelineno-0-52" name="__codelineno-0-52"></a> **/
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-53" id="__codelineno-0-53" name="__codelineno-0-53"></a>function cli_my_custom_cli_cmd($command_args) {
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-54" id="__codelineno-0-54" name="__codelineno-0-54"></a> $objType = null;
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-55" id="__codelineno-0-55" name="__codelineno-0-55"></a> $dn = null;
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-56" id="__codelineno-0-56" name="__codelineno-0-56"></a> $force_mode = false;
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-57" id="__codelineno-0-57" name="__codelineno-0-57"></a> foreach ($command_args as $arg) {
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-58" id="__codelineno-0-58" name="__codelineno-0-58"></a> if ($arg == '-f' || $arg == '--force')
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-59" id="__codelineno-0-59" name="__codelineno-0-59"></a> $force_mode = true;
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-60" id="__codelineno-0-60" name="__codelineno-0-60"></a> elseif (is_null($objType)) {
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-61" id="__codelineno-0-61" name="__codelineno-0-61"></a> $objType = $arg;
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-62" id="__codelineno-0-62" name="__codelineno-0-62"></a> }
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-63" id="__codelineno-0-63" name="__codelineno-0-63"></a> elseif (is_null($dn)) {
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-64" id="__codelineno-0-64" name="__codelineno-0-64"></a> $dn = $arg;
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-65" id="__codelineno-0-65" name="__codelineno-0-65"></a> }
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-66" id="__codelineno-0-66" name="__codelineno-0-66"></a> else
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-67" id="__codelineno-0-67" name="__codelineno-0-67"></a> LScli :: usage("Invalid $arg parameter.");
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-68" id="__codelineno-0-68" name="__codelineno-0-68"></a> }
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-69" id="__codelineno-0-69" name="__codelineno-0-69"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-70" id="__codelineno-0-70" name="__codelineno-0-70"></a> if (is_null($objType) || is_null($dn))
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-71" id="__codelineno-0-71" name="__codelineno-0-71"></a> LScli :: usage('You must provide LSobject type and DN.');
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-72" id="__codelineno-0-72" name="__codelineno-0-72"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-73" id="__codelineno-0-73" name="__codelineno-0-73"></a> if (!LSsession :: loadLSobject($objType))
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-74" id="__codelineno-0-74" name="__codelineno-0-74"></a> return false;
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-75" id="__codelineno-0-75" name="__codelineno-0-75"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-76" id="__codelineno-0-76" name="__codelineno-0-76"></a> $obj = new $objType();
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-77" id="__codelineno-0-77" name="__codelineno-0-77"></a> if (!$obj->loadData($dn)) {
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-78" id="__codelineno-0-78" name="__codelineno-0-78"></a> self :: log_fatal("Fail to load object $dn data from LDAP");
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-79" id="__codelineno-0-79" name="__codelineno-0-79"></a> return false;
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-80" id="__codelineno-0-80" name="__codelineno-0-80"></a> }
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-81" id="__codelineno-0-81" name="__codelineno-0-81"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-82" id="__codelineno-0-82" name="__codelineno-0-82"></a> // Do some stuff on loaded object
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-83" id="__codelineno-0-83" name="__codelineno-0-83"></a> [...]
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-84" id="__codelineno-0-84" name="__codelineno-0-84"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-85" id="__codelineno-0-85" name="__codelineno-0-85"></a> return true;
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-86" id="__codelineno-0-86" name="__codelineno-0-86"></a>}
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-87" id="__codelineno-0-87" name="__codelineno-0-87"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-88" id="__codelineno-0-88" name="__codelineno-0-88"></a>/**
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-89" id="__codelineno-0-89" name="__codelineno-0-89"></a> * Args autocompleter for CLI my_custom_cli_cmd command
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-90" id="__codelineno-0-90" name="__codelineno-0-90"></a> *
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-91" id="__codelineno-0-91" name="__codelineno-0-91"></a> * @param array<string> $command_args List of already typed words of the command
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-92" id="__codelineno-0-92" name="__codelineno-0-92"></a> * @param int $comp_word_num The command word number to autocomplete
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-93" id="__codelineno-0-93" name="__codelineno-0-93"></a> * @param string $comp_word The command word to autocomplete
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-94" id="__codelineno-0-94" name="__codelineno-0-94"></a> * @param array<string> $opts List of global available options
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-95" id="__codelineno-0-95" name="__codelineno-0-95"></a> *
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-96" id="__codelineno-0-96" name="__codelineno-0-96"></a> * @return array<string> List of available options for the word to autocomplete
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-97" id="__codelineno-0-97" name="__codelineno-0-97"></a> **/
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-98" id="__codelineno-0-98" name="__codelineno-0-98"></a>public static function cli_my_custom_cli_cmd_autocompleter($command_args, $comp_word_num, $comp_word, $opts) {
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-99" id="__codelineno-0-99" name="__codelineno-0-99"></a> $opts = array_merge($opts, array ('-f', '--force'));
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-100" id="__codelineno-0-100" name="__codelineno-0-100"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-101" id="__codelineno-0-101" name="__codelineno-0-101"></a> // Handle positional args
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-102" id="__codelineno-0-102" name="__codelineno-0-102"></a> $objType = null;
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-103" id="__codelineno-0-103" name="__codelineno-0-103"></a> $objType_arg_num = null;
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-104" id="__codelineno-0-104" name="__codelineno-0-104"></a> $dn = null;
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-105" id="__codelineno-0-105" name="__codelineno-0-105"></a> $dn_arg_num = null;
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-106" id="__codelineno-0-106" name="__codelineno-0-106"></a> for ($i=0; $i < count($command_args); $i++) {
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-107" id="__codelineno-0-107" name="__codelineno-0-107"></a> if (!in_array($command_args[$i], $opts)) {
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-108" id="__codelineno-0-108" name="__codelineno-0-108"></a> // If object type not defined
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-109" id="__codelineno-0-109" name="__codelineno-0-109"></a> if (is_null($objType)) {
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-110" id="__codelineno-0-110" name="__codelineno-0-110"></a> // Defined it
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-111" id="__codelineno-0-111" name="__codelineno-0-111"></a> $objType = $command_args[$i];
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-112" id="__codelineno-0-112" name="__codelineno-0-112"></a> LScli :: unquote_word($objType);
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-113" id="__codelineno-0-113" name="__codelineno-0-113"></a> $objType_arg_num = $i;
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-114" id="__codelineno-0-114" name="__codelineno-0-114"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-115" id="__codelineno-0-115" name="__codelineno-0-115"></a> // Check object type exists
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-116" id="__codelineno-0-116" name="__codelineno-0-116"></a> $objTypes = LScli :: autocomplete_LSobject_types($objType);
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-117" id="__codelineno-0-117" name="__codelineno-0-117"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-118" id="__codelineno-0-118" name="__codelineno-0-118"></a> // Load it if exist and not trying to complete it
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-119" id="__codelineno-0-119" name="__codelineno-0-119"></a> if (in_array($objType, $objTypes) && $i != $comp_word_num) {
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-120" id="__codelineno-0-120" name="__codelineno-0-120"></a> LSsession :: loadLSobject($objType, false);
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-121" id="__codelineno-0-121" name="__codelineno-0-121"></a> }
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-122" id="__codelineno-0-122" name="__codelineno-0-122"></a> }
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-123" id="__codelineno-0-123" name="__codelineno-0-123"></a> elseif (is_null($dn)) {
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-124" id="__codelineno-0-124" name="__codelineno-0-124"></a> $dn = $command_args[$i];
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-125" id="__codelineno-0-125" name="__codelineno-0-125"></a> LScli :: unquote_word($dn);
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-126" id="__codelineno-0-126" name="__codelineno-0-126"></a> $dn_arg_num = $i;
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-127" id="__codelineno-0-127" name="__codelineno-0-127"></a> }
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-128" id="__codelineno-0-128" name="__codelineno-0-128"></a> }
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-129" id="__codelineno-0-129" name="__codelineno-0-129"></a> }
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-130" id="__codelineno-0-130" name="__codelineno-0-130"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-131" id="__codelineno-0-131" name="__codelineno-0-131"></a> // If objType not already choiced (or currently autocomplete), add LSobject types to available options
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-132" id="__codelineno-0-132" name="__codelineno-0-132"></a> if (!$objType || $objType_arg_num == $comp_word_num)
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-133" id="__codelineno-0-133" name="__codelineno-0-133"></a> $opts = array_merge($opts, LScli :: autocomplete_LSobject_types($comp_word));
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-134" id="__codelineno-0-134" name="__codelineno-0-134"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-135" id="__codelineno-0-135" name="__codelineno-0-135"></a> // If dn not alreay choiced (or currently autocomplete), try autocomplete it
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-136" id="__codelineno-0-136" name="__codelineno-0-136"></a> elseif (!$dn || $dn_arg_num == $comp_word_num)
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-137" id="__codelineno-0-137" name="__codelineno-0-137"></a> $opts = array_merge($opts, LScli :: autocomplete_LSobject_dn($objType, $comp_word));
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-138" id="__codelineno-0-138" name="__codelineno-0-138"></a>
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-139" id="__codelineno-0-139" name="__codelineno-0-139"></a> return LScli :: autocomplete_opts($opts, $comp_word);
|
||
<a href="#contrib-addons-cli-commands-__codelineno-0-140" id="__codelineno-0-140" name="__codelineno-0-140"></a>}
|
||
</code></pre></div></section><h1 class="nav-section-title-end">Ended: Les addons (LSaddon)</h1><section class="print-page" id="contrib-form-elements"><h1 id="contrib-form-elements-les-elements-des-formulaires-lsformelement">Les éléments des formulaires (LSformElement)</h1>
|
||
<p>Les <a href="#contrib-form-elements-lsformelements">LSformElements</a> sont les types de champs de formulaire supportés par
|
||
l'application.</p>
|
||
<p>Pour chaque type implémenté, on devra trouver :</p>
|
||
<ul>
|
||
<li>Une classe PHP dérivée de la classe <code>LSattr_html</code> et devant s'appeler
|
||
<code>LSattr_html_[nom du type d'attribut HTML]</code>. Dans celle-ci, il devra être défini à minima la
|
||
variable de classe <code>LSformElement_type</code> permettant de référencer le type
|
||
d'<a href="#contrib-form-elements-lsformelements">LSformElement</a> à utiliser ;</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p>Une classe PHP dérivée de la classe <code>LSformElement</code> et devant s'appeler
|
||
<code>LSformElement_[nom du type d'LSformElement]</code>. Cette classe implémentera tout ce qui concerne
|
||
l'affichage du champ dans le formulaire et le traitement d'une valeur retournée par ce dernier.
|
||
Cela concerne notamment les méthodes suivantes :</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>getDisplay()</code></p>
|
||
<p>Retourne les informations d'affichage du champ dans un formulaire sous la forme d'un tableau
|
||
<em>(implémentation obligatoire, pas de méthode par défaut)</em>. Il sera possible de s'appuyer sur la
|
||
méthode <code>getLabelInfos()</code> permettant de générer et récupérer tout ce qui concerne le label du
|
||
champ du formulaire. Il faudra cependant à minima fournir également la clé <code>html</code> dans le
|
||
tableau retourné qui devra contenir le bout de code HTML correspondant au champ du formulaire.
|
||
Communément, ce code HTML est généré en appelant la méthode <code>fetchTemplate()</code>.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>fetchTemplate()</code></p>
|
||
<p>Retourne le code HTML du champ dans le formulaire. L'implémentation de cette méthode est
|
||
facultative et par défaut, cette méthode utilisera la variable de classe <code>$template</code> pour
|
||
connaître le fichier de template à utiliser. Ce fichier de template permettra la génération de
|
||
la liste de tous les champs associés à chacune des valeurs de l'attribut. Individuellement, le
|
||
champ d'une des valeurs de l'attribut est généré à l'aide du fichier de template référencé dans
|
||
la variable de class <code>$fieldTemplate</code>.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>La variable de classe <code>$fieldTemplate</code> est également utilisée par la méthode
|
||
<code>LSformElement :: getEmptyField()</code> qui sert à générer le code HTML d'un champ du formulaire
|
||
pour une nouvelle valeur de l'attribut. Cette méthode est notamment utilisée lorsque l'on
|
||
clique sur le bouton permettant d'ajouter une valeur à un champ du formulaire.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>getPostData()</code></p>
|
||
<p>Récupère dans les données postées par le formulaire, celle concernant ce champ. Cette méthode
|
||
devra potentiellement traiter l'ensemble des valeurs de l'attribut envoyées par le formulaire
|
||
et les définir dans le tableau passé en référence en tant que premier argument, les valeurs de
|
||
l'attribut. L'implémentation de cette méthode est facultative et par défaut, un tableau de
|
||
valeurs portant le nom de l'attribut LDAP correspondant sera récupérée comme valeur de
|
||
l'attribut.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Pour plus d'informations sur le rôle et fonctionnement de cette méthode, référer à la
|
||
méthode par défaut, définie dans la classe PHP parente <code>LSformElement</code>.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>setValueFromPostData()</code></p>
|
||
<p>Définit les valeurs de l'attribut à partir des données reçues du formulaire (et récupérées par
|
||
la méthode <code>getPostData</code>). L'implémentation de cette méthode est facultative et par défaut,
|
||
aucune transformation ne sera faites à cette étape sur les données récupérées depuis le
|
||
formulaire. Implémenter cette méthode pourra cependant se révéler utile en cas de champs de
|
||
formulaire complexe (attribut composite par exemple).</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>autocomplete_attr_values()</code></p>
|
||
<p>Génère de la liste des valeurs possibles de l'attribut dans un contexte <em>CLI</em>.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Pour plus d'informations sur le rôle et fonctionnement de cette méthode, référer aux
|
||
commentaires de la méthode par défaut, définie dans la classe PHP parente <code>LSformElement</code>.
|
||
Vous pouvez également vous inspirer des exemples d'implémentations fournies avec les autres
|
||
type d'<a href="#contrib-form-elements-lsformelements">LSformElement</a>.</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>Un (ou plusieurs) fichier template pour la génération du code HTML du champ du formulaire.
|
||
Communément, le fichier <code>LSformElement.tpl</code> est utilisé pour générer la structure de la liste des
|
||
champs correspondant aux différentes valeurs de l'attribut. Ce template utilise une variable
|
||
<code>$fieldTemplate</code> pour définir quel fichier template devra être utilisé pour générer le code HTML
|
||
de chaque champ associés à une valeur. C'est ce second fichier de template qui est en général à
|
||
fournir à minima avec votre <a href="#contrib-form-elements-lsformelements">LSformElement</a>.</li>
|
||
</ul>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Il peut être utile d'étendre un type d'<a href="#contrib-form-elements-lsformelements">LSformElement</a> existant pour faciliter
|
||
l'implémentation d'un nouveau type. Pour cela, vous devez utiliser l'héritage de classe PHP en
|
||
faisant dériver vos nouvelles classes des classes du <a href="#contrib-form-elements-lsformelements">LSformElement</a> dont vous
|
||
vous inspirer, plutôt que les classes génériques. Vous pouvez prendre exemple sur le type
|
||
d'<a href="#contrib-form-elements-lsformelements">LSformElement</a> <code>pre</code> qui s'inspire du type <code>textarea</code>, ou encore du type
|
||
<code>url</code> dérivé du type <code>text</code>.</p>
|
||
</div></section><section class="print-page" id="contrib-form-rules"><h1 id="contrib-form-rules-les-regles-de-validation-syntaxiques-lsformrule">Les règles de validation syntaxiques (LSformRule)</h1>
|
||
<p>Les <a href="#contrib-form-rules-lsformrules">LSformRules</a> sont les règles syntaxiques applicables aux champs des formulaires.
|
||
Ces règles serviront à s'assurer que les valeurs des champs récupérées des formulaires sont
|
||
syntaxiquement correctes. Elles seront configurables via le paramètre <code>check_data</code> des attributs des
|
||
<a href="#conf-configuration-lsobject">LSobjects</a>.</p>
|
||
<p>Pour chaque type implémenté, on trouvera une classe PHP dérivée de la classe <code>LSformRule</code> et devant
|
||
s'appeler <code>LSattr_rule_[nom du type]</code>. Dans celle-ci, il devra être défini la méthode statique
|
||
<code>validate()</code> qui implémentera le contrôle syntaxique. Cette méthode prendra en paramètres :</p>
|
||
<ul>
|
||
<li>
|
||
<p><code>$value</code></p>
|
||
<p>La valeur à tester.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>$options</code></p>
|
||
<p>Un tableau des options définies dans la configuration pour ce contrôle syntaxique.</p>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li>
|
||
<p><code>$formElement</code></p>
|
||
<p>Une référence au champ du formulaire (objet <a href="#contrib-form-rules-lsformelements">LSformElement</a>).</p>
|
||
</li>
|
||
</ul>
|
||
<p>Cette méthode devra retourner <code>True</code> ou <code>False</code> si la valeur testée est respectivement valide ou
|
||
invalide. Elle pourra également déclencher une exception <code>LSformRuleException</code> qui lui permettra de
|
||
donner des messages d'erreurs elle-même sur le(s) problème(s) detecté(s) durant l'analyse de la
|
||
valeur passée. Le constructeur de ce type d'exception prend en tant que premier paramètre un tableau
|
||
de messages d'erreurs (ou un simple message d'erreur) qui seront retournés à l'utilisateur.</p>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Par défaut, les valeurs de l'attribut sont testées une à une via la méthode <code>validate()</code>.
|
||
Cependant, il est possible d'implémenter une méthode de validation pour toutes les valeurs de
|
||
l'attribut en une seule fois en affectant la valeur <code>false</code> à la constante de classe
|
||
<code>validate_one_by_one</code>. Dans ce cas, l'ensemble des valeurs de l'attribut seront passées via le
|
||
paramètre <code>$value</code> à la méthode <code>validate()</code> (sous la forme d'un tableau). Cela pourra par
|
||
exemple être utile pour implémenter une validation de la cohérence des valeurs les unes vis à
|
||
vis des autres (unicité, nombre maximum de valeurs, …).</p>
|
||
</div></section><h1 class="nav-section-title-end">Ended: Contribution</h1></div>
|
||
</article>
|
||
</div>
|
||
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
|
||
</div>
|
||
</main>
|
||
<footer class="md-footer">
|
||
<div class="md-footer-meta md-typeset">
|
||
<div class="md-footer-meta__inner md-grid">
|
||
<div class="md-copyright">
|
||
<div class="md-copyright__highlight">
|
||
Easter-eggs
|
||
</div>
|
||
|
||
|
||
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">{"base": "../..", "features": [], "search": "../assets/javascripts/workers/search.b8dbb3d2.min.js", "translations": {"clipboard.copied": "Copi\u00e9 dans le presse-papier", "clipboard.copy": "Copier dans le presse-papier", "search.result.more.one": "1 de plus sur cette page", "search.result.more.other": "# de plus sur cette page", "search.result.none": "Aucun document trouv\u00e9", "search.result.one": "1 document trouv\u00e9", "search.result.other": "# documents trouv\u00e9s", "search.result.placeholder": "Taper pour d\u00e9marrer la recherche", "search.result.term.missing": "Non trouv\u00e9", "select.version": "S\u00e9lectionner la version"}, "version": {"provider": "mike"}}</script>
|
||
<script src="data:application/javascript,%22use%20strict%22%3B%28%28%29%3D%3E%7Bvar%20_i%3DObject.create%3Bvar%20br%3DObject.defineProperty%3Bvar%20Ai%3DObject.getOwnPropertyDescriptor%3Bvar%20Ci%3DObject.getOwnPropertyNames%2CFt%3DObject.getOwnPropertySymbols%2Cki%3DObject.getPrototypeOf%2Cvr%3DObject.prototype.hasOwnProperty%2Ceo%3DObject.prototype.propertyIsEnumerable%3Bvar%20Zr%3D%28e%2Ct%2Cr%29%3D%3Et%20in%20e%3Fbr%28e%2Ct%2C%7Benumerable%3A%210%2Cconfigurable%3A%210%2Cwritable%3A%210%2Cvalue%3Ar%7D%29%3Ae%5Bt%5D%3Dr%2CF%3D%28e%2Ct%29%3D%3E%7Bfor%28var%20r%20in%20t%7C%7C%28t%3D%7B%7D%29%29vr.call%28t%2Cr%29%26%26Zr%28e%2Cr%2Ct%5Br%5D%29%3Bif%28Ft%29for%28var%20r%20of%20Ft%28t%29%29eo.call%28t%2Cr%29%26%26Zr%28e%2Cr%2Ct%5Br%5D%29%3Breturn%20e%7D%3Bvar%20to%3D%28e%2Ct%29%3D%3E%7Bvar%20r%3D%7B%7D%3Bfor%28var%20o%20in%20e%29vr.call%28e%2Co%29%26%26t.indexOf%28o%29%3C0%26%26%28r%5Bo%5D%3De%5Bo%5D%29%3Bif%28e%21%3Dnull%26%26Ft%29for%28var%20o%20of%20Ft%28e%29%29t.indexOf%28o%29%3C0%26%26eo.call%28e%2Co%29%26%26%28r%5Bo%5D%3De%5Bo%5D%29%3Breturn%20r%7D%3Bvar%20gr%3D%28e%2Ct%29%3D%3E%28%29%3D%3E%28t%7C%7Ce%28%28t%3D%7Bexports%3A%7B%7D%7D%29.exports%2Ct%29%2Ct.exports%29%3Bvar%20Hi%3D%28e%2Ct%2Cr%2Co%29%3D%3E%7Bif%28t%26%26typeof%20t%3D%3D%22object%22%7C%7Ctypeof%20t%3D%3D%22function%22%29for%28let%20n%20of%20Ci%28t%29%29%21vr.call%28e%2Cn%29%26%26n%21%3D%3Dr%26%26br%28e%2Cn%2C%7Bget%3A%28%29%3D%3Et%5Bn%5D%2Cenumerable%3A%21%28o%3DAi%28t%2Cn%29%29%7C%7Co.enumerable%7D%29%3Breturn%20e%7D%3Bvar%20jt%3D%28e%2Ct%2Cr%29%3D%3E%28r%3De%21%3Dnull%3F_i%28ki%28e%29%29%3A%7B%7D%2CHi%28t%7C%7C%21e%7C%7C%21e.__esModule%3Fbr%28r%2C%22default%22%2C%7Bvalue%3Ae%2Cenumerable%3A%210%7D%29%3Ar%2Ce%29%29%3Bvar%20ro%3D%28e%2Ct%2Cr%29%3D%3Enew%20Promise%28%28o%2Cn%29%3D%3E%7Bvar%20i%3Dc%3D%3E%7Btry%7Ba%28r.next%28c%29%29%7Dcatch%28p%29%7Bn%28p%29%7D%7D%2Cs%3Dc%3D%3E%7Btry%7Ba%28r.throw%28c%29%29%7Dcatch%28p%29%7Bn%28p%29%7D%7D%2Ca%3Dc%3D%3Ec.done%3Fo%28c.value%29%3APromise.resolve%28c.value%29.then%28i%2Cs%29%3Ba%28%28r%3Dr.apply%28e%2Ct%29%29.next%28%29%29%7D%29%3Bvar%20no%3Dgr%28%28xr%2Coo%29%3D%3E%7B%28function%28e%2Ct%29%7Btypeof%20xr%3D%3D%22object%22%26%26typeof%20oo%21%3D%22undefined%22%3Ft%28%29%3Atypeof%20define%3D%3D%22function%22%26%26define.amd%3Fdefine%28t%29%3At%28%29%7D%29%28xr%2Cfunction%28%29%7B%22use%20strict%22%3Bfunction%20e%28r%29%7Bvar%20o%3D%210%2Cn%3D%211%2Ci%3Dnull%2Cs%3D%7Btext%3A%210%2Csearch%3A%210%2Curl%3A%210%2Ctel%3A%210%2Cemail%3A%210%2Cpassword%3A%210%2Cnumber%3A%210%2Cdate%3A%210%2Cmonth%3A%210%2Cweek%3A%210%2Ctime%3A%210%2Cdatetime%3A%210%2C%22datetime-local%22%3A%210%7D%3Bfunction%20a%28C%29%7Breturn%21%21%28C%26%26C%21%3D%3Ddocument%26%26C.nodeName%21%3D%3D%22HTML%22%26%26C.nodeName%21%3D%3D%22BODY%22%26%26%22classList%22in%20C%26%26%22contains%22in%20C.classList%29%7Dfunction%20c%28C%29%7Bvar%20ct%3DC.type%2CNe%3DC.tagName%3Breturn%21%21%28Ne%3D%3D%3D%22INPUT%22%26%26s%5Bct%5D%26%26%21C.readOnly%7C%7CNe%3D%3D%3D%22TEXTAREA%22%26%26%21C.readOnly%7C%7CC.isContentEditable%29%7Dfunction%20p%28C%29%7BC.classList.contains%28%22focus-visible%22%29%7C%7C%28C.classList.add%28%22focus-visible%22%29%2CC.setAttribute%28%22data-focus-visible-added%22%2C%22%22%29%29%7Dfunction%20l%28C%29%7BC.hasAttribute%28%22data-focus-visible-added%22%29%26%26%28C.classList.remove%28%22focus-visible%22%29%2CC.removeAttribute%28%22data-focus-visible-added%22%29%29%7Dfunction%20f%28C%29%7BC.metaKey%7C%7CC.altKey%7C%7CC.ctrlKey%7C%7C%28a%28r.activeElement%29%26%26p%28r.activeElement%29%2Co%3D%210%29%7Dfunction%20u%28C%29%7Bo%3D%211%7Dfunction%20h%28C%29%7Ba%28C.target%29%26%26%28o%7C%7Cc%28C.target%29%29%26%26p%28C.target%29%7Dfunction%20w%28C%29%7Ba%28C.target%29%26%26%28C.target.classList.contains%28%22focus-visible%22%29%7C%7CC.target.hasAttribute%28%22data-focus-visible-added%22%29%29%26%26%28n%3D%210%2Cwindow.clearTimeout%28i%29%2Ci%3Dwindow.setTimeout%28function%28%29%7Bn%3D%211%7D%2C100%29%2Cl%28C.target%29%29%7Dfunction%20A%28C%29%7Bdocument.visibilityState%3D%3D%3D%22hidden%22%26%26%28n%26%26%28o%3D%210%29%2CZ%28%29%29%7Dfunction%20Z%28%29%7Bdocument.addEventListener%28%22mousemove%22%2CJ%29%2Cdocument.addEventListener%28%22mousedown%22%2CJ%29%2Cdocument.addEventListener%28%22mouseup%22%2CJ%29%2Cdocument.addEventListener%28%22pointermove%22%2CJ%29%2Cdocument.addEventListener%28%22pointerdown%22%2CJ%29%2Cdocument.addEventListener%28%22pointerup%22%2CJ%29%2Cdocument.addEventListener%28%22touchmove%22%2CJ%29%2Cdocument.addEventListener%28%22touchstart%22%2CJ%29%2Cdocument.addEventListener%28%22touchend%22%2CJ%29%7Dfunction%20te%28%29%7Bdocument.removeEventListener%28%22mousemove%22%2CJ%29%2Cdocument.removeEventListener%28%22mousedown%22%2CJ%29%2Cdocument.removeEventListener%28%22mouseup%22%2CJ%29%2Cdocument.removeEventListener%28%22pointermove%22%2CJ%29%2Cdocument.removeEventListener%28%22pointerdown%22%2CJ%29%2Cdocument.removeEventListener%28%22pointerup%22%2CJ%29%2Cdocument.removeEventListener%28%22touchmove%22%2CJ%29%2Cdocument.removeEventListener%28%22touchstart%22%2CJ%29%2Cdocument.removeEventListener%28%22touchend%22%2CJ%29%7Dfunction%20J%28C%29%7BC.target.nodeName%26%26C.target.nodeName.toLowerCase%28%29%3D%3D%3D%22html%22%7C%7C%28o%3D%211%2Cte%28%29%29%7Ddocument.addEventListener%28%22keydown%22%2Cf%2C%210%29%2Cdocument.addEventListener%28%22mousedown%22%2Cu%2C%210%29%2Cdocument.addEventListener%28%22pointerdown%22%2Cu%2C%210%29%2Cdocument.addEventListener%28%22touchstart%22%2Cu%2C%210%29%2Cdocument.addEventListener%28%22visibilitychange%22%2CA%2C%210%29%2CZ%28%29%2Cr.addEventListener%28%22focus%22%2Ch%2C%210%29%2Cr.addEventListener%28%22blur%22%2Cw%2C%210%29%2Cr.nodeType%3D%3D%3DNode.DOCUMENT_FRAGMENT_NODE%26%26r.host%3Fr.host.setAttribute%28%22data-js-focus-visible%22%2C%22%22%29%3Ar.nodeType%3D%3D%3DNode.DOCUMENT_NODE%26%26%28document.documentElement.classList.add%28%22js-focus-visible%22%29%2Cdocument.documentElement.setAttribute%28%22data-js-focus-visible%22%2C%22%22%29%29%7Dif%28typeof%20window%21%3D%22undefined%22%26%26typeof%20document%21%3D%22undefined%22%29%7Bwindow.applyFocusVisiblePolyfill%3De%3Bvar%20t%3Btry%7Bt%3Dnew%20CustomEvent%28%22focus-visible-polyfill-ready%22%29%7Dcatch%28r%29%7Bt%3Ddocument.createEvent%28%22CustomEvent%22%29%2Ct.initCustomEvent%28%22focus-visible-polyfill-ready%22%2C%211%2C%211%2C%7B%7D%29%7Dwindow.dispatchEvent%28t%29%7Dtypeof%20document%21%3D%22undefined%22%26%26e%28document%29%7D%29%7D%29%3Bvar%20zr%3Dgr%28%28kt%2CVr%29%3D%3E%7B/%2A%21%0A%20%2A%20clipboard.js%20v2.0.11%0A%20%2A%20https%3A//clipboardjs.com/%0A%20%2A%0A%20%2A%20Licensed%20MIT%20%C2%A9%20Zeno%20Rocha%0A%20%2A/%28function%28t%2Cr%29%7Btypeof%20kt%3D%3D%22object%22%26%26typeof%20Vr%3D%3D%22object%22%3FVr.exports%3Dr%28%29%3Atypeof%20define%3D%3D%22function%22%26%26define.amd%3Fdefine%28%5B%5D%2Cr%29%3Atypeof%20kt%3D%3D%22object%22%3Fkt.ClipboardJS%3Dr%28%29%3At.ClipboardJS%3Dr%28%29%7D%29%28kt%2Cfunction%28%29%7Breturn%20function%28%29%7Bvar%20e%3D%7B686%3Afunction%28o%2Cn%2Ci%29%7B%22use%20strict%22%3Bi.d%28n%2C%7Bdefault%3Afunction%28%29%7Breturn%20Li%7D%7D%29%3Bvar%20s%3Di%28279%29%2Ca%3Di.n%28s%29%2Cc%3Di%28370%29%2Cp%3Di.n%28c%29%2Cl%3Di%28817%29%2Cf%3Di.n%28l%29%3Bfunction%20u%28D%29%7Btry%7Breturn%20document.execCommand%28D%29%7Dcatch%28M%29%7Breturn%211%7D%7Dvar%20h%3Dfunction%28M%29%7Bvar%20O%3Df%28%29%28M%29%3Breturn%20u%28%22cut%22%29%2CO%7D%2Cw%3Dh%3Bfunction%20A%28D%29%7Bvar%20M%3Ddocument.documentElement.getAttribute%28%22dir%22%29%3D%3D%3D%22rtl%22%2CO%3Ddocument.createElement%28%22textarea%22%29%3BO.style.fontSize%3D%2212pt%22%2CO.style.border%3D%220%22%2CO.style.padding%3D%220%22%2CO.style.margin%3D%220%22%2CO.style.position%3D%22absolute%22%2CO.style%5BM%3F%22right%22%3A%22left%22%5D%3D%22-9999px%22%3Bvar%20I%3Dwindow.pageYOffset%7C%7Cdocument.documentElement.scrollTop%3Breturn%20O.style.top%3D%22%22.concat%28I%2C%22px%22%29%2CO.setAttribute%28%22readonly%22%2C%22%22%29%2CO.value%3DD%2CO%7Dvar%20Z%3Dfunction%28M%2CO%29%7Bvar%20I%3DA%28M%29%3BO.container.appendChild%28I%29%3Bvar%20W%3Df%28%29%28I%29%3Breturn%20u%28%22copy%22%29%2CI.remove%28%29%2CW%7D%2Cte%3Dfunction%28M%29%7Bvar%20O%3Darguments.length%3E1%26%26arguments%5B1%5D%21%3D%3Dvoid%200%3Farguments%5B1%5D%3A%7Bcontainer%3Adocument.body%7D%2CI%3D%22%22%3Breturn%20typeof%20M%3D%3D%22string%22%3FI%3DZ%28M%2CO%29%3AM%20instanceof%20HTMLInputElement%26%26%21%5B%22text%22%2C%22search%22%2C%22url%22%2C%22tel%22%2C%22password%22%5D.includes%28M%3D%3Dnull%3Fvoid%200%3AM.type%29%3FI%3DZ%28M.value%2CO%29%3A%28I%3Df%28%29%28M%29%2Cu%28%22copy%22%29%29%2CI%7D%2CJ%3Dte%3Bfunction%20C%28D%29%7B%22%40babel/helpers%20-%20typeof%22%3Breturn%20typeof%20Symbol%3D%3D%22function%22%26%26typeof%20Symbol.iterator%3D%3D%22symbol%22%3FC%3Dfunction%28O%29%7Breturn%20typeof%20O%7D%3AC%3Dfunction%28O%29%7Breturn%20O%26%26typeof%20Symbol%3D%3D%22function%22%26%26O.constructor%3D%3D%3DSymbol%26%26O%21%3D%3DSymbol.prototype%3F%22symbol%22%3Atypeof%20O%7D%2CC%28D%29%7Dvar%20ct%3Dfunction%28%29%7Bvar%20M%3Darguments.length%3E0%26%26arguments%5B0%5D%21%3D%3Dvoid%200%3Farguments%5B0%5D%3A%7B%7D%2CO%3DM.action%2CI%3DO%3D%3D%3Dvoid%200%3F%22copy%22%3AO%2CW%3DM.container%2CK%3DM.target%2CCe%3DM.text%3Bif%28I%21%3D%3D%22copy%22%26%26I%21%3D%3D%22cut%22%29throw%20new%20Error%28%27Invalid%20%22action%22%20value%2C%20use%20either%20%22copy%22%20or%20%22cut%22%27%29%3Bif%28K%21%3D%3Dvoid%200%29if%28K%26%26C%28K%29%3D%3D%3D%22object%22%26%26K.nodeType%3D%3D%3D1%29%7Bif%28I%3D%3D%3D%22copy%22%26%26K.hasAttribute%28%22disabled%22%29%29throw%20new%20Error%28%27Invalid%20%22target%22%20attribute.%20Please%20use%20%22readonly%22%20instead%20of%20%22disabled%22%20attribute%27%29%3Bif%28I%3D%3D%3D%22cut%22%26%26%28K.hasAttribute%28%22readonly%22%29%7C%7CK.hasAttribute%28%22disabled%22%29%29%29throw%20new%20Error%28%60Invalid%20%22target%22%20attribute.%20You%20can%27t%20cut%20text%20from%20elements%20with%20%22readonly%22%20or%20%22disabled%22%20attributes%60%29%7Delse%20throw%20new%20Error%28%27Invalid%20%22target%22%20value%2C%20use%20a%20valid%20Element%27%29%3Bif%28Ce%29return%20J%28Ce%2C%7Bcontainer%3AW%7D%29%3Bif%28K%29return%20I%3D%3D%3D%22cut%22%3Fw%28K%29%3AJ%28K%2C%7Bcontainer%3AW%7D%29%7D%2CNe%3Dct%3Bfunction%20Pe%28D%29%7B%22%40babel/helpers%20-%20typeof%22%3Breturn%20typeof%20Symbol%3D%3D%22function%22%26%26typeof%20Symbol.iterator%3D%3D%22symbol%22%3FPe%3Dfunction%28O%29%7Breturn%20typeof%20O%7D%3APe%3Dfunction%28O%29%7Breturn%20O%26%26typeof%20Symbol%3D%3D%22function%22%26%26O.constructor%3D%3D%3DSymbol%26%26O%21%3D%3DSymbol.prototype%3F%22symbol%22%3Atypeof%20O%7D%2CPe%28D%29%7Dfunction%20xi%28D%2CM%29%7Bif%28%21%28D%20instanceof%20M%29%29throw%20new%20TypeError%28%22Cannot%20call%20a%20class%20as%20a%20function%22%29%7Dfunction%20Xr%28D%2CM%29%7Bfor%28var%20O%3D0%3BO%3CM.length%3BO%2B%2B%29%7Bvar%20I%3DM%5BO%5D%3BI.enumerable%3DI.enumerable%7C%7C%211%2CI.configurable%3D%210%2C%22value%22in%20I%26%26%28I.writable%3D%210%29%2CObject.defineProperty%28D%2CI.key%2CI%29%7D%7Dfunction%20yi%28D%2CM%2CO%29%7Breturn%20M%26%26Xr%28D.prototype%2CM%29%2CO%26%26Xr%28D%2CO%29%2CD%7Dfunction%20Ei%28D%2CM%29%7Bif%28typeof%20M%21%3D%22function%22%26%26M%21%3D%3Dnull%29throw%20new%20TypeError%28%22Super%20expression%20must%20either%20be%20null%20or%20a%20function%22%29%3BD.prototype%3DObject.create%28M%26%26M.prototype%2C%7Bconstructor%3A%7Bvalue%3AD%2Cwritable%3A%210%2Cconfigurable%3A%210%7D%7D%29%2CM%26%26dr%28D%2CM%29%7Dfunction%20dr%28D%2CM%29%7Breturn%20dr%3DObject.setPrototypeOf%7C%7Cfunction%28I%2CW%29%7Breturn%20I.__proto__%3DW%2CI%7D%2Cdr%28D%2CM%29%7Dfunction%20wi%28D%29%7Bvar%20M%3DOi%28%29%3Breturn%20function%28%29%7Bvar%20I%3DPt%28D%29%2CW%3Bif%28M%29%7Bvar%20K%3DPt%28this%29.constructor%3BW%3DReflect.construct%28I%2Carguments%2CK%29%7Delse%20W%3DI.apply%28this%2Carguments%29%3Breturn%20Ti%28this%2CW%29%7D%7Dfunction%20Ti%28D%2CM%29%7Breturn%20M%26%26%28Pe%28M%29%3D%3D%3D%22object%22%7C%7Ctypeof%20M%3D%3D%22function%22%29%3FM%3ASi%28D%29%7Dfunction%20Si%28D%29%7Bif%28D%3D%3D%3Dvoid%200%29throw%20new%20ReferenceError%28%22this%20hasn%27t%20been%20initialised%20-%20super%28%29%20hasn%27t%20been%20called%22%29%3Breturn%20D%7Dfunction%20Oi%28%29%7Bif%28typeof%20Reflect%3D%3D%22undefined%22%7C%7C%21Reflect.construct%7C%7CReflect.construct.sham%29return%211%3Bif%28typeof%20Proxy%3D%3D%22function%22%29return%210%3Btry%7Breturn%20Date.prototype.toString.call%28Reflect.construct%28Date%2C%5B%5D%2Cfunction%28%29%7B%7D%29%29%2C%210%7Dcatch%28D%29%7Breturn%211%7D%7Dfunction%20Pt%28D%29%7Breturn%20Pt%3DObject.setPrototypeOf%3FObject.getPrototypeOf%3Afunction%28O%29%7Breturn%20O.__proto__%7C%7CObject.getPrototypeOf%28O%29%7D%2CPt%28D%29%7Dfunction%20hr%28D%2CM%29%7Bvar%20O%3D%22data-clipboard-%22.concat%28D%29%3Bif%28M.hasAttribute%28O%29%29return%20M.getAttribute%28O%29%7Dvar%20Mi%3Dfunction%28D%29%7BEi%28O%2CD%29%3Bvar%20M%3Dwi%28O%29%3Bfunction%20O%28I%2CW%29%7Bvar%20K%3Breturn%20xi%28this%2CO%29%2CK%3DM.call%28this%29%2CK.resolveOptions%28W%29%2CK.listenClick%28I%29%2CK%7Dreturn%20yi%28O%2C%5B%7Bkey%3A%22resolveOptions%22%2Cvalue%3Afunction%28%29%7Bvar%20W%3Darguments.length%3E0%26%26arguments%5B0%5D%21%3D%3Dvoid%200%3Farguments%5B0%5D%3A%7B%7D%3Bthis.action%3Dtypeof%20W.action%3D%3D%22function%22%3FW.action%3Athis.defaultAction%2Cthis.target%3Dtypeof%20W.target%3D%3D%22function%22%3FW.target%3Athis.defaultTarget%2Cthis.text%3Dtypeof%20W.text%3D%3D%22function%22%3FW.text%3Athis.defaultText%2Cthis.container%3DPe%28W.container%29%3D%3D%3D%22object%22%3FW.container%3Adocument.body%7D%7D%2C%7Bkey%3A%22listenClick%22%2Cvalue%3Afunction%28W%29%7Bvar%20K%3Dthis%3Bthis.listener%3Dp%28%29%28W%2C%22click%22%2Cfunction%28Ce%29%7Breturn%20K.onClick%28Ce%29%7D%29%7D%7D%2C%7Bkey%3A%22onClick%22%2Cvalue%3Afunction%28W%29%7Bvar%20K%3DW.delegateTarget%7C%7CW.currentTarget%2CCe%3Dthis.action%28K%29%7C%7C%22copy%22%2CIt%3DNe%28%7Baction%3ACe%2Ccontainer%3Athis.container%2Ctarget%3Athis.target%28K%29%2Ctext%3Athis.text%28K%29%7D%29%3Bthis.emit%28It%3F%22success%22%3A%22error%22%2C%7Baction%3ACe%2Ctext%3AIt%2Ctrigger%3AK%2CclearSelection%3Afunction%28%29%7BK%26%26K.focus%28%29%2Cwindow.getSelection%28%29.removeAllRanges%28%29%7D%7D%29%7D%7D%2C%7Bkey%3A%22defaultAction%22%2Cvalue%3Afunction%28W%29%7Breturn%20hr%28%22action%22%2CW%29%7D%7D%2C%7Bkey%3A%22defaultTarget%22%2Cvalue%3Afunction%28W%29%7Bvar%20K%3Dhr%28%22target%22%2CW%29%3Bif%28K%29return%20document.querySelector%28K%29%7D%7D%2C%7Bkey%3A%22defaultText%22%2Cvalue%3Afunction%28W%29%7Breturn%20hr%28%22text%22%2CW%29%7D%7D%2C%7Bkey%3A%22destroy%22%2Cvalue%3Afunction%28%29%7Bthis.listener.destroy%28%29%7D%7D%5D%2C%5B%7Bkey%3A%22copy%22%2Cvalue%3Afunction%28W%29%7Bvar%20K%3Darguments.length%3E1%26%26arguments%5B1%5D%21%3D%3Dvoid%200%3Farguments%5B1%5D%3A%7Bcontainer%3Adocument.body%7D%3Breturn%20J%28W%2CK%29%7D%7D%2C%7Bkey%3A%22cut%22%2Cvalue%3Afunction%28W%29%7Breturn%20w%28W%29%7D%7D%2C%7Bkey%3A%22isSupported%22%2Cvalue%3Afunction%28%29%7Bvar%20W%3Darguments.length%3E0%26%26arguments%5B0%5D%21%3D%3Dvoid%200%3Farguments%5B0%5D%3A%5B%22copy%22%2C%22cut%22%5D%2CK%3Dtypeof%20W%3D%3D%22string%22%3F%5BW%5D%3AW%2CCe%3D%21%21document.queryCommandSupported%3Breturn%20K.forEach%28function%28It%29%7BCe%3DCe%26%26%21%21document.queryCommandSupported%28It%29%7D%29%2CCe%7D%7D%5D%29%2CO%7D%28a%28%29%29%2CLi%3DMi%7D%2C828%3Afunction%28o%29%7Bvar%20n%3D9%3Bif%28typeof%20Element%21%3D%22undefined%22%26%26%21Element.prototype.matches%29%7Bvar%20i%3DElement.prototype%3Bi.matches%3Di.matchesSelector%7C%7Ci.mozMatchesSelector%7C%7Ci.msMatchesSelector%7C%7Ci.oMatchesSelector%7C%7Ci.webkitMatchesSelector%7Dfunction%20s%28a%2Cc%29%7Bfor%28%3Ba%26%26a.nodeType%21%3D%3Dn%3B%29%7Bif%28typeof%20a.matches%3D%3D%22function%22%26%26a.matches%28c%29%29return%20a%3Ba%3Da.parentNode%7D%7Do.exports%3Ds%7D%2C438%3Afunction%28o%2Cn%2Ci%29%7Bvar%20s%3Di%28828%29%3Bfunction%20a%28l%2Cf%2Cu%2Ch%2Cw%29%7Bvar%20A%3Dp.apply%28this%2Carguments%29%3Breturn%20l.addEventListener%28u%2CA%2Cw%29%2C%7Bdestroy%3Afunction%28%29%7Bl.removeEventListener%28u%2CA%2Cw%29%7D%7D%7Dfunction%20c%28l%2Cf%2Cu%2Ch%2Cw%29%7Breturn%20typeof%20l.addEventListener%3D%3D%22function%22%3Fa.apply%28null%2Carguments%29%3Atypeof%20u%3D%3D%22function%22%3Fa.bind%28null%2Cdocument%29.apply%28null%2Carguments%29%3A%28typeof%20l%3D%3D%22string%22%26%26%28l%3Ddocument.querySelectorAll%28l%29%29%2CArray.prototype.map.call%28l%2Cfunction%28A%29%7Breturn%20a%28A%2Cf%2Cu%2Ch%2Cw%29%7D%29%29%7Dfunction%20p%28l%2Cf%2Cu%2Ch%29%7Breturn%20function%28w%29%7Bw.delegateTarget%3Ds%28w.target%2Cf%29%2Cw.delegateTarget%26%26h.call%28l%2Cw%29%7D%7Do.exports%3Dc%7D%2C879%3Afunction%28o%2Cn%29%7Bn.node%3Dfunction%28i%29%7Breturn%20i%21%3D%3Dvoid%200%26%26i%20instanceof%20HTMLElement%26%26i.nodeType%3D%3D%3D1%7D%2Cn.nodeList%3Dfunction%28i%29%7Bvar%20s%3DObject.prototype.toString.call%28i%29%3Breturn%20i%21%3D%3Dvoid%200%26%26%28s%3D%3D%3D%22%5Bobject%20NodeList%5D%22%7C%7Cs%3D%3D%3D%22%5Bobject%20HTMLCollection%5D%22%29%26%26%22length%22in%20i%26%26%28i.length%3D%3D%3D0%7C%7Cn.node%28i%5B0%5D%29%29%7D%2Cn.string%3Dfunction%28i%29%7Breturn%20typeof%20i%3D%3D%22string%22%7C%7Ci%20instanceof%20String%7D%2Cn.fn%3Dfunction%28i%29%7Bvar%20s%3DObject.prototype.toString.call%28i%29%3Breturn%20s%3D%3D%3D%22%5Bobject%20Function%5D%22%7D%7D%2C370%3Afunction%28o%2Cn%2Ci%29%7Bvar%20s%3Di%28879%29%2Ca%3Di%28438%29%3Bfunction%20c%28u%2Ch%2Cw%29%7Bif%28%21u%26%26%21h%26%26%21w%29throw%20new%20Error%28%22Missing%20required%20arguments%22%29%3Bif%28%21s.string%28h%29%29throw%20new%20TypeError%28%22Second%20argument%20must%20be%20a%20String%22%29%3Bif%28%21s.fn%28w%29%29throw%20new%20TypeError%28%22Third%20argument%20must%20be%20a%20Function%22%29%3Bif%28s.node%28u%29%29return%20p%28u%2Ch%2Cw%29%3Bif%28s.nodeList%28u%29%29return%20l%28u%2Ch%2Cw%29%3Bif%28s.string%28u%29%29return%20f%28u%2Ch%2Cw%29%3Bthrow%20new%20TypeError%28%22First%20argument%20must%20be%20a%20String%2C%20HTMLElement%2C%20HTMLCollection%2C%20or%20NodeList%22%29%7Dfunction%20p%28u%2Ch%2Cw%29%7Breturn%20u.addEventListener%28h%2Cw%29%2C%7Bdestroy%3Afunction%28%29%7Bu.removeEventListener%28h%2Cw%29%7D%7D%7Dfunction%20l%28u%2Ch%2Cw%29%7Breturn%20Array.prototype.forEach.call%28u%2Cfunction%28A%29%7BA.addEventListener%28h%2Cw%29%7D%29%2C%7Bdestroy%3Afunction%28%29%7BArray.prototype.forEach.call%28u%2Cfunction%28A%29%7BA.removeEventListener%28h%2Cw%29%7D%29%7D%7D%7Dfunction%20f%28u%2Ch%2Cw%29%7Breturn%20a%28document.body%2Cu%2Ch%2Cw%29%7Do.exports%3Dc%7D%2C817%3Afunction%28o%29%7Bfunction%20n%28i%29%7Bvar%20s%3Bif%28i.nodeName%3D%3D%3D%22SELECT%22%29i.focus%28%29%2Cs%3Di.value%3Belse%20if%28i.nodeName%3D%3D%3D%22INPUT%22%7C%7Ci.nodeName%3D%3D%3D%22TEXTAREA%22%29%7Bvar%20a%3Di.hasAttribute%28%22readonly%22%29%3Ba%7C%7Ci.setAttribute%28%22readonly%22%2C%22%22%29%2Ci.select%28%29%2Ci.setSelectionRange%280%2Ci.value.length%29%2Ca%7C%7Ci.removeAttribute%28%22readonly%22%29%2Cs%3Di.value%7Delse%7Bi.hasAttribute%28%22contenteditable%22%29%26%26i.focus%28%29%3Bvar%20c%3Dwindow.getSelection%28%29%2Cp%3Ddocument.createRange%28%29%3Bp.selectNodeContents%28i%29%2Cc.removeAllRanges%28%29%2Cc.addRange%28p%29%2Cs%3Dc.toString%28%29%7Dreturn%20s%7Do.exports%3Dn%7D%2C279%3Afunction%28o%29%7Bfunction%20n%28%29%7B%7Dn.prototype%3D%7Bon%3Afunction%28i%2Cs%2Ca%29%7Bvar%20c%3Dthis.e%7C%7C%28this.e%3D%7B%7D%29%3Breturn%28c%5Bi%5D%7C%7C%28c%5Bi%5D%3D%5B%5D%29%29.push%28%7Bfn%3As%2Cctx%3Aa%7D%29%2Cthis%7D%2Conce%3Afunction%28i%2Cs%2Ca%29%7Bvar%20c%3Dthis%3Bfunction%20p%28%29%7Bc.off%28i%2Cp%29%2Cs.apply%28a%2Carguments%29%7Dreturn%20p._%3Ds%2Cthis.on%28i%2Cp%2Ca%29%7D%2Cemit%3Afunction%28i%29%7Bvar%20s%3D%5B%5D.slice.call%28arguments%2C1%29%2Ca%3D%28%28this.e%7C%7C%28this.e%3D%7B%7D%29%29%5Bi%5D%7C%7C%5B%5D%29.slice%28%29%2Cc%3D0%2Cp%3Da.length%3Bfor%28c%3Bc%3Cp%3Bc%2B%2B%29a%5Bc%5D.fn.apply%28a%5Bc%5D.ctx%2Cs%29%3Breturn%20this%7D%2Coff%3Afunction%28i%2Cs%29%7Bvar%20a%3Dthis.e%7C%7C%28this.e%3D%7B%7D%29%2Cc%3Da%5Bi%5D%2Cp%3D%5B%5D%3Bif%28c%26%26s%29for%28var%20l%3D0%2Cf%3Dc.length%3Bl%3Cf%3Bl%2B%2B%29c%5Bl%5D.fn%21%3D%3Ds%26%26c%5Bl%5D.fn._%21%3D%3Ds%26%26p.push%28c%5Bl%5D%29%3Breturn%20p.length%3Fa%5Bi%5D%3Dp%3Adelete%20a%5Bi%5D%2Cthis%7D%7D%2Co.exports%3Dn%2Co.exports.TinyEmitter%3Dn%7D%7D%2Ct%3D%7B%7D%3Bfunction%20r%28o%29%7Bif%28t%5Bo%5D%29return%20t%5Bo%5D.exports%3Bvar%20n%3Dt%5Bo%5D%3D%7Bexports%3A%7B%7D%7D%3Breturn%20e%5Bo%5D%28n%2Cn.exports%2Cr%29%2Cn.exports%7Dreturn%20function%28%29%7Br.n%3Dfunction%28o%29%7Bvar%20n%3Do%26%26o.__esModule%3Ffunction%28%29%7Breturn%20o.default%7D%3Afunction%28%29%7Breturn%20o%7D%3Breturn%20r.d%28n%2C%7Ba%3An%7D%29%2Cn%7D%7D%28%29%2Cfunction%28%29%7Br.d%3Dfunction%28o%2Cn%29%7Bfor%28var%20i%20in%20n%29r.o%28n%2Ci%29%26%26%21r.o%28o%2Ci%29%26%26Object.defineProperty%28o%2Ci%2C%7Benumerable%3A%210%2Cget%3An%5Bi%5D%7D%29%7D%7D%28%29%2Cfunction%28%29%7Br.o%3Dfunction%28o%2Cn%29%7Breturn%20Object.prototype.hasOwnProperty.call%28o%2Cn%29%7D%7D%28%29%2Cr%28686%29%7D%28%29.default%7D%29%7D%29%3Bvar%20Kn%3Dgr%28%28Cw%2Cqn%29%3D%3E%7B%22use%20strict%22%3B/%2A%21%0A%20%2A%20escape-html%0A%20%2A%20Copyright%28c%29%202012-2013%20TJ%20Holowaychuk%0A%20%2A%20Copyright%28c%29%202015%20Andreas%20Lubbe%0A%20%2A%20Copyright%28c%29%202015%20Tiancheng%20%22Timothy%22%20Gu%0A%20%2A%20MIT%20Licensed%0A%20%2A/var%20Va%3D/%5B%22%27%26%3C%3E%5D/%3Bqn.exports%3Dza%3Bfunction%20za%28e%29%7Bvar%20t%3D%22%22%2Be%2Cr%3DVa.exec%28t%29%3Bif%28%21r%29return%20t%3Bvar%20o%2Cn%3D%22%22%2Ci%3D0%2Cs%3D0%3Bfor%28i%3Dr.index%3Bi%3Ct.length%3Bi%2B%2B%29%7Bswitch%28t.charCodeAt%28i%29%29%7Bcase%2034%3Ao%3D%22%26quot%3B%22%3Bbreak%3Bcase%2038%3Ao%3D%22%26amp%3B%22%3Bbreak%3Bcase%2039%3Ao%3D%22%26%2339%3B%22%3Bbreak%3Bcase%2060%3Ao%3D%22%26lt%3B%22%3Bbreak%3Bcase%2062%3Ao%3D%22%26gt%3B%22%3Bbreak%3Bdefault%3Acontinue%7Ds%21%3D%3Di%26%26%28n%2B%3Dt.substring%28s%2Ci%29%29%2Cs%3Di%2B1%2Cn%2B%3Do%7Dreturn%20s%21%3D%3Di%3Fn%2Bt.substring%28s%2Ci%29%3An%7D%7D%29%3Bvar%20mM%3Djt%28no%28%29%29%3B/%2A%21%20%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%0ACopyright%20%28c%29%20Microsoft%20Corporation.%0A%0APermission%20to%20use%2C%20copy%2C%20modify%2C%20and/or%20distribute%20this%20software%20for%20any%0Apurpose%20with%20or%20without%20fee%20is%20hereby%20granted.%0A%0ATHE%20SOFTWARE%20IS%20PROVIDED%20%22AS%20IS%22%20AND%20THE%20AUTHOR%20DISCLAIMS%20ALL%20WARRANTIES%20WITH%0AREGARD%20TO%20THIS%20SOFTWARE%20INCLUDING%20ALL%20IMPLIED%20WARRANTIES%20OF%20MERCHANTABILITY%0AAND%20FITNESS.%20IN%20NO%20EVENT%20SHALL%20THE%20AUTHOR%20BE%20LIABLE%20FOR%20ANY%20SPECIAL%2C%20DIRECT%2C%0AINDIRECT%2C%20OR%20CONSEQUENTIAL%20DAMAGES%20OR%20ANY%20DAMAGES%20WHATSOEVER%20RESULTING%20FROM%0ALOSS%20OF%20USE%2C%20DATA%20OR%20PROFITS%2C%20WHETHER%20IN%20AN%20ACTION%20OF%20CONTRACT%2C%20NEGLIGENCE%20OR%0AOTHER%20TORTIOUS%20ACTION%2C%20ARISING%20OUT%20OF%20OR%20IN%20CONNECTION%20WITH%20THE%20USE%20OR%0APERFORMANCE%20OF%20THIS%20SOFTWARE.%0A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%2A%20%2A/var%20yr%3Dfunction%28e%2Ct%29%7Breturn%20yr%3DObject.setPrototypeOf%7C%7C%7B__proto__%3A%5B%5D%7Dinstanceof%20Array%26%26function%28r%2Co%29%7Br.__proto__%3Do%7D%7C%7Cfunction%28r%2Co%29%7Bfor%28var%20n%20in%20o%29Object.prototype.hasOwnProperty.call%28o%2Cn%29%26%26%28r%5Bn%5D%3Do%5Bn%5D%29%7D%2Cyr%28e%2Ct%29%7D%3Bfunction%20se%28e%2Ct%29%7Bif%28typeof%20t%21%3D%22function%22%26%26t%21%3D%3Dnull%29throw%20new%20TypeError%28%22Class%20extends%20value%20%22%2BString%28t%29%2B%22%20is%20not%20a%20constructor%20or%20null%22%29%3Byr%28e%2Ct%29%3Bfunction%20r%28%29%7Bthis.constructor%3De%7De.prototype%3Dt%3D%3D%3Dnull%3FObject.create%28t%29%3A%28r.prototype%3Dt.prototype%2Cnew%20r%29%7Dfunction%20io%28e%2Ct%2Cr%2Co%29%7Bfunction%20n%28i%29%7Breturn%20i%20instanceof%20r%3Fi%3Anew%20r%28function%28s%29%7Bs%28i%29%7D%29%7Dreturn%20new%28r%7C%7C%28r%3DPromise%29%29%28function%28i%2Cs%29%7Bfunction%20a%28l%29%7Btry%7Bp%28o.next%28l%29%29%7Dcatch%28f%29%7Bs%28f%29%7D%7Dfunction%20c%28l%29%7Btry%7Bp%28o.throw%28l%29%29%7Dcatch%28f%29%7Bs%28f%29%7D%7Dfunction%20p%28l%29%7Bl.done%3Fi%28l.value%29%3An%28l.value%29.then%28a%2Cc%29%7Dp%28%28o%3Do.apply%28e%2Ct%7C%7C%5B%5D%29%29.next%28%29%29%7D%29%7Dfunction%20Ut%28e%2Ct%29%7Bvar%20r%3D%7Blabel%3A0%2Csent%3Afunction%28%29%7Bif%28i%5B0%5D%261%29throw%20i%5B1%5D%3Breturn%20i%5B1%5D%7D%2Ctrys%3A%5B%5D%2Cops%3A%5B%5D%7D%2Co%2Cn%2Ci%2Cs%3Breturn%20s%3D%7Bnext%3Aa%280%29%2Cthrow%3Aa%281%29%2Creturn%3Aa%282%29%7D%2Ctypeof%20Symbol%3D%3D%22function%22%26%26%28s%5BSymbol.iterator%5D%3Dfunction%28%29%7Breturn%20this%7D%29%2Cs%3Bfunction%20a%28p%29%7Breturn%20function%28l%29%7Breturn%20c%28%5Bp%2Cl%5D%29%7D%7Dfunction%20c%28p%29%7Bif%28o%29throw%20new%20TypeError%28%22Generator%20is%20already%20executing.%22%29%3Bfor%28%3Br%3B%29try%7Bif%28o%3D1%2Cn%26%26%28i%3Dp%5B0%5D%262%3Fn.return%3Ap%5B0%5D%3Fn.throw%7C%7C%28%28i%3Dn.return%29%26%26i.call%28n%29%2C0%29%3An.next%29%26%26%21%28i%3Di.call%28n%2Cp%5B1%5D%29%29.done%29return%20i%3Bswitch%28n%3D0%2Ci%26%26%28p%3D%5Bp%5B0%5D%262%2Ci.value%5D%29%2Cp%5B0%5D%29%7Bcase%200%3Acase%201%3Ai%3Dp%3Bbreak%3Bcase%204%3Areturn%20r.label%2B%2B%2C%7Bvalue%3Ap%5B1%5D%2Cdone%3A%211%7D%3Bcase%205%3Ar.label%2B%2B%2Cn%3Dp%5B1%5D%2Cp%3D%5B0%5D%3Bcontinue%3Bcase%207%3Ap%3Dr.ops.pop%28%29%2Cr.trys.pop%28%29%3Bcontinue%3Bdefault%3Aif%28i%3Dr.trys%2C%21%28i%3Di.length%3E0%26%26i%5Bi.length-1%5D%29%26%26%28p%5B0%5D%3D%3D%3D6%7C%7Cp%5B0%5D%3D%3D%3D2%29%29%7Br%3D0%3Bcontinue%7Dif%28p%5B0%5D%3D%3D%3D3%26%26%28%21i%7C%7Cp%5B1%5D%3Ei%5B0%5D%26%26p%5B1%5D%3Ci%5B3%5D%29%29%7Br.label%3Dp%5B1%5D%3Bbreak%7Dif%28p%5B0%5D%3D%3D%3D6%26%26r.label%3Ci%5B1%5D%29%7Br.label%3Di%5B1%5D%2Ci%3Dp%3Bbreak%7Dif%28i%26%26r.label%3Ci%5B2%5D%29%7Br.label%3Di%5B2%5D%2Cr.ops.push%28p%29%3Bbreak%7Di%5B2%5D%26%26r.ops.pop%28%29%2Cr.trys.pop%28%29%3Bcontinue%7Dp%3Dt.call%28e%2Cr%29%7Dcatch%28l%29%7Bp%3D%5B6%2Cl%5D%2Cn%3D0%7Dfinally%7Bo%3Di%3D0%7Dif%28p%5B0%5D%265%29throw%20p%5B1%5D%3Breturn%7Bvalue%3Ap%5B0%5D%3Fp%5B1%5D%3Avoid%200%2Cdone%3A%210%7D%7D%7Dfunction%20ue%28e%29%7Bvar%20t%3Dtypeof%20Symbol%3D%3D%22function%22%26%26Symbol.iterator%2Cr%3Dt%26%26e%5Bt%5D%2Co%3D0%3Bif%28r%29return%20r.call%28e%29%3Bif%28e%26%26typeof%20e.length%3D%3D%22number%22%29return%7Bnext%3Afunction%28%29%7Breturn%20e%26%26o%3E%3De.length%26%26%28e%3Dvoid%200%29%2C%7Bvalue%3Ae%26%26e%5Bo%2B%2B%5D%2Cdone%3A%21e%7D%7D%7D%3Bthrow%20new%20TypeError%28t%3F%22Object%20is%20not%20iterable.%22%3A%22Symbol.iterator%20is%20not%20defined.%22%29%7Dfunction%20V%28e%2Ct%29%7Bvar%20r%3Dtypeof%20Symbol%3D%3D%22function%22%26%26e%5BSymbol.iterator%5D%3Bif%28%21r%29return%20e%3Bvar%20o%3Dr.call%28e%29%2Cn%2Ci%3D%5B%5D%2Cs%3Btry%7Bfor%28%3B%28t%3D%3D%3Dvoid%200%7C%7Ct--%20%3E0%29%26%26%21%28n%3Do.next%28%29%29.done%3B%29i.push%28n.value%29%7Dcatch%28a%29%7Bs%3D%7Berror%3Aa%7D%7Dfinally%7Btry%7Bn%26%26%21n.done%26%26%28r%3Do.return%29%26%26r.call%28o%29%7Dfinally%7Bif%28s%29throw%20s.error%7D%7Dreturn%20i%7Dfunction%20z%28e%2Ct%2Cr%29%7Bif%28r%7C%7Carguments.length%3D%3D%3D2%29for%28var%20o%3D0%2Cn%3Dt.length%2Ci%3Bo%3Cn%3Bo%2B%2B%29%28i%7C%7C%21%28o%20in%20t%29%29%26%26%28i%7C%7C%28i%3DArray.prototype.slice.call%28t%2C0%2Co%29%29%2Ci%5Bo%5D%3Dt%5Bo%5D%29%3Breturn%20e.concat%28i%7C%7CArray.prototype.slice.call%28t%29%29%7Dfunction%20ot%28e%29%7Breturn%20this%20instanceof%20ot%3F%28this.v%3De%2Cthis%29%3Anew%20ot%28e%29%7Dfunction%20ao%28e%2Ct%2Cr%29%7Bif%28%21Symbol.asyncIterator%29throw%20new%20TypeError%28%22Symbol.asyncIterator%20is%20not%20defined.%22%29%3Bvar%20o%3Dr.apply%28e%2Ct%7C%7C%5B%5D%29%2Cn%2Ci%3D%5B%5D%3Breturn%20n%3D%7B%7D%2Cs%28%22next%22%29%2Cs%28%22throw%22%29%2Cs%28%22return%22%29%2Cn%5BSymbol.asyncIterator%5D%3Dfunction%28%29%7Breturn%20this%7D%2Cn%3Bfunction%20s%28u%29%7Bo%5Bu%5D%26%26%28n%5Bu%5D%3Dfunction%28h%29%7Breturn%20new%20Promise%28function%28w%2CA%29%7Bi.push%28%5Bu%2Ch%2Cw%2CA%5D%29%3E1%7C%7Ca%28u%2Ch%29%7D%29%7D%29%7Dfunction%20a%28u%2Ch%29%7Btry%7Bc%28o%5Bu%5D%28h%29%29%7Dcatch%28w%29%7Bf%28i%5B0%5D%5B3%5D%2Cw%29%7D%7Dfunction%20c%28u%29%7Bu.value%20instanceof%20ot%3FPromise.resolve%28u.value.v%29.then%28p%2Cl%29%3Af%28i%5B0%5D%5B2%5D%2Cu%29%7Dfunction%20p%28u%29%7Ba%28%22next%22%2Cu%29%7Dfunction%20l%28u%29%7Ba%28%22throw%22%2Cu%29%7Dfunction%20f%28u%2Ch%29%7Bu%28h%29%2Ci.shift%28%29%2Ci.length%26%26a%28i%5B0%5D%5B0%5D%2Ci%5B0%5D%5B1%5D%29%7D%7Dfunction%20so%28e%29%7Bif%28%21Symbol.asyncIterator%29throw%20new%20TypeError%28%22Symbol.asyncIterator%20is%20not%20defined.%22%29%3Bvar%20t%3De%5BSymbol.asyncIterator%5D%2Cr%3Breturn%20t%3Ft.call%28e%29%3A%28e%3Dtypeof%20ue%3D%3D%22function%22%3Fue%28e%29%3Ae%5BSymbol.iterator%5D%28%29%2Cr%3D%7B%7D%2Co%28%22next%22%29%2Co%28%22throw%22%29%2Co%28%22return%22%29%2Cr%5BSymbol.asyncIterator%5D%3Dfunction%28%29%7Breturn%20this%7D%2Cr%29%3Bfunction%20o%28i%29%7Br%5Bi%5D%3De%5Bi%5D%26%26function%28s%29%7Breturn%20new%20Promise%28function%28a%2Cc%29%7Bs%3De%5Bi%5D%28s%29%2Cn%28a%2Cc%2Cs.done%2Cs.value%29%7D%29%7D%7Dfunction%20n%28i%2Cs%2Ca%2Cc%29%7BPromise.resolve%28c%29.then%28function%28p%29%7Bi%28%7Bvalue%3Ap%2Cdone%3Aa%7D%29%7D%2Cs%29%7D%7Dfunction%20k%28e%29%7Breturn%20typeof%20e%3D%3D%22function%22%7Dfunction%20pt%28e%29%7Bvar%20t%3Dfunction%28o%29%7BError.call%28o%29%2Co.stack%3Dnew%20Error%28%29.stack%7D%2Cr%3De%28t%29%3Breturn%20r.prototype%3DObject.create%28Error.prototype%29%2Cr.prototype.constructor%3Dr%2Cr%7Dvar%20Wt%3Dpt%28function%28e%29%7Breturn%20function%28r%29%7Be%28this%29%2Cthis.message%3Dr%3Fr.length%2B%60%20errors%20occurred%20during%20unsubscription%3A%0A%60%2Br.map%28function%28o%2Cn%29%7Breturn%20n%2B1%2B%22%29%20%22%2Bo.toString%28%29%7D%29.join%28%60%0A%20%20%60%29%3A%22%22%2Cthis.name%3D%22UnsubscriptionError%22%2Cthis.errors%3Dr%7D%7D%29%3Bfunction%20Ve%28e%2Ct%29%7Bif%28e%29%7Bvar%20r%3De.indexOf%28t%29%3B0%3C%3Dr%26%26e.splice%28r%2C1%29%7D%7Dvar%20Ie%3Dfunction%28%29%7Bfunction%20e%28t%29%7Bthis.initialTeardown%3Dt%2Cthis.closed%3D%211%2Cthis._parentage%3Dnull%2Cthis._finalizers%3Dnull%7Dreturn%20e.prototype.unsubscribe%3Dfunction%28%29%7Bvar%20t%2Cr%2Co%2Cn%2Ci%3Bif%28%21this.closed%29%7Bthis.closed%3D%210%3Bvar%20s%3Dthis._parentage%3Bif%28s%29if%28this._parentage%3Dnull%2CArray.isArray%28s%29%29try%7Bfor%28var%20a%3Due%28s%29%2Cc%3Da.next%28%29%3B%21c.done%3Bc%3Da.next%28%29%29%7Bvar%20p%3Dc.value%3Bp.remove%28this%29%7D%7Dcatch%28A%29%7Bt%3D%7Berror%3AA%7D%7Dfinally%7Btry%7Bc%26%26%21c.done%26%26%28r%3Da.return%29%26%26r.call%28a%29%7Dfinally%7Bif%28t%29throw%20t.error%7D%7Delse%20s.remove%28this%29%3Bvar%20l%3Dthis.initialTeardown%3Bif%28k%28l%29%29try%7Bl%28%29%7Dcatch%28A%29%7Bi%3DA%20instanceof%20Wt%3FA.errors%3A%5BA%5D%7Dvar%20f%3Dthis._finalizers%3Bif%28f%29%7Bthis._finalizers%3Dnull%3Btry%7Bfor%28var%20u%3Due%28f%29%2Ch%3Du.next%28%29%3B%21h.done%3Bh%3Du.next%28%29%29%7Bvar%20w%3Dh.value%3Btry%7Bco%28w%29%7Dcatch%28A%29%7Bi%3Di%21%3Dnull%3Fi%3A%5B%5D%2CA%20instanceof%20Wt%3Fi%3Dz%28z%28%5B%5D%2CV%28i%29%29%2CV%28A.errors%29%29%3Ai.push%28A%29%7D%7D%7Dcatch%28A%29%7Bo%3D%7Berror%3AA%7D%7Dfinally%7Btry%7Bh%26%26%21h.done%26%26%28n%3Du.return%29%26%26n.call%28u%29%7Dfinally%7Bif%28o%29throw%20o.error%7D%7D%7Dif%28i%29throw%20new%20Wt%28i%29%7D%7D%2Ce.prototype.add%3Dfunction%28t%29%7Bvar%20r%3Bif%28t%26%26t%21%3D%3Dthis%29if%28this.closed%29co%28t%29%3Belse%7Bif%28t%20instanceof%20e%29%7Bif%28t.closed%7C%7Ct._hasParent%28this%29%29return%3Bt._addParent%28this%29%7D%28this._finalizers%3D%28r%3Dthis._finalizers%29%21%3D%3Dnull%26%26r%21%3D%3Dvoid%200%3Fr%3A%5B%5D%29.push%28t%29%7D%7D%2Ce.prototype._hasParent%3Dfunction%28t%29%7Bvar%20r%3Dthis._parentage%3Breturn%20r%3D%3D%3Dt%7C%7CArray.isArray%28r%29%26%26r.includes%28t%29%7D%2Ce.prototype._addParent%3Dfunction%28t%29%7Bvar%20r%3Dthis._parentage%3Bthis._parentage%3DArray.isArray%28r%29%3F%28r.push%28t%29%2Cr%29%3Ar%3F%5Br%2Ct%5D%3At%7D%2Ce.prototype._removeParent%3Dfunction%28t%29%7Bvar%20r%3Dthis._parentage%3Br%3D%3D%3Dt%3Fthis._parentage%3Dnull%3AArray.isArray%28r%29%26%26Ve%28r%2Ct%29%7D%2Ce.prototype.remove%3Dfunction%28t%29%7Bvar%20r%3Dthis._finalizers%3Br%26%26Ve%28r%2Ct%29%2Ct%20instanceof%20e%26%26t._removeParent%28this%29%7D%2Ce.EMPTY%3Dfunction%28%29%7Bvar%20t%3Dnew%20e%3Breturn%20t.closed%3D%210%2Ct%7D%28%29%2Ce%7D%28%29%3Bvar%20Er%3DIe.EMPTY%3Bfunction%20Dt%28e%29%7Breturn%20e%20instanceof%20Ie%7C%7Ce%26%26%22closed%22in%20e%26%26k%28e.remove%29%26%26k%28e.add%29%26%26k%28e.unsubscribe%29%7Dfunction%20co%28e%29%7Bk%28e%29%3Fe%28%29%3Ae.unsubscribe%28%29%7Dvar%20ke%3D%7BonUnhandledError%3Anull%2ConStoppedNotification%3Anull%2CPromise%3Avoid%200%2CuseDeprecatedSynchronousErrorHandling%3A%211%2CuseDeprecatedNextContext%3A%211%7D%3Bvar%20lt%3D%7BsetTimeout%3Afunction%28e%2Ct%29%7Bfor%28var%20r%3D%5B%5D%2Co%3D2%3Bo%3Carguments.length%3Bo%2B%2B%29r%5Bo-2%5D%3Darguments%5Bo%5D%3Bvar%20n%3Dlt.delegate%3Breturn%20n%21%3Dnull%26%26n.setTimeout%3Fn.setTimeout.apply%28n%2Cz%28%5Be%2Ct%5D%2CV%28r%29%29%29%3AsetTimeout.apply%28void%200%2Cz%28%5Be%2Ct%5D%2CV%28r%29%29%29%7D%2CclearTimeout%3Afunction%28e%29%7Bvar%20t%3Dlt.delegate%3Breturn%28%28t%3D%3Dnull%3Fvoid%200%3At.clearTimeout%29%7C%7CclearTimeout%29%28e%29%7D%2Cdelegate%3Avoid%200%7D%3Bfunction%20Nt%28e%29%7Blt.setTimeout%28function%28%29%7Bvar%20t%3Dke.onUnhandledError%3Bif%28t%29t%28e%29%3Belse%20throw%20e%7D%29%7Dfunction%20Se%28%29%7B%7Dvar%20po%3Dfunction%28%29%7Breturn%20wr%28%22C%22%2Cvoid%200%2Cvoid%200%29%7D%28%29%3Bfunction%20lo%28e%29%7Breturn%20wr%28%22E%22%2Cvoid%200%2Ce%29%7Dfunction%20mo%28e%29%7Breturn%20wr%28%22N%22%2Ce%2Cvoid%200%29%7Dfunction%20wr%28e%2Ct%2Cr%29%7Breturn%7Bkind%3Ae%2Cvalue%3At%2Cerror%3Ar%7D%7Dvar%20nt%3Dnull%3Bfunction%20mt%28e%29%7Bif%28ke.useDeprecatedSynchronousErrorHandling%29%7Bvar%20t%3D%21nt%3Bif%28t%26%26%28nt%3D%7BerrorThrown%3A%211%2Cerror%3Anull%7D%29%2Ce%28%29%2Ct%29%7Bvar%20r%3Dnt%2Co%3Dr.errorThrown%2Cn%3Dr.error%3Bif%28nt%3Dnull%2Co%29throw%20n%7D%7Delse%20e%28%29%7Dfunction%20fo%28e%29%7Bke.useDeprecatedSynchronousErrorHandling%26%26nt%26%26%28nt.errorThrown%3D%210%2Cnt.error%3De%29%7Dvar%20Tt%3Dfunction%28e%29%7Bse%28t%2Ce%29%3Bfunction%20t%28r%29%7Bvar%20o%3De.call%28this%29%7C%7Cthis%3Breturn%20o.isStopped%3D%211%2Cr%3F%28o.destination%3Dr%2CDt%28r%29%26%26r.add%28o%29%29%3Ao.destination%3DIi%2Co%7Dreturn%20t.create%3Dfunction%28r%2Co%2Cn%29%7Breturn%20new%20it%28r%2Co%2Cn%29%7D%2Ct.prototype.next%3Dfunction%28r%29%7Bthis.isStopped%3FSr%28mo%28r%29%2Cthis%29%3Athis._next%28r%29%7D%2Ct.prototype.error%3Dfunction%28r%29%7Bthis.isStopped%3FSr%28lo%28r%29%2Cthis%29%3A%28this.isStopped%3D%210%2Cthis._error%28r%29%29%7D%2Ct.prototype.complete%3Dfunction%28%29%7Bthis.isStopped%3FSr%28po%2Cthis%29%3A%28this.isStopped%3D%210%2Cthis._complete%28%29%29%7D%2Ct.prototype.unsubscribe%3Dfunction%28%29%7Bthis.closed%7C%7C%28this.isStopped%3D%210%2Ce.prototype.unsubscribe.call%28this%29%2Cthis.destination%3Dnull%29%7D%2Ct.prototype._next%3Dfunction%28r%29%7Bthis.destination.next%28r%29%7D%2Ct.prototype._error%3Dfunction%28r%29%7Btry%7Bthis.destination.error%28r%29%7Dfinally%7Bthis.unsubscribe%28%29%7D%7D%2Ct.prototype._complete%3Dfunction%28%29%7Btry%7Bthis.destination.complete%28%29%7Dfinally%7Bthis.unsubscribe%28%29%7D%7D%2Ct%7D%28Ie%29%3Bvar%20%24i%3DFunction.prototype.bind%3Bfunction%20Tr%28e%2Ct%29%7Breturn%20%24i.call%28e%2Ct%29%7Dvar%20Ri%3Dfunction%28%29%7Bfunction%20e%28t%29%7Bthis.partialObserver%3Dt%7Dreturn%20e.prototype.next%3Dfunction%28t%29%7Bvar%20r%3Dthis.partialObserver%3Bif%28r.next%29try%7Br.next%28t%29%7Dcatch%28o%29%7BVt%28o%29%7D%7D%2Ce.prototype.error%3Dfunction%28t%29%7Bvar%20r%3Dthis.partialObserver%3Bif%28r.error%29try%7Br.error%28t%29%7Dcatch%28o%29%7BVt%28o%29%7Delse%20Vt%28t%29%7D%2Ce.prototype.complete%3Dfunction%28%29%7Bvar%20t%3Dthis.partialObserver%3Bif%28t.complete%29try%7Bt.complete%28%29%7Dcatch%28r%29%7BVt%28r%29%7D%7D%2Ce%7D%28%29%2Cit%3Dfunction%28e%29%7Bse%28t%2Ce%29%3Bfunction%20t%28r%2Co%2Cn%29%7Bvar%20i%3De.call%28this%29%7C%7Cthis%2Cs%3Bif%28k%28r%29%7C%7C%21r%29s%3D%7Bnext%3Ar%21%3Dnull%3Fr%3Avoid%200%2Cerror%3Ao%21%3Dnull%3Fo%3Avoid%200%2Ccomplete%3An%21%3Dnull%3Fn%3Avoid%200%7D%3Belse%7Bvar%20a%3Bi%26%26ke.useDeprecatedNextContext%3F%28a%3DObject.create%28r%29%2Ca.unsubscribe%3Dfunction%28%29%7Breturn%20i.unsubscribe%28%29%7D%2Cs%3D%7Bnext%3Ar.next%26%26Tr%28r.next%2Ca%29%2Cerror%3Ar.error%26%26Tr%28r.error%2Ca%29%2Ccomplete%3Ar.complete%26%26Tr%28r.complete%2Ca%29%7D%29%3As%3Dr%7Dreturn%20i.destination%3Dnew%20Ri%28s%29%2Ci%7Dreturn%20t%7D%28Tt%29%3Bfunction%20Vt%28e%29%7Bke.useDeprecatedSynchronousErrorHandling%3Ffo%28e%29%3ANt%28e%29%7Dfunction%20Pi%28e%29%7Bthrow%20e%7Dfunction%20Sr%28e%2Ct%29%7Bvar%20r%3Dke.onStoppedNotification%3Br%26%26lt.setTimeout%28function%28%29%7Breturn%20r%28e%2Ct%29%7D%29%7Dvar%20Ii%3D%7Bclosed%3A%210%2Cnext%3ASe%2Cerror%3APi%2Ccomplete%3ASe%7D%3Bvar%20ft%3Dfunction%28%29%7Breturn%20typeof%20Symbol%3D%3D%22function%22%26%26Symbol.observable%7C%7C%22%40%40observable%22%7D%28%29%3Bfunction%20ce%28e%29%7Breturn%20e%7Dfunction%20uo%28%29%7Bfor%28var%20e%3D%5B%5D%2Ct%3D0%3Bt%3Carguments.length%3Bt%2B%2B%29e%5Bt%5D%3Darguments%5Bt%5D%3Breturn%20Or%28e%29%7Dfunction%20Or%28e%29%7Breturn%20e.length%3D%3D%3D0%3Fce%3Ae.length%3D%3D%3D1%3Fe%5B0%5D%3Afunction%28r%29%7Breturn%20e.reduce%28function%28o%2Cn%29%7Breturn%20n%28o%29%7D%2Cr%29%7D%7Dvar%20j%3Dfunction%28%29%7Bfunction%20e%28t%29%7Bt%26%26%28this._subscribe%3Dt%29%7Dreturn%20e.prototype.lift%3Dfunction%28t%29%7Bvar%20r%3Dnew%20e%3Breturn%20r.source%3Dthis%2Cr.operator%3Dt%2Cr%7D%2Ce.prototype.subscribe%3Dfunction%28t%2Cr%2Co%29%7Bvar%20n%3Dthis%2Ci%3Dji%28t%29%3Ft%3Anew%20it%28t%2Cr%2Co%29%3Breturn%20mt%28function%28%29%7Bvar%20s%3Dn%2Ca%3Ds.operator%2Cc%3Ds.source%3Bi.add%28a%3Fa.call%28i%2Cc%29%3Ac%3Fn._subscribe%28i%29%3An._trySubscribe%28i%29%29%7D%29%2Ci%7D%2Ce.prototype._trySubscribe%3Dfunction%28t%29%7Btry%7Breturn%20this._subscribe%28t%29%7Dcatch%28r%29%7Bt.error%28r%29%7D%7D%2Ce.prototype.forEach%3Dfunction%28t%2Cr%29%7Bvar%20o%3Dthis%3Breturn%20r%3Dho%28r%29%2Cnew%20r%28function%28n%2Ci%29%7Bvar%20s%3Dnew%20it%28%7Bnext%3Afunction%28a%29%7Btry%7Bt%28a%29%7Dcatch%28c%29%7Bi%28c%29%2Cs.unsubscribe%28%29%7D%7D%2Cerror%3Ai%2Ccomplete%3An%7D%29%3Bo.subscribe%28s%29%7D%29%7D%2Ce.prototype._subscribe%3Dfunction%28t%29%7Bvar%20r%3Breturn%28r%3Dthis.source%29%3D%3D%3Dnull%7C%7Cr%3D%3D%3Dvoid%200%3Fvoid%200%3Ar.subscribe%28t%29%7D%2Ce.prototype%5Bft%5D%3Dfunction%28%29%7Breturn%20this%7D%2Ce.prototype.pipe%3Dfunction%28%29%7Bfor%28var%20t%3D%5B%5D%2Cr%3D0%3Br%3Carguments.length%3Br%2B%2B%29t%5Br%5D%3Darguments%5Br%5D%3Breturn%20Or%28t%29%28this%29%7D%2Ce.prototype.toPromise%3Dfunction%28t%29%7Bvar%20r%3Dthis%3Breturn%20t%3Dho%28t%29%2Cnew%20t%28function%28o%2Cn%29%7Bvar%20i%3Br.subscribe%28function%28s%29%7Breturn%20i%3Ds%7D%2Cfunction%28s%29%7Breturn%20n%28s%29%7D%2Cfunction%28%29%7Breturn%20o%28i%29%7D%29%7D%29%7D%2Ce.create%3Dfunction%28t%29%7Breturn%20new%20e%28t%29%7D%2Ce%7D%28%29%3Bfunction%20ho%28e%29%7Bvar%20t%3Breturn%28t%3De%21%3Dnull%3Fe%3Ake.Promise%29%21%3D%3Dnull%26%26t%21%3D%3Dvoid%200%3Ft%3APromise%7Dfunction%20Fi%28e%29%7Breturn%20e%26%26k%28e.next%29%26%26k%28e.error%29%26%26k%28e.complete%29%7Dfunction%20ji%28e%29%7Breturn%20e%26%26e%20instanceof%20Tt%7C%7CFi%28e%29%26%26Dt%28e%29%7Dfunction%20Ui%28e%29%7Breturn%20k%28e%3D%3Dnull%3Fvoid%200%3Ae.lift%29%7Dfunction%20x%28e%29%7Breturn%20function%28t%29%7Bif%28Ui%28t%29%29return%20t.lift%28function%28r%29%7Btry%7Breturn%20e%28r%2Cthis%29%7Dcatch%28o%29%7Bthis.error%28o%29%7D%7D%29%3Bthrow%20new%20TypeError%28%22Unable%20to%20lift%20unknown%20Observable%20type%22%29%7D%7Dfunction%20S%28e%2Ct%2Cr%2Co%2Cn%29%7Breturn%20new%20Wi%28e%2Ct%2Cr%2Co%2Cn%29%7Dvar%20Wi%3Dfunction%28e%29%7Bse%28t%2Ce%29%3Bfunction%20t%28r%2Co%2Cn%2Ci%2Cs%2Ca%29%7Bvar%20c%3De.call%28this%2Cr%29%7C%7Cthis%3Breturn%20c.onFinalize%3Ds%2Cc.shouldUnsubscribe%3Da%2Cc._next%3Do%3Ffunction%28p%29%7Btry%7Bo%28p%29%7Dcatch%28l%29%7Br.error%28l%29%7D%7D%3Ae.prototype._next%2Cc._error%3Di%3Ffunction%28p%29%7Btry%7Bi%28p%29%7Dcatch%28l%29%7Br.error%28l%29%7Dfinally%7Bthis.unsubscribe%28%29%7D%7D%3Ae.prototype._error%2Cc._complete%3Dn%3Ffunction%28%29%7Btry%7Bn%28%29%7Dcatch%28p%29%7Br.error%28p%29%7Dfinally%7Bthis.unsubscribe%28%29%7D%7D%3Ae.prototype._complete%2Cc%7Dreturn%20t.prototype.unsubscribe%3Dfunction%28%29%7Bvar%20r%3Bif%28%21this.shouldUnsubscribe%7C%7Cthis.shouldUnsubscribe%28%29%29%7Bvar%20o%3Dthis.closed%3Be.prototype.unsubscribe.call%28this%29%2C%21o%26%26%28%28r%3Dthis.onFinalize%29%3D%3D%3Dnull%7C%7Cr%3D%3D%3Dvoid%200%7C%7Cr.call%28this%29%29%7D%7D%2Ct%7D%28Tt%29%3Bvar%20ut%3D%7Bschedule%3Afunction%28e%29%7Bvar%20t%3DrequestAnimationFrame%2Cr%3DcancelAnimationFrame%2Co%3Dut.delegate%3Bo%26%26%28t%3Do.requestAnimationFrame%2Cr%3Do.cancelAnimationFrame%29%3Bvar%20n%3Dt%28function%28i%29%7Br%3Dvoid%200%2Ce%28i%29%7D%29%3Breturn%20new%20Ie%28function%28%29%7Breturn%20r%3D%3Dnull%3Fvoid%200%3Ar%28n%29%7D%29%7D%2CrequestAnimationFrame%3Afunction%28%29%7Bfor%28var%20e%3D%5B%5D%2Ct%3D0%3Bt%3Carguments.length%3Bt%2B%2B%29e%5Bt%5D%3Darguments%5Bt%5D%3Bvar%20r%3Dut.delegate%3Breturn%28%28r%3D%3Dnull%3Fvoid%200%3Ar.requestAnimationFrame%29%7C%7CrequestAnimationFrame%29.apply%28void%200%2Cz%28%5B%5D%2CV%28e%29%29%29%7D%2CcancelAnimationFrame%3Afunction%28%29%7Bfor%28var%20e%3D%5B%5D%2Ct%3D0%3Bt%3Carguments.length%3Bt%2B%2B%29e%5Bt%5D%3Darguments%5Bt%5D%3Bvar%20r%3Dut.delegate%3Breturn%28%28r%3D%3Dnull%3Fvoid%200%3Ar.cancelAnimationFrame%29%7C%7CcancelAnimationFrame%29.apply%28void%200%2Cz%28%5B%5D%2CV%28e%29%29%29%7D%2Cdelegate%3Avoid%200%7D%3Bvar%20bo%3Dpt%28function%28e%29%7Breturn%20function%28%29%7Be%28this%29%2Cthis.name%3D%22ObjectUnsubscribedError%22%2Cthis.message%3D%22object%20unsubscribed%22%7D%7D%29%3Bvar%20v%3Dfunction%28e%29%7Bse%28t%2Ce%29%3Bfunction%20t%28%29%7Bvar%20r%3De.call%28this%29%7C%7Cthis%3Breturn%20r.closed%3D%211%2Cr.currentObservers%3Dnull%2Cr.observers%3D%5B%5D%2Cr.isStopped%3D%211%2Cr.hasError%3D%211%2Cr.thrownError%3Dnull%2Cr%7Dreturn%20t.prototype.lift%3Dfunction%28r%29%7Bvar%20o%3Dnew%20vo%28this%2Cthis%29%3Breturn%20o.operator%3Dr%2Co%7D%2Ct.prototype._throwIfClosed%3Dfunction%28%29%7Bif%28this.closed%29throw%20new%20bo%7D%2Ct.prototype.next%3Dfunction%28r%29%7Bvar%20o%3Dthis%3Bmt%28function%28%29%7Bvar%20n%2Ci%3Bif%28o._throwIfClosed%28%29%2C%21o.isStopped%29%7Bo.currentObservers%7C%7C%28o.currentObservers%3DArray.from%28o.observers%29%29%3Btry%7Bfor%28var%20s%3Due%28o.currentObservers%29%2Ca%3Ds.next%28%29%3B%21a.done%3Ba%3Ds.next%28%29%29%7Bvar%20c%3Da.value%3Bc.next%28r%29%7D%7Dcatch%28p%29%7Bn%3D%7Berror%3Ap%7D%7Dfinally%7Btry%7Ba%26%26%21a.done%26%26%28i%3Ds.return%29%26%26i.call%28s%29%7Dfinally%7Bif%28n%29throw%20n.error%7D%7D%7D%7D%29%7D%2Ct.prototype.error%3Dfunction%28r%29%7Bvar%20o%3Dthis%3Bmt%28function%28%29%7Bif%28o._throwIfClosed%28%29%2C%21o.isStopped%29%7Bo.hasError%3Do.isStopped%3D%210%2Co.thrownError%3Dr%3Bfor%28var%20n%3Do.observers%3Bn.length%3B%29n.shift%28%29.error%28r%29%7D%7D%29%7D%2Ct.prototype.complete%3Dfunction%28%29%7Bvar%20r%3Dthis%3Bmt%28function%28%29%7Bif%28r._throwIfClosed%28%29%2C%21r.isStopped%29%7Br.isStopped%3D%210%3Bfor%28var%20o%3Dr.observers%3Bo.length%3B%29o.shift%28%29.complete%28%29%7D%7D%29%7D%2Ct.prototype.unsubscribe%3Dfunction%28%29%7Bthis.isStopped%3Dthis.closed%3D%210%2Cthis.observers%3Dthis.currentObservers%3Dnull%7D%2CObject.defineProperty%28t.prototype%2C%22observed%22%2C%7Bget%3Afunction%28%29%7Bvar%20r%3Breturn%28%28r%3Dthis.observers%29%3D%3D%3Dnull%7C%7Cr%3D%3D%3Dvoid%200%3Fvoid%200%3Ar.length%29%3E0%7D%2Cenumerable%3A%211%2Cconfigurable%3A%210%7D%29%2Ct.prototype._trySubscribe%3Dfunction%28r%29%7Breturn%20this._throwIfClosed%28%29%2Ce.prototype._trySubscribe.call%28this%2Cr%29%7D%2Ct.prototype._subscribe%3Dfunction%28r%29%7Breturn%20this._throwIfClosed%28%29%2Cthis._checkFinalizedStatuses%28r%29%2Cthis._innerSubscribe%28r%29%7D%2Ct.prototype._innerSubscribe%3Dfunction%28r%29%7Bvar%20o%3Dthis%2Cn%3Dthis%2Ci%3Dn.hasError%2Cs%3Dn.isStopped%2Ca%3Dn.observers%3Breturn%20i%7C%7Cs%3FEr%3A%28this.currentObservers%3Dnull%2Ca.push%28r%29%2Cnew%20Ie%28function%28%29%7Bo.currentObservers%3Dnull%2CVe%28a%2Cr%29%7D%29%29%7D%2Ct.prototype._checkFinalizedStatuses%3Dfunction%28r%29%7Bvar%20o%3Dthis%2Cn%3Do.hasError%2Ci%3Do.thrownError%2Cs%3Do.isStopped%3Bn%3Fr.error%28i%29%3As%26%26r.complete%28%29%7D%2Ct.prototype.asObservable%3Dfunction%28%29%7Bvar%20r%3Dnew%20j%3Breturn%20r.source%3Dthis%2Cr%7D%2Ct.create%3Dfunction%28r%2Co%29%7Breturn%20new%20vo%28r%2Co%29%7D%2Ct%7D%28j%29%3Bvar%20vo%3Dfunction%28e%29%7Bse%28t%2Ce%29%3Bfunction%20t%28r%2Co%29%7Bvar%20n%3De.call%28this%29%7C%7Cthis%3Breturn%20n.destination%3Dr%2Cn.source%3Do%2Cn%7Dreturn%20t.prototype.next%3Dfunction%28r%29%7Bvar%20o%2Cn%3B%28n%3D%28o%3Dthis.destination%29%3D%3D%3Dnull%7C%7Co%3D%3D%3Dvoid%200%3Fvoid%200%3Ao.next%29%3D%3D%3Dnull%7C%7Cn%3D%3D%3Dvoid%200%7C%7Cn.call%28o%2Cr%29%7D%2Ct.prototype.error%3Dfunction%28r%29%7Bvar%20o%2Cn%3B%28n%3D%28o%3Dthis.destination%29%3D%3D%3Dnull%7C%7Co%3D%3D%3Dvoid%200%3Fvoid%200%3Ao.error%29%3D%3D%3Dnull%7C%7Cn%3D%3D%3Dvoid%200%7C%7Cn.call%28o%2Cr%29%7D%2Ct.prototype.complete%3Dfunction%28%29%7Bvar%20r%2Co%3B%28o%3D%28r%3Dthis.destination%29%3D%3D%3Dnull%7C%7Cr%3D%3D%3Dvoid%200%3Fvoid%200%3Ar.complete%29%3D%3D%3Dnull%7C%7Co%3D%3D%3Dvoid%200%7C%7Co.call%28r%29%7D%2Ct.prototype._subscribe%3Dfunction%28r%29%7Bvar%20o%2Cn%3Breturn%28n%3D%28o%3Dthis.source%29%3D%3D%3Dnull%7C%7Co%3D%3D%3Dvoid%200%3Fvoid%200%3Ao.subscribe%28r%29%29%21%3D%3Dnull%26%26n%21%3D%3Dvoid%200%3Fn%3AEr%7D%2Ct%7D%28v%29%3Bvar%20St%3D%7Bnow%3Afunction%28%29%7Breturn%28St.delegate%7C%7CDate%29.now%28%29%7D%2Cdelegate%3Avoid%200%7D%3Bvar%20Ot%3Dfunction%28e%29%7Bse%28t%2Ce%29%3Bfunction%20t%28r%2Co%2Cn%29%7Br%3D%3D%3Dvoid%200%26%26%28r%3D1/0%29%2Co%3D%3D%3Dvoid%200%26%26%28o%3D1/0%29%2Cn%3D%3D%3Dvoid%200%26%26%28n%3DSt%29%3Bvar%20i%3De.call%28this%29%7C%7Cthis%3Breturn%20i._bufferSize%3Dr%2Ci._windowTime%3Do%2Ci._timestampProvider%3Dn%2Ci._buffer%3D%5B%5D%2Ci._infiniteTimeWindow%3D%210%2Ci._infiniteTimeWindow%3Do%3D%3D%3D1/0%2Ci._bufferSize%3DMath.max%281%2Cr%29%2Ci._windowTime%3DMath.max%281%2Co%29%2Ci%7Dreturn%20t.prototype.next%3Dfunction%28r%29%7Bvar%20o%3Dthis%2Cn%3Do.isStopped%2Ci%3Do._buffer%2Cs%3Do._infiniteTimeWindow%2Ca%3Do._timestampProvider%2Cc%3Do._windowTime%3Bn%7C%7C%28i.push%28r%29%2C%21s%26%26i.push%28a.now%28%29%2Bc%29%29%2Cthis._trimBuffer%28%29%2Ce.prototype.next.call%28this%2Cr%29%7D%2Ct.prototype._subscribe%3Dfunction%28r%29%7Bthis._throwIfClosed%28%29%2Cthis._trimBuffer%28%29%3Bfor%28var%20o%3Dthis._innerSubscribe%28r%29%2Cn%3Dthis%2Ci%3Dn._infiniteTimeWindow%2Cs%3Dn._buffer%2Ca%3Ds.slice%28%29%2Cc%3D0%3Bc%3Ca.length%26%26%21r.closed%3Bc%2B%3Di%3F1%3A2%29r.next%28a%5Bc%5D%29%3Breturn%20this._checkFinalizedStatuses%28r%29%2Co%7D%2Ct.prototype._trimBuffer%3Dfunction%28%29%7Bvar%20r%3Dthis%2Co%3Dr._bufferSize%2Cn%3Dr._timestampProvider%2Ci%3Dr._buffer%2Cs%3Dr._infiniteTimeWindow%2Ca%3D%28s%3F1%3A2%29%2Ao%3Bif%28o%3C1/0%26%26a%3Ci.length%26%26i.splice%280%2Ci.length-a%29%2C%21s%29%7Bfor%28var%20c%3Dn.now%28%29%2Cp%3D0%2Cl%3D1%3Bl%3Ci.length%26%26i%5Bl%5D%3C%3Dc%3Bl%2B%3D2%29p%3Dl%3Bp%26%26i.splice%280%2Cp%2B1%29%7D%7D%2Ct%7D%28v%29%3Bvar%20go%3Dfunction%28e%29%7Bse%28t%2Ce%29%3Bfunction%20t%28r%2Co%29%7Breturn%20e.call%28this%29%7C%7Cthis%7Dreturn%20t.prototype.schedule%3Dfunction%28r%2Co%29%7Breturn%20o%3D%3D%3Dvoid%200%26%26%28o%3D0%29%2Cthis%7D%2Ct%7D%28Ie%29%3Bvar%20Mt%3D%7BsetInterval%3Afunction%28e%2Ct%29%7Bfor%28var%20r%3D%5B%5D%2Co%3D2%3Bo%3Carguments.length%3Bo%2B%2B%29r%5Bo-2%5D%3Darguments%5Bo%5D%3Bvar%20n%3DMt.delegate%3Breturn%20n%21%3Dnull%26%26n.setInterval%3Fn.setInterval.apply%28n%2Cz%28%5Be%2Ct%5D%2CV%28r%29%29%29%3AsetInterval.apply%28void%200%2Cz%28%5Be%2Ct%5D%2CV%28r%29%29%29%7D%2CclearInterval%3Afunction%28e%29%7Bvar%20t%3DMt.delegate%3Breturn%28%28t%3D%3Dnull%3Fvoid%200%3At.clearInterval%29%7C%7CclearInterval%29%28e%29%7D%2Cdelegate%3Avoid%200%7D%3Bvar%20zt%3Dfunction%28e%29%7Bse%28t%2Ce%29%3Bfunction%20t%28r%2Co%29%7Bvar%20n%3De.call%28this%2Cr%2Co%29%7C%7Cthis%3Breturn%20n.scheduler%3Dr%2Cn.work%3Do%2Cn.pending%3D%211%2Cn%7Dreturn%20t.prototype.schedule%3Dfunction%28r%2Co%29%7Bvar%20n%3Bif%28o%3D%3D%3Dvoid%200%26%26%28o%3D0%29%2Cthis.closed%29return%20this%3Bthis.state%3Dr%3Bvar%20i%3Dthis.id%2Cs%3Dthis.scheduler%3Breturn%20i%21%3Dnull%26%26%28this.id%3Dthis.recycleAsyncId%28s%2Ci%2Co%29%29%2Cthis.pending%3D%210%2Cthis.delay%3Do%2Cthis.id%3D%28n%3Dthis.id%29%21%3D%3Dnull%26%26n%21%3D%3Dvoid%200%3Fn%3Athis.requestAsyncId%28s%2Cthis.id%2Co%29%2Cthis%7D%2Ct.prototype.requestAsyncId%3Dfunction%28r%2Co%2Cn%29%7Breturn%20n%3D%3D%3Dvoid%200%26%26%28n%3D0%29%2CMt.setInterval%28r.flush.bind%28r%2Cthis%29%2Cn%29%7D%2Ct.prototype.recycleAsyncId%3Dfunction%28r%2Co%2Cn%29%7Bif%28n%3D%3D%3Dvoid%200%26%26%28n%3D0%29%2Cn%21%3Dnull%26%26this.delay%3D%3D%3Dn%26%26this.pending%3D%3D%3D%211%29return%20o%3Bo%21%3Dnull%26%26Mt.clearInterval%28o%29%7D%2Ct.prototype.execute%3Dfunction%28r%2Co%29%7Bif%28this.closed%29return%20new%20Error%28%22executing%20a%20cancelled%20action%22%29%3Bthis.pending%3D%211%3Bvar%20n%3Dthis._execute%28r%2Co%29%3Bif%28n%29return%20n%3Bthis.pending%3D%3D%3D%211%26%26this.id%21%3Dnull%26%26%28this.id%3Dthis.recycleAsyncId%28this.scheduler%2Cthis.id%2Cnull%29%29%7D%2Ct.prototype._execute%3Dfunction%28r%2Co%29%7Bvar%20n%3D%211%2Ci%3Btry%7Bthis.work%28r%29%7Dcatch%28s%29%7Bn%3D%210%2Ci%3Ds%7C%7Cnew%20Error%28%22Scheduled%20action%20threw%20falsy%20error%22%29%7Dif%28n%29return%20this.unsubscribe%28%29%2Ci%7D%2Ct.prototype.unsubscribe%3Dfunction%28%29%7Bif%28%21this.closed%29%7Bvar%20r%3Dthis%2Co%3Dr.id%2Cn%3Dr.scheduler%2Ci%3Dn.actions%3Bthis.work%3Dthis.state%3Dthis.scheduler%3Dnull%2Cthis.pending%3D%211%2CVe%28i%2Cthis%29%2Co%21%3Dnull%26%26%28this.id%3Dthis.recycleAsyncId%28n%2Co%2Cnull%29%29%2Cthis.delay%3Dnull%2Ce.prototype.unsubscribe.call%28this%29%7D%7D%2Ct%7D%28go%29%3Bvar%20Mr%3Dfunction%28%29%7Bfunction%20e%28t%2Cr%29%7Br%3D%3D%3Dvoid%200%26%26%28r%3De.now%29%2Cthis.schedulerActionCtor%3Dt%2Cthis.now%3Dr%7Dreturn%20e.prototype.schedule%3Dfunction%28t%2Cr%2Co%29%7Breturn%20r%3D%3D%3Dvoid%200%26%26%28r%3D0%29%2Cnew%20this.schedulerActionCtor%28this%2Ct%29.schedule%28o%2Cr%29%7D%2Ce.now%3DSt.now%2Ce%7D%28%29%3Bvar%20qt%3Dfunction%28e%29%7Bse%28t%2Ce%29%3Bfunction%20t%28r%2Co%29%7Bo%3D%3D%3Dvoid%200%26%26%28o%3DMr.now%29%3Bvar%20n%3De.call%28this%2Cr%2Co%29%7C%7Cthis%3Breturn%20n.actions%3D%5B%5D%2Cn._active%3D%211%2Cn%7Dreturn%20t.prototype.flush%3Dfunction%28r%29%7Bvar%20o%3Dthis.actions%3Bif%28this._active%29%7Bo.push%28r%29%3Breturn%7Dvar%20n%3Bthis._active%3D%210%3Bdo%20if%28n%3Dr.execute%28r.state%2Cr.delay%29%29break%3Bwhile%28r%3Do.shift%28%29%29%3Bif%28this._active%3D%211%2Cn%29%7Bfor%28%3Br%3Do.shift%28%29%3B%29r.unsubscribe%28%29%3Bthrow%20n%7D%7D%2Ct%7D%28Mr%29%3Bvar%20ie%3Dnew%20qt%28zt%29%2CLr%3Die%3Bvar%20xo%3Dfunction%28e%29%7Bse%28t%2Ce%29%3Bfunction%20t%28r%2Co%29%7Bvar%20n%3De.call%28this%2Cr%2Co%29%7C%7Cthis%3Breturn%20n.scheduler%3Dr%2Cn.work%3Do%2Cn%7Dreturn%20t.prototype.requestAsyncId%3Dfunction%28r%2Co%2Cn%29%7Breturn%20n%3D%3D%3Dvoid%200%26%26%28n%3D0%29%2Cn%21%3D%3Dnull%26%26n%3E0%3Fe.prototype.requestAsyncId.call%28this%2Cr%2Co%2Cn%29%3A%28r.actions.push%28this%29%2Cr._scheduled%7C%7C%28r._scheduled%3Dut.requestAnimationFrame%28function%28%29%7Breturn%20r.flush%28void%200%29%7D%29%29%29%7D%2Ct.prototype.recycleAsyncId%3Dfunction%28r%2Co%2Cn%29%7Bvar%20i%3Bif%28n%3D%3D%3Dvoid%200%26%26%28n%3D0%29%2Cn%21%3Dnull%3Fn%3E0%3Athis.delay%3E0%29return%20e.prototype.recycleAsyncId.call%28this%2Cr%2Co%2Cn%29%3Bvar%20s%3Dr.actions%3Bo%21%3Dnull%26%26%28%28i%3Ds%5Bs.length-1%5D%29%3D%3D%3Dnull%7C%7Ci%3D%3D%3Dvoid%200%3Fvoid%200%3Ai.id%29%21%3D%3Do%26%26%28ut.cancelAnimationFrame%28o%29%2Cr._scheduled%3Dvoid%200%29%7D%2Ct%7D%28zt%29%3Bvar%20yo%3Dfunction%28e%29%7Bse%28t%2Ce%29%3Bfunction%20t%28%29%7Breturn%20e%21%3D%3Dnull%26%26e.apply%28this%2Carguments%29%7C%7Cthis%7Dreturn%20t.prototype.flush%3Dfunction%28r%29%7Bthis._active%3D%210%3Bvar%20o%3Dthis._scheduled%3Bthis._scheduled%3Dvoid%200%3Bvar%20n%3Dthis.actions%2Ci%3Br%3Dr%7C%7Cn.shift%28%29%3Bdo%20if%28i%3Dr.execute%28r.state%2Cr.delay%29%29break%3Bwhile%28%28r%3Dn%5B0%5D%29%26%26r.id%3D%3D%3Do%26%26n.shift%28%29%29%3Bif%28this._active%3D%211%2Ci%29%7Bfor%28%3B%28r%3Dn%5B0%5D%29%26%26r.id%3D%3D%3Do%26%26n.shift%28%29%3B%29r.unsubscribe%28%29%3Bthrow%20i%7D%7D%2Ct%7D%28qt%29%3Bvar%20de%3Dnew%20yo%28xo%29%3Bvar%20L%3Dnew%20j%28function%28e%29%7Breturn%20e.complete%28%29%7D%29%3Bfunction%20Kt%28e%29%7Breturn%20e%26%26k%28e.schedule%29%7Dfunction%20_r%28e%29%7Breturn%20e%5Be.length-1%5D%7Dfunction%20Je%28e%29%7Breturn%20k%28_r%28e%29%29%3Fe.pop%28%29%3Avoid%200%7Dfunction%20Ae%28e%29%7Breturn%20Kt%28_r%28e%29%29%3Fe.pop%28%29%3Avoid%200%7Dfunction%20Qt%28e%2Ct%29%7Breturn%20typeof%20_r%28e%29%3D%3D%22number%22%3Fe.pop%28%29%3At%7Dvar%20dt%3Dfunction%28e%29%7Breturn%20e%26%26typeof%20e.length%3D%3D%22number%22%26%26typeof%20e%21%3D%22function%22%7D%3Bfunction%20Yt%28e%29%7Breturn%20k%28e%3D%3Dnull%3Fvoid%200%3Ae.then%29%7Dfunction%20Bt%28e%29%7Breturn%20k%28e%5Bft%5D%29%7Dfunction%20Gt%28e%29%7Breturn%20Symbol.asyncIterator%26%26k%28e%3D%3Dnull%3Fvoid%200%3Ae%5BSymbol.asyncIterator%5D%29%7Dfunction%20Jt%28e%29%7Breturn%20new%20TypeError%28%22You%20provided%20%22%2B%28e%21%3D%3Dnull%26%26typeof%20e%3D%3D%22object%22%3F%22an%20invalid%20object%22%3A%22%27%22%2Be%2B%22%27%22%29%2B%22%20where%20a%20stream%20was%20expected.%20You%20can%20provide%20an%20Observable%2C%20Promise%2C%20ReadableStream%2C%20Array%2C%20AsyncIterable%2C%20or%20Iterable.%22%29%7Dfunction%20Di%28%29%7Breturn%20typeof%20Symbol%21%3D%22function%22%7C%7C%21Symbol.iterator%3F%22%40%40iterator%22%3ASymbol.iterator%7Dvar%20Xt%3DDi%28%29%3Bfunction%20Zt%28e%29%7Breturn%20k%28e%3D%3Dnull%3Fvoid%200%3Ae%5BXt%5D%29%7Dfunction%20er%28e%29%7Breturn%20ao%28this%2Carguments%2Cfunction%28%29%7Bvar%20r%2Co%2Cn%2Ci%3Breturn%20Ut%28this%2Cfunction%28s%29%7Bswitch%28s.label%29%7Bcase%200%3Ar%3De.getReader%28%29%2Cs.label%3D1%3Bcase%201%3As.trys.push%28%5B1%2C%2C9%2C10%5D%29%2Cs.label%3D2%3Bcase%202%3Areturn%5B4%2Cot%28r.read%28%29%29%5D%3Bcase%203%3Areturn%20o%3Ds.sent%28%29%2Cn%3Do.value%2Ci%3Do.done%2Ci%3F%5B4%2Cot%28void%200%29%5D%3A%5B3%2C5%5D%3Bcase%204%3Areturn%5B2%2Cs.sent%28%29%5D%3Bcase%205%3Areturn%5B4%2Cot%28n%29%5D%3Bcase%206%3Areturn%5B4%2Cs.sent%28%29%5D%3Bcase%207%3Areturn%20s.sent%28%29%2C%5B3%2C2%5D%3Bcase%208%3Areturn%5B3%2C10%5D%3Bcase%209%3Areturn%20r.releaseLock%28%29%2C%5B7%5D%3Bcase%2010%3Areturn%5B2%5D%7D%7D%29%7D%29%7Dfunction%20tr%28e%29%7Breturn%20k%28e%3D%3Dnull%3Fvoid%200%3Ae.getReader%29%7Dfunction%20N%28e%29%7Bif%28e%20instanceof%20j%29return%20e%3Bif%28e%21%3Dnull%29%7Bif%28Bt%28e%29%29return%20Ni%28e%29%3Bif%28dt%28e%29%29return%20Vi%28e%29%3Bif%28Yt%28e%29%29return%20zi%28e%29%3Bif%28Gt%28e%29%29return%20Eo%28e%29%3Bif%28Zt%28e%29%29return%20qi%28e%29%3Bif%28tr%28e%29%29return%20Ki%28e%29%7Dthrow%20Jt%28e%29%7Dfunction%20Ni%28e%29%7Breturn%20new%20j%28function%28t%29%7Bvar%20r%3De%5Bft%5D%28%29%3Bif%28k%28r.subscribe%29%29return%20r.subscribe%28t%29%3Bthrow%20new%20TypeError%28%22Provided%20object%20does%20not%20correctly%20implement%20Symbol.observable%22%29%7D%29%7Dfunction%20Vi%28e%29%7Breturn%20new%20j%28function%28t%29%7Bfor%28var%20r%3D0%3Br%3Ce.length%26%26%21t.closed%3Br%2B%2B%29t.next%28e%5Br%5D%29%3Bt.complete%28%29%7D%29%7Dfunction%20zi%28e%29%7Breturn%20new%20j%28function%28t%29%7Be.then%28function%28r%29%7Bt.closed%7C%7C%28t.next%28r%29%2Ct.complete%28%29%29%7D%2Cfunction%28r%29%7Breturn%20t.error%28r%29%7D%29.then%28null%2CNt%29%7D%29%7Dfunction%20qi%28e%29%7Breturn%20new%20j%28function%28t%29%7Bvar%20r%2Co%3Btry%7Bfor%28var%20n%3Due%28e%29%2Ci%3Dn.next%28%29%3B%21i.done%3Bi%3Dn.next%28%29%29%7Bvar%20s%3Di.value%3Bif%28t.next%28s%29%2Ct.closed%29return%7D%7Dcatch%28a%29%7Br%3D%7Berror%3Aa%7D%7Dfinally%7Btry%7Bi%26%26%21i.done%26%26%28o%3Dn.return%29%26%26o.call%28n%29%7Dfinally%7Bif%28r%29throw%20r.error%7D%7Dt.complete%28%29%7D%29%7Dfunction%20Eo%28e%29%7Breturn%20new%20j%28function%28t%29%7BQi%28e%2Ct%29.catch%28function%28r%29%7Breturn%20t.error%28r%29%7D%29%7D%29%7Dfunction%20Ki%28e%29%7Breturn%20Eo%28er%28e%29%29%7Dfunction%20Qi%28e%2Ct%29%7Bvar%20r%2Co%2Cn%2Ci%3Breturn%20io%28this%2Cvoid%200%2Cvoid%200%2Cfunction%28%29%7Bvar%20s%2Ca%3Breturn%20Ut%28this%2Cfunction%28c%29%7Bswitch%28c.label%29%7Bcase%200%3Ac.trys.push%28%5B0%2C5%2C6%2C11%5D%29%2Cr%3Dso%28e%29%2Cc.label%3D1%3Bcase%201%3Areturn%5B4%2Cr.next%28%29%5D%3Bcase%202%3Aif%28o%3Dc.sent%28%29%2C%21%21o.done%29return%5B3%2C4%5D%3Bif%28s%3Do.value%2Ct.next%28s%29%2Ct.closed%29return%5B2%5D%3Bc.label%3D3%3Bcase%203%3Areturn%5B3%2C1%5D%3Bcase%204%3Areturn%5B3%2C11%5D%3Bcase%205%3Areturn%20a%3Dc.sent%28%29%2Cn%3D%7Berror%3Aa%7D%2C%5B3%2C11%5D%3Bcase%206%3Areturn%20c.trys.push%28%5B6%2C%2C9%2C10%5D%29%2Co%26%26%21o.done%26%26%28i%3Dr.return%29%3F%5B4%2Ci.call%28r%29%5D%3A%5B3%2C8%5D%3Bcase%207%3Ac.sent%28%29%2Cc.label%3D8%3Bcase%208%3Areturn%5B3%2C10%5D%3Bcase%209%3Aif%28n%29throw%20n.error%3Breturn%5B7%5D%3Bcase%2010%3Areturn%5B7%5D%3Bcase%2011%3Areturn%20t.complete%28%29%2C%5B2%5D%7D%7D%29%7D%29%7Dfunction%20xe%28e%2Ct%2Cr%2Co%2Cn%29%7Bo%3D%3D%3Dvoid%200%26%26%28o%3D0%29%2Cn%3D%3D%3Dvoid%200%26%26%28n%3D%211%29%3Bvar%20i%3Dt.schedule%28function%28%29%7Br%28%29%2Cn%3Fe.add%28this.schedule%28null%2Co%29%29%3Athis.unsubscribe%28%29%7D%2Co%29%3Bif%28e.add%28i%29%2C%21n%29return%20i%7Dfunction%20Oe%28e%2Ct%29%7Breturn%20t%3D%3D%3Dvoid%200%26%26%28t%3D0%29%2Cx%28function%28r%2Co%29%7Br.subscribe%28S%28o%2Cfunction%28n%29%7Breturn%20xe%28o%2Ce%2Cfunction%28%29%7Breturn%20o.next%28n%29%7D%2Ct%29%7D%2Cfunction%28%29%7Breturn%20xe%28o%2Ce%2Cfunction%28%29%7Breturn%20o.complete%28%29%7D%2Ct%29%7D%2Cfunction%28n%29%7Breturn%20xe%28o%2Ce%2Cfunction%28%29%7Breturn%20o.error%28n%29%7D%2Ct%29%7D%29%29%7D%29%7Dfunction%20ze%28e%2Ct%29%7Breturn%20t%3D%3D%3Dvoid%200%26%26%28t%3D0%29%2Cx%28function%28r%2Co%29%7Bo.add%28e.schedule%28function%28%29%7Breturn%20r.subscribe%28o%29%7D%2Ct%29%29%7D%29%7Dfunction%20wo%28e%2Ct%29%7Breturn%20N%28e%29.pipe%28ze%28t%29%2COe%28t%29%29%7Dfunction%20To%28e%2Ct%29%7Breturn%20N%28e%29.pipe%28ze%28t%29%2COe%28t%29%29%7Dfunction%20So%28e%2Ct%29%7Breturn%20new%20j%28function%28r%29%7Bvar%20o%3D0%3Breturn%20t.schedule%28function%28%29%7Bo%3D%3D%3De.length%3Fr.complete%28%29%3A%28r.next%28e%5Bo%2B%2B%5D%29%2Cr.closed%7C%7Cthis.schedule%28%29%29%7D%29%7D%29%7Dfunction%20Oo%28e%2Ct%29%7Breturn%20new%20j%28function%28r%29%7Bvar%20o%3Breturn%20xe%28r%2Ct%2Cfunction%28%29%7Bo%3De%5BXt%5D%28%29%2Cxe%28r%2Ct%2Cfunction%28%29%7Bvar%20n%2Ci%2Cs%3Btry%7Bn%3Do.next%28%29%2Ci%3Dn.value%2Cs%3Dn.done%7Dcatch%28a%29%7Br.error%28a%29%3Breturn%7Ds%3Fr.complete%28%29%3Ar.next%28i%29%7D%2C0%2C%210%29%7D%29%2Cfunction%28%29%7Breturn%20k%28o%3D%3Dnull%3Fvoid%200%3Ao.return%29%26%26o.return%28%29%7D%7D%29%7Dfunction%20rr%28e%2Ct%29%7Bif%28%21e%29throw%20new%20Error%28%22Iterable%20cannot%20be%20null%22%29%3Breturn%20new%20j%28function%28r%29%7Bxe%28r%2Ct%2Cfunction%28%29%7Bvar%20o%3De%5BSymbol.asyncIterator%5D%28%29%3Bxe%28r%2Ct%2Cfunction%28%29%7Bo.next%28%29.then%28function%28n%29%7Bn.done%3Fr.complete%28%29%3Ar.next%28n.value%29%7D%29%7D%2C0%2C%210%29%7D%29%7D%29%7Dfunction%20Mo%28e%2Ct%29%7Breturn%20rr%28er%28e%29%2Ct%29%7Dfunction%20Lo%28e%2Ct%29%7Bif%28e%21%3Dnull%29%7Bif%28Bt%28e%29%29return%20wo%28e%2Ct%29%3Bif%28dt%28e%29%29return%20So%28e%2Ct%29%3Bif%28Yt%28e%29%29return%20To%28e%2Ct%29%3Bif%28Gt%28e%29%29return%20rr%28e%2Ct%29%3Bif%28Zt%28e%29%29return%20Oo%28e%2Ct%29%3Bif%28tr%28e%29%29return%20Mo%28e%2Ct%29%7Dthrow%20Jt%28e%29%7Dfunction%20fe%28e%2Ct%29%7Breturn%20t%3FLo%28e%2Ct%29%3AN%28e%29%7Dfunction%20%24%28%29%7Bfor%28var%20e%3D%5B%5D%2Ct%3D0%3Bt%3Carguments.length%3Bt%2B%2B%29e%5Bt%5D%3Darguments%5Bt%5D%3Bvar%20r%3DAe%28e%29%3Breturn%20fe%28e%2Cr%29%7Dfunction%20Ar%28e%2Ct%29%7Bvar%20r%3Dk%28e%29%3Fe%3Afunction%28%29%7Breturn%20e%7D%2Co%3Dfunction%28n%29%7Breturn%20n.error%28r%28%29%29%7D%3Breturn%20new%20j%28t%3Ffunction%28n%29%7Breturn%20t.schedule%28o%2C0%2Cn%29%7D%3Ao%29%7Dvar%20or%3Dpt%28function%28e%29%7Breturn%20function%28%29%7Be%28this%29%2Cthis.name%3D%22EmptyError%22%2Cthis.message%3D%22no%20elements%20in%20sequence%22%7D%7D%29%3Bfunction%20_o%28e%29%7Breturn%20e%20instanceof%20Date%26%26%21isNaN%28e%29%7Dfunction%20m%28e%2Ct%29%7Breturn%20x%28function%28r%2Co%29%7Bvar%20n%3D0%3Br.subscribe%28S%28o%2Cfunction%28i%29%7Bo.next%28e.call%28t%2Ci%2Cn%2B%2B%29%29%7D%29%29%7D%29%7Dvar%20Yi%3DArray.isArray%3Bfunction%20Bi%28e%2Ct%29%7Breturn%20Yi%28t%29%3Fe.apply%28void%200%2Cz%28%5B%5D%2CV%28t%29%29%29%3Ae%28t%29%7Dfunction%20Xe%28e%29%7Breturn%20m%28function%28t%29%7Breturn%20Bi%28e%2Ct%29%7D%29%7Dvar%20Gi%3DArray.isArray%2CJi%3DObject.getPrototypeOf%2CXi%3DObject.prototype%2CZi%3DObject.keys%3Bfunction%20Ao%28e%29%7Bif%28e.length%3D%3D%3D1%29%7Bvar%20t%3De%5B0%5D%3Bif%28Gi%28t%29%29return%7Bargs%3At%2Ckeys%3Anull%7D%3Bif%28ea%28t%29%29%7Bvar%20r%3DZi%28t%29%3Breturn%7Bargs%3Ar.map%28function%28o%29%7Breturn%20t%5Bo%5D%7D%29%2Ckeys%3Ar%7D%7D%7Dreturn%7Bargs%3Ae%2Ckeys%3Anull%7D%7Dfunction%20ea%28e%29%7Breturn%20e%26%26typeof%20e%3D%3D%22object%22%26%26Ji%28e%29%3D%3D%3DXi%7Dfunction%20Co%28e%2Ct%29%7Breturn%20e.reduce%28function%28r%2Co%2Cn%29%7Breturn%20r%5Bo%5D%3Dt%5Bn%5D%2Cr%7D%2C%7B%7D%29%7Dfunction%20Q%28%29%7Bfor%28var%20e%3D%5B%5D%2Ct%3D0%3Bt%3Carguments.length%3Bt%2B%2B%29e%5Bt%5D%3Darguments%5Bt%5D%3Bvar%20r%3DAe%28e%29%2Co%3DJe%28e%29%2Cn%3DAo%28e%29%2Ci%3Dn.args%2Cs%3Dn.keys%3Bif%28i.length%3D%3D%3D0%29return%20fe%28%5B%5D%2Cr%29%3Bvar%20a%3Dnew%20j%28Cr%28i%2Cr%2Cs%3Ffunction%28c%29%7Breturn%20Co%28s%2Cc%29%7D%3Ace%29%29%3Breturn%20o%3Fa.pipe%28Xe%28o%29%29%3Aa%7Dfunction%20Cr%28e%2Ct%2Cr%29%7Breturn%20r%3D%3D%3Dvoid%200%26%26%28r%3Dce%29%2Cfunction%28o%29%7Bko%28t%2Cfunction%28%29%7Bfor%28var%20n%3De.length%2Ci%3Dnew%20Array%28n%29%2Cs%3Dn%2Ca%3Dn%2Cc%3Dfunction%28l%29%7Bko%28t%2Cfunction%28%29%7Bvar%20f%3Dfe%28e%5Bl%5D%2Ct%29%2Cu%3D%211%3Bf.subscribe%28S%28o%2Cfunction%28h%29%7Bi%5Bl%5D%3Dh%2Cu%7C%7C%28u%3D%210%2Ca--%29%2Ca%7C%7Co.next%28r%28i.slice%28%29%29%29%7D%2Cfunction%28%29%7B--s%7C%7Co.complete%28%29%7D%29%29%7D%2Co%29%7D%2Cp%3D0%3Bp%3Cn%3Bp%2B%2B%29c%28p%29%7D%2Co%29%7D%7Dfunction%20ko%28e%2Ct%2Cr%29%7Be%3Fxe%28r%2Ce%2Ct%29%3At%28%29%7Dfunction%20Ho%28e%2Ct%2Cr%2Co%2Cn%2Ci%2Cs%2Ca%29%7Bvar%20c%3D%5B%5D%2Cp%3D0%2Cl%3D0%2Cf%3D%211%2Cu%3Dfunction%28%29%7Bf%26%26%21c.length%26%26%21p%26%26t.complete%28%29%7D%2Ch%3Dfunction%28A%29%7Breturn%20p%3Co%3Fw%28A%29%3Ac.push%28A%29%7D%2Cw%3Dfunction%28A%29%7Bi%26%26t.next%28A%29%2Cp%2B%2B%3Bvar%20Z%3D%211%3BN%28r%28A%2Cl%2B%2B%29%29.subscribe%28S%28t%2Cfunction%28te%29%7Bn%3D%3Dnull%7C%7Cn%28te%29%2Ci%3Fh%28te%29%3At.next%28te%29%7D%2Cfunction%28%29%7BZ%3D%210%7D%2Cvoid%200%2Cfunction%28%29%7Bif%28Z%29try%7Bp--%3Bfor%28var%20te%3Dfunction%28%29%7Bvar%20J%3Dc.shift%28%29%3Bs%3Fxe%28t%2Cs%2Cfunction%28%29%7Breturn%20w%28J%29%7D%29%3Aw%28J%29%7D%3Bc.length%26%26p%3Co%3B%29te%28%29%3Bu%28%29%7Dcatch%28J%29%7Bt.error%28J%29%7D%7D%29%29%7D%3Breturn%20e.subscribe%28S%28t%2Ch%2Cfunction%28%29%7Bf%3D%210%2Cu%28%29%7D%29%29%2Cfunction%28%29%7Ba%3D%3Dnull%7C%7Ca%28%29%7D%7Dfunction%20re%28e%2Ct%2Cr%29%7Breturn%20r%3D%3D%3Dvoid%200%26%26%28r%3D1/0%29%2Ck%28t%29%3Fre%28function%28o%2Cn%29%7Breturn%20m%28function%28i%2Cs%29%7Breturn%20t%28o%2Ci%2Cn%2Cs%29%7D%29%28N%28e%28o%2Cn%29%29%29%7D%2Cr%29%3A%28typeof%20t%3D%3D%22number%22%26%26%28r%3Dt%29%2Cx%28function%28o%2Cn%29%7Breturn%20Ho%28o%2Cn%2Ce%2Cr%29%7D%29%29%7Dfunction%20ht%28e%29%7Breturn%20e%3D%3D%3Dvoid%200%26%26%28e%3D1/0%29%2Cre%28ce%2Ce%29%7Dfunction%20%24o%28%29%7Breturn%20ht%281%29%7Dfunction%20Fe%28%29%7Bfor%28var%20e%3D%5B%5D%2Ct%3D0%3Bt%3Carguments.length%3Bt%2B%2B%29e%5Bt%5D%3Darguments%5Bt%5D%3Breturn%20%24o%28%29%28fe%28e%2CAe%28e%29%29%29%7Dfunction%20H%28e%29%7Breturn%20new%20j%28function%28t%29%7BN%28e%28%29%29.subscribe%28t%29%7D%29%7Dvar%20ta%3D%5B%22addListener%22%2C%22removeListener%22%5D%2Cra%3D%5B%22addEventListener%22%2C%22removeEventListener%22%5D%2Coa%3D%5B%22on%22%2C%22off%22%5D%3Bfunction%20d%28e%2Ct%2Cr%2Co%29%7Bif%28k%28r%29%26%26%28o%3Dr%2Cr%3Dvoid%200%29%2Co%29return%20d%28e%2Ct%2Cr%29.pipe%28Xe%28o%29%29%3Bvar%20n%3DV%28aa%28e%29%3Fra.map%28function%28a%29%7Breturn%20function%28c%29%7Breturn%20e%5Ba%5D%28t%2Cc%2Cr%29%7D%7D%29%3Ana%28e%29%3Fta.map%28Ro%28e%2Ct%29%29%3Aia%28e%29%3Foa.map%28Ro%28e%2Ct%29%29%3A%5B%5D%2C2%29%2Ci%3Dn%5B0%5D%2Cs%3Dn%5B1%5D%3Bif%28%21i%26%26dt%28e%29%29return%20re%28function%28a%29%7Breturn%20d%28a%2Ct%2Cr%29%7D%29%28N%28e%29%29%3Bif%28%21i%29throw%20new%20TypeError%28%22Invalid%20event%20target%22%29%3Breturn%20new%20j%28function%28a%29%7Bvar%20c%3Dfunction%28%29%7Bfor%28var%20p%3D%5B%5D%2Cl%3D0%3Bl%3Carguments.length%3Bl%2B%2B%29p%5Bl%5D%3Darguments%5Bl%5D%3Breturn%20a.next%281%3Cp.length%3Fp%3Ap%5B0%5D%29%7D%3Breturn%20i%28c%29%2Cfunction%28%29%7Breturn%20s%28c%29%7D%7D%29%7Dfunction%20Ro%28e%2Ct%29%7Breturn%20function%28r%29%7Breturn%20function%28o%29%7Breturn%20e%5Br%5D%28t%2Co%29%7D%7D%7Dfunction%20na%28e%29%7Breturn%20k%28e.addListener%29%26%26k%28e.removeListener%29%7Dfunction%20ia%28e%29%7Breturn%20k%28e.on%29%26%26k%28e.off%29%7Dfunction%20aa%28e%29%7Breturn%20k%28e.addEventListener%29%26%26k%28e.removeEventListener%29%7Dfunction%20nr%28e%2Ct%2Cr%29%7Breturn%20r%3Fnr%28e%2Ct%29.pipe%28Xe%28r%29%29%3Anew%20j%28function%28o%29%7Bvar%20n%3Dfunction%28%29%7Bfor%28var%20s%3D%5B%5D%2Ca%3D0%3Ba%3Carguments.length%3Ba%2B%2B%29s%5Ba%5D%3Darguments%5Ba%5D%3Breturn%20o.next%28s.length%3D%3D%3D1%3Fs%5B0%5D%3As%29%7D%2Ci%3De%28n%29%3Breturn%20k%28t%29%3Ffunction%28%29%7Breturn%20t%28n%2Ci%29%7D%3Avoid%200%7D%29%7Dfunction%20Ze%28e%2Ct%2Cr%29%7Be%3D%3D%3Dvoid%200%26%26%28e%3D0%29%2Cr%3D%3D%3Dvoid%200%26%26%28r%3DLr%29%3Bvar%20o%3D-1%3Breturn%20t%21%3Dnull%26%26%28Kt%28t%29%3Fr%3Dt%3Ao%3Dt%29%2Cnew%20j%28function%28n%29%7Bvar%20i%3D_o%28e%29%3F%2Be-r.now%28%29%3Ae%3Bi%3C0%26%26%28i%3D0%29%3Bvar%20s%3D0%3Breturn%20r.schedule%28function%28%29%7Bn.closed%7C%7C%28n.next%28s%2B%2B%29%2C0%3C%3Do%3Fthis.schedule%28void%200%2Co%29%3An.complete%28%29%29%7D%2Ci%29%7D%29%7Dfunction%20T%28%29%7Bfor%28var%20e%3D%5B%5D%2Ct%3D0%3Bt%3Carguments.length%3Bt%2B%2B%29e%5Bt%5D%3Darguments%5Bt%5D%3Bvar%20r%3DAe%28e%29%2Co%3DQt%28e%2C1/0%29%2Cn%3De%3Breturn%20n.length%3Fn.length%3D%3D%3D1%3FN%28n%5B0%5D%29%3Aht%28o%29%28fe%28n%2Cr%29%29%3AL%7Dvar%20qe%3Dnew%20j%28Se%29%3Bvar%20sa%3DArray.isArray%3Bfunction%20bt%28e%29%7Breturn%20e.length%3D%3D%3D1%26%26sa%28e%5B0%5D%29%3Fe%5B0%5D%3Ae%7Dfunction%20g%28e%2Ct%29%7Breturn%20x%28function%28r%2Co%29%7Bvar%20n%3D0%3Br.subscribe%28S%28o%2Cfunction%28i%29%7Breturn%20e.call%28t%2Ci%2Cn%2B%2B%29%26%26o.next%28i%29%7D%29%29%7D%29%7Dfunction%20Lt%28%29%7Bfor%28var%20e%3D%5B%5D%2Ct%3D0%3Bt%3Carguments.length%3Bt%2B%2B%29e%5Bt%5D%3Darguments%5Bt%5D%3Bvar%20r%3DJe%28e%29%2Co%3Dbt%28e%29%3Breturn%20o.length%3Fnew%20j%28function%28n%29%7Bvar%20i%3Do.map%28function%28%29%7Breturn%5B%5D%7D%29%2Cs%3Do.map%28function%28%29%7Breturn%211%7D%29%3Bn.add%28function%28%29%7Bi%3Ds%3Dnull%7D%29%3Bfor%28var%20a%3Dfunction%28p%29%7BN%28o%5Bp%5D%29.subscribe%28S%28n%2Cfunction%28l%29%7Bif%28i%5Bp%5D.push%28l%29%2Ci.every%28function%28u%29%7Breturn%20u.length%7D%29%29%7Bvar%20f%3Di.map%28function%28u%29%7Breturn%20u.shift%28%29%7D%29%3Bn.next%28r%3Fr.apply%28void%200%2Cz%28%5B%5D%2CV%28f%29%29%29%3Af%29%2Ci.some%28function%28u%2Ch%29%7Breturn%21u.length%26%26s%5Bh%5D%7D%29%26%26n.complete%28%29%7D%7D%2Cfunction%28%29%7Bs%5Bp%5D%3D%210%2C%21i%5Bp%5D.length%26%26n.complete%28%29%7D%29%29%7D%2Cc%3D0%3B%21n.closed%26%26c%3Co.length%3Bc%2B%2B%29a%28c%29%3Breturn%20function%28%29%7Bi%3Ds%3Dnull%7D%7D%29%3AL%7Dfunction%20Po%28e%29%7Breturn%20x%28function%28t%2Cr%29%7Bvar%20o%3D%211%2Cn%3Dnull%2Ci%3Dnull%2Cs%3D%211%2Ca%3Dfunction%28%29%7Bif%28i%3D%3Dnull%7C%7Ci.unsubscribe%28%29%2Ci%3Dnull%2Co%29%7Bo%3D%211%3Bvar%20p%3Dn%3Bn%3Dnull%2Cr.next%28p%29%7Ds%26%26r.complete%28%29%7D%2Cc%3Dfunction%28%29%7Bi%3Dnull%2Cs%26%26r.complete%28%29%7D%3Bt.subscribe%28S%28r%2Cfunction%28p%29%7Bo%3D%210%2Cn%3Dp%2Ci%7C%7CN%28e%28p%29%29.subscribe%28i%3DS%28r%2Ca%2Cc%29%29%7D%2Cfunction%28%29%7Bs%3D%210%2C%28%21o%7C%7C%21i%7C%7Ci.closed%29%26%26r.complete%28%29%7D%29%29%7D%29%7Dfunction%20Me%28e%2Ct%29%7Breturn%20t%3D%3D%3Dvoid%200%26%26%28t%3Die%29%2CPo%28function%28%29%7Breturn%20Ze%28e%2Ct%29%7D%29%7Dfunction%20Ke%28e%2Ct%29%7Breturn%20t%3D%3D%3Dvoid%200%26%26%28t%3Dnull%29%2Ct%3Dt%21%3Dnull%3Ft%3Ae%2Cx%28function%28r%2Co%29%7Bvar%20n%3D%5B%5D%2Ci%3D0%3Br.subscribe%28S%28o%2Cfunction%28s%29%7Bvar%20a%2Cc%2Cp%2Cl%2Cf%3Dnull%3Bi%2B%2B%25t%3D%3D%3D0%26%26n.push%28%5B%5D%29%3Btry%7Bfor%28var%20u%3Due%28n%29%2Ch%3Du.next%28%29%3B%21h.done%3Bh%3Du.next%28%29%29%7Bvar%20w%3Dh.value%3Bw.push%28s%29%2Ce%3C%3Dw.length%26%26%28f%3Df%21%3Dnull%3Ff%3A%5B%5D%2Cf.push%28w%29%29%7D%7Dcatch%28te%29%7Ba%3D%7Berror%3Ate%7D%7Dfinally%7Btry%7Bh%26%26%21h.done%26%26%28c%3Du.return%29%26%26c.call%28u%29%7Dfinally%7Bif%28a%29throw%20a.error%7D%7Dif%28f%29try%7Bfor%28var%20A%3Due%28f%29%2CZ%3DA.next%28%29%3B%21Z.done%3BZ%3DA.next%28%29%29%7Bvar%20w%3DZ.value%3BVe%28n%2Cw%29%2Co.next%28w%29%7D%7Dcatch%28te%29%7Bp%3D%7Berror%3Ate%7D%7Dfinally%7Btry%7BZ%26%26%21Z.done%26%26%28l%3DA.return%29%26%26l.call%28A%29%7Dfinally%7Bif%28p%29throw%20p.error%7D%7D%7D%2Cfunction%28%29%7Bvar%20s%2Ca%3Btry%7Bfor%28var%20c%3Due%28n%29%2Cp%3Dc.next%28%29%3B%21p.done%3Bp%3Dc.next%28%29%29%7Bvar%20l%3Dp.value%3Bo.next%28l%29%7D%7Dcatch%28f%29%7Bs%3D%7Berror%3Af%7D%7Dfinally%7Btry%7Bp%26%26%21p.done%26%26%28a%3Dc.return%29%26%26a.call%28c%29%7Dfinally%7Bif%28s%29throw%20s.error%7D%7Do.complete%28%29%7D%2Cvoid%200%2Cfunction%28%29%7Bn%3Dnull%7D%29%29%7D%29%7Dfunction%20he%28e%29%7Breturn%20x%28function%28t%2Cr%29%7Bvar%20o%3Dnull%2Cn%3D%211%2Ci%3Bo%3Dt.subscribe%28S%28r%2Cvoid%200%2Cvoid%200%2Cfunction%28s%29%7Bi%3DN%28e%28s%2Che%28e%29%28t%29%29%29%2Co%3F%28o.unsubscribe%28%29%2Co%3Dnull%2Ci.subscribe%28r%29%29%3An%3D%210%7D%29%29%2Cn%26%26%28o.unsubscribe%28%29%2Co%3Dnull%2Ci.subscribe%28r%29%29%7D%29%7Dfunction%20Io%28e%2Ct%2Cr%2Co%2Cn%29%7Breturn%20function%28i%2Cs%29%7Bvar%20a%3Dr%2Cc%3Dt%2Cp%3D0%3Bi.subscribe%28S%28s%2Cfunction%28l%29%7Bvar%20f%3Dp%2B%2B%3Bc%3Da%3Fe%28c%2Cl%2Cf%29%3A%28a%3D%210%2Cl%29%2Co%26%26s.next%28c%29%7D%2Cn%26%26function%28%29%7Ba%26%26s.next%28c%29%2Cs.complete%28%29%7D%29%29%7D%7Dfunction%20kr%28%29%7Bfor%28var%20e%3D%5B%5D%2Ct%3D0%3Bt%3Carguments.length%3Bt%2B%2B%29e%5Bt%5D%3Darguments%5Bt%5D%3Bvar%20r%3DJe%28e%29%3Breturn%20r%3Fuo%28kr.apply%28void%200%2Cz%28%5B%5D%2CV%28e%29%29%29%2CXe%28r%29%29%3Ax%28function%28o%2Cn%29%7BCr%28z%28%5Bo%5D%2CV%28bt%28e%29%29%29%29%28n%29%7D%29%7Dfunction%20je%28%29%7Bfor%28var%20e%3D%5B%5D%2Ct%3D0%3Bt%3Carguments.length%3Bt%2B%2B%29e%5Bt%5D%3Darguments%5Bt%5D%3Breturn%20kr.apply%28void%200%2Cz%28%5B%5D%2CV%28e%29%29%29%7Dfunction%20be%28e%2Ct%29%7Breturn%20t%3D%3D%3Dvoid%200%26%26%28t%3Die%29%2Cx%28function%28r%2Co%29%7Bvar%20n%3Dnull%2Ci%3Dnull%2Cs%3Dnull%2Ca%3Dfunction%28%29%7Bif%28n%29%7Bn.unsubscribe%28%29%2Cn%3Dnull%3Bvar%20p%3Di%3Bi%3Dnull%2Co.next%28p%29%7D%7D%3Bfunction%20c%28%29%7Bvar%20p%3Ds%2Be%2Cl%3Dt.now%28%29%3Bif%28l%3Cp%29%7Bn%3Dthis.schedule%28void%200%2Cp-l%29%2Co.add%28n%29%3Breturn%7Da%28%29%7Dr.subscribe%28S%28o%2Cfunction%28p%29%7Bi%3Dp%2Cs%3Dt.now%28%29%2Cn%7C%7C%28n%3Dt.schedule%28c%2Ce%29%2Co.add%28n%29%29%7D%2Cfunction%28%29%7Ba%28%29%2Co.complete%28%29%7D%2Cvoid%200%2Cfunction%28%29%7Bi%3Dn%3Dnull%7D%29%29%7D%29%7Dfunction%20Qe%28e%29%7Breturn%20x%28function%28t%2Cr%29%7Bvar%20o%3D%211%3Bt.subscribe%28S%28r%2Cfunction%28n%29%7Bo%3D%210%2Cr.next%28n%29%7D%2Cfunction%28%29%7Bo%7C%7Cr.next%28e%29%2Cr.complete%28%29%7D%29%29%7D%29%7Dfunction%20ye%28e%29%7Breturn%20e%3C%3D0%3Ffunction%28%29%7Breturn%20L%7D%3Ax%28function%28t%2Cr%29%7Bvar%20o%3D0%3Bt.subscribe%28S%28r%2Cfunction%28n%29%7B%2B%2Bo%3C%3De%26%26%28r.next%28n%29%2Ce%3C%3Do%26%26r.complete%28%29%29%7D%29%29%7D%29%7Dfunction%20ee%28%29%7Breturn%20x%28function%28e%2Ct%29%7Be.subscribe%28S%28t%2CSe%29%29%7D%29%7Dfunction%20Fo%28e%29%7Breturn%20m%28function%28%29%7Breturn%20e%7D%29%7Dfunction%20Hr%28e%2Ct%29%7Breturn%20t%3Ffunction%28r%29%7Breturn%20Fe%28t.pipe%28ye%281%29%2Cee%28%29%29%2Cr.pipe%28Hr%28e%29%29%29%7D%3Are%28function%28r%2Co%29%7Breturn%20N%28e%28r%2Co%29%29.pipe%28ye%281%29%2CFo%28r%29%29%7D%29%7Dfunction%20Ye%28e%2Ct%29%7Bt%3D%3D%3Dvoid%200%26%26%28t%3Die%29%3Bvar%20r%3DZe%28e%2Ct%29%3Breturn%20Hr%28function%28%29%7Breturn%20r%7D%29%7Dfunction%20Y%28e%2Ct%29%7Breturn%20t%3D%3D%3Dvoid%200%26%26%28t%3Dce%29%2Ce%3De%21%3Dnull%3Fe%3Aca%2Cx%28function%28r%2Co%29%7Bvar%20n%2Ci%3D%210%3Br.subscribe%28S%28o%2Cfunction%28s%29%7Bvar%20a%3Dt%28s%29%3B%28i%7C%7C%21e%28n%2Ca%29%29%26%26%28i%3D%211%2Cn%3Da%2Co.next%28s%29%29%7D%29%29%7D%29%7Dfunction%20ca%28e%2Ct%29%7Breturn%20e%3D%3D%3Dt%7Dfunction%20X%28e%2Ct%29%7Breturn%20Y%28function%28r%2Co%29%7Breturn%20t%3Ft%28r%5Be%5D%2Co%5Be%5D%29%3Ar%5Be%5D%3D%3D%3Do%5Be%5D%7D%29%7Dfunction%20jo%28e%29%7Breturn%20e%3D%3D%3Dvoid%200%26%26%28e%3Dpa%29%2Cx%28function%28t%2Cr%29%7Bvar%20o%3D%211%3Bt.subscribe%28S%28r%2Cfunction%28n%29%7Bo%3D%210%2Cr.next%28n%29%7D%2Cfunction%28%29%7Breturn%20o%3Fr.complete%28%29%3Ar.error%28e%28%29%29%7D%29%29%7D%29%7Dfunction%20pa%28%29%7Breturn%20new%20or%7Dfunction%20oe%28%29%7Bfor%28var%20e%3D%5B%5D%2Ct%3D0%3Bt%3Carguments.length%3Bt%2B%2B%29e%5Bt%5D%3Darguments%5Bt%5D%3Breturn%20function%28r%29%7Breturn%20Fe%28r%2C%24.apply%28void%200%2Cz%28%5B%5D%2CV%28e%29%29%29%29%7D%7Dfunction%20_%28e%29%7Breturn%20x%28function%28t%2Cr%29%7Btry%7Bt.subscribe%28r%29%7Dfinally%7Br.add%28e%29%7D%7D%29%7Dfunction%20He%28e%2Ct%29%7Bvar%20r%3Darguments.length%3E%3D2%3Breturn%20function%28o%29%7Breturn%20o.pipe%28e%3Fg%28function%28n%2Ci%29%7Breturn%20e%28n%2Ci%2Co%29%7D%29%3Ace%2Cye%281%29%2Cr%3FQe%28t%29%3Ajo%28function%28%29%7Breturn%20new%20or%7D%29%29%7D%7Dfunction%20%24r%28e%29%7Breturn%20e%3C%3D0%3Ffunction%28%29%7Breturn%20L%7D%3Ax%28function%28t%2Cr%29%7Bvar%20o%3D%5B%5D%3Bt.subscribe%28S%28r%2Cfunction%28n%29%7Bo.push%28n%29%2Ce%3Co.length%26%26o.shift%28%29%7D%2Cfunction%28%29%7Bvar%20n%2Ci%3Btry%7Bfor%28var%20s%3Due%28o%29%2Ca%3Ds.next%28%29%3B%21a.done%3Ba%3Ds.next%28%29%29%7Bvar%20c%3Da.value%3Br.next%28c%29%7D%7Dcatch%28p%29%7Bn%3D%7Berror%3Ap%7D%7Dfinally%7Btry%7Ba%26%26%21a.done%26%26%28i%3Ds.return%29%26%26i.call%28s%29%7Dfinally%7Bif%28n%29throw%20n.error%7D%7Dr.complete%28%29%7D%2Cvoid%200%2Cfunction%28%29%7Bo%3Dnull%7D%29%29%7D%29%7Dfunction%20Uo%28%29%7Bfor%28var%20e%3D%5B%5D%2Ct%3D0%3Bt%3Carguments.length%3Bt%2B%2B%29e%5Bt%5D%3Darguments%5Bt%5D%3Bvar%20r%3DAe%28e%29%2Co%3DQt%28e%2C1/0%29%3Breturn%20e%3Dbt%28e%29%2Cx%28function%28n%2Ci%29%7Bht%28o%29%28fe%28z%28%5Bn%5D%2CV%28e%29%29%2Cr%29%29.subscribe%28i%29%7D%29%7Dfunction%20%24e%28%29%7Bfor%28var%20e%3D%5B%5D%2Ct%3D0%3Bt%3Carguments.length%3Bt%2B%2B%29e%5Bt%5D%3Darguments%5Bt%5D%3Breturn%20Uo.apply%28void%200%2Cz%28%5B%5D%2CV%28e%29%29%29%7Dfunction%20at%28e%29%7Bvar%20t%2Cr%3D1/0%2Co%3Breturn%20e%21%3Dnull%26%26%28typeof%20e%3D%3D%22object%22%3F%28t%3De.count%2Cr%3Dt%3D%3D%3Dvoid%200%3F1/0%3At%2Co%3De.delay%29%3Ar%3De%29%2Cr%3C%3D0%3Ffunction%28%29%7Breturn%20L%7D%3Ax%28function%28n%2Ci%29%7Bvar%20s%3D0%2Ca%2Cc%3Dfunction%28%29%7Bif%28a%3D%3Dnull%7C%7Ca.unsubscribe%28%29%2Ca%3Dnull%2Co%21%3Dnull%29%7Bvar%20l%3Dtypeof%20o%3D%3D%22number%22%3FZe%28o%29%3AN%28o%28s%29%29%2Cf%3DS%28i%2Cfunction%28%29%7Bf.unsubscribe%28%29%2Cp%28%29%7D%29%3Bl.subscribe%28f%29%7Delse%20p%28%29%7D%2Cp%3Dfunction%28%29%7Bvar%20l%3D%211%3Ba%3Dn.subscribe%28S%28i%2Cvoid%200%2Cfunction%28%29%7B%2B%2Bs%3Cr%3Fa%3Fc%28%29%3Al%3D%210%3Ai.complete%28%29%7D%29%29%2Cl%26%26c%28%29%7D%3Bp%28%29%7D%29%7Dfunction%20Rr%28e%2Ct%29%7Breturn%20x%28Io%28e%2Ct%2Carguments.length%3E%3D2%2C%210%29%29%7Dfunction%20le%28e%29%7Be%3D%3D%3Dvoid%200%26%26%28e%3D%7B%7D%29%3Bvar%20t%3De.connector%2Cr%3Dt%3D%3D%3Dvoid%200%3Ffunction%28%29%7Breturn%20new%20v%7D%3At%2Co%3De.resetOnError%2Cn%3Do%3D%3D%3Dvoid%200%3F%210%3Ao%2Ci%3De.resetOnComplete%2Cs%3Di%3D%3D%3Dvoid%200%3F%210%3Ai%2Ca%3De.resetOnRefCountZero%2Cc%3Da%3D%3D%3Dvoid%200%3F%210%3Aa%3Breturn%20function%28p%29%7Bvar%20l%2Cf%2Cu%2Ch%3D0%2Cw%3D%211%2CA%3D%211%2CZ%3Dfunction%28%29%7Bf%3D%3Dnull%7C%7Cf.unsubscribe%28%29%2Cf%3Dvoid%200%7D%2Cte%3Dfunction%28%29%7BZ%28%29%2Cl%3Du%3Dvoid%200%2Cw%3DA%3D%211%7D%2CJ%3Dfunction%28%29%7Bvar%20C%3Dl%3Bte%28%29%2CC%3D%3Dnull%7C%7CC.unsubscribe%28%29%7D%3Breturn%20x%28function%28C%2Cct%29%7Bh%2B%2B%2C%21A%26%26%21w%26%26Z%28%29%3Bvar%20Ne%3Du%3Du%21%3Dnull%3Fu%3Ar%28%29%3Bct.add%28function%28%29%7Bh--%2Ch%3D%3D%3D0%26%26%21A%26%26%21w%26%26%28f%3DPr%28J%2Cc%29%29%7D%29%2CNe.subscribe%28ct%29%2C%21l%26%26h%3E0%26%26%28l%3Dnew%20it%28%7Bnext%3Afunction%28Pe%29%7Breturn%20Ne.next%28Pe%29%7D%2Cerror%3Afunction%28Pe%29%7BA%3D%210%2CZ%28%29%2Cf%3DPr%28te%2Cn%2CPe%29%2CNe.error%28Pe%29%7D%2Ccomplete%3Afunction%28%29%7Bw%3D%210%2CZ%28%29%2Cf%3DPr%28te%2Cs%29%2CNe.complete%28%29%7D%7D%29%2CN%28C%29.subscribe%28l%29%29%7D%29%28p%29%7D%7Dfunction%20Pr%28e%2Ct%29%7Bfor%28var%20r%3D%5B%5D%2Co%3D2%3Bo%3Carguments.length%3Bo%2B%2B%29r%5Bo-2%5D%3Darguments%5Bo%5D%3Bif%28t%3D%3D%3D%210%29%7Be%28%29%3Breturn%7Dif%28t%21%3D%3D%211%29%7Bvar%20n%3Dnew%20it%28%7Bnext%3Afunction%28%29%7Bn.unsubscribe%28%29%2Ce%28%29%7D%7D%29%3Breturn%20N%28t.apply%28void%200%2Cz%28%5B%5D%2CV%28r%29%29%29%29.subscribe%28n%29%7D%7Dfunction%20B%28e%2Ct%2Cr%29%7Bvar%20o%2Cn%2Ci%2Cs%2Ca%3D%211%3Breturn%20e%26%26typeof%20e%3D%3D%22object%22%3F%28o%3De.bufferSize%2Cs%3Do%3D%3D%3Dvoid%200%3F1/0%3Ao%2Cn%3De.windowTime%2Ct%3Dn%3D%3D%3Dvoid%200%3F1/0%3An%2Ci%3De.refCount%2Ca%3Di%3D%3D%3Dvoid%200%3F%211%3Ai%2Cr%3De.scheduler%29%3As%3De%21%3Dnull%3Fe%3A1/0%2Cle%28%7Bconnector%3Afunction%28%29%7Breturn%20new%20Ot%28s%2Ct%2Cr%29%7D%2CresetOnError%3A%210%2CresetOnComplete%3A%211%2CresetOnRefCountZero%3Aa%7D%29%7Dfunction%20Le%28e%29%7Breturn%20g%28function%28t%2Cr%29%7Breturn%20e%3C%3Dr%7D%29%7Dfunction%20Ir%28e%29%7Breturn%20x%28function%28t%2Cr%29%7Bvar%20o%3D%211%2Cn%3DS%28r%2Cfunction%28%29%7Bn%3D%3Dnull%7C%7Cn.unsubscribe%28%29%2Co%3D%210%7D%2CSe%29%3BN%28e%29.subscribe%28n%29%2Ct.subscribe%28S%28r%2Cfunction%28i%29%7Breturn%20o%26%26r.next%28i%29%7D%29%29%7D%29%7Dfunction%20q%28%29%7Bfor%28var%20e%3D%5B%5D%2Ct%3D0%3Bt%3Carguments.length%3Bt%2B%2B%29e%5Bt%5D%3Darguments%5Bt%5D%3Bvar%20r%3DAe%28e%29%3Breturn%20x%28function%28o%2Cn%29%7B%28r%3FFe%28e%2Co%2Cr%29%3AFe%28e%2Co%29%29.subscribe%28n%29%7D%29%7Dfunction%20b%28e%2Ct%29%7Breturn%20x%28function%28r%2Co%29%7Bvar%20n%3Dnull%2Ci%3D0%2Cs%3D%211%2Ca%3Dfunction%28%29%7Breturn%20s%26%26%21n%26%26o.complete%28%29%7D%3Br.subscribe%28S%28o%2Cfunction%28c%29%7Bn%3D%3Dnull%7C%7Cn.unsubscribe%28%29%3Bvar%20p%3D0%2Cl%3Di%2B%2B%3BN%28e%28c%2Cl%29%29.subscribe%28n%3DS%28o%2Cfunction%28f%29%7Breturn%20o.next%28t%3Ft%28c%2Cf%2Cl%2Cp%2B%2B%29%3Af%29%7D%2Cfunction%28%29%7Bn%3Dnull%2Ca%28%29%7D%29%29%7D%2Cfunction%28%29%7Bs%3D%210%2Ca%28%29%7D%29%29%7D%29%7Dfunction%20U%28e%29%7Breturn%20x%28function%28t%2Cr%29%7BN%28e%29.subscribe%28S%28r%2Cfunction%28%29%7Breturn%20r.complete%28%29%7D%2CSe%29%29%2C%21r.closed%26%26t.subscribe%28r%29%7D%29%7Dfunction%20Fr%28e%2Ct%29%7Breturn%20t%3D%3D%3Dvoid%200%26%26%28t%3D%211%29%2Cx%28function%28r%2Co%29%7Bvar%20n%3D0%3Br.subscribe%28S%28o%2Cfunction%28i%29%7Bvar%20s%3De%28i%2Cn%2B%2B%29%3B%28s%7C%7Ct%29%26%26o.next%28i%29%2C%21s%26%26o.complete%28%29%7D%29%29%7D%29%7Dfunction%20y%28e%2Ct%2Cr%29%7Bvar%20o%3Dk%28e%29%7C%7Ct%7C%7Cr%3F%7Bnext%3Ae%2Cerror%3At%2Ccomplete%3Ar%7D%3Ae%3Breturn%20o%3Fx%28function%28n%2Ci%29%7Bvar%20s%3B%28s%3Do.subscribe%29%3D%3D%3Dnull%7C%7Cs%3D%3D%3Dvoid%200%7C%7Cs.call%28o%29%3Bvar%20a%3D%210%3Bn.subscribe%28S%28i%2Cfunction%28c%29%7Bvar%20p%3B%28p%3Do.next%29%3D%3D%3Dnull%7C%7Cp%3D%3D%3Dvoid%200%7C%7Cp.call%28o%2Cc%29%2Ci.next%28c%29%7D%2Cfunction%28%29%7Bvar%20c%3Ba%3D%211%2C%28c%3Do.complete%29%3D%3D%3Dnull%7C%7Cc%3D%3D%3Dvoid%200%7C%7Cc.call%28o%29%2Ci.complete%28%29%7D%2Cfunction%28c%29%7Bvar%20p%3Ba%3D%211%2C%28p%3Do.error%29%3D%3D%3Dnull%7C%7Cp%3D%3D%3Dvoid%200%7C%7Cp.call%28o%2Cc%29%2Ci.error%28c%29%7D%2Cfunction%28%29%7Bvar%20c%2Cp%3Ba%26%26%28%28c%3Do.unsubscribe%29%3D%3D%3Dnull%7C%7Cc%3D%3D%3Dvoid%200%7C%7Cc.call%28o%29%29%2C%28p%3Do.finalize%29%3D%3D%3Dnull%7C%7Cp%3D%3D%3Dvoid%200%7C%7Cp.call%28o%29%7D%29%29%7D%29%3Ace%7Dfunction%20Wo%28e%2Ct%29%7Breturn%20x%28function%28r%2Co%29%7Bvar%20n%3Dt%21%3Dnull%3Ft%3A%7B%7D%2Ci%3Dn.leading%2Cs%3Di%3D%3D%3Dvoid%200%3F%210%3Ai%2Ca%3Dn.trailing%2Cc%3Da%3D%3D%3Dvoid%200%3F%211%3Aa%2Cp%3D%211%2Cl%3Dnull%2Cf%3Dnull%2Cu%3D%211%2Ch%3Dfunction%28%29%7Bf%3D%3Dnull%7C%7Cf.unsubscribe%28%29%2Cf%3Dnull%2Cc%26%26%28Z%28%29%2Cu%26%26o.complete%28%29%29%7D%2Cw%3Dfunction%28%29%7Bf%3Dnull%2Cu%26%26o.complete%28%29%7D%2CA%3Dfunction%28te%29%7Breturn%20f%3DN%28e%28te%29%29.subscribe%28S%28o%2Ch%2Cw%29%29%7D%2CZ%3Dfunction%28%29%7Bif%28p%29%7Bp%3D%211%3Bvar%20te%3Dl%3Bl%3Dnull%2Co.next%28te%29%2C%21u%26%26A%28te%29%7D%7D%3Br.subscribe%28S%28o%2Cfunction%28te%29%7Bp%3D%210%2Cl%3Dte%2C%21%28f%26%26%21f.closed%29%26%26%28s%3FZ%28%29%3AA%28te%29%29%7D%2Cfunction%28%29%7Bu%3D%210%2C%21%28c%26%26p%26%26f%26%26%21f.closed%29%26%26o.complete%28%29%7D%29%29%7D%29%7Dfunction%20_t%28e%2Ct%2Cr%29%7Bt%3D%3D%3Dvoid%200%26%26%28t%3Die%29%3Bvar%20o%3DZe%28e%2Ct%29%3Breturn%20Wo%28function%28%29%7Breturn%20o%7D%2Cr%29%7Dfunction%20ae%28%29%7Bfor%28var%20e%3D%5B%5D%2Ct%3D0%3Bt%3Carguments.length%3Bt%2B%2B%29e%5Bt%5D%3Darguments%5Bt%5D%3Bvar%20r%3DJe%28e%29%3Breturn%20x%28function%28o%2Cn%29%7Bfor%28var%20i%3De.length%2Cs%3Dnew%20Array%28i%29%2Ca%3De.map%28function%28%29%7Breturn%211%7D%29%2Cc%3D%211%2Cp%3Dfunction%28f%29%7BN%28e%5Bf%5D%29.subscribe%28S%28n%2Cfunction%28u%29%7Bs%5Bf%5D%3Du%2C%21c%26%26%21a%5Bf%5D%26%26%28a%5Bf%5D%3D%210%2C%28c%3Da.every%28ce%29%29%26%26%28a%3Dnull%29%29%7D%2CSe%29%29%7D%2Cl%3D0%3Bl%3Ci%3Bl%2B%2B%29p%28l%29%3Bo.subscribe%28S%28n%2Cfunction%28f%29%7Bif%28c%29%7Bvar%20u%3Dz%28%5Bf%5D%2CV%28s%29%29%3Bn.next%28r%3Fr.apply%28void%200%2Cz%28%5B%5D%2CV%28u%29%29%29%3Au%29%7D%7D%29%29%7D%29%7Dfunction%20Do%28%29%7Bfor%28var%20e%3D%5B%5D%2Ct%3D0%3Bt%3Carguments.length%3Bt%2B%2B%29e%5Bt%5D%3Darguments%5Bt%5D%3Breturn%20x%28function%28r%2Co%29%7BLt.apply%28void%200%2Cz%28%5Br%5D%2CV%28e%29%29%29.subscribe%28o%29%7D%29%7Dfunction%20jr%28%29%7Bfor%28var%20e%3D%5B%5D%2Ct%3D0%3Bt%3Carguments.length%3Bt%2B%2B%29e%5Bt%5D%3Darguments%5Bt%5D%3Breturn%20Do.apply%28void%200%2Cz%28%5B%5D%2CV%28e%29%29%29%7Dfunction%20No%28%29%7Blet%20e%3Dnew%20Ot%281%29%3Breturn%20d%28document%2C%22DOMContentLoaded%22%2C%7Bonce%3A%210%7D%29.subscribe%28%28%29%3D%3Ee.next%28document%29%29%2Ce%7Dfunction%20R%28e%2Ct%3Ddocument%29%7Breturn%20Array.from%28t.querySelectorAll%28e%29%29%7Dfunction%20P%28e%2Ct%3Ddocument%29%7Blet%20r%3Dme%28e%2Ct%29%3Bif%28typeof%20r%3D%3D%22undefined%22%29throw%20new%20ReferenceError%28%60Missing%20element%3A%20expected%20%22%24%7Be%7D%22%20to%20be%20present%60%29%3Breturn%20r%7Dfunction%20me%28e%2Ct%3Ddocument%29%7Breturn%20t.querySelector%28e%29%7C%7Cvoid%200%7Dfunction%20Re%28%29%7Bvar%20e%2Ct%2Cr%2Co%3Breturn%28o%3D%28r%3D%28t%3D%28e%3Ddocument.activeElement%29%3D%3Dnull%3Fvoid%200%3Ae.shadowRoot%29%3D%3Dnull%3Fvoid%200%3At.activeElement%29%21%3Dnull%3Fr%3Adocument.activeElement%29%21%3Dnull%3Fo%3Avoid%200%7Dvar%20la%3DT%28d%28document.body%2C%22focusin%22%29%2Cd%28document.body%2C%22focusout%22%29%29.pipe%28be%281%29%2Cq%28void%200%29%2Cm%28%28%29%3D%3ERe%28%29%7C%7Cdocument.body%29%2CB%281%29%29%3Bfunction%20vt%28e%29%7Breturn%20la.pipe%28m%28t%3D%3Ee.contains%28t%29%29%2CY%28%29%29%7Dfunction%20Vo%28e%2Ct%29%7Breturn%20T%28d%28e%2C%22mouseenter%22%29.pipe%28m%28%28%29%3D%3E%210%29%29%2Cd%28e%2C%22mouseleave%22%29.pipe%28m%28%28%29%3D%3E%211%29%29%29.pipe%28t%3Fbe%28t%29%3Ace%2Cq%28%211%29%29%7Dfunction%20Ue%28e%29%7Breturn%7Bx%3Ae.offsetLeft%2Cy%3Ae.offsetTop%7D%7Dfunction%20zo%28e%29%7Breturn%20T%28d%28window%2C%22load%22%29%2Cd%28window%2C%22resize%22%29%29.pipe%28Me%280%2Cde%29%2Cm%28%28%29%3D%3EUe%28e%29%29%2Cq%28Ue%28e%29%29%29%7Dfunction%20ir%28e%29%7Breturn%7Bx%3Ae.scrollLeft%2Cy%3Ae.scrollTop%7D%7Dfunction%20et%28e%29%7Breturn%20T%28d%28e%2C%22scroll%22%29%2Cd%28window%2C%22resize%22%29%29.pipe%28Me%280%2Cde%29%2Cm%28%28%29%3D%3Eir%28e%29%29%2Cq%28ir%28e%29%29%29%7Dfunction%20qo%28e%2Ct%29%7Bif%28typeof%20t%3D%3D%22string%22%7C%7Ctypeof%20t%3D%3D%22number%22%29e.innerHTML%2B%3Dt.toString%28%29%3Belse%20if%28t%20instanceof%20Node%29e.appendChild%28t%29%3Belse%20if%28Array.isArray%28t%29%29for%28let%20r%20of%20t%29qo%28e%2Cr%29%7Dfunction%20E%28e%2Ct%2C...r%29%7Blet%20o%3Ddocument.createElement%28e%29%3Bif%28t%29for%28let%20n%20of%20Object.keys%28t%29%29typeof%20t%5Bn%5D%21%3D%22undefined%22%26%26%28typeof%20t%5Bn%5D%21%3D%22boolean%22%3Fo.setAttribute%28n%2Ct%5Bn%5D%29%3Ao.setAttribute%28n%2C%22%22%29%29%3Bfor%28let%20n%20of%20r%29qo%28o%2Cn%29%3Breturn%20o%7Dfunction%20ar%28e%29%7Bif%28e%3E999%29%7Blet%20t%3D%2B%28%28e-950%29%251e3%3E99%29%3Breturn%60%24%7B%28%28e%2B1e-6%29/1e3%29.toFixed%28t%29%7Dk%60%7Delse%20return%20e.toString%28%29%7Dfunction%20gt%28e%29%7Blet%20t%3DE%28%22script%22%2C%7Bsrc%3Ae%7D%29%3Breturn%20H%28%28%29%3D%3E%28document.head.appendChild%28t%29%2CT%28d%28t%2C%22load%22%29%2Cd%28t%2C%22error%22%29.pipe%28b%28%28%29%3D%3EAr%28%28%29%3D%3Enew%20ReferenceError%28%60Invalid%20script%3A%20%24%7Be%7D%60%29%29%29%29%29.pipe%28m%28%28%29%3D%3E%7B%7D%29%2C_%28%28%29%3D%3Edocument.head.removeChild%28t%29%29%2Cye%281%29%29%29%29%7Dvar%20Ko%3Dnew%20v%2Cma%3DH%28%28%29%3D%3Etypeof%20ResizeObserver%3D%3D%22undefined%22%3Fgt%28%22https%3A//unpkg.com/resize-observer-polyfill%22%29%3A%24%28void%200%29%29.pipe%28m%28%28%29%3D%3Enew%20ResizeObserver%28e%3D%3E%7Bfor%28let%20t%20of%20e%29Ko.next%28t%29%7D%29%29%2Cb%28e%3D%3ET%28qe%2C%24%28e%29%29.pipe%28_%28%28%29%3D%3Ee.disconnect%28%29%29%29%29%2CB%281%29%29%3Bfunction%20pe%28e%29%7Breturn%7Bwidth%3Ae.offsetWidth%2Cheight%3Ae.offsetHeight%7D%7Dfunction%20Ee%28e%29%7Breturn%20ma.pipe%28y%28t%3D%3Et.observe%28e%29%29%2Cb%28t%3D%3EKo.pipe%28g%28%28%7Btarget%3Ar%7D%29%3D%3Er%3D%3D%3De%29%2C_%28%28%29%3D%3Et.unobserve%28e%29%29%2Cm%28%28%29%3D%3Epe%28e%29%29%29%29%2Cq%28pe%28e%29%29%29%7Dfunction%20xt%28e%29%7Breturn%7Bwidth%3Ae.scrollWidth%2Cheight%3Ae.scrollHeight%7D%7Dfunction%20sr%28e%29%7Blet%20t%3De.parentElement%3Bfor%28%3Bt%26%26%28e.scrollWidth%3C%3Dt.scrollWidth%26%26e.scrollHeight%3C%3Dt.scrollHeight%29%3B%29t%3D%28e%3Dt%29.parentElement%3Breturn%20t%3Fe%3Avoid%200%7Dvar%20Qo%3Dnew%20v%2Cfa%3DH%28%28%29%3D%3E%24%28new%20IntersectionObserver%28e%3D%3E%7Bfor%28let%20t%20of%20e%29Qo.next%28t%29%7D%2C%7Bthreshold%3A0%7D%29%29%29.pipe%28b%28e%3D%3ET%28qe%2C%24%28e%29%29.pipe%28_%28%28%29%3D%3Ee.disconnect%28%29%29%29%29%2CB%281%29%29%3Bfunction%20yt%28e%29%7Breturn%20fa.pipe%28y%28t%3D%3Et.observe%28e%29%29%2Cb%28t%3D%3EQo.pipe%28g%28%28%7Btarget%3Ar%7D%29%3D%3Er%3D%3D%3De%29%2C_%28%28%29%3D%3Et.unobserve%28e%29%29%2Cm%28%28%7BisIntersecting%3Ar%7D%29%3D%3Er%29%29%29%29%7Dfunction%20Yo%28e%2Ct%3D16%29%7Breturn%20et%28e%29.pipe%28m%28%28%7By%3Ar%7D%29%3D%3E%7Blet%20o%3Dpe%28e%29%2Cn%3Dxt%28e%29%3Breturn%20r%3E%3Dn.height-o.height-t%7D%29%2CY%28%29%29%7Dvar%20cr%3D%7Bdrawer%3AP%28%22%5Bdata-md-toggle%3Ddrawer%5D%22%29%2Csearch%3AP%28%22%5Bdata-md-toggle%3Dsearch%5D%22%29%7D%3Bfunction%20Bo%28e%29%7Breturn%20cr%5Be%5D.checked%7Dfunction%20Be%28e%2Ct%29%7Bcr%5Be%5D.checked%21%3D%3Dt%26%26cr%5Be%5D.click%28%29%7Dfunction%20We%28e%29%7Blet%20t%3Dcr%5Be%5D%3Breturn%20d%28t%2C%22change%22%29.pipe%28m%28%28%29%3D%3Et.checked%29%2Cq%28t.checked%29%29%7Dfunction%20ua%28e%2Ct%29%7Bswitch%28e.constructor%29%7Bcase%20HTMLInputElement%3Areturn%20e.type%3D%3D%3D%22radio%22%3F/%5EArrow/.test%28t%29%3A%210%3Bcase%20HTMLSelectElement%3Acase%20HTMLTextAreaElement%3Areturn%210%3Bdefault%3Areturn%20e.isContentEditable%7D%7Dfunction%20da%28%29%7Breturn%20T%28d%28window%2C%22compositionstart%22%29.pipe%28m%28%28%29%3D%3E%210%29%29%2Cd%28window%2C%22compositionend%22%29.pipe%28m%28%28%29%3D%3E%211%29%29%29.pipe%28q%28%211%29%29%7Dfunction%20Go%28%29%7Blet%20e%3Dd%28window%2C%22keydown%22%29.pipe%28g%28t%3D%3E%21%28t.metaKey%7C%7Ct.ctrlKey%29%29%2Cm%28t%3D%3E%28%7Bmode%3ABo%28%22search%22%29%3F%22search%22%3A%22global%22%2Ctype%3At.key%2Cclaim%28%29%7Bt.preventDefault%28%29%2Ct.stopPropagation%28%29%7D%7D%29%29%2Cg%28%28%7Bmode%3At%2Ctype%3Ar%7D%29%3D%3E%7Bif%28t%3D%3D%3D%22global%22%29%7Blet%20o%3DRe%28%29%3Bif%28typeof%20o%21%3D%22undefined%22%29return%21ua%28o%2Cr%29%7Dreturn%210%7D%29%2Cle%28%29%29%3Breturn%20da%28%29.pipe%28b%28t%3D%3Et%3FL%3Ae%29%29%7Dfunction%20ve%28%29%7Breturn%20new%20URL%28location.href%29%7Dfunction%20st%28e%2Ct%3D%211%29%7Bif%28G%28%22navigation.instant%22%29%26%26%21t%29%7Blet%20r%3DE%28%22a%22%2C%7Bhref%3Ae.href%7D%29%3Bdocument.body.appendChild%28r%29%2Cr.click%28%29%2Cr.remove%28%29%7Delse%20location.href%3De.href%7Dfunction%20Jo%28%29%7Breturn%20new%20v%7Dfunction%20Xo%28%29%7Breturn%20location.hash.slice%281%29%7Dfunction%20Zo%28e%29%7Blet%20t%3DE%28%22a%22%2C%7Bhref%3Ae%7D%29%3Bt.addEventListener%28%22click%22%2Cr%3D%3Er.stopPropagation%28%29%29%2Ct.click%28%29%7Dfunction%20ha%28e%29%7Breturn%20T%28d%28window%2C%22hashchange%22%29%2Ce%29.pipe%28m%28Xo%29%2Cq%28Xo%28%29%29%2Cg%28t%3D%3Et.length%3E0%29%2CB%281%29%29%7Dfunction%20en%28e%29%7Breturn%20ha%28e%29.pipe%28m%28t%3D%3Eme%28%60%5Bid%3D%22%24%7Bt%7D%22%5D%60%29%29%2Cg%28t%3D%3Etypeof%20t%21%3D%22undefined%22%29%29%7Dfunction%20At%28e%29%7Blet%20t%3DmatchMedia%28e%29%3Breturn%20nr%28r%3D%3Et.addListener%28%28%29%3D%3Er%28t.matches%29%29%29.pipe%28q%28t.matches%29%29%7Dfunction%20tn%28%29%7Blet%20e%3DmatchMedia%28%22print%22%29%3Breturn%20T%28d%28window%2C%22beforeprint%22%29.pipe%28m%28%28%29%3D%3E%210%29%29%2Cd%28window%2C%22afterprint%22%29.pipe%28m%28%28%29%3D%3E%211%29%29%29.pipe%28q%28e.matches%29%29%7Dfunction%20Ur%28e%2Ct%29%7Breturn%20e.pipe%28b%28r%3D%3Er%3Ft%28%29%3AL%29%29%7Dfunction%20Wr%28e%2Ct%29%7Breturn%20new%20j%28r%3D%3E%7Blet%20o%3Dnew%20XMLHttpRequest%3Breturn%20o.open%28%22GET%22%2C%60%24%7Be%7D%60%29%2Co.responseType%3D%22blob%22%2Co.addEventListener%28%22load%22%2C%28%29%3D%3E%7Bo.status%3E%3D200%26%26o.status%3C300%3F%28r.next%28o.response%29%2Cr.complete%28%29%29%3Ar.error%28new%20Error%28o.statusText%29%29%7D%29%2Co.addEventListener%28%22error%22%2C%28%29%3D%3E%7Br.error%28new%20Error%28%22Network%20error%22%29%29%7D%29%2Co.addEventListener%28%22abort%22%2C%28%29%3D%3E%7Br.complete%28%29%7D%29%2Ctypeof%28t%3D%3Dnull%3Fvoid%200%3At.progress%24%29%21%3D%22undefined%22%26%26%28o.addEventListener%28%22progress%22%2Cn%3D%3E%7Bvar%20i%3Bif%28n.lengthComputable%29t.progress%24.next%28n.loaded/n.total%2A100%29%3Belse%7Blet%20s%3D%28i%3Do.getResponseHeader%28%22Content-Length%22%29%29%21%3Dnull%3Fi%3A0%3Bt.progress%24.next%28n.loaded/%2Bs%2A100%29%7D%7D%29%2Ct.progress%24.next%285%29%29%2Co.send%28%29%2C%28%29%3D%3Eo.abort%28%29%7D%29%7Dfunction%20De%28e%2Ct%29%7Breturn%20Wr%28e%2Ct%29.pipe%28b%28r%3D%3Er.text%28%29%29%2Cm%28r%3D%3EJSON.parse%28r%29%29%2CB%281%29%29%7Dfunction%20rn%28e%2Ct%29%7Blet%20r%3Dnew%20DOMParser%3Breturn%20Wr%28e%2Ct%29.pipe%28b%28o%3D%3Eo.text%28%29%29%2Cm%28o%3D%3Er.parseFromString%28o%2C%22text/html%22%29%29%2CB%281%29%29%7Dfunction%20on%28e%2Ct%29%7Blet%20r%3Dnew%20DOMParser%3Breturn%20Wr%28e%2Ct%29.pipe%28b%28o%3D%3Eo.text%28%29%29%2Cm%28o%3D%3Er.parseFromString%28o%2C%22text/xml%22%29%29%2CB%281%29%29%7Dfunction%20nn%28%29%7Breturn%7Bx%3AMath.max%280%2CscrollX%29%2Cy%3AMath.max%280%2CscrollY%29%7D%7Dfunction%20an%28%29%7Breturn%20T%28d%28window%2C%22scroll%22%2C%7Bpassive%3A%210%7D%29%2Cd%28window%2C%22resize%22%2C%7Bpassive%3A%210%7D%29%29.pipe%28m%28nn%29%2Cq%28nn%28%29%29%29%7Dfunction%20sn%28%29%7Breturn%7Bwidth%3AinnerWidth%2Cheight%3AinnerHeight%7D%7Dfunction%20cn%28%29%7Breturn%20d%28window%2C%22resize%22%2C%7Bpassive%3A%210%7D%29.pipe%28m%28sn%29%2Cq%28sn%28%29%29%29%7Dfunction%20pn%28%29%7Breturn%20Q%28%5Ban%28%29%2Ccn%28%29%5D%29.pipe%28m%28%28%5Be%2Ct%5D%29%3D%3E%28%7Boffset%3Ae%2Csize%3At%7D%29%29%2CB%281%29%29%7Dfunction%20pr%28e%2C%7Bviewport%24%3At%2Cheader%24%3Ar%7D%29%7Blet%20o%3Dt.pipe%28X%28%22size%22%29%29%2Cn%3DQ%28%5Bo%2Cr%5D%29.pipe%28m%28%28%29%3D%3EUe%28e%29%29%29%3Breturn%20Q%28%5Br%2Ct%2Cn%5D%29.pipe%28m%28%28%5B%7Bheight%3Ai%7D%2C%7Boffset%3As%2Csize%3Aa%7D%2C%7Bx%3Ac%2Cy%3Ap%7D%5D%29%3D%3E%28%7Boffset%3A%7Bx%3As.x-c%2Cy%3As.y-p%2Bi%7D%2Csize%3Aa%7D%29%29%29%7Dfunction%20ba%28e%29%7Breturn%20d%28e%2C%22message%22%2Ct%3D%3Et.data%29%7Dfunction%20va%28e%29%7Blet%20t%3Dnew%20v%3Breturn%20t.subscribe%28r%3D%3Ee.postMessage%28r%29%29%2Ct%7Dfunction%20ln%28e%2Ct%3Dnew%20Worker%28e%29%29%7Blet%20r%3Dba%28t%29%2Co%3Dva%28t%29%2Cn%3Dnew%20v%3Bn.subscribe%28o%29%3Blet%20i%3Do.pipe%28ee%28%29%2Coe%28%210%29%29%3Breturn%20n.pipe%28ee%28%29%2C%24e%28r.pipe%28U%28i%29%29%29%2Cle%28%29%29%7Dvar%20ga%3DP%28%22%23__config%22%29%2CEt%3DJSON.parse%28ga.textContent%29%3BEt.base%3D%60%24%7Bnew%20URL%28Et.base%2Cve%28%29%29%7D%60%3Bfunction%20we%28%29%7Breturn%20Et%7Dfunction%20G%28e%29%7Breturn%20Et.features.includes%28e%29%7Dfunction%20ge%28e%2Ct%29%7Breturn%20typeof%20t%21%3D%22undefined%22%3FEt.translations%5Be%5D.replace%28%22%23%22%2Ct.toString%28%29%29%3AEt.translations%5Be%5D%7Dfunction%20Te%28e%2Ct%3Ddocument%29%7Breturn%20P%28%60%5Bdata-md-component%3D%24%7Be%7D%5D%60%2Ct%29%7Dfunction%20ne%28e%2Ct%3Ddocument%29%7Breturn%20R%28%60%5Bdata-md-component%3D%24%7Be%7D%5D%60%2Ct%29%7Dfunction%20xa%28e%29%7Blet%20t%3DP%28%22.md-typeset%20%3E%20%3Afirst-child%22%2Ce%29%3Breturn%20d%28t%2C%22click%22%2C%7Bonce%3A%210%7D%29.pipe%28m%28%28%29%3D%3EP%28%22.md-typeset%22%2Ce%29%29%2Cm%28r%3D%3E%28%7Bhash%3A__md_hash%28r.innerHTML%29%7D%29%29%29%7Dfunction%20mn%28e%29%7Bif%28%21G%28%22announce.dismiss%22%29%7C%7C%21e.childElementCount%29return%20L%3Bif%28%21e.hidden%29%7Blet%20t%3DP%28%22.md-typeset%22%2Ce%29%3B__md_hash%28t.innerHTML%29%3D%3D%3D__md_get%28%22__announce%22%29%26%26%28e.hidden%3D%210%29%7Dreturn%20H%28%28%29%3D%3E%7Blet%20t%3Dnew%20v%3Breturn%20t.subscribe%28%28%7Bhash%3Ar%7D%29%3D%3E%7Be.hidden%3D%210%2C__md_set%28%22__announce%22%2Cr%29%7D%29%2Cxa%28e%29.pipe%28y%28r%3D%3Et.next%28r%29%29%2C_%28%28%29%3D%3Et.complete%28%29%29%2Cm%28r%3D%3EF%28%7Bref%3Ae%7D%2Cr%29%29%29%7D%29%7Dfunction%20ya%28e%2C%7Btarget%24%3At%7D%29%7Breturn%20t.pipe%28m%28r%3D%3E%28%7Bhidden%3Ar%21%3D%3De%7D%29%29%29%7Dfunction%20fn%28e%2Ct%29%7Blet%20r%3Dnew%20v%3Breturn%20r.subscribe%28%28%7Bhidden%3Ao%7D%29%3D%3E%7Be.hidden%3Do%7D%29%2Cya%28e%2Ct%29.pipe%28y%28o%3D%3Er.next%28o%29%29%2C_%28%28%29%3D%3Er.complete%28%29%29%2Cm%28o%3D%3EF%28%7Bref%3Ae%7D%2Co%29%29%29%7Dfunction%20Ct%28e%2Ct%29%7Breturn%20t%3D%3D%3D%22inline%22%3FE%28%22div%22%2C%7Bclass%3A%22md-tooltip%20md-tooltip--inline%22%2Cid%3Ae%2Crole%3A%22tooltip%22%7D%2CE%28%22div%22%2C%7Bclass%3A%22md-tooltip__inner%20md-typeset%22%7D%29%29%3AE%28%22div%22%2C%7Bclass%3A%22md-tooltip%22%2Cid%3Ae%2Crole%3A%22tooltip%22%7D%2CE%28%22div%22%2C%7Bclass%3A%22md-tooltip__inner%20md-typeset%22%7D%29%29%7Dfunction%20un%28e%2Ct%29%7Bif%28t%3Dt%3F%60%24%7Bt%7D_annotation_%24%7Be%7D%60%3Avoid%200%2Ct%29%7Blet%20r%3Dt%3F%60%23%24%7Bt%7D%60%3Avoid%200%3Breturn%20E%28%22aside%22%2C%7Bclass%3A%22md-annotation%22%2CtabIndex%3A0%7D%2CCt%28t%29%2CE%28%22a%22%2C%7Bhref%3Ar%2Cclass%3A%22md-annotation__index%22%2CtabIndex%3A-1%7D%2CE%28%22span%22%2C%7B%22data-md-annotation-id%22%3Ae%7D%29%29%29%7Delse%20return%20E%28%22aside%22%2C%7Bclass%3A%22md-annotation%22%2CtabIndex%3A0%7D%2CCt%28t%29%2CE%28%22span%22%2C%7Bclass%3A%22md-annotation__index%22%2CtabIndex%3A-1%7D%2CE%28%22span%22%2C%7B%22data-md-annotation-id%22%3Ae%7D%29%29%29%7Dfunction%20dn%28e%29%7Breturn%20E%28%22button%22%2C%7Bclass%3A%22md-clipboard%20md-icon%22%2Ctitle%3Age%28%22clipboard.copy%22%29%2C%22data-clipboard-target%22%3A%60%23%24%7Be%7D%20%3E%20code%60%7D%29%7Dfunction%20Dr%28e%2Ct%29%7Blet%20r%3Dt%262%2Co%3Dt%261%2Cn%3DObject.keys%28e.terms%29.filter%28c%3D%3E%21e.terms%5Bc%5D%29.reduce%28%28c%2Cp%29%3D%3E%5B...c%2CE%28%22del%22%2Cnull%2Cp%29%2C%22%20%22%5D%2C%5B%5D%29.slice%280%2C-1%29%2Ci%3Dwe%28%29%2Cs%3Dnew%20URL%28e.location%2Ci.base%29%3BG%28%22search.highlight%22%29%26%26s.searchParams.set%28%22h%22%2CObject.entries%28e.terms%29.filter%28%28%5B%2Cc%5D%29%3D%3Ec%29.reduce%28%28c%2C%5Bp%5D%29%3D%3E%60%24%7Bc%7D%20%24%7Bp%7D%60.trim%28%29%2C%22%22%29%29%3Blet%7Btags%3Aa%7D%3Dwe%28%29%3Breturn%20E%28%22a%22%2C%7Bhref%3A%60%24%7Bs%7D%60%2Cclass%3A%22md-search-result__link%22%2CtabIndex%3A-1%7D%2CE%28%22article%22%2C%7Bclass%3A%22md-search-result__article%20md-typeset%22%2C%22data-md-score%22%3Ae.score.toFixed%282%29%7D%2Cr%3E0%26%26E%28%22div%22%2C%7Bclass%3A%22md-search-result__icon%20md-icon%22%7D%29%2Cr%3E0%26%26E%28%22h1%22%2Cnull%2Ce.title%29%2Cr%3C%3D0%26%26E%28%22h2%22%2Cnull%2Ce.title%29%2Co%3E0%26%26e.text.length%3E0%26%26e.text%2Ce.tags%26%26e.tags.map%28c%3D%3E%7Blet%20p%3Da%3Fc%20in%20a%3F%60md-tag-icon%20md-tag--%24%7Ba%5Bc%5D%7D%60%3A%22md-tag-icon%22%3A%22%22%3Breturn%20E%28%22span%22%2C%7Bclass%3A%60md-tag%20%24%7Bp%7D%60%7D%2Cc%29%7D%29%2Co%3E0%26%26n.length%3E0%26%26E%28%22p%22%2C%7Bclass%3A%22md-search-result__terms%22%7D%2Cge%28%22search.result.term.missing%22%29%2C%22%3A%20%22%2C...n%29%29%29%7Dfunction%20hn%28e%29%7Blet%20t%3De%5B0%5D.score%2Cr%3D%5B...e%5D%2Co%3Dwe%28%29%2Cn%3Dr.findIndex%28l%3D%3E%21%60%24%7Bnew%20URL%28l.location%2Co.base%29%7D%60.includes%28%22%23%22%29%29%2C%5Bi%5D%3Dr.splice%28n%2C1%29%2Cs%3Dr.findIndex%28l%3D%3El.score%3Ct%29%3Bs%3D%3D%3D-1%26%26%28s%3Dr.length%29%3Blet%20a%3Dr.slice%280%2Cs%29%2Cc%3Dr.slice%28s%29%2Cp%3D%5BDr%28i%2C2%7C%2B%28%21n%26%26s%3D%3D%3D0%29%29%2C...a.map%28l%3D%3EDr%28l%2C1%29%29%2C...c.length%3F%5BE%28%22details%22%2C%7Bclass%3A%22md-search-result__more%22%7D%2CE%28%22summary%22%2C%7BtabIndex%3A-1%7D%2CE%28%22div%22%2Cnull%2Cc.length%3E0%26%26c.length%3D%3D%3D1%3Fge%28%22search.result.more.one%22%29%3Age%28%22search.result.more.other%22%2Cc.length%29%29%29%2C...c.map%28l%3D%3EDr%28l%2C1%29%29%29%5D%3A%5B%5D%5D%3Breturn%20E%28%22li%22%2C%7Bclass%3A%22md-search-result__item%22%7D%2Cp%29%7Dfunction%20bn%28e%29%7Breturn%20E%28%22ul%22%2C%7Bclass%3A%22md-source__facts%22%7D%2CObject.entries%28e%29.map%28%28%5Bt%2Cr%5D%29%3D%3EE%28%22li%22%2C%7Bclass%3A%60md-source__fact%20md-source__fact--%24%7Bt%7D%60%7D%2Ctypeof%20r%3D%3D%22number%22%3Far%28r%29%3Ar%29%29%29%7Dfunction%20Nr%28e%29%7Blet%20t%3D%60tabbed-control%20tabbed-control--%24%7Be%7D%60%3Breturn%20E%28%22div%22%2C%7Bclass%3At%2Chidden%3A%210%7D%2CE%28%22button%22%2C%7Bclass%3A%22tabbed-button%22%2CtabIndex%3A-1%2C%22aria-hidden%22%3A%22true%22%7D%29%29%7Dfunction%20vn%28e%29%7Breturn%20E%28%22div%22%2C%7Bclass%3A%22md-typeset__scrollwrap%22%7D%2CE%28%22div%22%2C%7Bclass%3A%22md-typeset__table%22%7D%2Ce%29%29%7Dfunction%20Ea%28e%29%7Blet%20t%3Dwe%28%29%2Cr%3Dnew%20URL%28%60../%24%7Be.version%7D/%60%2Ct.base%29%3Breturn%20E%28%22li%22%2C%7Bclass%3A%22md-version__item%22%7D%2CE%28%22a%22%2C%7Bhref%3A%60%24%7Br%7D%60%2Cclass%3A%22md-version__link%22%7D%2Ce.title%29%29%7Dfunction%20gn%28e%2Ct%29%7Breturn%20E%28%22div%22%2C%7Bclass%3A%22md-version%22%7D%2CE%28%22button%22%2C%7Bclass%3A%22md-version__current%22%2C%22aria-label%22%3Age%28%22select.version%22%29%7D%2Ct.title%29%2CE%28%22ul%22%2C%7Bclass%3A%22md-version__list%22%7D%2Ce.map%28Ea%29%29%29%7Dvar%20wa%3D0%3Bfunction%20Ta%28e%2Ct%29%7Bdocument.body.append%28e%29%3Blet%7Bwidth%3Ar%7D%3Dpe%28e%29%3Be.style.setProperty%28%22--md-tooltip-width%22%2C%60%24%7Br%7Dpx%60%29%2Ce.remove%28%29%3Blet%20o%3Dsr%28t%29%2Cn%3Dtypeof%20o%21%3D%22undefined%22%3Fet%28o%29%3A%24%28%7Bx%3A0%2Cy%3A0%7D%29%2Ci%3DT%28vt%28t%29%2CVo%28t%29%29.pipe%28Y%28%29%29%3Breturn%20Q%28%5Bi%2Cn%5D%29.pipe%28m%28%28%5Bs%2Ca%5D%29%3D%3E%7Blet%7Bx%3Ac%2Cy%3Ap%7D%3DUe%28t%29%2Cl%3Dpe%28t%29%2Cf%3Dt.closest%28%22table%22%29%3Breturn%20f%26%26t.parentElement%26%26%28c%2B%3Df.offsetLeft%2Bt.parentElement.offsetLeft%2Cp%2B%3Df.offsetTop%2Bt.parentElement.offsetTop%29%2C%7Bactive%3As%2Coffset%3A%7Bx%3Ac-a.x%2Bl.width/2-r/2%2Cy%3Ap-a.y%2Bl.height%2B8%7D%7D%7D%29%29%7Dfunction%20Ge%28e%29%7Blet%20t%3De.title%3Bif%28%21t.length%29return%20L%3Blet%20r%3D%60__tooltip_%24%7Bwa%2B%2B%7D%60%2Co%3DCt%28r%2C%22inline%22%29%2Cn%3DP%28%22.md-typeset%22%2Co%29%3Breturn%20n.innerHTML%3Dt%2CH%28%28%29%3D%3E%7Blet%20i%3Dnew%20v%3Breturn%20i.subscribe%28%7Bnext%28%7Boffset%3As%7D%29%7Bo.style.setProperty%28%22--md-tooltip-x%22%2C%60%24%7Bs.x%7Dpx%60%29%2Co.style.setProperty%28%22--md-tooltip-y%22%2C%60%24%7Bs.y%7Dpx%60%29%7D%2Ccomplete%28%29%7Bo.style.removeProperty%28%22--md-tooltip-x%22%29%2Co.style.removeProperty%28%22--md-tooltip-y%22%29%7D%7D%29%2CT%28i.pipe%28g%28%28%7Bactive%3As%7D%29%3D%3Es%29%29%2Ci.pipe%28be%28250%29%2Cg%28%28%7Bactive%3As%7D%29%3D%3E%21s%29%29%29.subscribe%28%7Bnext%28%7Bactive%3As%7D%29%7Bs%3F%28e.insertAdjacentElement%28%22afterend%22%2Co%29%2Ce.setAttribute%28%22aria-describedby%22%2Cr%29%2Ce.removeAttribute%28%22title%22%29%29%3A%28o.remove%28%29%2Ce.removeAttribute%28%22aria-describedby%22%29%2Ce.setAttribute%28%22title%22%2Ct%29%29%7D%2Ccomplete%28%29%7Bo.remove%28%29%2Ce.removeAttribute%28%22aria-describedby%22%29%2Ce.setAttribute%28%22title%22%2Ct%29%7D%7D%29%2Ci.pipe%28Me%2816%2Cde%29%29.subscribe%28%28%7Bactive%3As%7D%29%3D%3E%7Bo.classList.toggle%28%22md-tooltip--active%22%2Cs%29%7D%29%2Ci.pipe%28_t%28125%2Cde%29%2Cg%28%28%29%3D%3E%21%21e.offsetParent%29%2Cm%28%28%29%3D%3Ee.offsetParent.getBoundingClientRect%28%29%29%2Cm%28%28%7Bx%3As%7D%29%3D%3Es%29%29.subscribe%28%7Bnext%28s%29%7Bs%3Fo.style.setProperty%28%22--md-tooltip-0%22%2C%60%24%7B-s%7Dpx%60%29%3Ao.style.removeProperty%28%22--md-tooltip-0%22%29%7D%2Ccomplete%28%29%7Bo.style.removeProperty%28%22--md-tooltip-0%22%29%7D%7D%29%2CTa%28o%2Ce%29.pipe%28y%28s%3D%3Ei.next%28s%29%29%2C_%28%28%29%3D%3Ei.complete%28%29%29%2Cm%28s%3D%3EF%28%7Bref%3Ae%7D%2Cs%29%29%29%7D%29.pipe%28ze%28ie%29%29%7Dfunction%20Sa%28e%2Ct%29%7Blet%20r%3DH%28%28%29%3D%3EQ%28%5Bzo%28e%29%2Cet%28t%29%5D%29%29.pipe%28m%28%28%5B%7Bx%3Ao%2Cy%3An%7D%2Ci%5D%29%3D%3E%7Blet%7Bwidth%3As%2Cheight%3Aa%7D%3Dpe%28e%29%3Breturn%7Bx%3Ao-i.x%2Bs/2%2Cy%3An-i.y%2Ba/2%7D%7D%29%29%3Breturn%20vt%28e%29.pipe%28b%28o%3D%3Er.pipe%28m%28n%3D%3E%28%7Bactive%3Ao%2Coffset%3An%7D%29%29%2Cye%28%2B%21o%7C%7C1/0%29%29%29%29%7Dfunction%20xn%28e%2Ct%2C%7Btarget%24%3Ar%7D%29%7Blet%5Bo%2Cn%5D%3DArray.from%28e.children%29%3Breturn%20H%28%28%29%3D%3E%7Blet%20i%3Dnew%20v%2Cs%3Di.pipe%28ee%28%29%2Coe%28%210%29%29%3Breturn%20i.subscribe%28%7Bnext%28%7Boffset%3Aa%7D%29%7Be.style.setProperty%28%22--md-tooltip-x%22%2C%60%24%7Ba.x%7Dpx%60%29%2Ce.style.setProperty%28%22--md-tooltip-y%22%2C%60%24%7Ba.y%7Dpx%60%29%7D%2Ccomplete%28%29%7Be.style.removeProperty%28%22--md-tooltip-x%22%29%2Ce.style.removeProperty%28%22--md-tooltip-y%22%29%7D%7D%29%2Cyt%28e%29.pipe%28U%28s%29%29.subscribe%28a%3D%3E%7Be.toggleAttribute%28%22data-md-visible%22%2Ca%29%7D%29%2CT%28i.pipe%28g%28%28%7Bactive%3Aa%7D%29%3D%3Ea%29%29%2Ci.pipe%28be%28250%29%2Cg%28%28%7Bactive%3Aa%7D%29%3D%3E%21a%29%29%29.subscribe%28%7Bnext%28%7Bactive%3Aa%7D%29%7Ba%3Fe.prepend%28o%29%3Ao.remove%28%29%7D%2Ccomplete%28%29%7Be.prepend%28o%29%7D%7D%29%2Ci.pipe%28Me%2816%2Cde%29%29.subscribe%28%28%7Bactive%3Aa%7D%29%3D%3E%7Bo.classList.toggle%28%22md-tooltip--active%22%2Ca%29%7D%29%2Ci.pipe%28_t%28125%2Cde%29%2Cg%28%28%29%3D%3E%21%21e.offsetParent%29%2Cm%28%28%29%3D%3Ee.offsetParent.getBoundingClientRect%28%29%29%2Cm%28%28%7Bx%3Aa%7D%29%3D%3Ea%29%29.subscribe%28%7Bnext%28a%29%7Ba%3Fe.style.setProperty%28%22--md-tooltip-0%22%2C%60%24%7B-a%7Dpx%60%29%3Ae.style.removeProperty%28%22--md-tooltip-0%22%29%7D%2Ccomplete%28%29%7Be.style.removeProperty%28%22--md-tooltip-0%22%29%7D%7D%29%2Cd%28n%2C%22click%22%29.pipe%28U%28s%29%2Cg%28a%3D%3E%21%28a.metaKey%7C%7Ca.ctrlKey%29%29%29.subscribe%28a%3D%3E%7Ba.stopPropagation%28%29%2Ca.preventDefault%28%29%7D%29%2Cd%28n%2C%22mousedown%22%29.pipe%28U%28s%29%2Cae%28i%29%29.subscribe%28%28%5Ba%2C%7Bactive%3Ac%7D%5D%29%3D%3E%7Bvar%20p%3Bif%28a.button%21%3D%3D0%7C%7Ca.metaKey%7C%7Ca.ctrlKey%29a.preventDefault%28%29%3Belse%20if%28c%29%7Ba.preventDefault%28%29%3Blet%20l%3De.parentElement.closest%28%22.md-annotation%22%29%3Bl%20instanceof%20HTMLElement%3Fl.focus%28%29%3A%28p%3DRe%28%29%29%3D%3Dnull%7C%7Cp.blur%28%29%7D%7D%29%2Cr.pipe%28U%28s%29%2Cg%28a%3D%3Ea%3D%3D%3Do%29%2CYe%28125%29%29.subscribe%28%28%29%3D%3Ee.focus%28%29%29%2CSa%28e%2Ct%29.pipe%28y%28a%3D%3Ei.next%28a%29%29%2C_%28%28%29%3D%3Ei.complete%28%29%29%2Cm%28a%3D%3EF%28%7Bref%3Ae%7D%2Ca%29%29%29%7D%29%7Dfunction%20Oa%28e%29%7Breturn%20e.tagName%3D%3D%3D%22CODE%22%3FR%28%22.c%2C%20.c1%2C%20.cm%22%2Ce%29%3A%5Be%5D%7Dfunction%20Ma%28e%29%7Blet%20t%3D%5B%5D%3Bfor%28let%20r%20of%20Oa%28e%29%29%7Blet%20o%3D%5B%5D%2Cn%3Ddocument.createNodeIterator%28r%2CNodeFilter.SHOW_TEXT%29%3Bfor%28let%20i%3Dn.nextNode%28%29%3Bi%3Bi%3Dn.nextNode%28%29%29o.push%28i%29%3Bfor%28let%20i%20of%20o%29%7Blet%20s%3Bfor%28%3Bs%3D/%28%5C%28%5Cd%2B%5C%29%29%28%21%29%3F/.exec%28i.textContent%29%3B%29%7Blet%5B%2Ca%2Cc%5D%3Ds%3Bif%28typeof%20c%3D%3D%22undefined%22%29%7Blet%20p%3Di.splitText%28s.index%29%3Bi%3Dp.splitText%28a.length%29%2Ct.push%28p%29%7Delse%7Bi.textContent%3Da%2Ct.push%28i%29%3Bbreak%7D%7D%7D%7Dreturn%20t%7Dfunction%20yn%28e%2Ct%29%7Bt.append%28...Array.from%28e.childNodes%29%29%7Dfunction%20lr%28e%2Ct%2C%7Btarget%24%3Ar%2Cprint%24%3Ao%7D%29%7Blet%20n%3Dt.closest%28%22%5Bid%5D%22%29%2Ci%3Dn%3D%3Dnull%3Fvoid%200%3An.id%2Cs%3Dnew%20Map%3Bfor%28let%20a%20of%20Ma%28t%29%29%7Blet%5B%2Cc%5D%3Da.textContent.match%28/%5C%28%28%5Cd%2B%29%5C%29/%29%3Bme%28%60%3Ascope%20%3E%20li%3Anth-child%28%24%7Bc%7D%29%60%2Ce%29%26%26%28s.set%28c%2Cun%28c%2Ci%29%29%2Ca.replaceWith%28s.get%28c%29%29%29%7Dreturn%20s.size%3D%3D%3D0%3FL%3AH%28%28%29%3D%3E%7Blet%20a%3Dnew%20v%2Cc%3Da.pipe%28ee%28%29%2Coe%28%210%29%29%2Cp%3D%5B%5D%3Bfor%28let%5Bl%2Cf%5Dof%20s%29p.push%28%5BP%28%22.md-typeset%22%2Cf%29%2CP%28%60%3Ascope%20%3E%20li%3Anth-child%28%24%7Bl%7D%29%60%2Ce%29%5D%29%3Breturn%20o.pipe%28U%28c%29%29.subscribe%28l%3D%3E%7Be.hidden%3D%21l%2Ce.classList.toggle%28%22md-annotation-list%22%2Cl%29%3Bfor%28let%5Bf%2Cu%5Dof%20p%29l%3Fyn%28f%2Cu%29%3Ayn%28u%2Cf%29%7D%29%2CT%28...%5B...s%5D.map%28%28%5B%2Cl%5D%29%3D%3Exn%28l%2Ct%2C%7Btarget%24%3Ar%7D%29%29%29.pipe%28_%28%28%29%3D%3Ea.complete%28%29%29%2Cle%28%29%29%7D%29%7Dfunction%20En%28e%29%7Bif%28e.nextElementSibling%29%7Blet%20t%3De.nextElementSibling%3Bif%28t.tagName%3D%3D%3D%22OL%22%29return%20t%3Bif%28t.tagName%3D%3D%3D%22P%22%26%26%21t.children.length%29return%20En%28t%29%7D%7Dfunction%20wn%28e%2Ct%29%7Breturn%20H%28%28%29%3D%3E%7Blet%20r%3DEn%28e%29%3Breturn%20typeof%20r%21%3D%22undefined%22%3Flr%28r%2Ce%2Ct%29%3AL%7D%29%7Dvar%20Tn%3Djt%28zr%28%29%29%3Bvar%20La%3D0%3Bfunction%20Sn%28e%29%7Bif%28e.nextElementSibling%29%7Blet%20t%3De.nextElementSibling%3Bif%28t.tagName%3D%3D%3D%22OL%22%29return%20t%3Bif%28t.tagName%3D%3D%3D%22P%22%26%26%21t.children.length%29return%20Sn%28t%29%7D%7Dfunction%20_a%28e%29%7Breturn%20Ee%28e%29.pipe%28m%28%28%7Bwidth%3At%7D%29%3D%3E%28%7Bscrollable%3Axt%28e%29.width%3Et%7D%29%29%2CX%28%22scrollable%22%29%29%7Dfunction%20On%28e%2Ct%29%7Blet%7Bmatches%3Ar%7D%3DmatchMedia%28%22%28hover%29%22%29%2Co%3DH%28%28%29%3D%3E%7Blet%20n%3Dnew%20v%2Ci%3Dn.pipe%28%24r%281%29%29%3Bn.subscribe%28%28%7Bscrollable%3Ac%7D%29%3D%3E%7Bc%26%26r%3Fe.setAttribute%28%22tabindex%22%2C%220%22%29%3Ae.removeAttribute%28%22tabindex%22%29%7D%29%3Blet%20s%3D%5B%5D%3Bif%28Tn.default.isSupported%28%29%26%26%28e.closest%28%22.copy%22%29%7C%7CG%28%22content.code.copy%22%29%26%26%21e.closest%28%22.no-copy%22%29%29%29%7Blet%20c%3De.closest%28%22pre%22%29%3Bc.id%3D%60__code_%24%7BLa%2B%2B%7D%60%3Blet%20p%3Ddn%28c.id%29%3Bc.insertBefore%28p%2Ce%29%2CG%28%22content.tooltips%22%29%26%26s.push%28Ge%28p%29%29%7Dlet%20a%3De.closest%28%22.highlight%22%29%3Bif%28a%20instanceof%20HTMLElement%29%7Blet%20c%3DSn%28a%29%3Bif%28typeof%20c%21%3D%22undefined%22%26%26%28a.classList.contains%28%22annotate%22%29%7C%7CG%28%22content.code.annotate%22%29%29%29%7Blet%20p%3Dlr%28c%2Ce%2Ct%29%3Bs.push%28Ee%28a%29.pipe%28U%28i%29%2Cm%28%28%7Bwidth%3Al%2Cheight%3Af%7D%29%3D%3El%26%26f%29%2CY%28%29%2Cb%28l%3D%3El%3Fp%3AL%29%29%29%7D%7Dreturn%20_a%28e%29.pipe%28y%28c%3D%3En.next%28c%29%29%2C_%28%28%29%3D%3En.complete%28%29%29%2Cm%28c%3D%3EF%28%7Bref%3Ae%7D%2Cc%29%29%2C%24e%28...s%29%29%7D%29%3Breturn%20G%28%22content.lazy%22%29%3Fyt%28e%29.pipe%28g%28n%3D%3En%29%2Cye%281%29%2Cb%28%28%29%3D%3Eo%29%29%3Ao%7Dfunction%20Aa%28e%2C%7Btarget%24%3At%2Cprint%24%3Ar%7D%29%7Blet%20o%3D%210%3Breturn%20T%28t.pipe%28m%28n%3D%3En.closest%28%22details%3Anot%28%5Bopen%5D%29%22%29%29%2Cg%28n%3D%3Ee%3D%3D%3Dn%29%2Cm%28%28%29%3D%3E%28%7Baction%3A%22open%22%2Creveal%3A%210%7D%29%29%29%2Cr.pipe%28g%28n%3D%3En%7C%7C%21o%29%2Cy%28%28%29%3D%3Eo%3De.open%29%2Cm%28n%3D%3E%28%7Baction%3An%3F%22open%22%3A%22close%22%7D%29%29%29%29%7Dfunction%20Mn%28e%2Ct%29%7Breturn%20H%28%28%29%3D%3E%7Blet%20r%3Dnew%20v%3Breturn%20r.subscribe%28%28%7Baction%3Ao%2Creveal%3An%7D%29%3D%3E%7Be.toggleAttribute%28%22open%22%2Co%3D%3D%3D%22open%22%29%2Cn%26%26e.scrollIntoView%28%29%7D%29%2CAa%28e%2Ct%29.pipe%28y%28o%3D%3Er.next%28o%29%29%2C_%28%28%29%3D%3Er.complete%28%29%29%2Cm%28o%3D%3EF%28%7Bref%3Ae%7D%2Co%29%29%29%7D%29%7Dvar%20Ln%3D%22.node%20circle%2C.node%20ellipse%2C.node%20path%2C.node%20polygon%2C.node%20rect%7Bfill%3Avar%28--md-mermaid-node-bg-color%29%3Bstroke%3Avar%28--md-mermaid-node-fg-color%29%7Dmarker%7Bfill%3Avar%28--md-mermaid-edge-color%29%21important%7D.edgeLabel%20.label%20rect%7Bfill%3A%230000%7D.label%7Bcolor%3Avar%28--md-mermaid-label-fg-color%29%3Bfont-family%3Avar%28--md-mermaid-font-family%29%7D.label%20foreignObject%7Bline-height%3Anormal%3Boverflow%3Avisible%7D.label%20div%20.edgeLabel%7Bcolor%3Avar%28--md-mermaid-label-fg-color%29%7D.edgeLabel%2C.edgeLabel%20rect%2C.label%20div%20.edgeLabel%7Bbackground-color%3Avar%28--md-mermaid-label-bg-color%29%7D.edgeLabel%2C.edgeLabel%20rect%7Bfill%3Avar%28--md-mermaid-label-bg-color%29%3Bcolor%3Avar%28--md-mermaid-edge-color%29%7D.edgePath%20.path%2C.flowchart-link%7Bstroke%3Avar%28--md-mermaid-edge-color%29%3Bstroke-width%3A.05rem%7D.edgePath%20.arrowheadPath%7Bfill%3Avar%28--md-mermaid-edge-color%29%3Bstroke%3Anone%7D.cluster%20rect%7Bfill%3Avar%28--md-default-fg-color--lightest%29%3Bstroke%3Avar%28--md-default-fg-color--lighter%29%7D.cluster%20span%7Bcolor%3Avar%28--md-mermaid-label-fg-color%29%3Bfont-family%3Avar%28--md-mermaid-font-family%29%7Dg%20%23flowchart-circleEnd%2Cg%20%23flowchart-circleStart%2Cg%20%23flowchart-crossEnd%2Cg%20%23flowchart-crossStart%2Cg%20%23flowchart-pointEnd%2Cg%20%23flowchart-pointStart%7Bstroke%3Anone%7Dg.classGroup%20line%2Cg.classGroup%20rect%7Bfill%3Avar%28--md-mermaid-node-bg-color%29%3Bstroke%3Avar%28--md-mermaid-node-fg-color%29%7Dg.classGroup%20text%7Bfill%3Avar%28--md-mermaid-label-fg-color%29%3Bfont-family%3Avar%28--md-mermaid-font-family%29%7D.classLabel%20.box%7Bfill%3Avar%28--md-mermaid-label-bg-color%29%3Bbackground-color%3Avar%28--md-mermaid-label-bg-color%29%3Bopacity%3A1%7D.classLabel%20.label%7Bfill%3Avar%28--md-mermaid-label-fg-color%29%3Bfont-family%3Avar%28--md-mermaid-font-family%29%7D.node%20.divider%7Bstroke%3Avar%28--md-mermaid-node-fg-color%29%7D.relation%7Bstroke%3Avar%28--md-mermaid-edge-color%29%7D.cardinality%7Bfill%3Avar%28--md-mermaid-label-fg-color%29%3Bfont-family%3Avar%28--md-mermaid-font-family%29%7D.cardinality%20text%7Bfill%3Ainherit%21important%7Ddefs%20%23classDiagram-compositionEnd%2Cdefs%20%23classDiagram-compositionStart%2Cdefs%20%23classDiagram-dependencyEnd%2Cdefs%20%23classDiagram-dependencyStart%2Cdefs%20%23classDiagram-extensionEnd%2Cdefs%20%23classDiagram-extensionStart%7Bfill%3Avar%28--md-mermaid-edge-color%29%21important%3Bstroke%3Avar%28--md-mermaid-edge-color%29%21important%7Ddefs%20%23classDiagram-aggregationEnd%2Cdefs%20%23classDiagram-aggregationStart%7Bfill%3Avar%28--md-mermaid-label-bg-color%29%21important%3Bstroke%3Avar%28--md-mermaid-edge-color%29%21important%7Dg.stateGroup%20rect%7Bfill%3Avar%28--md-mermaid-node-bg-color%29%3Bstroke%3Avar%28--md-mermaid-node-fg-color%29%7Dg.stateGroup%20.state-title%7Bfill%3Avar%28--md-mermaid-label-fg-color%29%21important%3Bfont-family%3Avar%28--md-mermaid-font-family%29%7Dg.stateGroup%20.composit%7Bfill%3Avar%28--md-mermaid-label-bg-color%29%7D.nodeLabel%2C.nodeLabel%20p%7Bcolor%3Avar%28--md-mermaid-label-fg-color%29%3Bfont-family%3Avar%28--md-mermaid-font-family%29%7D.node%20circle.state-end%2C.node%20circle.state-start%2C.start-state%7Bfill%3Avar%28--md-mermaid-edge-color%29%3Bstroke%3Anone%7D.end-state-inner%2C.end-state-outer%7Bfill%3Avar%28--md-mermaid-edge-color%29%7D.end-state-inner%2C.node%20circle.state-end%7Bstroke%3Avar%28--md-mermaid-label-bg-color%29%7D.transition%7Bstroke%3Avar%28--md-mermaid-edge-color%29%7D%5Bid%5E%3Dstate-fork%5D%20rect%2C%5Bid%5E%3Dstate-join%5D%20rect%7Bfill%3Avar%28--md-mermaid-edge-color%29%21important%3Bstroke%3Anone%21important%7D.statediagram-cluster.statediagram-cluster%20.inner%7Bfill%3Avar%28--md-default-bg-color%29%7D.statediagram-cluster%20rect%7Bfill%3Avar%28--md-mermaid-node-bg-color%29%3Bstroke%3Avar%28--md-mermaid-node-fg-color%29%7D.statediagram-state%20rect.divider%7Bfill%3Avar%28--md-default-fg-color--lightest%29%3Bstroke%3Avar%28--md-default-fg-color--lighter%29%7Ddefs%20%23statediagram-barbEnd%7Bstroke%3Avar%28--md-mermaid-edge-color%29%7D.attributeBoxEven%2C.attributeBoxOdd%7Bfill%3Avar%28--md-mermaid-node-bg-color%29%3Bstroke%3Avar%28--md-mermaid-node-fg-color%29%7D.entityBox%7Bfill%3Avar%28--md-mermaid-label-bg-color%29%3Bstroke%3Avar%28--md-mermaid-node-fg-color%29%7D.entityLabel%7Bfill%3Avar%28--md-mermaid-label-fg-color%29%3Bfont-family%3Avar%28--md-mermaid-font-family%29%7D.relationshipLabelBox%7Bfill%3Avar%28--md-mermaid-label-bg-color%29%3Bfill-opacity%3A1%3Bbackground-color%3Avar%28--md-mermaid-label-bg-color%29%3Bopacity%3A1%7D.relationshipLabel%7Bfill%3Avar%28--md-mermaid-label-fg-color%29%7D.relationshipLine%7Bstroke%3Avar%28--md-mermaid-edge-color%29%7Ddefs%20%23ONE_OR_MORE_END%20%2A%2Cdefs%20%23ONE_OR_MORE_START%20%2A%2Cdefs%20%23ONLY_ONE_END%20%2A%2Cdefs%20%23ONLY_ONE_START%20%2A%2Cdefs%20%23ZERO_OR_MORE_END%20%2A%2Cdefs%20%23ZERO_OR_MORE_START%20%2A%2Cdefs%20%23ZERO_OR_ONE_END%20%2A%2Cdefs%20%23ZERO_OR_ONE_START%20%2A%7Bstroke%3Avar%28--md-mermaid-edge-color%29%21important%7Ddefs%20%23ZERO_OR_MORE_END%20circle%2Cdefs%20%23ZERO_OR_MORE_START%20circle%7Bfill%3Avar%28--md-mermaid-label-bg-color%29%7D.actor%7Bfill%3Avar%28--md-mermaid-sequence-actor-bg-color%29%3Bstroke%3Avar%28--md-mermaid-sequence-actor-border-color%29%7Dtext.actor%3Etspan%7Bfill%3Avar%28--md-mermaid-sequence-actor-fg-color%29%3Bfont-family%3Avar%28--md-mermaid-font-family%29%7Dline%7Bstroke%3Avar%28--md-mermaid-sequence-actor-line-color%29%7D.actor-man%20circle%2C.actor-man%20line%7Bfill%3Avar%28--md-mermaid-sequence-actorman-bg-color%29%3Bstroke%3Avar%28--md-mermaid-sequence-actorman-line-color%29%7D.messageLine0%2C.messageLine1%7Bstroke%3Avar%28--md-mermaid-sequence-message-line-color%29%7D.note%7Bfill%3Avar%28--md-mermaid-sequence-note-bg-color%29%3Bstroke%3Avar%28--md-mermaid-sequence-note-border-color%29%7D.loopText%2C.loopText%3Etspan%2C.messageText%2C.noteText%3Etspan%7Bstroke%3Anone%3Bfont-family%3Avar%28--md-mermaid-font-family%29%21important%7D.messageText%7Bfill%3Avar%28--md-mermaid-sequence-message-fg-color%29%7D.loopText%2C.loopText%3Etspan%7Bfill%3Avar%28--md-mermaid-sequence-loop-fg-color%29%7D.noteText%3Etspan%7Bfill%3Avar%28--md-mermaid-sequence-note-fg-color%29%7D%23arrowhead%20path%7Bfill%3Avar%28--md-mermaid-sequence-message-line-color%29%3Bstroke%3Anone%7D.loopLine%7Bfill%3Avar%28--md-mermaid-sequence-loop-bg-color%29%3Bstroke%3Avar%28--md-mermaid-sequence-loop-border-color%29%7D.labelBox%7Bfill%3Avar%28--md-mermaid-sequence-label-bg-color%29%3Bstroke%3Anone%7D.labelText%2C.labelText%3Espan%7Bfill%3Avar%28--md-mermaid-sequence-label-fg-color%29%3Bfont-family%3Avar%28--md-mermaid-font-family%29%7D.sequenceNumber%7Bfill%3Avar%28--md-mermaid-sequence-number-fg-color%29%7Drect.rect%7Bfill%3Avar%28--md-mermaid-sequence-box-bg-color%29%3Bstroke%3Anone%7Drect.rect%2Btext.text%7Bfill%3Avar%28--md-mermaid-sequence-box-fg-color%29%7Ddefs%20%23sequencenumber%7Bfill%3Avar%28--md-mermaid-sequence-number-bg-color%29%21important%7D%22%3Bvar%20qr%2Cka%3D0%3Bfunction%20Ha%28%29%7Breturn%20typeof%20mermaid%3D%3D%22undefined%22%7C%7Cmermaid%20instanceof%20Element%3Fgt%28%22https%3A//unpkg.com/mermaid%4010.7.0/dist/mermaid.min.js%22%29%3A%24%28void%200%29%7Dfunction%20_n%28e%29%7Breturn%20e.classList.remove%28%22mermaid%22%29%2Cqr%7C%7C%28qr%3DHa%28%29.pipe%28y%28%28%29%3D%3Emermaid.initialize%28%7BstartOnLoad%3A%211%2CthemeCSS%3ALn%2Csequence%3A%7BactorFontSize%3A%2216px%22%2CmessageFontSize%3A%2216px%22%2CnoteFontSize%3A%2216px%22%7D%7D%29%29%2Cm%28%28%29%3D%3E%7B%7D%29%2CB%281%29%29%29%2Cqr.subscribe%28%28%29%3D%3Ero%28this%2Cnull%2Cfunction%2A%28%29%7Be.classList.add%28%22mermaid%22%29%3Blet%20t%3D%60__mermaid_%24%7Bka%2B%2B%7D%60%2Cr%3DE%28%22div%22%2C%7Bclass%3A%22mermaid%22%7D%29%2Co%3De.textContent%2C%7Bsvg%3An%2Cfn%3Ai%7D%3Dyield%20mermaid.render%28t%2Co%29%2Cs%3Dr.attachShadow%28%7Bmode%3A%22closed%22%7D%29%3Bs.innerHTML%3Dn%2Ce.replaceWith%28r%29%2Ci%3D%3Dnull%7C%7Ci%28s%29%7D%29%29%2Cqr.pipe%28m%28%28%29%3D%3E%28%7Bref%3Ae%7D%29%29%29%7Dvar%20An%3DE%28%22table%22%29%3Bfunction%20Cn%28e%29%7Breturn%20e.replaceWith%28An%29%2CAn.replaceWith%28vn%28e%29%29%2C%24%28%7Bref%3Ae%7D%29%7Dfunction%20%24a%28e%29%7Blet%20t%3De.find%28r%3D%3Er.checked%29%7C%7Ce%5B0%5D%3Breturn%20T%28...e.map%28r%3D%3Ed%28r%2C%22change%22%29.pipe%28m%28%28%29%3D%3EP%28%60label%5Bfor%3D%22%24%7Br.id%7D%22%5D%60%29%29%29%29%29.pipe%28q%28P%28%60label%5Bfor%3D%22%24%7Bt.id%7D%22%5D%60%29%29%2Cm%28r%3D%3E%28%7Bactive%3Ar%7D%29%29%29%7Dfunction%20kn%28e%2C%7Bviewport%24%3At%2Ctarget%24%3Ar%7D%29%7Blet%20o%3DP%28%22.tabbed-labels%22%2Ce%29%2Cn%3DR%28%22%3Ascope%20%3E%20input%22%2Ce%29%2Ci%3DNr%28%22prev%22%29%3Be.append%28i%29%3Blet%20s%3DNr%28%22next%22%29%3Breturn%20e.append%28s%29%2CH%28%28%29%3D%3E%7Blet%20a%3Dnew%20v%2Cc%3Da.pipe%28ee%28%29%2Coe%28%210%29%29%3BQ%28%5Ba%2CEe%28e%29%5D%29.pipe%28U%28c%29%2CMe%281%2Cde%29%29.subscribe%28%7Bnext%28%5B%7Bactive%3Ap%7D%2Cl%5D%29%7Blet%20f%3DUe%28p%29%2C%7Bwidth%3Au%7D%3Dpe%28p%29%3Be.style.setProperty%28%22--md-indicator-x%22%2C%60%24%7Bf.x%7Dpx%60%29%2Ce.style.setProperty%28%22--md-indicator-width%22%2C%60%24%7Bu%7Dpx%60%29%3Blet%20h%3Dir%28o%29%3B%28f.x%3Ch.x%7C%7Cf.x%2Bu%3Eh.x%2Bl.width%29%26%26o.scrollTo%28%7Bleft%3AMath.max%280%2Cf.x-16%29%2Cbehavior%3A%22smooth%22%7D%29%7D%2Ccomplete%28%29%7Be.style.removeProperty%28%22--md-indicator-x%22%29%2Ce.style.removeProperty%28%22--md-indicator-width%22%29%7D%7D%29%2CQ%28%5Bet%28o%29%2CEe%28o%29%5D%29.pipe%28U%28c%29%29.subscribe%28%28%5Bp%2Cl%5D%29%3D%3E%7Blet%20f%3Dxt%28o%29%3Bi.hidden%3Dp.x%3C16%2Cs.hidden%3Dp.x%3Ef.width-l.width-16%7D%29%2CT%28d%28i%2C%22click%22%29.pipe%28m%28%28%29%3D%3E-1%29%29%2Cd%28s%2C%22click%22%29.pipe%28m%28%28%29%3D%3E1%29%29%29.pipe%28U%28c%29%29.subscribe%28p%3D%3E%7Blet%7Bwidth%3Al%7D%3Dpe%28o%29%3Bo.scrollBy%28%7Bleft%3Al%2Ap%2Cbehavior%3A%22smooth%22%7D%29%7D%29%2Cr.pipe%28U%28c%29%2Cg%28p%3D%3En.includes%28p%29%29%29.subscribe%28p%3D%3Ep.click%28%29%29%2Co.classList.add%28%22tabbed-labels--linked%22%29%3Bfor%28let%20p%20of%20n%29%7Blet%20l%3DP%28%60label%5Bfor%3D%22%24%7Bp.id%7D%22%5D%60%29%3Bl.replaceChildren%28E%28%22a%22%2C%7Bhref%3A%60%23%24%7Bl.htmlFor%7D%60%2CtabIndex%3A-1%7D%2C...Array.from%28l.childNodes%29%29%29%2Cd%28l.firstElementChild%2C%22click%22%29.pipe%28U%28c%29%2Cg%28f%3D%3E%21%28f.metaKey%7C%7Cf.ctrlKey%29%29%2Cy%28f%3D%3E%7Bf.preventDefault%28%29%2Cf.stopPropagation%28%29%7D%29%29.subscribe%28%28%29%3D%3E%7Bhistory.replaceState%28%7B%7D%2C%22%22%2C%60%23%24%7Bl.htmlFor%7D%60%29%2Cl.click%28%29%7D%29%7Dreturn%20G%28%22content.tabs.link%22%29%26%26a.pipe%28Le%281%29%2Cae%28t%29%29.subscribe%28%28%5B%7Bactive%3Ap%7D%2C%7Boffset%3Al%7D%5D%29%3D%3E%7Blet%20f%3Dp.innerText.trim%28%29%3Bif%28p.hasAttribute%28%22data-md-switching%22%29%29p.removeAttribute%28%22data-md-switching%22%29%3Belse%7Blet%20u%3De.offsetTop-l.y%3Bfor%28let%20w%20of%20R%28%22%5Bdata-tabs%5D%22%29%29for%28let%20A%20of%20R%28%22%3Ascope%20%3E%20input%22%2Cw%29%29%7Blet%20Z%3DP%28%60label%5Bfor%3D%22%24%7BA.id%7D%22%5D%60%29%3Bif%28Z%21%3D%3Dp%26%26Z.innerText.trim%28%29%3D%3D%3Df%29%7BZ.setAttribute%28%22data-md-switching%22%2C%22%22%29%2CA.click%28%29%3Bbreak%7D%7Dwindow.scrollTo%28%7Btop%3Ae.offsetTop-u%7D%29%3Blet%20h%3D__md_get%28%22__tabs%22%29%7C%7C%5B%5D%3B__md_set%28%22__tabs%22%2C%5B...new%20Set%28%5Bf%2C...h%5D%29%5D%29%7D%7D%29%2Ca.pipe%28U%28c%29%29.subscribe%28%28%29%3D%3E%7Bfor%28let%20p%20of%20R%28%22audio%2C%20video%22%2Ce%29%29p.pause%28%29%7D%29%2C%24a%28n%29.pipe%28y%28p%3D%3Ea.next%28p%29%29%2C_%28%28%29%3D%3Ea.complete%28%29%29%2Cm%28p%3D%3EF%28%7Bref%3Ae%7D%2Cp%29%29%29%7D%29.pipe%28ze%28ie%29%29%7Dfunction%20Hn%28e%2C%7Bviewport%24%3At%2Ctarget%24%3Ar%2Cprint%24%3Ao%7D%29%7Breturn%20T%28...R%28%22.annotate%3Anot%28.highlight%29%22%2Ce%29.map%28n%3D%3Ewn%28n%2C%7Btarget%24%3Ar%2Cprint%24%3Ao%7D%29%29%2C...R%28%22pre%3Anot%28.mermaid%29%20%3E%20code%22%2Ce%29.map%28n%3D%3EOn%28n%2C%7Btarget%24%3Ar%2Cprint%24%3Ao%7D%29%29%2C...R%28%22pre.mermaid%22%2Ce%29.map%28n%3D%3E_n%28n%29%29%2C...R%28%22table%3Anot%28%5Bclass%5D%29%22%2Ce%29.map%28n%3D%3ECn%28n%29%29%2C...R%28%22details%22%2Ce%29.map%28n%3D%3EMn%28n%2C%7Btarget%24%3Ar%2Cprint%24%3Ao%7D%29%29%2C...R%28%22%5Bdata-tabs%5D%22%2Ce%29.map%28n%3D%3Ekn%28n%2C%7Bviewport%24%3At%2Ctarget%24%3Ar%7D%29%29%2C...R%28%22%5Btitle%5D%22%2Ce%29.filter%28%28%29%3D%3EG%28%22content.tooltips%22%29%29.map%28n%3D%3EGe%28n%29%29%29%7Dfunction%20Ra%28e%2C%7Balert%24%3At%7D%29%7Breturn%20t.pipe%28b%28r%3D%3ET%28%24%28%210%29%2C%24%28%211%29.pipe%28Ye%282e3%29%29%29.pipe%28m%28o%3D%3E%28%7Bmessage%3Ar%2Cactive%3Ao%7D%29%29%29%29%29%7Dfunction%20%24n%28e%2Ct%29%7Blet%20r%3DP%28%22.md-typeset%22%2Ce%29%3Breturn%20H%28%28%29%3D%3E%7Blet%20o%3Dnew%20v%3Breturn%20o.subscribe%28%28%7Bmessage%3An%2Cactive%3Ai%7D%29%3D%3E%7Be.classList.toggle%28%22md-dialog--active%22%2Ci%29%2Cr.textContent%3Dn%7D%29%2CRa%28e%2Ct%29.pipe%28y%28n%3D%3Eo.next%28n%29%29%2C_%28%28%29%3D%3Eo.complete%28%29%29%2Cm%28n%3D%3EF%28%7Bref%3Ae%7D%2Cn%29%29%29%7D%29%7Dfunction%20Pa%28%7Bviewport%24%3Ae%7D%29%7Bif%28%21G%28%22header.autohide%22%29%29return%20%24%28%211%29%3Blet%20t%3De.pipe%28m%28%28%7Boffset%3A%7By%3An%7D%7D%29%3D%3En%29%2CKe%282%2C1%29%2Cm%28%28%5Bn%2Ci%5D%29%3D%3E%5Bn%3Ci%2Ci%5D%29%2CX%280%29%29%2Cr%3DQ%28%5Be%2Ct%5D%29.pipe%28g%28%28%5B%7Boffset%3An%7D%2C%5B%2Ci%5D%5D%29%3D%3EMath.abs%28i-n.y%29%3E100%29%2Cm%28%28%5B%2C%5Bn%5D%5D%29%3D%3En%29%2CY%28%29%29%2Co%3DWe%28%22search%22%29%3Breturn%20Q%28%5Be%2Co%5D%29.pipe%28m%28%28%5B%7Boffset%3An%7D%2Ci%5D%29%3D%3En.y%3E400%26%26%21i%29%2CY%28%29%2Cb%28n%3D%3En%3Fr%3A%24%28%211%29%29%2Cq%28%211%29%29%7Dfunction%20Rn%28e%2Ct%29%7Breturn%20H%28%28%29%3D%3EQ%28%5BEe%28e%29%2CPa%28t%29%5D%29%29.pipe%28m%28%28%5B%7Bheight%3Ar%7D%2Co%5D%29%3D%3E%28%7Bheight%3Ar%2Chidden%3Ao%7D%29%29%2CY%28%28r%2Co%29%3D%3Er.height%3D%3D%3Do.height%26%26r.hidden%3D%3D%3Do.hidden%29%2CB%281%29%29%7Dfunction%20Pn%28e%2C%7Bheader%24%3At%2Cmain%24%3Ar%7D%29%7Breturn%20H%28%28%29%3D%3E%7Blet%20o%3Dnew%20v%2Cn%3Do.pipe%28ee%28%29%2Coe%28%210%29%29%3Bo.pipe%28X%28%22active%22%29%2Cje%28t%29%29.subscribe%28%28%5B%7Bactive%3As%7D%2C%7Bhidden%3Aa%7D%5D%29%3D%3E%7Be.classList.toggle%28%22md-header--shadow%22%2Cs%26%26%21a%29%2Ce.hidden%3Da%7D%29%3Blet%20i%3Dfe%28R%28%22%5Btitle%5D%22%2Ce%29%29.pipe%28g%28%28%29%3D%3EG%28%22content.tooltips%22%29%29%2Cre%28s%3D%3EGe%28s%29%29%29%3Breturn%20r.subscribe%28o%29%2Ct.pipe%28U%28n%29%2Cm%28s%3D%3EF%28%7Bref%3Ae%7D%2Cs%29%29%2C%24e%28i.pipe%28U%28n%29%29%29%29%7D%29%7Dfunction%20Ia%28e%2C%7Bviewport%24%3At%2Cheader%24%3Ar%7D%29%7Breturn%20pr%28e%2C%7Bviewport%24%3At%2Cheader%24%3Ar%7D%29.pipe%28m%28%28%7Boffset%3A%7By%3Ao%7D%7D%29%3D%3E%7Blet%7Bheight%3An%7D%3Dpe%28e%29%3Breturn%7Bactive%3Ao%3E%3Dn%7D%7D%29%2CX%28%22active%22%29%29%7Dfunction%20In%28e%2Ct%29%7Breturn%20H%28%28%29%3D%3E%7Blet%20r%3Dnew%20v%3Br.subscribe%28%7Bnext%28%7Bactive%3An%7D%29%7Be.classList.toggle%28%22md-header__title--active%22%2Cn%29%7D%2Ccomplete%28%29%7Be.classList.remove%28%22md-header__title--active%22%29%7D%7D%29%3Blet%20o%3Dme%28%22.md-content%20h1%22%29%3Breturn%20typeof%20o%3D%3D%22undefined%22%3FL%3AIa%28o%2Ct%29.pipe%28y%28n%3D%3Er.next%28n%29%29%2C_%28%28%29%3D%3Er.complete%28%29%29%2Cm%28n%3D%3EF%28%7Bref%3Ae%7D%2Cn%29%29%29%7D%29%7Dfunction%20Fn%28e%2C%7Bviewport%24%3At%2Cheader%24%3Ar%7D%29%7Blet%20o%3Dr.pipe%28m%28%28%7Bheight%3Ai%7D%29%3D%3Ei%29%2CY%28%29%29%2Cn%3Do.pipe%28b%28%28%29%3D%3EEe%28e%29.pipe%28m%28%28%7Bheight%3Ai%7D%29%3D%3E%28%7Btop%3Ae.offsetTop%2Cbottom%3Ae.offsetTop%2Bi%7D%29%29%2CX%28%22bottom%22%29%29%29%29%3Breturn%20Q%28%5Bo%2Cn%2Ct%5D%29.pipe%28m%28%28%5Bi%2C%7Btop%3As%2Cbottom%3Aa%7D%2C%7Boffset%3A%7By%3Ac%7D%2Csize%3A%7Bheight%3Ap%7D%7D%5D%29%3D%3E%28p%3DMath.max%280%2Cp-Math.max%280%2Cs-c%2Ci%29-Math.max%280%2Cp%2Bc-a%29%29%2C%7Boffset%3As-i%2Cheight%3Ap%2Cactive%3As-i%3C%3Dc%7D%29%29%2CY%28%28i%2Cs%29%3D%3Ei.offset%3D%3D%3Ds.offset%26%26i.height%3D%3D%3Ds.height%26%26i.active%3D%3D%3Ds.active%29%29%7Dfunction%20Fa%28e%29%7Blet%20t%3D__md_get%28%22__palette%22%29%7C%7C%7Bindex%3Ae.findIndex%28o%3D%3EmatchMedia%28o.getAttribute%28%22data-md-color-media%22%29%29.matches%29%7D%2Cr%3DMath.max%280%2CMath.min%28t.index%2Ce.length-1%29%29%3Breturn%20%24%28...e%29.pipe%28re%28o%3D%3Ed%28o%2C%22change%22%29.pipe%28m%28%28%29%3D%3Eo%29%29%29%2Cq%28e%5Br%5D%29%2Cm%28o%3D%3E%28%7Bindex%3Ae.indexOf%28o%29%2Ccolor%3A%7Bmedia%3Ao.getAttribute%28%22data-md-color-media%22%29%2Cscheme%3Ao.getAttribute%28%22data-md-color-scheme%22%29%2Cprimary%3Ao.getAttribute%28%22data-md-color-primary%22%29%2Caccent%3Ao.getAttribute%28%22data-md-color-accent%22%29%7D%7D%29%29%2CB%281%29%29%7Dfunction%20jn%28e%29%7Blet%20t%3DR%28%22input%22%2Ce%29%2Cr%3DE%28%22meta%22%2C%7Bname%3A%22theme-color%22%7D%29%3Bdocument.head.appendChild%28r%29%3Blet%20o%3DE%28%22meta%22%2C%7Bname%3A%22color-scheme%22%7D%29%3Bdocument.head.appendChild%28o%29%3Blet%20n%3DAt%28%22%28prefers-color-scheme%3A%20light%29%22%29%3Breturn%20H%28%28%29%3D%3E%7Blet%20i%3Dnew%20v%3Breturn%20i.subscribe%28s%3D%3E%7Bif%28document.body.setAttribute%28%22data-md-color-switching%22%2C%22%22%29%2Cs.color.media%3D%3D%3D%22%28prefers-color-scheme%29%22%29%7Blet%20a%3DmatchMedia%28%22%28prefers-color-scheme%3A%20light%29%22%29%2Cc%3Ddocument.querySelector%28a.matches%3F%22%5Bdata-md-color-media%3D%27%28prefers-color-scheme%3A%20light%29%27%5D%22%3A%22%5Bdata-md-color-media%3D%27%28prefers-color-scheme%3A%20dark%29%27%5D%22%29%3Bs.color.scheme%3Dc.getAttribute%28%22data-md-color-scheme%22%29%2Cs.color.primary%3Dc.getAttribute%28%22data-md-color-primary%22%29%2Cs.color.accent%3Dc.getAttribute%28%22data-md-color-accent%22%29%7Dfor%28let%5Ba%2Cc%5Dof%20Object.entries%28s.color%29%29document.body.setAttribute%28%60data-md-color-%24%7Ba%7D%60%2Cc%29%3Bfor%28let%20a%3D0%3Ba%3Ct.length%3Ba%2B%2B%29%7Blet%20c%3Dt%5Ba%5D.nextElementSibling%3Bc%20instanceof%20HTMLElement%26%26%28c.hidden%3Ds.index%21%3D%3Da%29%7D__md_set%28%22__palette%22%2Cs%29%7D%29%2Ci.pipe%28m%28%28%29%3D%3E%7Blet%20s%3DTe%28%22header%22%29%2Ca%3Dwindow.getComputedStyle%28s%29%3Breturn%20o.content%3Da.colorScheme%2Ca.backgroundColor.match%28/%5Cd%2B/g%29.map%28c%3D%3E%28%2Bc%29.toString%2816%29.padStart%282%2C%220%22%29%29.join%28%22%22%29%7D%29%29.subscribe%28s%3D%3Er.content%3D%60%23%24%7Bs%7D%60%29%2Ci.pipe%28Oe%28ie%29%29.subscribe%28%28%29%3D%3E%7Bdocument.body.removeAttribute%28%22data-md-color-switching%22%29%7D%29%2CFa%28t%29.pipe%28U%28n.pipe%28Le%281%29%29%29%2Cat%28%29%2Cy%28s%3D%3Ei.next%28s%29%29%2C_%28%28%29%3D%3Ei.complete%28%29%29%2Cm%28s%3D%3EF%28%7Bref%3Ae%7D%2Cs%29%29%29%7D%29%7Dfunction%20Un%28e%2C%7Bprogress%24%3At%7D%29%7Breturn%20H%28%28%29%3D%3E%7Blet%20r%3Dnew%20v%3Breturn%20r.subscribe%28%28%7Bvalue%3Ao%7D%29%3D%3E%7Be.style.setProperty%28%22--md-progress-value%22%2C%60%24%7Bo%7D%60%29%7D%29%2Ct.pipe%28y%28o%3D%3Er.next%28%7Bvalue%3Ao%7D%29%29%2C_%28%28%29%3D%3Er.complete%28%29%29%2Cm%28o%3D%3E%28%7Bref%3Ae%2Cvalue%3Ao%7D%29%29%29%7D%29%7Dvar%20Kr%3Djt%28zr%28%29%29%3Bfunction%20ja%28e%29%7Be.setAttribute%28%22data-md-copying%22%2C%22%22%29%3Blet%20t%3De.closest%28%22%5Bdata-copy%5D%22%29%2Cr%3Dt%3Ft.getAttribute%28%22data-copy%22%29%3Ae.innerText%3Breturn%20e.removeAttribute%28%22data-md-copying%22%29%2Cr.trimEnd%28%29%7Dfunction%20Wn%28%7Balert%24%3Ae%7D%29%7BKr.default.isSupported%28%29%26%26new%20j%28t%3D%3E%7Bnew%20Kr.default%28%22%5Bdata-clipboard-target%5D%2C%20%5Bdata-clipboard-text%5D%22%2C%7Btext%3Ar%3D%3Er.getAttribute%28%22data-clipboard-text%22%29%7C%7Cja%28P%28r.getAttribute%28%22data-clipboard-target%22%29%29%29%7D%29.on%28%22success%22%2Cr%3D%3Et.next%28r%29%29%7D%29.pipe%28y%28t%3D%3E%7Bt.trigger.focus%28%29%7D%29%2Cm%28%28%29%3D%3Ege%28%22clipboard.copied%22%29%29%29.subscribe%28e%29%7Dfunction%20Dn%28e%2Ct%29%7Breturn%20e.protocol%3Dt.protocol%2Ce.hostname%3Dt.hostname%2Ce%7Dfunction%20Ua%28e%2Ct%29%7Blet%20r%3Dnew%20Map%3Bfor%28let%20o%20of%20R%28%22url%22%2Ce%29%29%7Blet%20n%3DP%28%22loc%22%2Co%29%2Ci%3D%5BDn%28new%20URL%28n.textContent%29%2Ct%29%5D%3Br.set%28%60%24%7Bi%5B0%5D%7D%60%2Ci%29%3Bfor%28let%20s%20of%20R%28%22%5Brel%3Dalternate%5D%22%2Co%29%29%7Blet%20a%3Ds.getAttribute%28%22href%22%29%3Ba%21%3Dnull%26%26i.push%28Dn%28new%20URL%28a%29%2Ct%29%29%7D%7Dreturn%20r%7Dfunction%20mr%28e%29%7Breturn%20on%28new%20URL%28%22sitemap.xml%22%2Ce%29%29.pipe%28m%28t%3D%3EUa%28t%2Cnew%20URL%28e%29%29%29%2Che%28%28%29%3D%3E%24%28new%20Map%29%29%29%7Dfunction%20Wa%28e%2Ct%29%7Bif%28%21%28e.target%20instanceof%20Element%29%29return%20L%3Blet%20r%3De.target.closest%28%22a%22%29%3Bif%28r%3D%3D%3Dnull%29return%20L%3Bif%28r.target%7C%7Ce.metaKey%7C%7Ce.ctrlKey%29return%20L%3Blet%20o%3Dnew%20URL%28r.href%29%3Breturn%20o.search%3Do.hash%3D%22%22%2Ct.has%28%60%24%7Bo%7D%60%29%3F%28e.preventDefault%28%29%2C%24%28new%20URL%28r.href%29%29%29%3AL%7Dfunction%20Nn%28e%29%7Blet%20t%3Dnew%20Map%3Bfor%28let%20r%20of%20R%28%22%3Ascope%20%3E%20%2A%22%2Ce.head%29%29t.set%28r.outerHTML%2Cr%29%3Breturn%20t%7Dfunction%20Vn%28e%29%7Bfor%28let%20t%20of%20R%28%22%5Bhref%5D%2C%20%5Bsrc%5D%22%2Ce%29%29for%28let%20r%20of%5B%22href%22%2C%22src%22%5D%29%7Blet%20o%3Dt.getAttribute%28r%29%3Bif%28o%26%26%21/%5E%28%3F%3A%5Ba-z%5D%2B%3A%29%3F%5C/%5C//i.test%28o%29%29%7Bt%5Br%5D%3Dt%5Br%5D%3Bbreak%7D%7Dreturn%20%24%28e%29%7Dfunction%20Da%28e%29%7Bfor%28let%20o%20of%5B%22%5Bdata-md-component%3Dannounce%5D%22%2C%22%5Bdata-md-component%3Dcontainer%5D%22%2C%22%5Bdata-md-component%3Dheader-topic%5D%22%2C%22%5Bdata-md-component%3Doutdated%5D%22%2C%22%5Bdata-md-component%3Dlogo%5D%22%2C%22%5Bdata-md-component%3Dskip%5D%22%2C...G%28%22navigation.tabs.sticky%22%29%3F%5B%22%5Bdata-md-component%3Dtabs%5D%22%5D%3A%5B%5D%5D%29%7Blet%20n%3Dme%28o%29%2Ci%3Dme%28o%2Ce%29%3Btypeof%20n%21%3D%22undefined%22%26%26typeof%20i%21%3D%22undefined%22%26%26n.replaceWith%28i%29%7Dlet%20t%3DNn%28document%29%3Bfor%28let%5Bo%2Cn%5Dof%20Nn%28e%29%29t.has%28o%29%3Ft.delete%28o%29%3Adocument.head.appendChild%28n%29%3Bfor%28let%20o%20of%20t.values%28%29%29o.remove%28%29%3Blet%20r%3DTe%28%22container%22%29%3Breturn%20Fe%28R%28%22script%22%2Cr%29%29.pipe%28b%28o%3D%3E%7Blet%20n%3De.createElement%28%22script%22%29%3Bif%28o.src%29%7Bfor%28let%20i%20of%20o.getAttributeNames%28%29%29n.setAttribute%28i%2Co.getAttribute%28i%29%29%3Breturn%20o.replaceWith%28n%29%2Cnew%20j%28i%3D%3E%7Bn.onload%3D%28%29%3D%3Ei.complete%28%29%7D%29%7Delse%20return%20n.textContent%3Do.textContent%2Co.replaceWith%28n%29%2CL%7D%29%2Cee%28%29%2Coe%28e%29%29%7Dfunction%20zn%28%7Blocation%24%3Ae%2Cviewport%24%3At%2Cprogress%24%3Ar%7D%29%7Blet%20o%3Dwe%28%29%3Bif%28location.protocol%3D%3D%3D%22file%3A%22%29return%20L%3Blet%20n%3Dmr%28o.base%29%3B%24%28document%29.subscribe%28Vn%29%3Blet%20i%3Dd%28document.body%2C%22click%22%29.pipe%28je%28n%29%2Cb%28%28%5Bc%2Cp%5D%29%3D%3EWa%28c%2Cp%29%29%2Cle%28%29%29%2Cs%3Dd%28window%2C%22popstate%22%29.pipe%28m%28ve%29%2Cle%28%29%29%3Bi.pipe%28ae%28t%29%29.subscribe%28%28%5Bc%2C%7Boffset%3Ap%7D%5D%29%3D%3E%7Bhistory.replaceState%28p%2C%22%22%29%2Chistory.pushState%28null%2C%22%22%2Cc%29%7D%29%2CT%28i%2Cs%29.subscribe%28e%29%3Blet%20a%3De.pipe%28X%28%22pathname%22%29%2Cb%28c%3D%3Ern%28c%2C%7Bprogress%24%3Ar%7D%29.pipe%28he%28%28%29%3D%3E%28st%28c%2C%210%29%2CL%29%29%29%29%2Cb%28Vn%29%2Cb%28Da%29%2Cle%28%29%29%3Breturn%20T%28a.pipe%28ae%28e%2C%28c%2Cp%29%3D%3Ep%29%29%2Ce.pipe%28X%28%22pathname%22%29%2Cb%28%28%29%3D%3Ee%29%2CX%28%22hash%22%29%29%2Ce.pipe%28Y%28%28c%2Cp%29%3D%3Ec.pathname%3D%3D%3Dp.pathname%26%26c.hash%3D%3D%3Dp.hash%29%2Cb%28%28%29%3D%3Ei%29%2Cy%28%28%29%3D%3Ehistory.back%28%29%29%29%29.subscribe%28c%3D%3E%7Bvar%20p%2Cl%3Bhistory.state%21%3D%3Dnull%7C%7C%21c.hash%3Fwindow.scrollTo%280%2C%28l%3D%28p%3Dhistory.state%29%3D%3Dnull%3Fvoid%200%3Ap.y%29%21%3Dnull%3Fl%3A0%29%3A%28history.scrollRestoration%3D%22auto%22%2CZo%28c.hash%29%2Chistory.scrollRestoration%3D%22manual%22%29%7D%29%2Ce.subscribe%28%28%29%3D%3E%7Bhistory.scrollRestoration%3D%22manual%22%7D%29%2Cd%28window%2C%22beforeunload%22%29.subscribe%28%28%29%3D%3E%7Bhistory.scrollRestoration%3D%22auto%22%7D%29%2Ct.pipe%28X%28%22offset%22%29%2Cbe%28100%29%29.subscribe%28%28%7Boffset%3Ac%7D%29%3D%3E%7Bhistory.replaceState%28c%2C%22%22%29%7D%29%2Ca%7Dvar%20Qn%3Djt%28Kn%28%29%29%3Bfunction%20Yn%28e%29%7Blet%20t%3De.separator.split%28%22%7C%22%29.map%28n%3D%3En.replace%28/%28%5C%28%5C%3F%5B%21%3D%3C%5D%5B%5E%29%5D%2B%5C%29%29/g%2C%22%22%29.length%3D%3D%3D0%3F%22%5CuFFFD%22%3An%29.join%28%22%7C%22%29%2Cr%3Dnew%20RegExp%28t%2C%22img%22%29%2Co%3D%28n%2Ci%2Cs%29%3D%3E%60%24%7Bi%7D%3Cmark%20data-md-highlight%3E%24%7Bs%7D%3C/mark%3E%60%3Breturn%20n%3D%3E%7Bn%3Dn.replace%28/%5B%5Cs%2A%2B%5C-%3A~%5E%5D%2B/g%2C%22%20%22%29.trim%28%29%3Blet%20i%3Dnew%20RegExp%28%60%28%5E%7C%24%7Be.separator%7D%7C%29%28%24%7Bn.replace%28/%5B%7C%5C%5C%7B%7D%28%29%5B%5C%5D%5E%24%2B%2A%3F.-%5D/g%2C%22%5C%5C%24%26%22%29.replace%28r%2C%22%7C%22%29%7D%29%60%2C%22img%22%29%3Breturn%20s%3D%3E%280%2CQn.default%29%28s%29.replace%28i%2Co%29.replace%28/%3C%5C/mark%3E%28%5Cs%2B%29%3Cmark%5B%5E%3E%5D%2A%3E/img%2C%22%241%22%29%7D%7Dfunction%20Ht%28e%29%7Breturn%20e.type%3D%3D%3D1%7Dfunction%20fr%28e%29%7Breturn%20e.type%3D%3D%3D3%7Dfunction%20Bn%28e%2Ct%29%7Blet%20r%3Dln%28e%29%3Breturn%20T%28%24%28location.protocol%21%3D%3D%22file%3A%22%29%2CWe%28%22search%22%29%29.pipe%28He%28o%3D%3Eo%29%2Cb%28%28%29%3D%3Et%29%29.subscribe%28%28%7Bconfig%3Ao%2Cdocs%3An%7D%29%3D%3Er.next%28%7Btype%3A0%2Cdata%3A%7Bconfig%3Ao%2Cdocs%3An%2Coptions%3A%7Bsuggest%3AG%28%22search.suggest%22%29%7D%7D%7D%29%29%2Cr%7Dfunction%20Gn%28%7Bdocument%24%3Ae%7D%29%7Blet%20t%3Dwe%28%29%2Cr%3DDe%28new%20URL%28%22../versions.json%22%2Ct.base%29%29.pipe%28he%28%28%29%3D%3EL%29%29%2Co%3Dr.pipe%28m%28n%3D%3E%7Blet%5B%2Ci%5D%3Dt.base.match%28/%28%5B%5E/%5D%2B%29%5C/%3F%24/%29%3Breturn%20n.find%28%28%7Bversion%3As%2Caliases%3Aa%7D%29%3D%3Es%3D%3D%3Di%7C%7Ca.includes%28i%29%29%7C%7Cn%5B0%5D%7D%29%29%3Br.pipe%28m%28n%3D%3Enew%20Map%28n.map%28i%3D%3E%5B%60%24%7Bnew%20URL%28%60../%24%7Bi.version%7D/%60%2Ct.base%29%7D%60%2Ci%5D%29%29%29%2Cb%28n%3D%3Ed%28document.body%2C%22click%22%29.pipe%28g%28i%3D%3E%21i.metaKey%26%26%21i.ctrlKey%29%2Cae%28o%29%2Cb%28%28%5Bi%2Cs%5D%29%3D%3E%7Bif%28i.target%20instanceof%20Element%29%7Blet%20a%3Di.target.closest%28%22a%22%29%3Bif%28a%26%26%21a.target%26%26n.has%28a.href%29%29%7Blet%20c%3Da.href%3Breturn%21i.target.closest%28%22.md-version%22%29%26%26n.get%28c%29%3D%3D%3Ds%3FL%3A%28i.preventDefault%28%29%2C%24%28c%29%29%7D%7Dreturn%20L%7D%29%2Cb%28i%3D%3E%7Blet%7Bversion%3As%7D%3Dn.get%28i%29%3Breturn%20mr%28new%20URL%28i%29%29.pipe%28m%28a%3D%3E%7Blet%20p%3Dve%28%29.href.replace%28t.base%2C%22%22%29%3Breturn%20a.has%28p.split%28%22%23%22%29%5B0%5D%29%3Fnew%20URL%28%60../%24%7Bs%7D/%24%7Bp%7D%60%2Ct.base%29%3Anew%20URL%28i%29%7D%29%29%7D%29%29%29%29.subscribe%28n%3D%3Est%28n%2C%210%29%29%2CQ%28%5Br%2Co%5D%29.subscribe%28%28%5Bn%2Ci%5D%29%3D%3E%7BP%28%22.md-header__topic%22%29.appendChild%28gn%28n%2Ci%29%29%7D%29%2Ce.pipe%28b%28%28%29%3D%3Eo%29%29.subscribe%28n%3D%3E%7Bvar%20s%3Blet%20i%3D__md_get%28%22__outdated%22%2CsessionStorage%29%3Bif%28i%3D%3D%3Dnull%29%7Bi%3D%210%3Blet%20a%3D%28%28s%3Dt.version%29%3D%3Dnull%3Fvoid%200%3As.default%29%7C%7C%22latest%22%3BArray.isArray%28a%29%7C%7C%28a%3D%5Ba%5D%29%3Be%3Afor%28let%20c%20of%20a%29for%28let%20p%20of%20n.aliases.concat%28n.version%29%29if%28new%20RegExp%28c%2C%22i%22%29.test%28p%29%29%7Bi%3D%211%3Bbreak%20e%7D__md_set%28%22__outdated%22%2Ci%2CsessionStorage%29%7Dif%28i%29for%28let%20a%20of%20ne%28%22outdated%22%29%29a.hidden%3D%211%7D%29%7Dfunction%20Ka%28e%2C%7Bworker%24%3At%7D%29%7Blet%7BsearchParams%3Ar%7D%3Dve%28%29%3Br.has%28%22q%22%29%26%26%28Be%28%22search%22%2C%210%29%2Ce.value%3Dr.get%28%22q%22%29%2Ce.focus%28%29%2CWe%28%22search%22%29.pipe%28He%28i%3D%3E%21i%29%29.subscribe%28%28%29%3D%3E%7Blet%20i%3Dve%28%29%3Bi.searchParams.delete%28%22q%22%29%2Chistory.replaceState%28%7B%7D%2C%22%22%2C%60%24%7Bi%7D%60%29%7D%29%29%3Blet%20o%3Dvt%28e%29%2Cn%3DT%28t.pipe%28He%28Ht%29%29%2Cd%28e%2C%22keyup%22%29%2Co%29.pipe%28m%28%28%29%3D%3Ee.value%29%2CY%28%29%29%3Breturn%20Q%28%5Bn%2Co%5D%29.pipe%28m%28%28%5Bi%2Cs%5D%29%3D%3E%28%7Bvalue%3Ai%2Cfocus%3As%7D%29%29%2CB%281%29%29%7Dfunction%20Jn%28e%2C%7Bworker%24%3At%7D%29%7Blet%20r%3Dnew%20v%2Co%3Dr.pipe%28ee%28%29%2Coe%28%210%29%29%3BQ%28%5Bt.pipe%28He%28Ht%29%29%2Cr%5D%2C%28i%2Cs%29%3D%3Es%29.pipe%28X%28%22value%22%29%29.subscribe%28%28%7Bvalue%3Ai%7D%29%3D%3Et.next%28%7Btype%3A2%2Cdata%3Ai%7D%29%29%2Cr.pipe%28X%28%22focus%22%29%29.subscribe%28%28%7Bfocus%3Ai%7D%29%3D%3E%7Bi%26%26Be%28%22search%22%2Ci%29%7D%29%2Cd%28e.form%2C%22reset%22%29.pipe%28U%28o%29%29.subscribe%28%28%29%3D%3Ee.focus%28%29%29%3Blet%20n%3DP%28%22header%20%5Bfor%3D__search%5D%22%29%3Breturn%20d%28n%2C%22click%22%29.subscribe%28%28%29%3D%3Ee.focus%28%29%29%2CKa%28e%2C%7Bworker%24%3At%7D%29.pipe%28y%28i%3D%3Er.next%28i%29%29%2C_%28%28%29%3D%3Er.complete%28%29%29%2Cm%28i%3D%3EF%28%7Bref%3Ae%7D%2Ci%29%29%2CB%281%29%29%7Dfunction%20Xn%28e%2C%7Bworker%24%3At%2Cquery%24%3Ar%7D%29%7Blet%20o%3Dnew%20v%2Cn%3DYo%28e.parentElement%29.pipe%28g%28Boolean%29%29%2Ci%3De.parentElement%2Cs%3DP%28%22%3Ascope%20%3E%20%3Afirst-child%22%2Ce%29%2Ca%3DP%28%22%3Ascope%20%3E%20%3Alast-child%22%2Ce%29%3BWe%28%22search%22%29.subscribe%28l%3D%3Ea.setAttribute%28%22role%22%2Cl%3F%22list%22%3A%22presentation%22%29%29%2Co.pipe%28ae%28r%29%2CIr%28t.pipe%28He%28Ht%29%29%29%29.subscribe%28%28%5B%7Bitems%3Al%7D%2C%7Bvalue%3Af%7D%5D%29%3D%3E%7Bswitch%28l.length%29%7Bcase%200%3As.textContent%3Df.length%3Fge%28%22search.result.none%22%29%3Age%28%22search.result.placeholder%22%29%3Bbreak%3Bcase%201%3As.textContent%3Dge%28%22search.result.one%22%29%3Bbreak%3Bdefault%3Alet%20u%3Dar%28l.length%29%3Bs.textContent%3Dge%28%22search.result.other%22%2Cu%29%7D%7D%29%3Blet%20c%3Do.pipe%28y%28%28%29%3D%3Ea.innerHTML%3D%22%22%29%2Cb%28%28%7Bitems%3Al%7D%29%3D%3ET%28%24%28...l.slice%280%2C10%29%29%2C%24%28...l.slice%2810%29%29.pipe%28Ke%284%29%2Cjr%28n%29%2Cb%28%28%5Bf%5D%29%3D%3Ef%29%29%29%29%2Cm%28hn%29%2Cle%28%29%29%3Breturn%20c.subscribe%28l%3D%3Ea.appendChild%28l%29%29%2Cc.pipe%28re%28l%3D%3E%7Blet%20f%3Dme%28%22details%22%2Cl%29%3Breturn%20typeof%20f%3D%3D%22undefined%22%3FL%3Ad%28f%2C%22toggle%22%29.pipe%28U%28o%29%2Cm%28%28%29%3D%3Ef%29%29%7D%29%29.subscribe%28l%3D%3E%7Bl.open%3D%3D%3D%211%26%26l.offsetTop%3C%3Di.scrollTop%26%26i.scrollTo%28%7Btop%3Al.offsetTop%7D%29%7D%29%2Ct.pipe%28g%28fr%29%2Cm%28%28%7Bdata%3Al%7D%29%3D%3El%29%29.pipe%28y%28l%3D%3Eo.next%28l%29%29%2C_%28%28%29%3D%3Eo.complete%28%29%29%2Cm%28l%3D%3EF%28%7Bref%3Ae%7D%2Cl%29%29%29%7Dfunction%20Qa%28e%2C%7Bquery%24%3At%7D%29%7Breturn%20t.pipe%28m%28%28%7Bvalue%3Ar%7D%29%3D%3E%7Blet%20o%3Dve%28%29%3Breturn%20o.hash%3D%22%22%2Cr%3Dr.replace%28/%5Cs%2B/g%2C%22%2B%22%29.replace%28/%26/g%2C%22%2526%22%29.replace%28/%3D/g%2C%22%253D%22%29%2Co.search%3D%60q%3D%24%7Br%7D%60%2C%7Burl%3Ao%7D%7D%29%29%7Dfunction%20Zn%28e%2Ct%29%7Blet%20r%3Dnew%20v%2Co%3Dr.pipe%28ee%28%29%2Coe%28%210%29%29%3Breturn%20r.subscribe%28%28%7Burl%3An%7D%29%3D%3E%7Be.setAttribute%28%22data-clipboard-text%22%2Ce.href%29%2Ce.href%3D%60%24%7Bn%7D%60%7D%29%2Cd%28e%2C%22click%22%29.pipe%28U%28o%29%29.subscribe%28n%3D%3En.preventDefault%28%29%29%2CQa%28e%2Ct%29.pipe%28y%28n%3D%3Er.next%28n%29%29%2C_%28%28%29%3D%3Er.complete%28%29%29%2Cm%28n%3D%3EF%28%7Bref%3Ae%7D%2Cn%29%29%29%7Dfunction%20ei%28e%2C%7Bworker%24%3At%2Ckeyboard%24%3Ar%7D%29%7Blet%20o%3Dnew%20v%2Cn%3DTe%28%22search-query%22%29%2Ci%3DT%28d%28n%2C%22keydown%22%29%2Cd%28n%2C%22focus%22%29%29.pipe%28Oe%28ie%29%2Cm%28%28%29%3D%3En.value%29%2CY%28%29%29%3Breturn%20o.pipe%28je%28i%29%2Cm%28%28%5B%7Bsuggest%3Aa%7D%2Cc%5D%29%3D%3E%7Blet%20p%3Dc.split%28/%28%5B%5Cs-%5D%2B%29/%29%3Bif%28a%21%3Dnull%26%26a.length%26%26p%5Bp.length-1%5D%29%7Blet%20l%3Da%5Ba.length-1%5D%3Bl.startsWith%28p%5Bp.length-1%5D%29%26%26%28p%5Bp.length-1%5D%3Dl%29%7Delse%20p.length%3D0%3Breturn%20p%7D%29%29.subscribe%28a%3D%3Ee.innerHTML%3Da.join%28%22%22%29.replace%28/%5Cs/g%2C%22%26nbsp%3B%22%29%29%2Cr.pipe%28g%28%28%7Bmode%3Aa%7D%29%3D%3Ea%3D%3D%3D%22search%22%29%29.subscribe%28a%3D%3E%7Bswitch%28a.type%29%7Bcase%22ArrowRight%22%3Ae.innerText.length%26%26n.selectionStart%3D%3D%3Dn.value.length%26%26%28n.value%3De.innerText%29%3Bbreak%7D%7D%29%2Ct.pipe%28g%28fr%29%2Cm%28%28%7Bdata%3Aa%7D%29%3D%3Ea%29%29.pipe%28y%28a%3D%3Eo.next%28a%29%29%2C_%28%28%29%3D%3Eo.complete%28%29%29%2Cm%28%28%29%3D%3E%28%7Bref%3Ae%7D%29%29%29%7Dfunction%20ti%28e%2C%7Bindex%24%3At%2Ckeyboard%24%3Ar%7D%29%7Blet%20o%3Dwe%28%29%3Btry%7Blet%20n%3DBn%28o.search%2Ct%29%2Ci%3DTe%28%22search-query%22%2Ce%29%2Cs%3DTe%28%22search-result%22%2Ce%29%3Bd%28e%2C%22click%22%29.pipe%28g%28%28%7Btarget%3Ac%7D%29%3D%3Ec%20instanceof%20Element%26%26%21%21c.closest%28%22a%22%29%29%29.subscribe%28%28%29%3D%3EBe%28%22search%22%2C%211%29%29%2Cr.pipe%28g%28%28%7Bmode%3Ac%7D%29%3D%3Ec%3D%3D%3D%22search%22%29%29.subscribe%28c%3D%3E%7Blet%20p%3DRe%28%29%3Bswitch%28c.type%29%7Bcase%22Enter%22%3Aif%28p%3D%3D%3Di%29%7Blet%20l%3Dnew%20Map%3Bfor%28let%20f%20of%20R%28%22%3Afirst-child%20%5Bhref%5D%22%2Cs%29%29%7Blet%20u%3Df.firstElementChild%3Bl.set%28f%2CparseFloat%28u.getAttribute%28%22data-md-score%22%29%29%29%7Dif%28l.size%29%7Blet%5B%5Bf%5D%5D%3D%5B...l%5D.sort%28%28%5B%2Cu%5D%2C%5B%2Ch%5D%29%3D%3Eh-u%29%3Bf.click%28%29%7Dc.claim%28%29%7Dbreak%3Bcase%22Escape%22%3Acase%22Tab%22%3ABe%28%22search%22%2C%211%29%2Ci.blur%28%29%3Bbreak%3Bcase%22ArrowUp%22%3Acase%22ArrowDown%22%3Aif%28typeof%20p%3D%3D%22undefined%22%29i.focus%28%29%3Belse%7Blet%20l%3D%5Bi%2C...R%28%22%3Anot%28details%29%20%3E%20%5Bhref%5D%2C%20summary%2C%20details%5Bopen%5D%20%5Bhref%5D%22%2Cs%29%5D%2Cf%3DMath.max%280%2C%28Math.max%280%2Cl.indexOf%28p%29%29%2Bl.length%2B%28c.type%3D%3D%3D%22ArrowUp%22%3F-1%3A1%29%29%25l.length%29%3Bl%5Bf%5D.focus%28%29%7Dc.claim%28%29%3Bbreak%3Bdefault%3Ai%21%3D%3DRe%28%29%26%26i.focus%28%29%7D%7D%29%2Cr.pipe%28g%28%28%7Bmode%3Ac%7D%29%3D%3Ec%3D%3D%3D%22global%22%29%29.subscribe%28c%3D%3E%7Bswitch%28c.type%29%7Bcase%22f%22%3Acase%22s%22%3Acase%22/%22%3Ai.focus%28%29%2Ci.select%28%29%2Cc.claim%28%29%3Bbreak%7D%7D%29%3Blet%20a%3DJn%28i%2C%7Bworker%24%3An%7D%29%3Breturn%20T%28a%2CXn%28s%2C%7Bworker%24%3An%2Cquery%24%3Aa%7D%29%29.pipe%28%24e%28...ne%28%22search-share%22%2Ce%29.map%28c%3D%3EZn%28c%2C%7Bquery%24%3Aa%7D%29%29%2C...ne%28%22search-suggest%22%2Ce%29.map%28c%3D%3Eei%28c%2C%7Bworker%24%3An%2Ckeyboard%24%3Ar%7D%29%29%29%29%7Dcatch%28n%29%7Breturn%20e.hidden%3D%210%2Cqe%7D%7Dfunction%20ri%28e%2C%7Bindex%24%3At%2Clocation%24%3Ar%7D%29%7Breturn%20Q%28%5Bt%2Cr.pipe%28q%28ve%28%29%29%2Cg%28o%3D%3E%21%21o.searchParams.get%28%22h%22%29%29%29%5D%29.pipe%28m%28%28%5Bo%2Cn%5D%29%3D%3EYn%28o.config%29%28n.searchParams.get%28%22h%22%29%29%29%2Cm%28o%3D%3E%7Bvar%20s%3Blet%20n%3Dnew%20Map%2Ci%3Ddocument.createNodeIterator%28e%2CNodeFilter.SHOW_TEXT%29%3Bfor%28let%20a%3Di.nextNode%28%29%3Ba%3Ba%3Di.nextNode%28%29%29if%28%28s%3Da.parentElement%29%21%3Dnull%26%26s.offsetHeight%29%7Blet%20c%3Da.textContent%2Cp%3Do%28c%29%3Bp.length%3Ec.length%26%26n.set%28a%2Cp%29%7Dfor%28let%5Ba%2Cc%5Dof%20n%29%7Blet%7BchildNodes%3Ap%7D%3DE%28%22span%22%2Cnull%2Cc%29%3Ba.replaceWith%28...Array.from%28p%29%29%7Dreturn%7Bref%3Ae%2Cnodes%3An%7D%7D%29%29%7Dfunction%20Ya%28e%2C%7Bviewport%24%3At%2Cmain%24%3Ar%7D%29%7Blet%20o%3De.closest%28%22.md-grid%22%29%2Cn%3Do.offsetTop-o.parentElement.offsetTop%3Breturn%20Q%28%5Br%2Ct%5D%29.pipe%28m%28%28%5B%7Boffset%3Ai%2Cheight%3As%7D%2C%7Boffset%3A%7By%3Aa%7D%7D%5D%29%3D%3E%28s%3Ds%2BMath.min%28n%2CMath.max%280%2Ca-i%29%29-n%2C%7Bheight%3As%2Clocked%3Aa%3E%3Di%2Bn%7D%29%29%2CY%28%28i%2Cs%29%3D%3Ei.height%3D%3D%3Ds.height%26%26i.locked%3D%3D%3Ds.locked%29%29%7Dfunction%20Qr%28e%2Co%29%7Bvar%20n%3Do%2C%7Bheader%24%3At%7D%3Dn%2Cr%3Dto%28n%2C%5B%22header%24%22%5D%29%3Blet%20i%3DP%28%22.md-sidebar__scrollwrap%22%2Ce%29%2C%7By%3As%7D%3DUe%28i%29%3Breturn%20H%28%28%29%3D%3E%7Blet%20a%3Dnew%20v%2Cc%3Da.pipe%28ee%28%29%2Coe%28%210%29%29%2Cp%3Da.pipe%28Me%280%2Cde%29%29%3Breturn%20p.pipe%28ae%28t%29%29.subscribe%28%7Bnext%28%5B%7Bheight%3Al%7D%2C%7Bheight%3Af%7D%5D%29%7Bi.style.height%3D%60%24%7Bl-2%2As%7Dpx%60%2Ce.style.top%3D%60%24%7Bf%7Dpx%60%7D%2Ccomplete%28%29%7Bi.style.height%3D%22%22%2Ce.style.top%3D%22%22%7D%7D%29%2Cp.pipe%28He%28%29%29.subscribe%28%28%29%3D%3E%7Bfor%28let%20l%20of%20R%28%22.md-nav__link--active%5Bhref%5D%22%2Ce%29%29%7Bif%28%21l.clientHeight%29continue%3Blet%20f%3Dl.closest%28%22.md-sidebar__scrollwrap%22%29%3Bif%28typeof%20f%21%3D%22undefined%22%29%7Blet%20u%3Dl.offsetTop-f.offsetTop%2C%7Bheight%3Ah%7D%3Dpe%28f%29%3Bf.scrollTo%28%7Btop%3Au-h/2%7D%29%7D%7D%7D%29%2Cfe%28R%28%22label%5Btabindex%5D%22%2Ce%29%29.pipe%28re%28l%3D%3Ed%28l%2C%22click%22%29.pipe%28Oe%28ie%29%2Cm%28%28%29%3D%3El%29%2CU%28c%29%29%29%29.subscribe%28l%3D%3E%7Blet%20f%3DP%28%60%5Bid%3D%22%24%7Bl.htmlFor%7D%22%5D%60%29%3BP%28%60%5Baria-labelledby%3D%22%24%7Bl.id%7D%22%5D%60%29.setAttribute%28%22aria-expanded%22%2C%60%24%7Bf.checked%7D%60%29%7D%29%2CYa%28e%2Cr%29.pipe%28y%28l%3D%3Ea.next%28l%29%29%2C_%28%28%29%3D%3Ea.complete%28%29%29%2Cm%28l%3D%3EF%28%7Bref%3Ae%7D%2Cl%29%29%29%7D%29%7Dfunction%20oi%28e%2Ct%29%7Bif%28typeof%20t%21%3D%22undefined%22%29%7Blet%20r%3D%60https%3A//api.github.com/repos/%24%7Be%7D/%24%7Bt%7D%60%3Breturn%20Lt%28De%28%60%24%7Br%7D/releases/latest%60%29.pipe%28he%28%28%29%3D%3EL%29%2Cm%28o%3D%3E%28%7Bversion%3Ao.tag_name%7D%29%29%2CQe%28%7B%7D%29%29%2CDe%28r%29.pipe%28he%28%28%29%3D%3EL%29%2Cm%28o%3D%3E%28%7Bstars%3Ao.stargazers_count%2Cforks%3Ao.forks_count%7D%29%29%2CQe%28%7B%7D%29%29%29.pipe%28m%28%28%5Bo%2Cn%5D%29%3D%3EF%28F%28%7B%7D%2Co%29%2Cn%29%29%29%7Delse%7Blet%20r%3D%60https%3A//api.github.com/users/%24%7Be%7D%60%3Breturn%20De%28r%29.pipe%28m%28o%3D%3E%28%7Brepositories%3Ao.public_repos%7D%29%29%2CQe%28%7B%7D%29%29%7D%7Dfunction%20ni%28e%2Ct%29%7Blet%20r%3D%60https%3A//%24%7Be%7D/api/v4/projects/%24%7BencodeURIComponent%28t%29%7D%60%3Breturn%20De%28r%29.pipe%28he%28%28%29%3D%3EL%29%2Cm%28%28%7Bstar_count%3Ao%2Cforks_count%3An%7D%29%3D%3E%28%7Bstars%3Ao%2Cforks%3An%7D%29%29%2CQe%28%7B%7D%29%29%7Dfunction%20ii%28e%29%7Blet%20t%3De.match%28/%5E.%2Bgithub%5C.com%5C/%28%5B%5E/%5D%2B%29%5C/%3F%28%5B%5E/%5D%2B%29%3F/i%29%3Bif%28t%29%7Blet%5B%2Cr%2Co%5D%3Dt%3Breturn%20oi%28r%2Co%29%7Dif%28t%3De.match%28/%5E.%2B%3F%28%5B%5E/%5D%2Agitlab%5B%5E/%5D%2B%29%5C/%28.%2B%3F%29%5C/%3F%24/i%29%2Ct%29%7Blet%5B%2Cr%2Co%5D%3Dt%3Breturn%20ni%28r%2Co%29%7Dreturn%20L%7Dvar%20Ba%3Bfunction%20Ga%28e%29%7Breturn%20Ba%7C%7C%28Ba%3DH%28%28%29%3D%3E%7Blet%20t%3D__md_get%28%22__source%22%2CsessionStorage%29%3Bif%28t%29return%20%24%28t%29%3Bif%28ne%28%22consent%22%29.length%29%7Blet%20o%3D__md_get%28%22__consent%22%29%3Bif%28%21%28o%26%26o.github%29%29return%20L%7Dreturn%20ii%28e.href%29.pipe%28y%28o%3D%3E__md_set%28%22__source%22%2Co%2CsessionStorage%29%29%29%7D%29.pipe%28he%28%28%29%3D%3EL%29%2Cg%28t%3D%3EObject.keys%28t%29.length%3E0%29%2Cm%28t%3D%3E%28%7Bfacts%3At%7D%29%29%2CB%281%29%29%29%7Dfunction%20ai%28e%29%7Blet%20t%3DP%28%22%3Ascope%20%3E%20%3Alast-child%22%2Ce%29%3Breturn%20H%28%28%29%3D%3E%7Blet%20r%3Dnew%20v%3Breturn%20r.subscribe%28%28%7Bfacts%3Ao%7D%29%3D%3E%7Bt.appendChild%28bn%28o%29%29%2Ct.classList.add%28%22md-source__repository--active%22%29%7D%29%2CGa%28e%29.pipe%28y%28o%3D%3Er.next%28o%29%29%2C_%28%28%29%3D%3Er.complete%28%29%29%2Cm%28o%3D%3EF%28%7Bref%3Ae%7D%2Co%29%29%29%7D%29%7Dfunction%20Ja%28e%2C%7Bviewport%24%3At%2Cheader%24%3Ar%7D%29%7Breturn%20Ee%28document.body%29.pipe%28b%28%28%29%3D%3Epr%28e%2C%7Bheader%24%3Ar%2Cviewport%24%3At%7D%29%29%2Cm%28%28%7Boffset%3A%7By%3Ao%7D%7D%29%3D%3E%28%7Bhidden%3Ao%3E%3D10%7D%29%29%2CX%28%22hidden%22%29%29%7Dfunction%20si%28e%2Ct%29%7Breturn%20H%28%28%29%3D%3E%7Blet%20r%3Dnew%20v%3Breturn%20r.subscribe%28%7Bnext%28%7Bhidden%3Ao%7D%29%7Be.hidden%3Do%7D%2Ccomplete%28%29%7Be.hidden%3D%211%7D%7D%29%2C%28G%28%22navigation.tabs.sticky%22%29%3F%24%28%7Bhidden%3A%211%7D%29%3AJa%28e%2Ct%29%29.pipe%28y%28o%3D%3Er.next%28o%29%29%2C_%28%28%29%3D%3Er.complete%28%29%29%2Cm%28o%3D%3EF%28%7Bref%3Ae%7D%2Co%29%29%29%7D%29%7Dfunction%20Xa%28e%2C%7Bviewport%24%3At%2Cheader%24%3Ar%7D%29%7Blet%20o%3Dnew%20Map%2Cn%3DR%28%22.md-nav__link%22%2Ce%29%3Bfor%28let%20a%20of%20n%29%7Blet%20c%3DdecodeURIComponent%28a.hash.substring%281%29%29%2Cp%3Dme%28%60%5Bid%3D%22%24%7Bc%7D%22%5D%60%29%3Btypeof%20p%21%3D%22undefined%22%26%26o.set%28a%2Cp%29%7Dlet%20i%3Dr.pipe%28X%28%22height%22%29%2Cm%28%28%7Bheight%3Aa%7D%29%3D%3E%7Blet%20c%3DTe%28%22main%22%29%2Cp%3DP%28%22%3Ascope%20%3E%20%3Afirst-child%22%2Cc%29%3Breturn%20a%2B.8%2A%28p.offsetTop-c.offsetTop%29%7D%29%2Cle%28%29%29%3Breturn%20Ee%28document.body%29.pipe%28X%28%22height%22%29%2Cb%28a%3D%3EH%28%28%29%3D%3E%7Blet%20c%3D%5B%5D%3Breturn%20%24%28%5B...o%5D.reduce%28%28p%2C%5Bl%2Cf%5D%29%3D%3E%7Bfor%28%3Bc.length%26%26o.get%28c%5Bc.length-1%5D%29.tagName%3E%3Df.tagName%3B%29c.pop%28%29%3Blet%20u%3Df.offsetTop%3Bfor%28%3B%21u%26%26f.parentElement%3B%29f%3Df.parentElement%2Cu%3Df.offsetTop%3Blet%20h%3Df.offsetParent%3Bfor%28%3Bh%3Bh%3Dh.offsetParent%29u%2B%3Dh.offsetTop%3Breturn%20p.set%28%5B...c%3D%5B...c%2Cl%5D%5D.reverse%28%29%2Cu%29%7D%2Cnew%20Map%29%29%7D%29.pipe%28m%28c%3D%3Enew%20Map%28%5B...c%5D.sort%28%28%5B%2Cp%5D%2C%5B%2Cl%5D%29%3D%3Ep-l%29%29%29%2Cje%28i%29%2Cb%28%28%5Bc%2Cp%5D%29%3D%3Et.pipe%28Rr%28%28%5Bl%2Cf%5D%2C%7Boffset%3A%7By%3Au%7D%2Csize%3Ah%7D%29%3D%3E%7Blet%20w%3Du%2Bh.height%3E%3DMath.floor%28a.height%29%3Bfor%28%3Bf.length%3B%29%7Blet%5B%2CA%5D%3Df%5B0%5D%3Bif%28A-p%3Cu%7C%7Cw%29l%3D%5B...l%2Cf.shift%28%29%5D%3Belse%20break%7Dfor%28%3Bl.length%3B%29%7Blet%5B%2CA%5D%3Dl%5Bl.length-1%5D%3Bif%28A-p%3E%3Du%26%26%21w%29f%3D%5Bl.pop%28%29%2C...f%5D%3Belse%20break%7Dreturn%5Bl%2Cf%5D%7D%2C%5B%5B%5D%2C%5B...c%5D%5D%29%2CY%28%28l%2Cf%29%3D%3El%5B0%5D%3D%3D%3Df%5B0%5D%26%26l%5B1%5D%3D%3D%3Df%5B1%5D%29%29%29%29%29%29.pipe%28m%28%28%5Ba%2Cc%5D%29%3D%3E%28%7Bprev%3Aa.map%28%28%5Bp%5D%29%3D%3Ep%29%2Cnext%3Ac.map%28%28%5Bp%5D%29%3D%3Ep%29%7D%29%29%2Cq%28%7Bprev%3A%5B%5D%2Cnext%3A%5B%5D%7D%29%2CKe%282%2C1%29%2Cm%28%28%5Ba%2Cc%5D%29%3D%3Ea.prev.length%3Cc.prev.length%3F%7Bprev%3Ac.prev.slice%28Math.max%280%2Ca.prev.length-1%29%2Cc.prev.length%29%2Cnext%3A%5B%5D%7D%3A%7Bprev%3Ac.prev.slice%28-1%29%2Cnext%3Ac.next.slice%280%2Cc.next.length-a.next.length%29%7D%29%29%7Dfunction%20ci%28e%2C%7Bviewport%24%3At%2Cheader%24%3Ar%2Cmain%24%3Ao%2Ctarget%24%3An%7D%29%7Breturn%20H%28%28%29%3D%3E%7Blet%20i%3Dnew%20v%2Cs%3Di.pipe%28ee%28%29%2Coe%28%210%29%29%3Bif%28i.subscribe%28%28%7Bprev%3Aa%2Cnext%3Ac%7D%29%3D%3E%7Bfor%28let%5Bp%5Dof%20c%29p.classList.remove%28%22md-nav__link--passed%22%29%2Cp.classList.remove%28%22md-nav__link--active%22%29%3Bfor%28let%5Bp%2C%5Bl%5D%5Dof%20a.entries%28%29%29l.classList.add%28%22md-nav__link--passed%22%29%2Cl.classList.toggle%28%22md-nav__link--active%22%2Cp%3D%3D%3Da.length-1%29%7D%29%2CG%28%22toc.follow%22%29%29%7Blet%20a%3DT%28t.pipe%28be%281%29%2Cm%28%28%29%3D%3E%7B%7D%29%29%2Ct.pipe%28be%28250%29%2Cm%28%28%29%3D%3E%22smooth%22%29%29%29%3Bi.pipe%28g%28%28%7Bprev%3Ac%7D%29%3D%3Ec.length%3E0%29%2Cje%28o.pipe%28Oe%28ie%29%29%29%2Cae%28a%29%29.subscribe%28%28%5B%5B%7Bprev%3Ac%7D%5D%2Cp%5D%29%3D%3E%7Blet%5Bl%5D%3Dc%5Bc.length-1%5D%3Bif%28l.offsetHeight%29%7Blet%20f%3Dsr%28l%29%3Bif%28typeof%20f%21%3D%22undefined%22%29%7Blet%20u%3Dl.offsetTop-f.offsetTop%2C%7Bheight%3Ah%7D%3Dpe%28f%29%3Bf.scrollTo%28%7Btop%3Au-h/2%2Cbehavior%3Ap%7D%29%7D%7D%7D%29%7Dreturn%20G%28%22navigation.tracking%22%29%26%26t.pipe%28U%28s%29%2CX%28%22offset%22%29%2Cbe%28250%29%2CLe%281%29%2CU%28n.pipe%28Le%281%29%29%29%2Cat%28%7Bdelay%3A250%7D%29%2Cae%28i%29%29.subscribe%28%28%5B%2C%7Bprev%3Aa%7D%5D%29%3D%3E%7Blet%20c%3Dve%28%29%2Cp%3Da%5Ba.length-1%5D%3Bif%28p%26%26p.length%29%7Blet%5Bl%5D%3Dp%2C%7Bhash%3Af%7D%3Dnew%20URL%28l.href%29%3Bc.hash%21%3D%3Df%26%26%28c.hash%3Df%2Chistory.replaceState%28%7B%7D%2C%22%22%2C%60%24%7Bc%7D%60%29%29%7Delse%20c.hash%3D%22%22%2Chistory.replaceState%28%7B%7D%2C%22%22%2C%60%24%7Bc%7D%60%29%7D%29%2CXa%28e%2C%7Bviewport%24%3At%2Cheader%24%3Ar%7D%29.pipe%28y%28a%3D%3Ei.next%28a%29%29%2C_%28%28%29%3D%3Ei.complete%28%29%29%2Cm%28a%3D%3EF%28%7Bref%3Ae%7D%2Ca%29%29%29%7D%29%7Dfunction%20Za%28e%2C%7Bviewport%24%3At%2Cmain%24%3Ar%2Ctarget%24%3Ao%7D%29%7Blet%20n%3Dt.pipe%28m%28%28%7Boffset%3A%7By%3As%7D%7D%29%3D%3Es%29%2CKe%282%2C1%29%2Cm%28%28%5Bs%2Ca%5D%29%3D%3Es%3Ea%26%26a%3E0%29%2CY%28%29%29%2Ci%3Dr.pipe%28m%28%28%7Bactive%3As%7D%29%3D%3Es%29%29%3Breturn%20Q%28%5Bi%2Cn%5D%29.pipe%28m%28%28%5Bs%2Ca%5D%29%3D%3E%21%28s%26%26a%29%29%2CY%28%29%2CU%28o.pipe%28Le%281%29%29%29%2Coe%28%210%29%2Cat%28%7Bdelay%3A250%7D%29%2Cm%28s%3D%3E%28%7Bhidden%3As%7D%29%29%29%7Dfunction%20pi%28e%2C%7Bviewport%24%3At%2Cheader%24%3Ar%2Cmain%24%3Ao%2Ctarget%24%3An%7D%29%7Blet%20i%3Dnew%20v%2Cs%3Di.pipe%28ee%28%29%2Coe%28%210%29%29%3Breturn%20i.subscribe%28%7Bnext%28%7Bhidden%3Aa%7D%29%7Be.hidden%3Da%2Ca%3F%28e.setAttribute%28%22tabindex%22%2C%22-1%22%29%2Ce.blur%28%29%29%3Ae.removeAttribute%28%22tabindex%22%29%7D%2Ccomplete%28%29%7Be.style.top%3D%22%22%2Ce.hidden%3D%210%2Ce.removeAttribute%28%22tabindex%22%29%7D%7D%29%2Cr.pipe%28U%28s%29%2CX%28%22height%22%29%29.subscribe%28%28%7Bheight%3Aa%7D%29%3D%3E%7Be.style.top%3D%60%24%7Ba%2B16%7Dpx%60%7D%29%2Cd%28e%2C%22click%22%29.subscribe%28a%3D%3E%7Ba.preventDefault%28%29%2Cwindow.scrollTo%28%7Btop%3A0%7D%29%7D%29%2CZa%28e%2C%7Bviewport%24%3At%2Cmain%24%3Ao%2Ctarget%24%3An%7D%29.pipe%28y%28a%3D%3Ei.next%28a%29%29%2C_%28%28%29%3D%3Ei.complete%28%29%29%2Cm%28a%3D%3EF%28%7Bref%3Ae%7D%2Ca%29%29%29%7Dfunction%20li%28%7Bdocument%24%3Ae%7D%29%7Be.pipe%28b%28%28%29%3D%3ER%28%22.md-ellipsis%22%29%29%2Cre%28t%3D%3Eyt%28t%29.pipe%28U%28e.pipe%28Le%281%29%29%29%2Cg%28r%3D%3Er%29%2Cm%28%28%29%3D%3Et%29%2Cye%281%29%29%29%2Cg%28t%3D%3Et.offsetWidth%3Ct.scrollWidth%29%2Cre%28t%3D%3E%7Blet%20r%3Dt.innerText%2Co%3Dt.closest%28%22a%22%29%7C%7Ct%3Breturn%20o.title%3Dr%2CGe%28o%29.pipe%28U%28e.pipe%28Le%281%29%29%29%2C_%28%28%29%3D%3Eo.removeAttribute%28%22title%22%29%29%29%7D%29%29.subscribe%28%29%2Ce.pipe%28b%28%28%29%3D%3ER%28%22.md-status%22%29%29%2Cre%28t%3D%3EGe%28t%29%29%29.subscribe%28%29%7Dfunction%20mi%28%7Bdocument%24%3Ae%2Ctablet%24%3At%7D%29%7Be.pipe%28b%28%28%29%3D%3ER%28%22.md-toggle--indeterminate%22%29%29%2Cy%28r%3D%3E%7Br.indeterminate%3D%210%2Cr.checked%3D%211%7D%29%2Cre%28r%3D%3Ed%28r%2C%22change%22%29.pipe%28Fr%28%28%29%3D%3Er.classList.contains%28%22md-toggle--indeterminate%22%29%29%2Cm%28%28%29%3D%3Er%29%29%29%2Cae%28t%29%29.subscribe%28%28%5Br%2Co%5D%29%3D%3E%7Br.classList.remove%28%22md-toggle--indeterminate%22%29%2Co%26%26%28r.checked%3D%211%29%7D%29%7Dfunction%20es%28%29%7Breturn/%28iPad%7CiPhone%7CiPod%29/.test%28navigator.userAgent%29%7Dfunction%20fi%28%7Bdocument%24%3Ae%7D%29%7Be.pipe%28b%28%28%29%3D%3ER%28%22%5Bdata-md-scrollfix%5D%22%29%29%2Cy%28t%3D%3Et.removeAttribute%28%22data-md-scrollfix%22%29%29%2Cg%28es%29%2Cre%28t%3D%3Ed%28t%2C%22touchstart%22%29.pipe%28m%28%28%29%3D%3Et%29%29%29%29.subscribe%28t%3D%3E%7Blet%20r%3Dt.scrollTop%3Br%3D%3D%3D0%3Ft.scrollTop%3D1%3Ar%2Bt.offsetHeight%3D%3D%3Dt.scrollHeight%26%26%28t.scrollTop%3Dr-1%29%7D%29%7Dfunction%20ui%28%7Bviewport%24%3Ae%2Ctablet%24%3At%7D%29%7BQ%28%5BWe%28%22search%22%29%2Ct%5D%29.pipe%28m%28%28%5Br%2Co%5D%29%3D%3Er%26%26%21o%29%2Cb%28r%3D%3E%24%28r%29.pipe%28Ye%28r%3F400%3A100%29%29%29%2Cae%28e%29%29.subscribe%28%28%5Br%2C%7Boffset%3A%7By%3Ao%7D%7D%5D%29%3D%3E%7Bif%28r%29document.body.setAttribute%28%22data-md-scrolllock%22%2C%22%22%29%2Cdocument.body.style.top%3D%60-%24%7Bo%7Dpx%60%3Belse%7Blet%20n%3D-1%2AparseInt%28document.body.style.top%2C10%29%3Bdocument.body.removeAttribute%28%22data-md-scrolllock%22%29%2Cdocument.body.style.top%3D%22%22%2Cn%26%26window.scrollTo%280%2Cn%29%7D%7D%29%7DObject.entries%7C%7C%28Object.entries%3Dfunction%28e%29%7Blet%20t%3D%5B%5D%3Bfor%28let%20r%20of%20Object.keys%28e%29%29t.push%28%5Br%2Ce%5Br%5D%5D%29%3Breturn%20t%7D%29%3BObject.values%7C%7C%28Object.values%3Dfunction%28e%29%7Blet%20t%3D%5B%5D%3Bfor%28let%20r%20of%20Object.keys%28e%29%29t.push%28e%5Br%5D%29%3Breturn%20t%7D%29%3Btypeof%20Element%21%3D%22undefined%22%26%26%28Element.prototype.scrollTo%7C%7C%28Element.prototype.scrollTo%3Dfunction%28e%2Ct%29%7Btypeof%20e%3D%3D%22object%22%3F%28this.scrollLeft%3De.left%2Cthis.scrollTop%3De.top%29%3A%28this.scrollLeft%3De%2Cthis.scrollTop%3Dt%29%7D%29%2CElement.prototype.replaceWith%7C%7C%28Element.prototype.replaceWith%3Dfunction%28...e%29%7Blet%20t%3Dthis.parentNode%3Bif%28t%29%7Be.length%3D%3D%3D0%26%26t.removeChild%28this%29%3Bfor%28let%20r%3De.length-1%3Br%3E%3D0%3Br--%29%7Blet%20o%3De%5Br%5D%3Btypeof%20o%3D%3D%22string%22%3Fo%3Ddocument.createTextNode%28o%29%3Ao.parentNode%26%26o.parentNode.removeChild%28o%29%2Cr%3Ft.insertBefore%28this.previousSibling%2Co%29%3At.replaceChild%28o%2Cthis%29%7D%7D%7D%29%29%3Bfunction%20ts%28%29%7Breturn%20location.protocol%3D%3D%3D%22file%3A%22%3Fgt%28%60%24%7Bnew%20URL%28%22search/search_index.js%22%2CYr.base%29%7D%60%29.pipe%28m%28%28%29%3D%3E__index%29%2CB%281%29%29%3ADe%28new%20URL%28%22search/search_index.json%22%2CYr.base%29%29%7Ddocument.documentElement.classList.remove%28%22no-js%22%29%3Bdocument.documentElement.classList.add%28%22js%22%29%3Bvar%20rt%3DNo%28%29%2CRt%3DJo%28%29%2Cwt%3Den%28Rt%29%2CBr%3DGo%28%29%2C_e%3Dpn%28%29%2Cur%3DAt%28%22%28min-width%3A%20960px%29%22%29%2Chi%3DAt%28%22%28min-width%3A%201220px%29%22%29%2Cbi%3Dtn%28%29%2CYr%3Dwe%28%29%2Cvi%3Ddocument.forms.namedItem%28%22search%22%29%3Fts%28%29%3Aqe%2CGr%3Dnew%20v%3BWn%28%7Balert%24%3AGr%7D%29%3Bvar%20Jr%3Dnew%20v%3BG%28%22navigation.instant%22%29%26%26zn%28%7Blocation%24%3ARt%2Cviewport%24%3A_e%2Cprogress%24%3AJr%7D%29.subscribe%28rt%29%3Bvar%20di%3B%28%28di%3DYr.version%29%3D%3Dnull%3Fvoid%200%3Adi.provider%29%3D%3D%3D%22mike%22%26%26Gn%28%7Bdocument%24%3Art%7D%29%3BT%28Rt%2Cwt%29.pipe%28Ye%28125%29%29.subscribe%28%28%29%3D%3E%7BBe%28%22drawer%22%2C%211%29%2CBe%28%22search%22%2C%211%29%7D%29%3BBr.pipe%28g%28%28%7Bmode%3Ae%7D%29%3D%3Ee%3D%3D%3D%22global%22%29%29.subscribe%28e%3D%3E%7Bswitch%28e.type%29%7Bcase%22p%22%3Acase%22%2C%22%3Alet%20t%3Dme%28%22link%5Brel%3Dprev%5D%22%29%3Btypeof%20t%21%3D%22undefined%22%26%26st%28t%29%3Bbreak%3Bcase%22n%22%3Acase%22.%22%3Alet%20r%3Dme%28%22link%5Brel%3Dnext%5D%22%29%3Btypeof%20r%21%3D%22undefined%22%26%26st%28r%29%3Bbreak%3Bcase%22Enter%22%3Alet%20o%3DRe%28%29%3Bo%20instanceof%20HTMLLabelElement%26%26o.click%28%29%7D%7D%29%3Bli%28%7Bdocument%24%3Art%7D%29%3Bmi%28%7Bdocument%24%3Art%2Ctablet%24%3Aur%7D%29%3Bfi%28%7Bdocument%24%3Art%7D%29%3Bui%28%7Bviewport%24%3A_e%2Ctablet%24%3Aur%7D%29%3Bvar%20tt%3DRn%28Te%28%22header%22%29%2C%7Bviewport%24%3A_e%7D%29%2C%24t%3Drt.pipe%28m%28%28%29%3D%3ETe%28%22main%22%29%29%2Cb%28e%3D%3EFn%28e%2C%7Bviewport%24%3A_e%2Cheader%24%3Att%7D%29%29%2CB%281%29%29%2Crs%3DT%28...ne%28%22consent%22%29.map%28e%3D%3Efn%28e%2C%7Btarget%24%3Awt%7D%29%29%2C...ne%28%22dialog%22%29.map%28e%3D%3E%24n%28e%2C%7Balert%24%3AGr%7D%29%29%2C...ne%28%22header%22%29.map%28e%3D%3EPn%28e%2C%7Bviewport%24%3A_e%2Cheader%24%3Att%2Cmain%24%3A%24t%7D%29%29%2C...ne%28%22palette%22%29.map%28e%3D%3Ejn%28e%29%29%2C...ne%28%22progress%22%29.map%28e%3D%3EUn%28e%2C%7Bprogress%24%3AJr%7D%29%29%2C...ne%28%22search%22%29.map%28e%3D%3Eti%28e%2C%7Bindex%24%3Avi%2Ckeyboard%24%3ABr%7D%29%29%2C...ne%28%22source%22%29.map%28e%3D%3Eai%28e%29%29%29%2Cos%3DH%28%28%29%3D%3ET%28...ne%28%22announce%22%29.map%28e%3D%3Emn%28e%29%29%2C...ne%28%22content%22%29.map%28e%3D%3EHn%28e%2C%7Bviewport%24%3A_e%2Ctarget%24%3Awt%2Cprint%24%3Abi%7D%29%29%2C...ne%28%22content%22%29.map%28e%3D%3EG%28%22search.highlight%22%29%3Fri%28e%2C%7Bindex%24%3Avi%2Clocation%24%3ARt%7D%29%3AL%29%2C...ne%28%22header-title%22%29.map%28e%3D%3EIn%28e%2C%7Bviewport%24%3A_e%2Cheader%24%3Att%7D%29%29%2C...ne%28%22sidebar%22%29.map%28e%3D%3Ee.getAttribute%28%22data-md-type%22%29%3D%3D%3D%22navigation%22%3FUr%28hi%2C%28%29%3D%3EQr%28e%2C%7Bviewport%24%3A_e%2Cheader%24%3Att%2Cmain%24%3A%24t%7D%29%29%3AUr%28ur%2C%28%29%3D%3EQr%28e%2C%7Bviewport%24%3A_e%2Cheader%24%3Att%2Cmain%24%3A%24t%7D%29%29%29%2C...ne%28%22tabs%22%29.map%28e%3D%3Esi%28e%2C%7Bviewport%24%3A_e%2Cheader%24%3Att%7D%29%29%2C...ne%28%22toc%22%29.map%28e%3D%3Eci%28e%2C%7Bviewport%24%3A_e%2Cheader%24%3Att%2Cmain%24%3A%24t%2Ctarget%24%3Awt%7D%29%29%2C...ne%28%22top%22%29.map%28e%3D%3Epi%28e%2C%7Bviewport%24%3A_e%2Cheader%24%3Att%2Cmain%24%3A%24t%2Ctarget%24%3Awt%7D%29%29%29%29%2Cgi%3Drt.pipe%28b%28%28%29%3D%3Eos%29%2C%24e%28rs%29%2CB%281%29%29%3Bgi.subscribe%28%29%3Bwindow.document%24%3Drt%3Bwindow.location%24%3DRt%3Bwindow.target%24%3Dwt%3Bwindow.keyboard%24%3DBr%3Bwindow.viewport%24%3D_e%3Bwindow.tablet%24%3Dur%3Bwindow.screen%24%3Dhi%3Bwindow.print%24%3Dbi%3Bwindow.alert%24%3DGr%3Bwindow.progress%24%3DJr%3Bwindow.component%24%3Dgi%3B%7D%29%28%29%3B%0A//%23%20sourceMappingURL%3Dbundle.8fd75fb4.min.js.map%0A%0A"></script><!--URL:../assets/javascripts/bundle.8fd75fb4.min.js-->
|
||
<script src="data:application/javascript,/%2A%20%0AJavascript%20functions%20to%20help%20make%20the%20print%20page%20more%20PDF%20friendly%0A%2A/%0A%0A/%2A%0AGenerates%20a%20table%20of%20contents%20for%20the%20print%20site%20page.%0AOnly%20called%20when%20print-site-plugin%20option%20%27add_table_of_contents%27%20is%20set%20to%20true%0A%2A/%0Afunction%20generate_toc%28%29%20%7B%0A%0A%20%20var%20ToC%20%3D%20%22%22%0A%0A%20%20var%20newLine%2C%20el%2C%20title%2C%20link%3B%0A%0A%20%20const%20toc_elements%20%3D%20document.querySelectorAll%28%0A%20%20%20%20%22%23print-site-page%20h1.nav-section-title%2C%20%23print-site-page%20h1.nav-section-title-end%2C%22%20%2B%0A%20%20%20%20%22%23print-site-page%20h2.nav-section-title%2C%20%23print-site-page%20h2.nav-section-title-end%2C%22%20%2B%0A%20%20%20%20%22%23print-site-page%20h3.nav-section-title%2C%20%23print-site-page%20h3.nav-section-title-end%2C%22%20%2B%0A%20%20%20%20%22%23print-site-page%20h4.nav-section-title%2C%20%23print-site-page%20h4.nav-section-title-end%2C%22%20%2B%0A%20%20%20%20%22%23print-site-page%20h5.nav-section-title%2C%20%23print-site-page%20h5.nav-section-title-end%2C%22%20%2B%0A%20%20%20%20%22%23print-site-page%20h6.nav-section-title%2C%20%23print-site-page%20h6.nav-section-title-end%2C%22%20%2B%0A%20%20%20%20%22section.print-page%20h1%2Csection.print-page%20h2%2Csection.print-page%20h3%2C%22%20%2B%0A%20%20%20%20%22section.print-page%20h4%2Csection.print-page%20h5%2Csection.print-page%20h6%22%29%0A%20%20%0A%20%20var%20current_heading_depth%20%3D%200%3B%0A%20%20var%20current_section_depth%20%3D%200%3B%0A%0A%20%20//%20Extract%20table%20of%20contents%20depth%0A%20%20//%20basically%20plugin%20setting%2C%20passed%20via%20a%20data%20attribute%0A%20%20var%20toc_depth%20%3D%20document.getElementById%28%22print-page-toc%22%29.getAttribute%28%22data-toc-depth%22%29%0A%0A%20%20for%20%28var%20i%20%3D%200%3B%20i%20%3C%20toc_elements.length%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20%0A%20%20%20%20//%20Get%20the%20info%20from%20the%20element%0A%20%20%20%20el%20%3D%20toc_elements%5Bi%5D%0A%20%20%20%20link%20%3D%20%22%23%22%20%2B%20el.id%3B%0A%20%20%20%20tag%20%3D%20el.tagName%0A%20%20%20%20tag_level%20%3D%20tag.substring%281%29%0A%20%20%20%20//%20Get%20the%20text%20of%20a%20heading%0A%20%20%20%20//%20We%20use%20.firstChild.nodeValue%20instead%20of%20.innerText%0A%20%20%20%20//%20because%20of%20elements%20like%3A%0A%20%20%20%20//%20%3Ch1%20id%3D%22index-mkdocs-print-site-plugin%22%3E%0A%20%20%20%20//%20%20%20%20%20mkdocs-print-site-plugin%3Ca%20class%3D%22headerlink%22%20href%3D%22%23index-mkdocs-print-site-plugin%22%20title%3D%22Permanent%20link%22%3E%E2%86%B5%3C/a%3E%0A%20%20%20%20//%20%20%3C/h1%3E%0A%20%20%20%20title%20%3D%20el.firstChild.nodeValue%3B%0A%20%20%20%20if%20%28%20%21%20title%20%29%20%7B%0A%20%20%20%20%20%20continue%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20Don%27t%20put%20the%20toc%20h1%20in%20the%20toc%0A%20%20%20%20if%20%28%20el.classList.contains%28%27print-page-toc-title%27%29%20%29%20%7B%0A%20%20%20%20%20%20continue%3B%0A%20%20%20%20%7D%0A%20%20%20%20//%20Ignore%20the%20MkDocs%20keyboard%20Model%0A%20%20%20%20if%20%28%20el.id.indexOf%28%22keyboardModalLabel%22%29%20%3E%20-1%20%29%20%7B%0A%20%20%20%20%20%20continue%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%20print-site-plugin%20has%20a%20setting%20to%20control%20TOC%20depth%0A%20%20%20%20if%20%28%20tag_level%20%3E%20toc_depth%20%29%20%7B%0A%20%20%20%20%20%20continue%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if%20%28el.classList.contains%28%27nav-section-title%27%29%20%29%20%7B%0A%20%20%20%20%20%20//%20Use%20the%20tag%20level%20of%20the%20first%20item%20in%20the%20section%20to%20close%20off%20any%20nested%20%3Cul%3E%0A%20%20%20%20%20%20el%20%3D%20toc_elements%5Bi%2B1%5D%0A%20%20%20%20%20%20link%20%3D%20%22%23%22%20%2B%20el.id%3B%0A%20%20%20%20%20%20tag%20%3D%20el.tagName%0A%20%20%20%20%20%20tag_level%20%3D%20tag.substring%281%29%0A%20%20%20%20%20%20while%20%28tag_level%20%3E%20current_heading_depth%29%20%7B%0A%20%20%20%20%20%20%20%20current_heading_depth%2B%2B%3B%0A%20%20%20%20%20%20%20%20ToC%20%2B%3D%20%22%3Cul%20class%3D%27print-site-toc-level-%22%20%2B%20current_heading_depth%20%2B%20%22%27%3E%22%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20while%20%28tag_level%20%3C%20current_heading_depth%29%20%7B%0A%20%20%20%20%20%20%20%20current_heading_depth--%3B%0A%20%20%20%20%20%20%20%20ToC%20%2B%3D%20%22%3C/ul%3E%22%3B%20%0A%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20//%20Insert%20a%20section%20heading%20%3Cli%3E%20item%2C%20however%20deeply%20we%20are%20nested.%0A%20%20%20%20%20%20current_section_depth%2B%2B%3B%0A%20%20%20%20%20%20//%20Insert%20item%20as%20a%20section%20title%20in%20the%20current%20list%0A%20%20%20%20%20%20ToC%20%2B%3D%20%22%3Cli%20class%3D%27toc-nav-section-title%20toc-nav-section-title-level-%22%20%2B%20%28current_section_depth%29%20%2B%20%22%27%3E%22%20%2B%20title%20%2B%20%22%3C/li%3E%22%3B%0A%20%20%20%20%20%20%0A%20%20%20%20%20%20//%20Start%20a%20new%20ul%20for%20the%20section%0A%20%20%20%20%20%20ToC%20%2B%3D%20%22%3Cul%20class%3D%27print-site-toc-level-%22%20%2B%20current_heading_depth%20%2B%20%22%20toc-section-line-border%27%3E%22%3B%0A%20%20%20%20%20%20continue%3B%0A%20%20%20%20%7D%0A%0A%0A%20%20%20%20if%20%28el.classList.contains%28%27nav-section-title-end%27%29%20%29%20%7B%0A%0A%20%20%20%20%20%20current_section_depth--%3B%0A%20%20%20%20%20%20//%20Close%20the%20special%20section%20ul%0A%20%20%20%20%20%20ToC%20%2B%3D%20%22%3C/ul%3E%22%3B%0A%0A%20%20%20%20%20%20continue%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20while%20%28tag_level%20%3E%20current_heading_depth%29%20%7B%0A%20%20%20%20%20%20current_heading_depth%2B%2B%3B%0A%20%20%20%20%20%20ToC%20%2B%3D%20%22%3Cul%20class%3D%27print-site-toc-level-%22%20%2B%20current_heading_depth%20%2B%20%22%27%3E%22%3B%0A%20%20%20%20%7D%0A%20%20%20%20while%20%28tag_level%20%3C%20current_heading_depth%29%20%7B%0A%20%20%20%20%20%20current_heading_depth--%3B%0A%20%20%20%20%20%20ToC%20%2B%3D%20%22%3C/ul%3E%22%3B%20%0A%20%20%20%20%7D%0A%0A%0A%20%20%20%20newLine%20%3D%20%22%3Cli%3E%22%20%2B%0A%20%20%20%20%20%20%22%3Ca%20href%3D%27%22%20%2B%20link%20%2B%20%22%27%3E%22%20%2B%0A%20%20%20%20%20%20%20%20title%20%2B%0A%20%20%20%20%20%20%22%3C/a%3E%22%20%2B%0A%20%20%20%20%22%3C/li%3E%22%3B%0A%0A%20%20%20%20ToC%20%2B%3D%20newLine%3B%0A%0A%20%20%7D%3B%0A%0A%20%20ToC%20%2B%3D%20%22%3C/ul%3E%22%0A%0A%20%20document.querySelectorAll%28%22%23print-page-toc%20nav%22%29%5B0%5D.insertAdjacentHTML%28%22beforeend%22%2C%20ToC%29%3B%0A%0A%7D"></script><!--URL:../js/print-site.js-->
|
||
</body></html><!--Generated by HTMLArk 2024-02-22 15:58:53.570856. Original URL public_html/print_page/index.html--> |