From 6fa11d3c342970e0bba525d29c4cd3b25b501f82 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Tue, 5 Nov 2024 12:35:20 +0700 Subject: [PATCH 01/36] feat: keymanweb new interfaces are done part 1 --- cdn/dev/css/kmw-body.css | 106 +++++++++++++++ cdn/dev/css/kmw-desktop.css | 69 ++++++++-- cdn/dev/css/kmw-header.css | 180 ++++++++++++++++++++++++ cdn/dev/img/keymanweb-mini-logo-88.png | Bin 0 -> 3182 bytes inc/head.php | 5 + index.php | 181 +++++++++++++++++-------- 6 files changed, 476 insertions(+), 65 deletions(-) create mode 100644 cdn/dev/css/kmw-body.css create mode 100644 cdn/dev/css/kmw-header.css create mode 100644 cdn/dev/img/keymanweb-mini-logo-88.png diff --git a/cdn/dev/css/kmw-body.css b/cdn/dev/css/kmw-body.css new file mode 100644 index 0000000..d9c7aae --- /dev/null +++ b/cdn/dev/css/kmw-body.css @@ -0,0 +1,106 @@ +body { + background-color: #F6F6F6; +} + +.text-area-container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; +} + +.type-your-keyboard { + width: 80%; + scroll-behavior: auto; + resize: none; + margin-top: 120px; +} + +.type-your-keyboard textarea { + box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgb(209, 213, 219) 0px 0px 0px 1px inset; + height: 500px; +} + +/* + keyboard +*/ +.keys { + display: flex; + list-style: none; +} + +.keyboard-container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 10px; +} +.keyboard-container div { + width: 50%; +} + +.keyboard-container div ul li { + box-shadow: 0px -6px 10px rgba(255, 255, 255, 1), 0px 4px 15px rgba(0, 0, 0, 0.15); + transition: 0.5s; + height: 2.5em; + font-size: 1em; + width: 3em; + margin: 0.3em; + background-color: #f2f2f2; + border-radius: 0.5em; + line-height: 2.5em; + letter-spacing: 1px; + text-align: center; +} + +.keyboard-container div ul li:hover { + box-shadow: 0 2px 0 rgba(0, 0, 0, 0.15); + cursor: pointer; + top: 3px; +} + +#red { + background-color: #a3f7bf; + width: 5em; +} + +#blue { + background-color: #9aebed; + width: 6em; +} + +#rebeca { + background-color: #fecd1a; + width: 8em; +} + +#green { + background-color: #fa86be; + width: 6em; +} + +#up { + background-color: #8594e4; + width: 8em; +} + +#yellow { + background-color: #fffcab; + width: 5em; +} + +#grey { + background-color: #898989; + width: 3.3em; +} + +#one { + background-color: #faafff; + width: 5em; +} + +#two { + width: 24.5em; +} \ No newline at end of file diff --git a/cdn/dev/css/kmw-desktop.css b/cdn/dev/css/kmw-desktop.css index 2e5003c..8c9afbe 100644 --- a/cdn/dev/css/kmw-desktop.css +++ b/cdn/dev/css/kmw-desktop.css @@ -45,7 +45,7 @@ header, #content, footer { .box { -webkit-border-radius: 8px;-moz-border-radius: 8px; border-radius: 8px; -moz-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); - } +} /* =================== @@ -53,9 +53,12 @@ header, #content, footer { =================== */ header { - margin-top:0px; - height: 96px; - } + position: fixed; + margin-left: auto; + margin-right: auto; + padding-bottom: 30px; + height: 70px; +} header > div > img { width: 100%; @@ -63,19 +66,57 @@ header > div > img { height: 8px; } +#headerBackground { + display: grid; + grid-template-columns: 10% 70% 20%; + justify-content: left; + align-items: center; + box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; + margin: 0px 0px; + background-color: white; +} + +#headerLeft { + display: flex; + flex-direction: row; +} + #headerLeft img { display: block; /* default (inline) display inserts an unwanted bottom border */ - margin-top:0px; - margin-left:28px; - height:88px; + margin: 0px 20px; + height:50px; /*width: 660px;*/ /*-webkit-border-radius: 0px 0px 8px 8px; -moz-border-radius: 0px 0px 8px 8px; border-radius: 0px 0px 8px 8px;*/ } + +#headerMiddle { + display: flex; + flex-direction: row; + justify-content: left; + align-items: center; + width: 100%; + margin-left: 20px; +} + +#headerMiddle div { + margin: 15px; +} + #headerRight { - display: block; - float: right; - text-align: right; - } + display: flex; + flex-direction: row; + justify-content: end; + align-items: center; + width: 100%; +} + +#headerRight div { + margin-right: 20px; +} + +#headerRight div > * { + margin-left: 10px; +} #headerRight-beta { display: block; @@ -88,6 +129,10 @@ header > div > img { #headerRight-link { padding: 0 12px 0; } + +#headerBar { + width: 100%; +} /* ==================== ==Content Elements== @@ -441,6 +486,8 @@ aside #learn { } .footer{ + bottom: 0; + left: 0; float: left; text-align: center; width: 100%; diff --git a/cdn/dev/css/kmw-header.css b/cdn/dev/css/kmw-header.css new file mode 100644 index 0000000..0114584 --- /dev/null +++ b/cdn/dev/css/kmw-header.css @@ -0,0 +1,180 @@ + +/* + Menu +*/ +svg { + fill-rule: evenodd; + clip-rule: evenodd; + stroke-linecap: round; + stroke-linejoin: round; + stroke-miterlimit: 1.5; + cursor:pointer; +} + +#menu path { + fill: none; + stroke: #FC7200; + stroke-width: 5px; +} + +svg + svg { + margin-left: 1.5rem; +} + +.icons { + display: flex; + flex-wrap: wrap; + justify-content: center; + align-items: center; +} + +#top, #bottom { + stroke-dasharray: 30, 75.39; + transition: all 0.6s cubic-bezier(0.6, 0.33, 0.67, 1.29); +} + +svg.active #top, svg.active #bottom { + stroke-dasharray: 75.39; + stroke-dashoffset: -60; +} + +svg:nth-child(2) { + transform: rotate(0deg); + transition: transform 0.6s cubic-bezier(0.165, 0.84, 0.44, 1); +} + +svg:nth-child(2) path { + transition: all 0.4s ease-in-out 0.6s; +} + +svg:nth-child(2).active { + transform: rotate(180deg); +} + +.rocket #top { + stroke-dasharray: 30, 88; +} + +#menu-list { + display: none; +} +/* + Search +*/ + +.form { + position: relative; + width: 50%; +} + +.form .left-pan { + position: absolute; + right: 17px; + top: 10px; + padding: 2px; + border-left: 1px solid #000000; +} + +.left-pan { + padding-left: 7px; +} + +.left-pan i { + padding-left: 10px; +} + +.form .form-input { + height: 50px; + width: 100%; + text-indent: 33px; + border-radius: 20px; + text-align: left; + background-color: rgb(233, 228, 228); +} + +.form-input:focus { + box-shadow: none; + border:none; +} + +/* + Keyboard Dropdown +*/ +.dropdown { + width: 25%; + background-color: #B92034; + color: white; + margin-left: 25px; +} + +.dropdown-toggle{ + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + height: 50px; + border: 2px solid #B92034; + font-weight: 600; +} +.dropdown-toggle:focus{ + box-shadow: none !important; +} + +.dropdown-toggle::after { + display: none; +} + +.dropdown-menu{ + width: 200px; + border: 2px solid #B92034; + padding: 0rem 0; + transform: translate3d(0px, 50px, 0px) !important; +} + +.dropdown-item:focus, .dropdown-item:hover { + color: #ffffff; + background-color: #B92034; + padding: 12px; +} + +.dropdown-item { + display: block; + width: 100%; + padding: 12px; +} + +/* + Tools +*/ + +input[type="range"] { + font-size: 1.5rem; + width: 100px; +} + +input[type="range"] { + color: #69B7D2; + --thumb-height: 1.125em; + --track-height: 0.125em; + --track-color: rgba(186, 0, 0, 0.2); + --brightness-hover: 180%; + --brightness-down: 80%; + --clip-edges: 0.125em; +} + +input[type="range"] { + position: relative; + background: #fff0; + overflow: hidden; +} + +input[type="range"]:active { + cursor: grabbing; +} + +input[type="range"]:disabled { + filter: grayscale(1); + opacity: 0.3; + cursor: not-allowed; +} + diff --git a/cdn/dev/img/keymanweb-mini-logo-88.png b/cdn/dev/img/keymanweb-mini-logo-88.png new file mode 100644 index 0000000000000000000000000000000000000000..c1b274e1b305b3b8e13859c2deb63f0714fe5120 GIT binary patch literal 3182 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 U{tjgMq5uE@07*qoM6N<$f<7Joj{pDw literal 0 HcmV?d00001 diff --git a/inc/head.php b/inc/head.php index caa4ddc..bc47e57 100644 --- a/inc/head.php +++ b/inc/head.php @@ -126,6 +126,11 @@ function doInitSentry() { " /> " /> " /> +" /> +" /> +" /> + + - + + + From bc905cb5d45bc04efa57a0bd4ef70c22a09c353d Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Thu, 14 Nov 2024 10:58:37 +0700 Subject: [PATCH 04/36] feat: delete a new folder frontend_kmw/index.php --- frontend_kmw/index.php | 82 ------------------------------------------ 1 file changed, 82 deletions(-) delete mode 100644 frontend_kmw/index.php diff --git a/frontend_kmw/index.php b/frontend_kmw/index.php deleted file mode 100644 index 3baf70a..0000000 --- a/frontend_kmw/index.php +++ /dev/null @@ -1,82 +0,0 @@ - - - -
-
-
- - Pre-release version - Return to version - - New release! - Try beta version - - -
-
- - " alt='KeymanWeb.com' title="KeymanWeb version " width="20px" height="20px"/> -
-
- " alt="" /> -
-
-
- - - - - - - - - From 2fccf982e3f167a423498341c4999057373ea2c0 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Wed, 19 Feb 2025 13:17:38 +0700 Subject: [PATCH 05/36] feat: a prototype design for keymanweb with new styles and scripts --- cdn/dev/css/kmw-body.css | 322 +++++++++++++----- cdn/dev/css/kmw-header.css | 353 ++++++++++++++------ cdn/dev/img/headerbar copy.png | Bin 0 -> 507 bytes cdn/dev/img/keyboard.png | Bin 0 -> 116931 bytes cdn/dev/img/keymanweb-mini-logo-88 copy.png | Bin 0 -> 3182 bytes cdn/dev/js/kmwBody.js | 130 +++++++ cdn/dev/js/kmwHeader.js | 297 +++++++++++----- inc/head.php | 10 +- index.php | 251 +++++--------- 9 files changed, 893 insertions(+), 470 deletions(-) create mode 100644 cdn/dev/img/headerbar copy.png create mode 100644 cdn/dev/img/keyboard.png create mode 100644 cdn/dev/img/keymanweb-mini-logo-88 copy.png create mode 100644 cdn/dev/js/kmwBody.js diff --git a/cdn/dev/css/kmw-body.css b/cdn/dev/css/kmw-body.css index ef7424e..5602ae1 100644 --- a/cdn/dev/css/kmw-body.css +++ b/cdn/dev/css/kmw-body.css @@ -1,105 +1,249 @@ +* { + box-sizing: border-box; +} + body { background-color: #F6F6F6; + overflow: hidden; } -.text-area-container { +.container-flex { display: flex; flex-direction: column; - justify-content: center; align-items: center; - width: 100%; -} - -.type-your-keyboard { - width: 80%; - scroll-behavior: auto; - resize: none; - margin-top: 95px; } -.type-your-keyboard textarea { - box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgb(209, 213, 219) 0px 0px 0px 1px inset; - height: 500px; +.hidden { + display: none; } -/* - keyboard -*/ -.keys { - display: flex; - list-style: none; +a { + margin: 0 !important; + padding: 0 !important; + text-decoration: none !important; } -.keyboard-container { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; -} -.keyboard-container div { - width: 50%; -} - -.keyboard-container div ul li { - box-shadow: 0px -6px 10px rgba(255, 255, 255, 1), 0px 4px 15px rgba(0, 0, 0, 0.15); - transition: 0.5s; - height: 2.5em; - font-size: 1em; - width: 3em; - margin: 0.3em; - background-color: #f2f2f2; - border-radius: 0.5em; - line-height: 2.5em; - letter-spacing: 1px; - text-align: center; -} - -.keyboard-container div ul li:hover { - box-shadow: 0 2px 0 rgba(0, 0, 0, 0.15); +/* Icons */ +.fa-keyboard, .fa-download { cursor: pointer; - top: 3px; -} - -#red { - background-color: #a3f7bf; - width: 5em; -} - -#blue { - background-color: #9aebed; - width: 6em; -} - -#rebeca { - background-color: #fecd1a; - width: 8em; -} - -#green { - background-color: #fa86be; - width: 6em; -} - -#up { - background-color: #8594e4; - width: 8em; -} - -#yellow { - background-color: #fffcab; - width: 5em; -} - -#grey { - background-color: #898989; - width: 3.3em; -} - -#one { - background-color: #faafff; - width: 5em; } -#two { - width: 24.5em; -} \ No newline at end of file +.fa-bars:hover { + cursor: ns-resize; +} + +/* End of Icons */ + +/* ================================ + Computer and Laptop screen sizes +================================ */ +@media screen and (min-width: 1000px) { + .item { + margin: 5px + } + /* + Text area + */ + .textarea-container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + } + + .textarea { + padding: 10px; + margin-top: 95px; + resize: none; + width: 100%; + height: 45vh; + box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgb(209, 213, 219) 0px 0px 0px 1px inset; + } + + #copyTool { + color: #2EADD3; + position: absolute; + right: 20px; + top: 125px; + opacity: 50%; + } + #copyTool:hover { + cursor: pointer; + opacity: 100%; + } + + #fullscreenTool { + color: #2EADD3; + position: absolute; + right: 20px; + bottom: 270px; + opacity: 50%; + } + #fullscreenTool:hover { + cursor: pointer; + opacity: 100%; + } + + .show-keyboard-box { + width: 100%; + text-align: center; + position: absolute; + bottom: 0; + } + + .show-keyboard-box:hover { + opacity: 80%; + } + + /* Divider */ + .divider-container { + user-select: none; + display: grid; + grid-template-columns: auto auto auto; + align-items: center; + justify-content: space-evenly; + width: 90%; + } + + .divider-container > * { + margin: 10px; + } + + .divider-container i { + opacity: 50%; + } + + .divider-container i:hover { + color: #FC7200; + opacity: 100%; + } + + /* Keyboard */ + .keyboard-and-download { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + } + + .example-box { + background-color: #2EADD3; + color: white; + width: 100%; + text-align: center; + padding: 5px; + border-bottom: 1px solid rgb(159, 159, 159); + display: grid; + grid-template-columns: auto 90% auto; + } + + .example-box p { + margin: 10px; + } + + .keyboard-container { + width: 50%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + } + + .keyboard-area { + user-select: none; + flex: 1; + width: 100%; + height: auto; + } + + .keyboard { + width: 100%; + } + + .keyboard-download-box { + width: 15%; + padding: 5px; + position: relative; + left: 100px; + border-radius: 10px; + box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgb(209, 213, 219) 0px 0px 0px 1px inset; + } + + .keyboard-download-box p { + margin: 10px; + text-align: center; + } + + .keyboard-download-box > * { + display: flex; + flex-direction: column; + align-items: center; + margin: 10px; + } +} + +/* ================================ + Tablet screen size +================================ */ + +@media screen and (min-width: 600px) { + .item { + margin: 5px + } + /* + Text area + */ + .textarea-container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + } + + .textarea { + padding: 10px; + margin-top: 95px; + resize: none; + width: 100%; + height: 45vh; + box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgb(209, 213, 219) 0px 0px 0px 1px inset; + } + + #copyTool { + color: #2EADD3; + position: absolute; + right: 20px; + top: 125px; + opacity: 50%; + } + #copyTool:hover { + cursor: pointer; + opacity: 100%; + } + + #fullscreenTool { + color: #2EADD3; + position: absolute; + right: 20px; + bottom: 270px; + opacity: 50%; + } + #fullscreenTool:hover { + cursor: pointer; + opacity: 100%; + } + + .show-keyboard-box { + width: 100%; + text-align: center; + position: absolute; + bottom: 0; + } + + .show-keyboard-box:hover { + opacity: 80%; + } +} diff --git a/cdn/dev/css/kmw-header.css b/cdn/dev/css/kmw-header.css index 052dfe6..1bfc594 100644 --- a/cdn/dev/css/kmw-header.css +++ b/cdn/dev/css/kmw-header.css @@ -1,112 +1,247 @@ - -/* - Search -*/ - -.form { - position: relative; - width: 50%; -} - -.form .left-pan { - position: absolute; - right: 17px; - top: 12px; - padding: 2px; - border-left: 1px solid #000000; -} - -.left-pan { - padding-left: 7px; -} - -.left-pan i { - padding-left: 10px; -} - -.form .form-input { - height: 50px; +/* ================================ + Computer and Laptop screen sizes +================================ */ +@media screen and (min-width: 1000px) { + header { + position: fixed; + margin-left: auto; + margin-right: auto; + padding-bottom: 30px; + z-index: 1; + } + + header > div > img { + width: 100%; + display: block; + height: 8px; + } + + header #headerBackground { + padding: 10px; + } + + #headerBackground { + display: grid; + grid-template-columns: 5% 85% 10%; + justify-content: left; + align-items: center; + box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; + margin: 0px 0px; + background-color: white; + } + + #headerLeft { + margin-left: 10px; + } + + #headerLeft img { + display: block; + height: 50px; + } + + #headerMiddle { + display: flex; + flex-direction: row; + justify-content: left; + align-items: center; + width: 70%; + margin: 0px 10px; + } + + #headerMiddle > div { + margin-right: 10px; + } + + #headerRight { + display: grid; + grid-template-columns: 50% 50%; + justify-items: end; + align-items: center; + width: 100%; + } + + /* + Language Search Menu + */ + + .form { + position: relative; + width: 50%; + } + + .form .left-pan { + position: absolute; + right: 17px; + top: 12px; + padding: 2px; + border-left: 1px solid #000000; + } + + .left-pan { + padding-left: 7px; + } + + .left-pan i { + padding-left: 10px; + } + + .form .form-input { + height: 50px; + width: 100%; + text-indent: 15px; + border-radius: 15px; + text-align: left; + background-color: rgb(233, 228, 228); + } + + .form-input:focus { + box-shadow: none; + border:none; + } + /* Search Dropdown list */ + + ul.dropdown-menu { + padding: 10px; + margin: 0; + } + + .dropdown-submenu .dropdown-menu li.dropdown-item{ + width: 100%; + } + + .dropdown-submenu { + position: relative; + } + + .dropdown-submenu .dropdown-menu { + margin-top: -6px; + border-radius: 0.25rem; + width: fit-content; + } + + .dropdown-submenu:hover > .dropdown-menu { + display: inline; + } + + #headerMiddle .dropdown-menu .top-row .setting { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + margin: 10px 10px !important; + } + + #headerMiddle .dropdown-menu .top-row .setting .col:last-child { + position: relative; + left: 150px; + } + + /* Selected Keyboard Menu */ + #keyboardSelectionDropdown { + width: fit-content !important; + overflow: hidden; + } + + #keyboardSelectionDropdown > * { + width: 100%; + } + + #keyboardSelectionList { + display: grid; + grid-template-columns: 50% 50%; + } + + #keyboardSelectionList ul { + width: 369px; + } + + .language-name { + display: grid; + grid-template-columns: 95% 5%; + align-items: center; + } + + .language-name i { + opacity: 100%; + float: right; + color: #B92034; + } + + .language { + margin: 10px; + } + + .language ul { + list-style: none; + } + + #removeLanguage { + cursor: pointer; + } + + .keyboard-list i { + float: right; + opacity: 50%; + } + } + + +@media screen and (min-width: 600px) { + header { + position: fixed; + margin-left: auto; + margin-right: auto; + padding-bottom: 30px; + z-index: 1; + } + + header > div > img { width: 100%; - text-indent: 15px; - border-radius: 15px; - text-align: left; - background-color: rgb(233, 228, 228); -} - -.form-input:focus { - box-shadow: none; - border:none; -} - -#dropdown-menu { - width: 100%; -} - -ul.dropdown-menu { - padding: 0; - margin: 0; -} - -.dropdown-menu { - max-width: inherit; -} + display: block; + height: 8px; + } -.dropdown-submenu .dropdown-menu li.dropdown-item{ - width: 100%; -} - -.dropdown-submenu { - position: relative; -} - -.dropdown-submenu .dropdown-menu { - margin-top: -6px; - border-radius: 0.25rem; - width: fit-content; -} - -.dropdown-submenu:hover > .dropdown-menu { - display: inline; -} - -/* - Keyboard Dropdown -*/ -.dropdown button { + header #headerBackground { padding: 10px; -} - -/* - Tools -*/ - -input[type="range"] { - font-size: 1.1rem; - width: 100px; -} - -input[type="range"] { - color: #69B7D2; - --thumb-height: 1.125em; - --track-height: 0.125em; - --track-color: rgba(186, 0, 0, 0.2); - --brightness-hover: 180%; - --brightness-down: 80%; - --clip-edges: 0.125em; -} - -input[type="range"] { - position: relative; - background: #fff0; - overflow: hidden; -} - -input[type="range"]:active { - cursor: grabbing; -} - -input[type="range"]:disabled { - filter: grayscale(1); - opacity: 0.3; - cursor: not-allowed; -} + } + + #headerBackground { + display: grid; + grid-template-columns: 5% 85% 10%; + justify-content: left; + align-items: center; + box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; + margin: 0px 0px; + background-color: white; + } + + #headerLeft { + margin-left: 10px; + } + + #headerLeft img { + display: block; + height: 50px; + } + + #headerMiddle { + display: flex; + flex-direction: row; + justify-content: left; + align-items: center; + width: 70%; + margin: 0px 10px; + } + + #headerMiddle > div { + margin-right: 10px; + } + + #headerRight { + display: grid; + grid-template-columns: 50% 50%; + justify-items: end; + align-items: center; + width: 100%; + } +} \ No newline at end of file diff --git a/cdn/dev/img/headerbar copy.png b/cdn/dev/img/headerbar copy.png new file mode 100644 index 0000000000000000000000000000000000000000..19a21025d1f7cc1580c8b3d46579fa26584edf6a GIT binary patch literal 507 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 U{tjgMq5uE@07*qoM6N<$f<7Joj{pDw literal 0 HcmV?d00001 diff --git a/cdn/dev/js/kmwBody.js b/cdn/dev/js/kmwBody.js new file mode 100644 index 0000000..acd4997 --- /dev/null +++ b/cdn/dev/js/kmwBody.js @@ -0,0 +1,130 @@ +document.addEventListener('DOMContentLoaded', function() { + // Define the divider, text area and keyboard + const divider = document.getElementById('Divider') + const resizer = divider.querySelector('.fa-bars') + let prevElement = divider.previousElementSibling.querySelector('.textarea'); + let nextElement = divider.nextElementSibling; + + // Define the heights of text area, keyboard, and the vertical screen + let prevElementHeight = 0; + let nextElementHeight = 0; + let nextElementWidth = 0; + let verticalViewport = 0; + + const mouseDownHandler = (e) => { + e.preventDefault(); + // Get the Y coordinate of mouse click & Text Area + Keyboard heights + prevElementHeight = prevElement.getBoundingClientRect().height; + nextElementHeight = nextElement.getBoundingClientRect().height; + nextElementWidth = nextElement.getBoundingClientRect().width; + verticalViewport = e.clientY; + + document.addEventListener('mousemove', mouseMoveHandler) + document.addEventListener('mouseup', mouseUpHandler) + + resizer.style.cursor = 'ns-resize' + document.body.style.cursor = 'ns-resize' + } + + const mouseUpHandler = () => { + resizer.style.removeProperty('cursor') + document.body.style.removeProperty('cursor'); + + prevElement.style.removeProperty('user-select') + prevElement.style.removeProperty('pointer-events') + + nextElement.style.removeProperty('user-select') + nextElement.style.removeProperty('pointer-events') + + // Remove the handlers of mousemove and mouseup + document.removeEventListener('mousemove', mouseMoveHandler); + document.removeEventListener('mouseup', mouseUpHandler); + } + + const mouseMoveHandler = function (e) { + // Calculate the cursor movement + let value = e.clientY - verticalViewport + calcElementSize(value) + } + + function calcElementSize(val) { + // Get the dynamic heights of both elements + let newPrevHeight = prevElementHeight + val; + let newNextHeight = nextElementHeight - val; + let newNextWidth = nextElementWidth - val; + + let keyboardElements = divider.nextElementSibling.querySelectorAll('.keyboard-and-download') + + // Define minimum and maximum heights + const minPrevHeight = 200; + const maxPrevHeight = window.innerHeight * 0.8; + const minNextHeight = 200; + const maxNextHeight = 800; + const minNextWidth = 10; + const maxNextWidth = 100; + + // Ensure the heights do need exceed the define heights + newPrevHeight = Math.max(minPrevHeight, Math.min(newPrevHeight, maxPrevHeight)); + newNextHeight = Math.max(minNextHeight, Math.min(newNextHeight, maxNextHeight)); + newNextWidth = Math.max(minNextWidth, Math.min(newNextWidth, maxNextWidth)); + + // Update the heights of Prev and Next Elements + prevElement.style.height = `${newPrevHeight}px`; + if (newPrevHeight >= maxPrevHeight) { + fullScreenSize() + } + else { + keyboardElements.forEach(element => { + element.style.height = `${newNextHeight}px`; + element.style.width = `${newNextWidth}%` + }) + divider.style.display = "flex" + nextElement.style.display = 'flex'; + } + } + + let showKeyboardContainer = document.querySelector(".show-keyboard-box") + let showKeyboardButton = document.querySelector(".show-keyboard") + + function defaultSize() { + prevElement.style.height= "45vh" + divider.style.display = "flex" + nextElement.style.display = "flex" + showKeyboardContainer.classList.add('hidden') + } + + function fullScreenSize() { + nextElement.style.display = "none" + divider.style.display = "none" + prevElement.style.height = '88vh' + + let scrollPosition = window.scrollY + window.innerHeight + let pageHeight = document.documentElement.scrollHeight + + if (scrollPosition >= pageHeight - 10) { + showKeyboardPopupBtn() + } else { + showKeyboardContainer.classList.add('hidden') + } + showKeyboardButton.addEventListener('click', () => { + defaultSize() + }) + } + + function showKeyboardPopupBtn() { + showKeyboardContainer.classList.remove('hidden') + showKeyboardContainer.style.height = "50px" + showKeyboardButton.style.opacity = "0%" + showKeyboardContainer.addEventListener('mouseover', function() { + showKeyboardButton.style.opacity = "80%" + }) + showKeyboardContainer.addEventListener('mouseleave', function() { + showKeyboardButton.style.opacity = "0%" + }) + } + + const hideKeyboardBtn = document.getElementById('hideKeyboard') + hideKeyboardBtn.onclick = () => fullScreenSize() + + resizer.addEventListener('mousedown', mouseDownHandler) +}) \ No newline at end of file diff --git a/cdn/dev/js/kmwHeader.js b/cdn/dev/js/kmwHeader.js index e414718..6929519 100644 --- a/cdn/dev/js/kmwHeader.js +++ b/cdn/dev/js/kmwHeader.js @@ -1,111 +1,228 @@ -dropdownItems = [ +languages = [ { - text: 'Brao (SIL) Keyboard', - href: '#' + language: "Achterhoeks", + keyboard: + [ + { + name: 'EuroLatin (SIL)', + script: '', + }, + ] }, { - text: 'Bunong (SIL) Keyboard', - href: '#' + language: "Finnish", + keyboard: + [ + { + name: 'Finnish Basic', + script: 'fi', + }, + { + name: 'Finnish-Swidish with Sami-Basic', + script: 'fi', + }, + { + name: 'Malar Braille', + script: 'fi-brai', + } + ] }, { - text: 'Khmer Angkor Keyboard', - href: '#' + language: "Khmer", + keyboard: + [ + { + name: 'Khmer Basic', + script: 'km', + }, + { + name: 'Khmer (NIDA) Basic', + script: 'km', + }, + { + name: 'Khmer Advanced', + script: 'km', + }, + { + name: 'Khmer Angkor', + script: 'km', + }, + { + name: 'Khmer (SIL)', + script: 'km', + } + ] + }, + { + language: "Rotokas", + keyboard: + [ + { + name: 'US Basic', + script: 'roo-latn', + }, + { + name: 'Xpert', + script: 'roo-latn', + } + ] }, { - text: 'Khmer (SIL) Keyboard', - href: '#' + language: "Sogdian", + keyboard: + [ + { + name: 'Manichaean', + script: 'sog-mani', + }, + { + name: 'Old Sogdian', + script: 'sog-sogo', + }, + { + name: 'Sogdian Phonetic', + script: 'sog', + }, + ] } ] -// Draft - // [ - // { - // language: 'Khmer', - // keyboards: [ - // 'Brao (SIL)', - // 'Bunong (SIL)' - - // ] - // } - // ] -// -function function1() { - const dropdownMenu = document.getElementById('dropdown-menu'); - dropdownMenu.innerHTML = ''; // Clear existing items - - // Create 10 rows with 4 columns each - for (let i = 1; i <= 5; i++) { - const rowDiv = document.createElement('div') - rowDiv.classList.add('row'); - - for (let j = 1; j <= 4; j++) { - const colDiv = document.createElement('div'); - colDiv.classList.add('col'); - - for(let k = 1; k<=4; k++) { - - let li = document.createElement('li') - li.classList.add('dropdown-submenu') - li.textContent = "Khmer" - - const subUl = document.createElement('ul') - subUl.classList.add('dropdown-menu') - dropdownItems.forEach(element => { - const subLi = document.createElement('li') - subLi.classList.add('dropdown-item') - subLi.setAttribute('id', element.text) - subLi.textContent = element.text - subUl.appendChild(subLi) - - subLi.addEventListener('click', function () { - alert(`You clicked on: ${element.text}`); - populateSelectedKeyboard('Khmer') - }); - }); - - li.appendChild(subUl) - colDiv.appendChild(li) - } - - rowDiv.appendChild(colDiv); +// Global Variables +const numOfLangPara = document.createElement('p') +let selectedLanguagesList = [] +const keyboardSelectionButton = document.getElementById('keyboardSelectionButton') + +function languageSearch() { + const languageSearchList = document.getElementById('languageSearchList'); + languageSearchList.innerHTML = ''; // Clear existing items + + // Create
+ let rowDiv = document.createElement('div') + rowDiv.classList.add('row'); + // Insert `
- " alt="" /> +
-
-
-
- -
-
-
+
+
+ + + +
-
-
-
    -
  • " width="20px">
  • -
  • 1
  • -
  • 2
  • -
  • 3
  • -
  • 4
  • -
  • 5
  • -
  • 6
  • -
  • 7
  • -
  • 7
  • -
  • 8
  • -
  • 0
  • -
  • _
  • -
  • =
  • -
  • ๐ŸŽจ
  • -
-
    -
  • ๐ŸŒต
  • -
  • Q
  • -
  • W
  • -
  • E
  • -
  • R
  • -
  • T
  • -
  • Y
  • -
  • U
  • -
  • I
  • -
  • O
  • -
  • P
  • -
  • [
  • -
  • ]
  • -
  • \
  • -
-
    -
  • ๐Ÿงข
  • -
  • A
  • -
  • S
  • -
  • D
  • -
  • F
  • -
  • G
  • -
  • H
  • -
  • J
  • -
  • K
  • -
  • L
  • -
  • ;
  • -
  • ""
  • -
  • ๐Ÿ”ซ
  • -
-
    -
  • ๐Ÿ”ฅ
  • -
  • Z
  • -
  • X
  • -
  • C
  • -
  • V
  • -
  • B
  • -
  • N
  • -
  • M
  • -
  • ,
  • -
  • .
  • -
  • ?
  • -
  • ๐Ÿงฌ
  • -
-
    -
  • ctrl
  • -
  • alt
  • -
  • cmd
  • -
  • -
  • cmd
  • -
  • alt
  • -
+
+ + + + + +
+
+
+
+
+ +

No example is available for this keyboard.

+
+
+ +
+
+
+

+ Use Undetermined Keyboard in any Windows app! + + Download + Free and open source! +

- - - - + + From b2a8b50b6704c6546ebf41d2cbccfb2da58050d8 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Fri, 21 Feb 2025 15:18:59 +0700 Subject: [PATCH 06/36] feat: css media query, clean unused css & js, js resize and default width --- cdn/dev/css/kmw-body.css | 340 +++++++------- cdn/dev/css/kmw-header.css | 430 +++++++++--------- .../{keyboard.png => desktop-keyboard.png} | Bin cdn/dev/img/phone-keyboard.png | Bin 0 -> 81945 bytes cdn/dev/js/kmwBody.js | 77 ++-- index.php | 20 +- 6 files changed, 414 insertions(+), 453 deletions(-) rename cdn/dev/img/{keyboard.png => desktop-keyboard.png} (100%) create mode 100644 cdn/dev/img/phone-keyboard.png diff --git a/cdn/dev/css/kmw-body.css b/cdn/dev/css/kmw-body.css index 5602ae1..f64fe76 100644 --- a/cdn/dev/css/kmw-body.css +++ b/cdn/dev/css/kmw-body.css @@ -24,6 +24,7 @@ a { } /* Icons */ + .fa-keyboard, .fa-download { cursor: pointer; } @@ -34,216 +35,207 @@ a { /* End of Icons */ -/* ================================ - Computer and Laptop screen sizes -================================ */ -@media screen and (min-width: 1000px) { - .item { - margin: 5px - } - /* - Text area - */ - .textarea-container { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - width: 100%; - } +/* Section Tag */ - .textarea { - padding: 10px; - margin-top: 95px; - resize: none; - width: 100%; - height: 45vh; - box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgb(209, 213, 219) 0px 0px 0px 1px inset; - } +/* + Text area +*/ +.textarea-container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; +} - #copyTool { - color: #2EADD3; - position: absolute; - right: 20px; - top: 125px; - opacity: 50%; - } - #copyTool:hover { - cursor: pointer; - opacity: 100%; - } +.textarea { + padding: 10px; + resize: none; + width: 100%; + height: 45vh; + box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgb(209, 213, 219) 0px 0px 0px 1px inset; +} - #fullscreenTool { - color: #2EADD3; - position: absolute; - right: 20px; - bottom: 270px; - opacity: 50%; - } - #fullscreenTool:hover { - cursor: pointer; - opacity: 100%; - } +#copyTool { + color: var(--keyman-blue); + position: absolute; + right: 10px; + top: 110px; + opacity: 50%; +} +#copyTool:hover { + cursor: pointer; + opacity: 100%; +} - .show-keyboard-box { - width: 100%; - text-align: center; - position: absolute; - bottom: 0; - } +#fullscreenTool { + color: var(--keyman-blue); + position: absolute; + right: 20px; + bottom: 270px; + opacity: 50%; +} - .show-keyboard-box:hover { - opacity: 80%; - } +#fullscreenTool:hover { + cursor: pointer; + opacity: 100%; +} - /* Divider */ - .divider-container { - user-select: none; - display: grid; - grid-template-columns: auto auto auto; - align-items: center; - justify-content: space-evenly; - width: 90%; - } +.show-keyboard-box { + width: 100%; + text-align: center; + position: absolute; + bottom: 0; +} - .divider-container > * { - margin: 10px; - } +.show-keyboard-box:hover { + opacity: 80%; +} - .divider-container i { - opacity: 50%; - } +/* Divider */ +.divider-container { + user-select: none; + display: flex; + flex-direction: row; + justify-content: space-between; + width: 40%; +} - .divider-container i:hover { - color: #FC7200; - opacity: 100%; - } +.divider-container > * { + margin: 10px; +} - /* Keyboard */ - .keyboard-and-download { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - } +.divider-container i { + opacity: 50%; +} - .example-box { - background-color: #2EADD3; - color: white; - width: 100%; - text-align: center; - padding: 5px; - border-bottom: 1px solid rgb(159, 159, 159); - display: grid; - grid-template-columns: auto 90% auto; - } +.divider-container i:hover { + color: var(--keyman-orange); + opacity: 100%; +} - .example-box p { - margin: 10px; - } +/* Keyboard */ +.keyboard-and-download { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; +} - .keyboard-container { - width: 50%; - height: 100%; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - } +.example-box { + background-color: var(--keyman-blue); + color: white; + width: 100%; + text-align: center; + padding: 5px; + border-bottom: 1px solid rgb(159, 159, 159); + display: grid; + grid-template-columns: auto 90% auto; +} - .keyboard-area { - user-select: none; - flex: 1; - width: 100%; - height: auto; - } +.example-box p { + margin: 10px; +} - .keyboard { - width: 100%; - } +.keyboard-container { + width: calc(100% - 40%); + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} - .keyboard-download-box { - width: 15%; - padding: 5px; - position: relative; - left: 100px; - border-radius: 10px; - box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgb(209, 213, 219) 0px 0px 0px 1px inset; - } +.keyboard-area { + user-select: none; + flex: 1; + width: 100%; + height: auto; +} - .keyboard-download-box p { - margin: 10px; - text-align: center; - } +.desktop-keyboard { + width: 100%; +} - .keyboard-download-box > * { - display: flex; - flex-direction: column; - align-items: center; - margin: 10px; - } +.phone-keyboard { + display: none; +} + +.keyboard-download-box { + width: calc(30% - 15%); + padding: 5px; + position: relative; + left: calc(10% - 7%); + border-radius: 10px; + box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgb(209, 213, 219) 0px 0px 0px 1px inset; +} + +.keyboard-download-box p { + margin: 10px; + text-align: center; +} + +.keyboard-download-box > * { + display: flex; + flex-direction: column; + align-items: center; + margin: 10px; } +/* End of Section Tag */ + /* ================================ - Tablet screen size + Computer and Laptop screen sizes ================================ */ - -@media screen and (min-width: 600px) { +@media screen and (min-width: 940px) { .item { margin: 5px } - /* - Text area - */ - .textarea-container { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; +} + +/* ================================ + Most Tablet to Phone sizes +================================ */ + +@media screen and (max-width: 940px) { + /* Divider */ + .divider-container { width: 100%; + padding: 10px; + border-radius: 5px; + box-shadow: var(--box-shadow); } - .textarea { - padding: 10px; - margin-top: 95px; - resize: none; + /* Keyboard */ + .keyboard-container { width: 100%; - height: 45vh; - box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgb(209, 213, 219) 0px 0px 0px 1px inset; + height: 100%; } - #copyTool { - color: #2EADD3; - position: absolute; - right: 20px; - top: 125px; - opacity: 50%; - } - #copyTool:hover { - cursor: pointer; - opacity: 100%; + .desktop-keyboard { + display: none; } - #fullscreenTool { - color: #2EADD3; - position: absolute; - right: 20px; - bottom: 270px; - opacity: 50%; + .phone-keyboard { + width: 100%; + display: block; } - #fullscreenTool:hover { - cursor: pointer; - opacity: 100%; + + .keyboard-download-box { + display: none; } - .show-keyboard-box { - width: 100%; - text-align: center; - position: absolute; - bottom: 0; + .spacing-purpose { + display: none; } +} + +/* ================================ + Smallest Phone sizes +================================ */ - .show-keyboard-box:hover { - opacity: 80%; +@media screen and (max-width: 380px) { + .example-box p { + font-size: 12px; } -} +} diff --git a/cdn/dev/css/kmw-header.css b/cdn/dev/css/kmw-header.css index 1bfc594..92ef995 100644 --- a/cdn/dev/css/kmw-header.css +++ b/cdn/dev/css/kmw-header.css @@ -1,247 +1,227 @@ +:root { + --box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; + --keyman-orange: #FC7200; + --keyman-red: #B92034; + --keyman-blue: #2EADD3; +} + +header > div > img { + width: 100%; + display: block; + height: 8px; +} + +#headerBackground { + display: grid; + justify-content: left; + align-items: center; + height: 75px; + padding: 10px; + background-color: white; + box-shadow: var(--box-shadow); +} + +#headerLeft { + display: flex; + flex-direction: row; + justify-content: left; + align-items: center; +} + +#headerLeft > * { + margin-right: 10px; +} + +#headerRight { + display: grid; + grid-template-columns: 1fr 1fr; + justify-items: end; + align-items: center; +} + +/* +Language Search box +*/ +.form { + position: relative; + width: 50%; +} + +.search-icon-span { + position: absolute; + right: 17px; + top: 12px; + border-left: 1px solid black; +} + +.search-icon-span i { + padding-left: 10px; +} + +.form .form-input { + height: 50px; + width: 100%; + text-indent: 10px; + border-radius: 15px; + text-align: left; + background-color: rgb(233, 228, 228); +} + +.form-input:focus { + box-shadow: none; + border:none; +} + +/* Search Dropdown list */ + +ul.dropdown-menu { + padding: 10px; + margin: 0;; +} + +.dropdown-submenu .dropdown-menu li.dropdown-item{ + width: 100%; +} + +.dropdown-submenu { + position: relative; +} + +.dropdown-submenu .dropdown-menu { + margin-top: -6px; + border-radius: 0.25rem; + width: fit-content; +} + +.dropdown-submenu:hover > .dropdown-menu { + display: inline; +} + +#headerLeft .dropdown-menu .top-row .setting { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + margin: 10px 10px !important; +} + +#headerLeft .dropdown-menu .top-row .setting .col:last-child { + position: relative; + left: 150px; +} + +/* Selected Keyboard Menu */ +#keyboardSelectionDropdown { + width: fit-content !important; + overflow: hidden; +} + +#keyboardSelectionDropdown > * { + width: 100%; +} + +#keyboardSelectionList { + display: grid; + grid-template-columns: 50% 50%; +} + +#keyboardSelectionList ul { + width: 369px; +} + +.language-name { + display: grid; + grid-template-columns: 95% 5%; + align-items: center; +} + +.language-name i { + opacity: 100%; + float: right; + color: var(--keyman-red); +} + +.language { + margin: 10px; +} + +.language ul { + list-style: none; +} + +#removeLanguage { + cursor: pointer; +} + +.keyboard-list i { + float: right; + opacity: 50%; +} + /* ================================ - Computer and Laptop screen sizes + Computer, Laptop, some Tablet screen sizes ================================ */ -@media screen and (min-width: 1000px) { - header { - position: fixed; - margin-left: auto; - margin-right: auto; - padding-bottom: 30px; - z-index: 1; - } - - header > div > img { - width: 100%; - display: block; - height: 8px; - } - - header #headerBackground { - padding: 10px; - } - - #headerBackground { - display: grid; - grid-template-columns: 5% 85% 10%; - justify-content: left; - align-items: center; - box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; - margin: 0px 0px; - background-color: white; - } - - #headerLeft { - margin-left: 10px; - } - - #headerLeft img { - display: block; - height: 50px; - } - - #headerMiddle { - display: flex; - flex-direction: row; - justify-content: left; - align-items: center; - width: 70%; - margin: 0px 10px; - } - - #headerMiddle > div { - margin-right: 10px; - } - - #headerRight { - display: grid; - grid-template-columns: 50% 50%; - justify-items: end; - align-items: center; - width: 100%; - } - - /* - Language Search Menu - */ - - .form { - position: relative; - width: 50%; - } - - .form .left-pan { - position: absolute; - right: 17px; - top: 12px; - padding: 2px; - border-left: 1px solid #000000; - } - - .left-pan { - padding-left: 7px; - } - - .left-pan i { - padding-left: 10px; - } - - .form .form-input { - height: 50px; - width: 100%; - text-indent: 15px; - border-radius: 15px; - text-align: left; - background-color: rgb(233, 228, 228); - } - - .form-input:focus { - box-shadow: none; - border:none; - } - /* Search Dropdown list */ - - ul.dropdown-menu { - padding: 10px; - margin: 0; - } - - .dropdown-submenu .dropdown-menu li.dropdown-item{ - width: 100%; - } - - .dropdown-submenu { - position: relative; - } - - .dropdown-submenu .dropdown-menu { - margin-top: -6px; - border-radius: 0.25rem; - width: fit-content; - } - - .dropdown-submenu:hover > .dropdown-menu { - display: inline; - } - - #headerMiddle .dropdown-menu .top-row .setting { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - margin: 10px 10px !important; - } - - #headerMiddle .dropdown-menu .top-row .setting .col:last-child { - position: relative; - left: 150px; - } - - /* Selected Keyboard Menu */ - #keyboardSelectionDropdown { - width: fit-content !important; - overflow: hidden; - } - - #keyboardSelectionDropdown > * { - width: 100%; - } - - #keyboardSelectionList { - display: grid; - grid-template-columns: 50% 50%; - } - - #keyboardSelectionList ul { - width: 369px; - } - - .language-name { - display: grid; - grid-template-columns: 95% 5%; - align-items: center; - } - - .language-name i { - opacity: 100%; - float: right; - color: #B92034; - } - - .language { - margin: 10px; - } - - .language ul { - list-style: none; - } - - #removeLanguage { - cursor: pointer; - } - - .keyboard-list i { - float: right; - opacity: 50%; - } +@media screen and (min-width: 1045px) { + #headerBackground { + grid-template-columns: 2fr 1fr; } - +} -@media screen and (min-width: 600px) { - header { - position: fixed; - margin-left: auto; - margin-right: auto; - padding-bottom: 30px; - z-index: 1; +/* Expanding the search box */ +@media screen and (940px <= width <= 1045px) { + #headerBackground { + grid-template-columns: 3fr 1fr; } - header > div > img { - width: 100%; - display: block; - height: 8px; + /* + Language Search box + */ + .form { + position: relative; + width: 70%; } +} - header #headerBackground { - padding: 10px; - } +/* ================================ + Most Tablet to Phone sizes +================================ */ +@media screen and (max-width: 940px) { #headerBackground { - display: grid; - grid-template-columns: 5% 85% 10%; - justify-content: left; - align-items: center; - box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; - margin: 0px 0px; - background-color: white; + grid-template-columns: 1fr 1fr; } #headerLeft { - margin-left: 10px; + align-items: center; + justify-content: left; + align-items: center; } #headerLeft img { - display: block; - height: 50px; + display: none; } - #headerMiddle { - display: flex; - flex-direction: row; - justify-content: left; - align-items: center; - width: 70%; - margin: 0px 10px; - } - - #headerMiddle > div { - margin-right: 10px; + /* + Language Search box + */ + .form { + position: relative; + width: inherit; } - #headerRight { - display: grid; - grid-template-columns: 50% 50%; - justify-items: end; - align-items: center; - width: 100%; + .search-icon-span { + position: static; + border: none; + } + + .search-icon-span i { + padding: 10px; + border-radius: 5px; + background-color: gray; + color: white; + } + + .form .form-input { + display: none; } } \ No newline at end of file diff --git a/cdn/dev/img/keyboard.png b/cdn/dev/img/desktop-keyboard.png similarity index 100% rename from cdn/dev/img/keyboard.png rename to cdn/dev/img/desktop-keyboard.png diff --git a/cdn/dev/img/phone-keyboard.png b/cdn/dev/img/phone-keyboard.png new file mode 100644 index 0000000000000000000000000000000000000000..9dc95254031081e9dc1c427b07130fc829a3cd95 GIT binary patch literal 81945 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 C0V>G= literal 0 HcmV?d00001 diff --git a/cdn/dev/js/kmwBody.js b/cdn/dev/js/kmwBody.js index acd4997..5f59194 100644 --- a/cdn/dev/js/kmwBody.js +++ b/cdn/dev/js/kmwBody.js @@ -4,99 +4,81 @@ document.addEventListener('DOMContentLoaded', function() { const resizer = divider.querySelector('.fa-bars') let prevElement = divider.previousElementSibling.querySelector('.textarea'); let nextElement = divider.nextElementSibling; + let isResizing = false; // Define the heights of text area, keyboard, and the vertical screen let prevElementHeight = 0; + let prevElementWidth = 0; let nextElementHeight = 0; let nextElementWidth = 0; let verticalViewport = 0; const mouseDownHandler = (e) => { e.preventDefault(); + resizer.style.cursor = 'ns-resize' + isResizing = true + // Get the Y coordinate of mouse click & Text Area + Keyboard heights prevElementHeight = prevElement.getBoundingClientRect().height; + prevElementWidth = prevElement.getBoundingClientRect().width; nextElementHeight = nextElement.getBoundingClientRect().height; nextElementWidth = nextElement.getBoundingClientRect().width; verticalViewport = e.clientY; document.addEventListener('mousemove', mouseMoveHandler) document.addEventListener('mouseup', mouseUpHandler) - - resizer.style.cursor = 'ns-resize' - document.body.style.cursor = 'ns-resize' } const mouseUpHandler = () => { resizer.style.removeProperty('cursor') - document.body.style.removeProperty('cursor'); - - prevElement.style.removeProperty('user-select') - prevElement.style.removeProperty('pointer-events') - - nextElement.style.removeProperty('user-select') - nextElement.style.removeProperty('pointer-events') - - // Remove the handlers of mousemove and mouseup - document.removeEventListener('mousemove', mouseMoveHandler); - document.removeEventListener('mouseup', mouseUpHandler); + isResizing = false } const mouseMoveHandler = function (e) { + if (!isResizing) return; // Calculate the cursor movement let value = e.clientY - verticalViewport - calcElementSize(value) + let clientX = e.clientX + calcElementSize(value, clientX) } - function calcElementSize(val) { + function calcElementSize(val, x) { // Get the dynamic heights of both elements let newPrevHeight = prevElementHeight + val; - let newNextHeight = nextElementHeight - val; - let newNextWidth = nextElementWidth - val; + let newNextWidth = (x / prevElementWidth) * 150; + console.log("New Next Width", newNextWidth) - let keyboardElements = divider.nextElementSibling.querySelectorAll('.keyboard-and-download') - // Define minimum and maximum heights - const minPrevHeight = 200; - const maxPrevHeight = window.innerHeight * 0.8; - const minNextHeight = 200; - const maxNextHeight = 800; - const minNextWidth = 10; - const maxNextWidth = 100; + const minPrevHeight = 150; + const maxPrevHeight = window.innerHeight * 0.6; + const minNextWidth = 50; + const maxNextWidth = 80; + console.log("Max Next Width: ", maxNextWidth) // Ensure the heights do need exceed the define heights newPrevHeight = Math.max(minPrevHeight, Math.min(newPrevHeight, maxPrevHeight)); - newNextHeight = Math.max(minNextHeight, Math.min(newNextHeight, maxNextHeight)); newNextWidth = Math.max(minNextWidth, Math.min(newNextWidth, maxNextWidth)); + const keyboardContainer = nextElement.querySelector('.keyboard-container') + // Update the heights of Prev and Next Elements - prevElement.style.height = `${newPrevHeight}px`; + prevElement.style.height = `${newPrevHeight}px` + if (newPrevHeight >= maxPrevHeight) { fullScreenSize() - } - else { - keyboardElements.forEach(element => { - element.style.height = `${newNextHeight}px`; - element.style.width = `${newNextWidth}%` - }) + } else if (newPrevHeight < maxPrevHeight) { divider.style.display = "flex" - nextElement.style.display = 'flex'; + nextElement.style.display = "flex" } } let showKeyboardContainer = document.querySelector(".show-keyboard-box") let showKeyboardButton = document.querySelector(".show-keyboard") - function defaultSize() { - prevElement.style.height= "45vh" - divider.style.display = "flex" - nextElement.style.display = "flex" - showKeyboardContainer.classList.add('hidden') - } - function fullScreenSize() { - nextElement.style.display = "none" + prevElement.style.height = "85vh" divider.style.display = "none" - prevElement.style.height = '88vh' + nextElement.style.display = "none" let scrollPosition = window.scrollY + window.innerHeight let pageHeight = document.documentElement.scrollHeight @@ -123,6 +105,13 @@ document.addEventListener('DOMContentLoaded', function() { }) } + function defaultSize() { + prevElement.style.height= "38vh" + divider.style.display = "flex" + nextElement.style.display = "flex" + showKeyboardContainer.classList.add('hidden') + } + const hideKeyboardBtn = document.getElementById('hideKeyboard') hideKeyboardBtn.onclick = () => fullScreenSize() diff --git a/index.php b/index.php index 6ae5978..b75b733 100644 --- a/index.php +++ b/index.php @@ -7,14 +7,13 @@
-
+
+ KeymanWeb.com -
-
- +
- -
-
- - - -
-
-
- -
-
- + +
+
-
- + + +
+ +
+ +
-
-
- -
-
- -

No example is available for this keyboard.

+
+ +
+
-
- - +
+
+ +
+
+

No example is available for this keyboard.

+
+
+ + +
- -
-
+

From 58f6cd63a7afae47403174835af7d8f077d269a1 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Thu, 5 Jun 2025 10:17:32 +0700 Subject: [PATCH 13/36] feat: search --- cdn/dev/css/kmw-body.css | 1 + cdn/dev/css/kmw-header.css | 14 +++++++ cdn/dev/js/kmwHeader.js | 1 + index.php | 85 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+) diff --git a/cdn/dev/css/kmw-body.css b/cdn/dev/css/kmw-body.css index c51517f..3e424d5 100644 --- a/cdn/dev/css/kmw-body.css +++ b/cdn/dev/css/kmw-body.css @@ -68,6 +68,7 @@ i:hover { opacity: 50%; } + #copyTool:hover { cursor: pointer; opacity: 100%; diff --git a/cdn/dev/css/kmw-header.css b/cdn/dev/css/kmw-header.css index 45f2a27..57af914 100644 --- a/cdn/dev/css/kmw-header.css +++ b/cdn/dev/css/kmw-header.css @@ -33,6 +33,10 @@ header > div > img { box-shadow: var(--box-shadow); } +/* Left side of Header: + Search + Keyboard dropdown +*/ /* Left side of Header: Search Keyboard dropdown @@ -382,6 +386,7 @@ Language Search box align-items: center; } +.middle-header i, .right-header i { .middle-header i, .right-header i { font-size: 24px; opacity: 50%; @@ -398,6 +403,11 @@ Language Search box Hamburger menu */ +/* Right side of the header: + Tools + Hamburger menu +*/ + .right-header { display: grid; grid-template-columns: 90% 10%; @@ -412,12 +422,16 @@ Language Search box color: var(--keyman-blue); } +/* Font size slider + Hide/show keyboard */ /* Font size slider + Hide/show keyboard */ .tool-container { display: flex; flex-direction: row; justify-content: center; align-items: center; + flex-direction: row; + justify-content: center; + align-items: center; } .tool-container > * { diff --git a/cdn/dev/js/kmwHeader.js b/cdn/dev/js/kmwHeader.js index af1e85d..640456d 100644 --- a/cdn/dev/js/kmwHeader.js +++ b/cdn/dev/js/kmwHeader.js @@ -436,6 +436,7 @@ function generateKbUI(selectedKbList) { keyboardSelectionButton.classList.remove('btn-secondary') keyboardSelectionButton.classList.add('btn-keyman-orange') + keyboardSelectionButton.classList.add('btn-keyman-orange') selectedKbList.forEach(data => { // Language Parent tags diff --git a/index.php b/index.php index dfaf683..3033991 100644 --- a/index.php +++ b/index.php @@ -54,6 +54,17 @@ + + + +
+ +
+
@@ -169,6 +253,7 @@ + From 3f311339ae801d753e929c2c42565432efeb9567 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Thu, 5 Jun 2025 10:43:27 +0700 Subject: [PATCH 14/36] Revert "feat: search" This reverts commit 58f6cd63a7afae47403174835af7d8f077d269a1. --- cdn/dev/css/kmw-body.css | 1 - cdn/dev/css/kmw-header.css | 14 ------- cdn/dev/js/kmwHeader.js | 1 - index.php | 85 -------------------------------------- 4 files changed, 101 deletions(-) diff --git a/cdn/dev/css/kmw-body.css b/cdn/dev/css/kmw-body.css index 3e424d5..c51517f 100644 --- a/cdn/dev/css/kmw-body.css +++ b/cdn/dev/css/kmw-body.css @@ -68,7 +68,6 @@ i:hover { opacity: 50%; } - #copyTool:hover { cursor: pointer; opacity: 100%; diff --git a/cdn/dev/css/kmw-header.css b/cdn/dev/css/kmw-header.css index 57af914..45f2a27 100644 --- a/cdn/dev/css/kmw-header.css +++ b/cdn/dev/css/kmw-header.css @@ -33,10 +33,6 @@ header > div > img { box-shadow: var(--box-shadow); } -/* Left side of Header: - Search - Keyboard dropdown -*/ /* Left side of Header: Search Keyboard dropdown @@ -386,7 +382,6 @@ Language Search box align-items: center; } -.middle-header i, .right-header i { .middle-header i, .right-header i { font-size: 24px; opacity: 50%; @@ -403,11 +398,6 @@ Language Search box Hamburger menu */ -/* Right side of the header: - Tools - Hamburger menu -*/ - .right-header { display: grid; grid-template-columns: 90% 10%; @@ -422,16 +412,12 @@ Language Search box color: var(--keyman-blue); } -/* Font size slider + Hide/show keyboard */ /* Font size slider + Hide/show keyboard */ .tool-container { display: flex; flex-direction: row; justify-content: center; align-items: center; - flex-direction: row; - justify-content: center; - align-items: center; } .tool-container > * { diff --git a/cdn/dev/js/kmwHeader.js b/cdn/dev/js/kmwHeader.js index 640456d..af1e85d 100644 --- a/cdn/dev/js/kmwHeader.js +++ b/cdn/dev/js/kmwHeader.js @@ -436,7 +436,6 @@ function generateKbUI(selectedKbList) { keyboardSelectionButton.classList.remove('btn-secondary') keyboardSelectionButton.classList.add('btn-keyman-orange') - keyboardSelectionButton.classList.add('btn-keyman-orange') selectedKbList.forEach(data => { // Language Parent tags diff --git a/index.php b/index.php index 3033991..dfaf683 100644 --- a/index.php +++ b/index.php @@ -54,17 +54,6 @@ - - - -
- -
-
@@ -253,7 +169,6 @@ - From 078a8cea78ada999196de64b4772535aee83cfa8 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Tue, 17 Jun 2025 11:58:54 +0700 Subject: [PATCH 15/36] feat: integrate KeymanWeb Map with polished components and usability + code section for feats of search --- cdn/dev/css/kmw-header.css | 92 +++++++++++-- cdn/dev/js/kmwControls.js | 10 ++ cdn/dev/js/kmwHeader.js | 258 +++++++++++++++++++++++++++---------- inc/head.php | 31 ++--- index.php | 17 +-- 5 files changed, 303 insertions(+), 105 deletions(-) create mode 100644 cdn/dev/js/kmwControls.js diff --git a/cdn/dev/css/kmw-header.css b/cdn/dev/css/kmw-header.css index 45f2a27..f8e9bda 100644 --- a/cdn/dev/css/kmw-header.css +++ b/cdn/dev/css/kmw-header.css @@ -48,7 +48,7 @@ Language Search box */ .form { position: relative; - width: 500px; + width: 550px; margin-right: 10px; } @@ -111,7 +111,7 @@ Language Search box } /* Map and Most download */ -.left-header .dropdown-menu .top-row .setting { +.left-header .dropdown-menu .top-row #worldMap { display: flex; flex-direction: row; justify-content: space-between; @@ -119,10 +119,62 @@ Language Search box margin: 10px 10px !important; } -.setting span { +#worldMap span { opacity: 50%; } +#worldMap span:hover { + opacity: 100%; + cursor: pointer; +} + +#KeymanWebControl #kmw_controls +{ + display: flex !important; + flex-direction: row; + justify-content: space-evenly; + border-radius: 20px; + box-shadow: var(--box-shadow); + height: 35px; + padding: 5px; +} + +#KeymanWebControl .kmw_button, +#keymanWebControl .kmw_button_disabled, +#KeymanWebControl .kmw_button_selected +{ + width: fit-content !important; + background: none !important; + height: 0 !important; +} + +#KeymanWebControl #kmw_controls_start, +#KeymanWebControl #kmw_btn_osk, +.kmw_bar, #kmw_controls_end { + display: none; +} + +#KeymanWebControl .kmw_language { + padding: 3px; +} + +#kmw_control_keyboards { + width: fit-content; +} + +#kmw_selector_regions { + height: 100%; + overflow: hidden; + position: relative; +} + +.kmw_selector_region { + overflow-y: scroll; + overflow-x: hidden; + scrollbar-width: thin; + height: 600px; +} + /* Search Dropdown cards */ #languageSearchList > * { margin-bottom: 5px; @@ -139,6 +191,29 @@ Language Search box border-radius: 10px; letter-spacing: .05rem; overflow: hidden; + margin-bottom: 5px; +} + +.card-wrap.disabled { + opacity: 0.5; + pointer-events: none; + position: relative; +} + +.card-wrap.disabled .kb-icon-plus { + pointer-events: auto; + opacity: 1; + position: absolute; + right: 15px; + z-index: 1; +} + +.kb-icon-plus { + transition: 0.5s ease; +} + +.kb-icon-plus.animate { + color: green; } .keyboard-id { @@ -208,17 +283,6 @@ Language Search box color: var(--keyman-red); } -@keyframes fly-in { - from { - transform: translateY(0%); - opacity: 1; - } - to { - transform: translateY(200%); - opacity: 0; - } -} - /* Pagination */ #languageSearchDropdown .bottom-row-search { background-color: white; diff --git a/cdn/dev/js/kmwControls.js b/cdn/dev/js/kmwControls.js new file mode 100644 index 0000000..e1445f0 --- /dev/null +++ b/cdn/dev/js/kmwControls.js @@ -0,0 +1,10 @@ +/* + This is the code to modify the fetched + KeymanWebControls (Map, Examples, Keyboards...etc) +*/ + +$(document).ready(function() { + $("#KeymanWebControls").show( function() { + alert("Show") + }) +}) \ No newline at end of file diff --git a/cdn/dev/js/kmwHeader.js b/cdn/dev/js/kmwHeader.js index af1e85d..e76e114 100644 --- a/cdn/dev/js/kmwHeader.js +++ b/cdn/dev/js/kmwHeader.js @@ -92,16 +92,7 @@ function handleSearch(value = "") { function resetSearch() { paginationCtrl.style.display = 'none' - kbSearchCard.innerHTML = ` -
-
Instruction
-
    -
  1. Search for any Keyman keyboard
  2. -
  3. Once the keyboard you are looking for appears, click on it will enable and store it in the keyboard selection (arrow icon next to search)
  4. -
  5. You can switch between keyboards and start typing.
  6. -
-
- ` + displayTopDownloads() } function updateSearchIcon(value) { @@ -119,43 +110,42 @@ function debounceSearch(query, page) { } } -/* Display top downloads with search Instruction - ON PAUSED -*/ +/* Display top downloads with search Instruction */ +const defaultInstruction = ` +
+
Instruction
+
    +
  1. Search for any Keyman keyboard
  2. +
  3. Once the keyboard you are looking for appears, click on it will enable and store it in the keyboard selection (arrow icon next to search)
  4. +
  5. You can switch between keyboards and start typing.
  6. +
+
` async function displayTopDownloads() { - kbSearchCard.innerHTML = `
Loading...
` + kbSearchCard.innerHTML = `

Loading...

` try { - let response = await fetch(`https://api.keyman.com/cloud/4.0/languages?p=${currentPage}`) + let response = await fetch(`https://api.keyman.com/search/2.0?q=p:popular`) if (!response.ok) { throw new Error(`API request failed with status ${response.status}`) } let data = await response.json() - console.log(data) - let dataLanguages = data.languages.languages - if (!dataLanguages || !Array.isArray(dataLanguages)) { - throw new Error(`Invalid API response structure`) - } + let mostDownloadkb = data.keyboards - if (data.context) { - currentPage = data.context.pageNumber || 1 - totalPage = data.context.totalPage || 1 - } else { - totalPage = Math.ceil(dataLanguages.length / itemPerPage) + if (!mostDownloadkb || !Array.isArray(mostDownloadkb)) { + throw new Error(`Invalid API response structure`) } - updatePaginationCtrl() - displaySearch(dataLanguages, dataLanguages.length) + displaySearch(mostDownloadkb) + paginationCtrl.style.display = 'none' } catch(error) { - console.error(`Error fetching languages ${error}`) - kbSearchCard.innerHTML = `
No languages are found.
` + console.error(`Error fetching ${error}`) + kbSearchCard.innerHTML = `
No keyboards are found.
` paginationCtrl.style.display = 'none' } } /* Get query and return search */ -let dataKbForRemoval async function searchKeyboard(query = null, page) { kbSearchCard.innerHTML = `
Searching ${query}...
` kbSearchCard.style.display = 'block' @@ -187,14 +177,37 @@ async function searchKeyboard(query = null, page) { displaySearch(keyboardData, totalFound, query) } +/* PAUSED */ +const historyKbSelection = (() => { + const maxItem = 3 + let history = [] + + return { + add(kbItem) { + history = history.filter(item => item.id != kbItem.id) + history.unshift(kbItem) + if (history.length > maxItem) history.pop() + }, + getHistory() { + return [...history] + }, + clear() { + history = [] + } + } +}) + /* Display items return from search */ let selectedKbList = [] let selectedKbData = [] -function displaySearch(data, total = 0, query) { +let dataKbForRemoval +const keyboardSelectionButton = document.getElementById('keyboardSelectionButton') + +function displaySearch(data, total = 0, query = '') { kbSearchCard.innerHTML = ''; if (!data || data.length == 0) { - kbSearchCard.innerHTML = '
No language found.
' + kbSearchCard.innerHTML = 'No keyboards are found.' paginationCtrl.style.display = 'none' return } @@ -270,6 +283,7 @@ function displaySearch(data, total = 0, query) { kbIconPTag.textContent = "+" kbIconPTag.style.fontSize = '20px' kbIconPTag.style.cursor = 'pointer' + kbIconPTag.classList.add('kb-icon-plus') const kbIdPTag = document.createElement('p') kbIdPTag.classList.add('keyboard-id') @@ -340,44 +354,83 @@ function displaySearch(data, total = 0, query) { cardWrap.appendChild(kbIdPTag) cardWrap.appendChild(kbDescHeading) cardWrap.appendChild(kbSpecs) + // kbSearchCard.appendChild(defaultInstruction) kbSearchCard.appendChild(cardWrap) + if (kbFoundInList) { + kbIconPTag.textContent = 'โœ“' + kbIconPTag.classList.add('animate') + cardWrap.classList.add('disabled') + + setTimeout(() => { + kbIconPTag.textContent = '-' + kbIconPTag.classList.remove('animate') + }, 600) + } // Choose keyboard to selection - kbIconPTag.onclick = () => { - selectedKbData.push({ - "id": kb.id, - "name": kb.name, - "version": kb.version, - "helpLink": kb.helpLink, - "platformSupport": kb.platformSupport, - "totalDownloads": kb.match.totalDownloads, + kbIconPTag.onclick = (e) => { + e.preventDefault() + let isSelected = selectedKbList.some(selected => selected.id == kb.id) + // Disable keyboard card in search + if (isSelected) { + removeKeyboard(kb.id) + } else { + addKeyboard(kb) + console.log(kb) + populateSelectedKeyboard(kb) + } + + selectedKbList.forEach(data => { + let kbName = data.id + let langCode = data.script + + changeKeyboard(kbName, langCode) }) - populateSelectedKeyboard(kb) + // console.log("Recent:", historyKbSelection.getHistory()); displaySearch(data, total, query) } - - // Disable keyboard card in search - if (kbFoundInList) { - cardWrap.classList.add('disabled') - cardWrap.style.pointerEvents = 'none' - cardWrap.style.opacity = "50%" - } dataKbForRemoval = selectedKbData }) paginationCtrl.style.display = 'flex'; } +const downloadBtn = document.getElementById('kbDownloadPage') +const textArea = document.getElementById('textArea') +async function changeKeyboard(kbdname, languageCode) { + console.log("kbdname: ", kbdname, " + ", "languageCode: ", languageCode) + if(kbdname == '') { + if (textArea) textArea.placeholder = 'Select a keyboard and start typing' + } + location.replace('#' + languageCode + ',Keyboard_' + kbdname); + + var kbd = keyman.getKeyboard(kbdname, languageCode); // Good + await keyman.setActiveKeyboard(kbdname, languageCode) // Good + console.log("kbd: ", kbd) + + if(kbd) { + textArea.placeholder = 'The ' + kbd.InternalName + ' keyboard is selected. Start typing...' + } + + const kbSpan = document.querySelector('#kbSpan') + const kbHelpDocATag = document.querySelector('#kbHelpdocLink') + textArea.placeholder = `The ${kbdname} keyboard is selected. Please start typing...` + kbSpan.innerHTML = `${kbdname}` + // kbHelpDocATag.href = `${kbdHelpLink}` + + if(typeof(KeyboardChange_EmbedFonts) != 'undefined') KeyboardChange_EmbedFonts(kbdname); +} + /* Platform Support */ function platformSupport(data) { const platformMap = { - android: "Android", - desktopWeb: "Web", - ios: "iPhone and iPad", - linux: "Linux", - macos: "macOS", - mobileWeb: "Mobile web", - windows: "Windows" - } + android: "Android", + desktopWeb: "Web", + ios: "iPhone and iPad", + linux: "Linux", + macos: "macOS", + mobileWeb: "Mobile web", + windows: "Windows" + } let platformSpan = Object.entries(data) .filter(([_, supportLevel]) => supportLevel == 'full') .map(([platform]) => `${platformMap[platform]}`).join('') @@ -404,23 +457,33 @@ function populateSelectedKeyboard(language = null) { generateKbUI(selectedKbList) } -/* Compare and remove keyboard - ON PAUSED -*/ -function removeKeyboard(kbId) { +/* Add keyboard for kb search and selection UI */ +function addKeyboard(kb) { + const kbInfo = { + "id": kb.id, + "name": kb.name, + "script": kb.match.tag, + "version": kb.version, + "helpLink": kb.helpLink, + "platformSupport": kb.platformSupport, + "totalDownloads": kb.match.totalDownloads, + } + // historyKbSelection.add(kbInfo) + selectedKbData.push(kbInfo) + selectedKbList.push(kbInfo) +} + +/* Compare and remove keyboard */ +function removeKeyboard(kbId, data) { if(kbId) { selectedKbList = selectedKbList.filter(kb => kb.id !== kbId) + selectedKbData = selectedKbData.filter(kb => kb.id !== kbId) } - // populateSelectedKeyboard(selectedKbList) - // console.log(dataKbForRemoval) - displaySearch(selectedKbList) } /* Generate Language's keyboards ON PAUSED */ -const keyboardSelectionButton = document.getElementById('keyboardSelectionButton') - function generateKbUI(selectedKbList) { const keyboardSelection = document.getElementById("keyboardSelection") keyboardSelection.innerHTML = '' @@ -517,6 +580,9 @@ function generateKbUI(selectedKbList) { }) } +/* + Behavior of the Selected Keyboard +*/ const kbSelection = document.querySelector('#keyboardSelection') keyboardSelectionButton.addEventListener('mouseenter', () => { kbSelection.style.width = "100%" @@ -527,3 +593,65 @@ keyboardSelectionButton.addEventListener('click', () => { kbSelection.addEventListener('mouseleave', () => { kbSelection.style.width = "0px" }) + +/* + Toggle between World Map and Search +*/ +const worldMapBtn = document.querySelector('#worldMap') +const kmwControls = document.querySelector('#KeymanWebControl') +const langSearchDropdown = document.querySelector('#languageSearchDropdown') +const caretRightIcon = keyboardSelectionButton.querySelector('.fa-caret-right') + +let mapIsOpen +worldMapBtn.onclick = () => { + toggleMapAndKb() +} + +function toggleMapAndKb() { + if (mapIsOpen == true) { + openSearch() + } else { + openMap() + returnToSearchBtn() + } +} + +function openMap() { + mapIsOpen = true + searchBtn.style.display = "none" + + kmwControls.classList.remove('hidden') + kmwControls.style.display = "block" + langSearchDropdown.classList.add('hidden') + + searchBoxForm.innerHTML = '' + searchBoxForm.appendChild(kmwControls) +} + +function openSearch() { + mapIsOpen = false + searchBtn.style.display = "block" + + kmwControls.classList.add('hidden') + kmwControls.style.display = "none" + langSearchDropdown.classList.remove('hidden') + + searchBoxForm.innerHTML = '' + searchBoxForm.appendChild(searchBtn) + searchBoxForm.appendChild(langSearchDropdown) +} + +function returnToSearchBtn() { + caretRightIcon.classList.remove('fa-caret-right') + caretRightIcon.classList.add('fa-magnifying-glass') + keyboardSelectionButton.style.backgroundColor = "var(--keyman-orange)" + keyboardSelectionButton.style.border = '0px' + keyboardSelection.style.display = "none" + keyboardSelectionButton.onclick = () => { + caretRightIcon.classList.remove('fa-magnifying-glass') + caretRightIcon.classList.add('fa-caret-right') + keyboardSelectionButton.style.backgroundColor = "" + keyboardSelection.style.display = "block" + openSearch() + } +} diff --git a/inc/head.php b/inc/head.php index d60e07f..9d73cee 100644 --- a/inc/head.php +++ b/inc/head.php @@ -61,7 +61,6 @@ " /> " /> - @@ -116,9 +115,8 @@ function bcp47ToISO6393(bcp) { var localKeyboard, localLanguage; - // Find # in the URL and then load the keyboard? function loadKeyboardFromHash() { - var locationHash = location.hash.match(/^#(.+),(.+)$/i); + var locationHash = location.hash.match(/^#(.+),(Keyboard_.+)$/i); if(locationHash) { localKeyboard = locationHash[2]; localLanguage = locationHash[1]; @@ -143,6 +141,7 @@ function loadKeyboardFromHash() { } } + @@ -153,8 +152,8 @@ function loadKeyboardFromHash() { - - - - + diff --git a/index.php b/index.php index dfaf683..4797c2c 100644 --- a/index.php +++ b/index.php @@ -18,8 +18,8 @@ -
- - - - - + + + + + + From 83389eb418b913187be9b5a360e6e84996b40e53 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Mon, 23 Jun 2025 11:43:01 +0700 Subject: [PATCH 16/36] feat: two different search UIs, tick on kb click, kb count, and prepare kb selection menu --- cdn/dev/css/kmw-header.css | 52 +++- cdn/dev/js/kmwHeader.js | 624 ++++++++++++++++++++----------------- index.php | 25 +- 3 files changed, 403 insertions(+), 298 deletions(-) diff --git a/cdn/dev/css/kmw-header.css b/cdn/dev/css/kmw-header.css index f8e9bda..32cfd25 100644 --- a/cdn/dev/css/kmw-header.css +++ b/cdn/dev/css/kmw-header.css @@ -95,19 +95,48 @@ Language Search box width: 100%; max-height: 600px; overflow: auto; + scrollbar-width: thin; +} + +#languageSearchDropdown hr { + margin: 15px 0; +} + +/* Enable keyboard Animation */ +.kb-icon-plus-animate { + animation: plustoTickToMinus 2s forwards; +} + +@keyframes plustoTickToMinus { + 0% { + content: "+"; + transform: scale(1); + } + 30% { + color: lime; + content: "โœ“"; + transform: scale(1.5); + } + 60% { + color: lime; + content: "โœ“"; + transform: scale(1.3); + } + 100% { + content: "-"; + transform: scale(1); + } } /* Instruction on dropdown */ -.search-instruction { - display: flex; - flex-direction: column; - justify-content: center; - align-items: start; +.instruction-title, .keyboard-title { + width: 100%; } -.search-instruction:hover { - box-shadow: none; - cursor: default; +.instruction-title p, .keyboard-title { + font-weight: 500; + font-size: 16px; + text-align: center; } /* Map and Most download */ @@ -326,10 +355,11 @@ Language Search box overflow-y: hidden; transition: all .5s ease-in-out; scrollbar-width: none; - margin-left: -7px; + margin-left: -10px; border-radius: 10px; z-index: 0; white-space: nowrap; + text-indent: 15px; } #keyboardSelection > * { @@ -349,6 +379,10 @@ Language Search box border-right: 1px solid black; } +.kb-item:hover { + cursor: pointer +} + ::-webkit-scrollbar:horizontal { height: 5px; } diff --git a/cdn/dev/js/kmwHeader.js b/cdn/dev/js/kmwHeader.js index e76e114..c7077df 100644 --- a/cdn/dev/js/kmwHeader.js +++ b/cdn/dev/js/kmwHeader.js @@ -86,13 +86,12 @@ function handleSearch(value = "") { resetSearch() return } - debounceSearch(currentQuery, currentPage) } function resetSearch() { paginationCtrl.style.display = 'none' - displayTopDownloads() + defaultSearch() } function updateSearchIcon(value) { @@ -111,16 +110,7 @@ function debounceSearch(query, page) { } /* Display top downloads with search Instruction */ -const defaultInstruction = ` -
-
Instruction
-
    -
  1. Search for any Keyman keyboard
  2. -
  3. Once the keyboard you are looking for appears, click on it will enable and store it in the keyboard selection (arrow icon next to search)
  4. -
  5. You can switch between keyboards and start typing.
  6. -
-
` -async function displayTopDownloads() { +async function defaultSearch() { kbSearchCard.innerHTML = `

Loading...

` try { let response = await fetch(`https://api.keyman.com/search/2.0?q=p:popular`) @@ -136,7 +126,6 @@ async function displayTopDownloads() { throw new Error(`Invalid API response structure`) } displaySearch(mostDownloadkb) - paginationCtrl.style.display = 'none' } catch(error) { console.error(`Error fetching ${error}`) @@ -149,7 +138,7 @@ async function displayTopDownloads() { async function searchKeyboard(query = null, page) { kbSearchCard.innerHTML = `
Searching ${query}...
` kbSearchCard.style.display = 'block' - + let response = await fetch(`https://api.keyman.com/search/2.0?q=${encodeURIComponent(query)}&p=${page}`) if (!response.ok) { throw new Error(`API request failed with status ${response.status}`) @@ -177,6 +166,121 @@ async function searchKeyboard(query = null, page) { displaySearch(keyboardData, totalFound, query) } +function searchKbCardUI(kb, marked = '', selectedKbList = '') { + // For checking if the keyboard exists in selected Kbs + let kbFoundInList = selectedKbList.some(selected => selected.id == kb.id) + + // Keyboard card container + let cardWrap = document.createElement('div') + cardWrap.classList.add('card-wrap') + cardWrap.setAttribute('id', 'keyboardCardWrap') + + // Keyboard header container + let cardHeader = document.createElement('div') + cardHeader.classList.add('card-header') + + const {matchFound, matchField, matchValue} = highlightSearchContext(kb, marked) + + const kbNameHeading = matchFound ? showMarkedContext(kb, matchField, matchValue) + : (() => { + const heading = document.createElement('h4') + heading.innerHTML = kb.name + return heading + }) + + // Keyboard Plus (+) icon + const kbIconPTag = document.createElement('p') + kbIconPTag.textContent = "+" + kbIconPTag.style.fontSize = '20px' + kbIconPTag.style.cursor = 'pointer' + kbIconPTag.classList.add('kb-icon-plus') + + // Keyboard ID + const kbIdPTag = document.createElement('p') + kbIdPTag.classList.add('keyboard-id') + kbIdPTag.textContent = kb.id + + // Keyboard Description + const kbDescHeading = truncateDesc(kb, matchField, marked) + + // Keyboard monthly downloads and platform support + const kbSpecs = document.createElement('div') + kbSpecs.classList.add('keyboard-specs') + + const kbDownloadHeading = document.createElement('h6') + kbDownloadHeading.textContent = `${kb.match.downloads} monthly downloads` + kbDownloadHeading.classList.add('monthly-download') + + const kbPlatformSupport = document.createElement('div') + kbPlatformSupport.classList.add('platform') + kbPlatformSupport.innerHTML = platformSupport(kb.platformSupport) + + // Append children + cardHeader.appendChild(kbNameHeading) + cardHeader.appendChild(kbIconPTag) + + kbSpecs.appendChild(kbDownloadHeading) + kbSpecs.appendChild(kbPlatformSupport) + + cardWrap.appendChild(cardHeader) + cardWrap.appendChild(kbIdPTag) + cardWrap.appendChild(kbDescHeading) + cardWrap.appendChild(kbSpecs) + + // Choose keyboard to selection + kbIconPTag.onclick = () => addKbToSelectionMenu(kbIconPTag, cardWrap, kb) + // console.log("Recent:", historyKbSelection.getHistory()); + + return cardWrap +} + +function addKbToSelectionMenu(kbIconPTag, cardWrap, kb) { + + let isSelected = selectedKbList.some(selected => selected.id == kb.id) + // Disable keyboard card in search + if (isSelected) { + removeKbSelected(kb.id) + kbIconPTag.textContent = '+' + cardWrap.classList.remove('disabled') + } else { + addKbToSelection(kb) + populateSelectedKeyboard(kb) + triggerKbCount(selectedKbList) + kbIconPTag.textContent = 'โœ“' + kbIconPTag.classList.add('kb-icon-plus-animate') + cardWrap.classList.add('disabled') + + setTimeout(() => { + kbIconPTag.textContent = '-' + kbIconPTag.classList.remove('kb-icon-plus-animate') + }, 800) + } +} + +/* Add keyboard for kb search and selection UI */ +function addKbToSelection(kb) { + const kbInfo = { + "id": kb.id, + "name": kb.name, + "script": kb.match.tag, + "version": kb.version, + "helpLink": kb.helpLink, + "platformSupport": kb.platformSupport, + "totalDownloads": kb.match.totalDownloads, + } + // historyKbSelection.add(kbInfo) + selectedKbData.push(kbInfo) + selectedKbList.push(kbInfo) +} + +/* Compare and remove keyboard */ +function removeKbSelected(kbId, data) { + if(kbId) { + selectedKbList = selectedKbList.filter(kb => kb.id !== kbId) + selectedKbData = selectedKbData.filter(kb => kb.id !== kbId) + } +} + /* PAUSED */ const historyKbSelection = (() => { const maxItem = 3 @@ -197,6 +301,115 @@ const historyKbSelection = (() => { } }) +function getMarkedContext(query) { + let escapedTerm = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + return new RegExp(escapedTerm, 'i') +} + +// Find a match between Search Context and Language, Keyboard name, Description +function highlightSearchContext(kb, marked) { + let matchFound = false + let matchField = "" + let matchValue = "" + + // Get and find language that matches the search + for (lang in kb.languages) { + let langData = kb.languages[lang] + for (key in langData) { + const value = langData[key] + if (typeof value == "string" && marked.test(value)) { + matchFound = true + matchValue = value.replace(marked, '$&') + matchField = "language" + break + } + } + } + + // Find a match for keyboard name if language is not a match + if (!matchFound && marked.test(kb.name)) { + matchFound = true + matchValue = kb.name.replace(marked, '$&') + matchField = "keyboard" + } + + // Find a match for keyboard description if name is not a match + if (!matchFound && marked.test(kb.description)) { + matchFound = true + matchField = "description" + } + + return {matchField, matchValue, matchFound} +} + +// Display Highlighted Search Context +function showMarkedContext(kb, matchField, matchValue) { + const kbNameHeading = document.createElement('h4') + // Display matched language + const langNameSpan = document.createElement('span') + langNameSpan.style.fontSize = "14px" + if (matchField == "language") { + langNameSpan.innerHTML = matchField == "language" ? ` (${matchValue} language)` : "" + } + + // Display matched keyboard + if (matchField == "keyboard") { + kbNameHeading.innerHTML = matchValue + } else { + kbNameHeading.innerHTML = kb.name + } + kbNameHeading.appendChild(langNameSpan) + + return kbNameHeading +} + +// Truncated Keyboard Description +function truncateDesc(kb, matchField, marked) { + const kbDescHeading = document.createElement('h6') + kbDescHeading.classList.add("keyboard-description") + const word_limits = 90 + + let temp = document.createElement('div') + temp.innerHTML = kb.description + + let fullDesc = kb.description + let plainText = temp.textContent + let shortText = "" + + let isTruncated = false + + if (plainText.length >= word_limits) { + shortText = plainText.slice(0, word_limits) + "..." + kbDescHeading.innerHTML = shortText + isTruncated = true + } else { + kbDescHeading.innerHTML = fullDesc + isTruncated = false + } + + if (isTruncated) { + const toggleBtn = document.createElement('a') + toggleBtn.href = "#" + toggleBtn.style.marginLeft = "6px" + toggleBtn.textContent = "Show more" + + toggleBtn.addEventListener('click', e => { + e.preventDefault() + const isExpanded = toggleBtn.textContent == "Show more" + kbDescHeading.innerHTML = !isExpanded ? shortText.replace(marked, '$&') : fullDesc + if (matchField == 'description') { + kbDescHeading.innerHTML = isExpanded ? fullDesc.replace(marked, '$&') : shortText + } + kbDescHeading.style.color = isExpanded ? 'black' : 'gray' + toggleBtn.textContent = isExpanded ? "Show less" : "Show more" + kbDescHeading.appendChild(toggleBtn) + }) + kbDescHeading.appendChild(toggleBtn) + } + + return kbDescHeading +} + /* Display items return from search */ let selectedKbList = [] let selectedKbData = [] @@ -218,178 +431,23 @@ function displaySearch(data, total = 0, query = '') { } // Getting searched Word ready for highlight - let escapedTerm = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') - let marked = new RegExp(escapedTerm, 'i') - - // Loop through the keyboard data - data.forEach(kb => { - let matchFound = false - let matchField = "" - let matchValue = "" + const marked = getMarkedContext(query) - // For checking if the keyboard exists - let kbFoundInList = selectedKbList.some(selected => selected.id == kb.id) - - let cardWrap = document.createElement('div') - cardWrap.classList.add('card-wrap') - cardWrap.setAttribute('id', 'keyboardCardWrap') - - let cardHeader = document.createElement('div') - cardHeader.classList.add('card-header') - - let kbNameHeading = document.createElement('h4') - - // Get language that matches the search term - for (lang in kb.languages) { - let langData = kb.languages[lang] - for (key in langData) { - const value = langData[key] - if (typeof value == "string" && marked.test(value)) { - matchFound = true - matchValue = value.replace(marked, '$&') - matchField = "language" - break - } - } - } - - // Find a match - if (!matchFound && marked.test(kb.name)) { - matchFound = true - matchValue = kb.name.replace(marked, '$&') - matchField = "keyboard" - } - - if (!matchFound && marked.test(kb.description)) { - matchFound = true - matchField = "description" - } - - // Display matched language - const langNameSpan = document.createElement('span') - langNameSpan.style.fontSize = "14px" - if (matchField == "language") { - langNameSpan.innerHTML = matchField == "language" ? ` (${matchValue} language)` : "" - } + const searchInstruction = document.querySelector('.search-instruction') + const kbHrTitle = document.querySelector('.keyboard-title') + if (!query) { + searchInstruction.classList.remove("hidden") + kbHrTitle.textContent = "Most Downloads" + } else { + searchInstruction.classList.add("hidden") + kbHrTitle.textContent = "" + } - // Display matched keyboard - if (matchField == "keyboard") { - kbNameHeading.innerHTML = matchValue - } else { - kbNameHeading.innerHTML = kb.name - } + data.forEach(kb => { + const card = searchKbCardUI(kb, marked, selectedKbList) + kbSearchCard.appendChild(card) - const kbIconPTag = document.createElement('p') - kbIconPTag.textContent = "+" - kbIconPTag.style.fontSize = '20px' - kbIconPTag.style.cursor = 'pointer' - kbIconPTag.classList.add('kb-icon-plus') - - const kbIdPTag = document.createElement('p') - kbIdPTag.classList.add('keyboard-id') - kbIdPTag.textContent = kb.id - - kbNameHeading.appendChild(langNameSpan) - cardHeader.appendChild(kbNameHeading) - cardHeader.appendChild(kbIconPTag) - - // Keyboard Description - const kbDescHeading = document.createElement('h6') - kbDescHeading.classList.add("keyboard-description") - const word_limits = 90 - - let temp = document.createElement('div') - temp.innerHTML = kb.description - - let fullDesc = kb.description - let plainText = temp.textContent - let shortText = "" - - let isTruncated = false - - if (plainText.length >= word_limits) { - shortText = plainText.slice(0, word_limits) + "..." - kbDescHeading.innerHTML = shortText - isTruncated = true - } else { - kbDescHeading.innerHTML = fullDesc - isTruncated = false - } - - if (isTruncated) { - const toggleBtn = document.createElement('a') - toggleBtn.href = "#" - toggleBtn.style.marginLeft = "6px" - toggleBtn.textContent = "Show more" - - toggleBtn.addEventListener('click', e => { - e.preventDefault() - const isExpanded = toggleBtn.textContent == "Show more" - kbDescHeading.innerHTML = !isExpanded ? shortText.replace(marked, '$&') : fullDesc - if (matchField == 'description') { - kbDescHeading.innerHTML = isExpanded ? fullDesc.replace(marked, '$&') : shortText - } - kbDescHeading.style.color = isExpanded ? 'black' : 'gray' - toggleBtn.textContent = isExpanded ? "Show less" : "Show more" - kbDescHeading.appendChild(toggleBtn) - }) - kbDescHeading.appendChild(toggleBtn) - } - - const kbSpecs = document.createElement('div') - kbSpecs.classList.add('keyboard-specs') - - const kbDownloadHeading = document.createElement('h6') - kbDownloadHeading.textContent = `${kb.match.downloads} monthly downloads` - kbDownloadHeading.classList.add('monthly-download') - - const kbPlatformSupport = document.createElement('div') - kbPlatformSupport.classList.add('platform') - kbPlatformSupport.innerHTML = platformSupport(kb.platformSupport) - - kbSpecs.appendChild(kbDownloadHeading) - kbSpecs.appendChild(kbPlatformSupport) - - cardWrap.appendChild(cardHeader) - cardWrap.appendChild(kbIdPTag) - cardWrap.appendChild(kbDescHeading) - cardWrap.appendChild(kbSpecs) - // kbSearchCard.appendChild(defaultInstruction) - kbSearchCard.appendChild(cardWrap) - - if (kbFoundInList) { - kbIconPTag.textContent = 'โœ“' - kbIconPTag.classList.add('animate') - cardWrap.classList.add('disabled') - - setTimeout(() => { - kbIconPTag.textContent = '-' - kbIconPTag.classList.remove('animate') - }, 600) - } - // Choose keyboard to selection - kbIconPTag.onclick = (e) => { - e.preventDefault() - let isSelected = selectedKbList.some(selected => selected.id == kb.id) - // Disable keyboard card in search - if (isSelected) { - removeKeyboard(kb.id) - } else { - addKeyboard(kb) - console.log(kb) - populateSelectedKeyboard(kb) - } - - selectedKbList.forEach(data => { - let kbName = data.id - let langCode = data.script - - changeKeyboard(kbName, langCode) - }) - // console.log("Recent:", historyKbSelection.getHistory()); - displaySearch(data, total, query) - } - dataKbForRemoval = selectedKbData + // dataKbForRemoval = selectedKbData }) paginationCtrl.style.display = 'flex'; } @@ -397,6 +455,13 @@ function displaySearch(data, total = 0, query = '') { const downloadBtn = document.getElementById('kbDownloadPage') const textArea = document.getElementById('textArea') async function changeKeyboard(kbdname, languageCode) { + + // selectedKbList.forEach(data => { + // let kbName = data.id + // let langCode = data.script + + // changeKeyboard(kbName, langCode) + // }) console.log("kbdname: ", kbdname, " + ", "languageCode: ", languageCode) if(kbdname == '') { if (textArea) textArea.placeholder = 'Select a keyboard and start typing' @@ -438,7 +503,7 @@ function platformSupport(data) { return platformSpan } -/* Selected Keyboard Selection */ +/* Selected Keyboard List */ function populateSelectedKeyboard(language = null) { if(selectedKbList.length > 4) { alert("The maximum keyboard selection is 5") @@ -453,37 +518,10 @@ function populateSelectedKeyboard(language = null) { }) } } - // Create the Language List generateKbUI(selectedKbList) } -/* Add keyboard for kb search and selection UI */ -function addKeyboard(kb) { - const kbInfo = { - "id": kb.id, - "name": kb.name, - "script": kb.match.tag, - "version": kb.version, - "helpLink": kb.helpLink, - "platformSupport": kb.platformSupport, - "totalDownloads": kb.match.totalDownloads, - } - // historyKbSelection.add(kbInfo) - selectedKbData.push(kbInfo) - selectedKbList.push(kbInfo) -} - -/* Compare and remove keyboard */ -function removeKeyboard(kbId, data) { - if(kbId) { - selectedKbList = selectedKbList.filter(kb => kb.id !== kbId) - selectedKbData = selectedKbData.filter(kb => kb.id !== kbId) - } -} - -/* Generate Language's keyboards - ON PAUSED -*/ +/* A UI for keyboard selection menu */ function generateKbUI(selectedKbList) { const keyboardSelection = document.getElementById("keyboardSelection") keyboardSelection.innerHTML = '' @@ -491,97 +529,112 @@ function generateKbUI(selectedKbList) { if (!selectedKbList.length) { keyboardSelectionButton.classList.remove('btn-keyman-orange') keyboardSelectionButton.classList.add('btn-secondary') - const noKbPTag = document.createElement('p') - noKbPTag.textContent = "Open Search to get your keyboard" - keyboardSelection.appendChild(noKbPTag) + keyboardSelection.textContent = "Open Search to get your keyboard" return } keyboardSelectionButton.classList.remove('btn-secondary') keyboardSelectionButton.classList.add('btn-keyman-orange') - selectedKbList.forEach(data => { - // Language Parent tags const kbDiv = document.createElement('div') kbDiv.classList.add("kb-item") kbDiv.setAttribute('id', `${data.id}`) + kbDiv.textContent = data.name const item = selectedKbData.find(kb => kb.id == data.id) - // console.log(selectedKbData) if (!item) return; - kbDiv.textContent = data.keyboard - const kbDetails = document.createElement('div') - kbDetails.setAttribute('id', 'keyboardDetails') - kbDetails.classList.add('hidden') - kbDetails.innerHTML = ` -
    -
  • - - - -
  • -
  • -
    -
    Version
    -
    ${item.version || "N/A"}
    -
    -
  • - -
  • -
    -
    Total downloads
    -
    ${item.totalDownloads || 0}
    -
    -
  • -
  • -
    -
    Supported Platforms
    -
    - ${platformSupport(item.platformSupport) || 'No platforms supported'} -
    -
    -
  • -
- ` - // kbDiv.addEventListener('mouseenter', () => { - // kbDiv.style.cursor = "pointer" - // openKbDetails() - // }) + const kbDetails = displayKbDetails(item) - kbDiv.addEventListener('click', async (e) => { - e.preventDefault() - - if (!data.id || !data || !item.helpLink) { - console.error("Missing Data or Item") - } - - let kbName = `Keyboard_${data.id}` - let keyboards = keyman.getKeyboards(); - let keyboard = keyboards.find(keyboard => keyboard.InternalName == kbName) - - // console.log("All keyboards: ", keyboards) - // console.log("My keyboard: " + keyboard) - if(keyboard) { - languageCode = keyboard.LanguageCode - changeKeyboard(data.id, languageCode, item.helpLink) - } else { - console.warn("Keyboard not found: ", kbName) - } - - }) kbDiv.appendChild(kbDetails) keyboardSelection.appendChild(kbDiv) + kbDiv.onclick = () => enableKbToType() + kbDiv.onmouseenter = () => displayKbDetails() + }) +} + +function triggerKbCount(selectedKbList) { + const kbSelectedLength = selectedKbList.length + const keyboardCount = document.querySelector('#kbCount') + if (kbSelectedLength > 0) { + keyboardCount.classList.remove('fa-caret-right') + } + keyboardCount.textContent = `${kbSelectedLength}` +} + +function displayKbDetails(item) { + const kbDetails = document.createElement('div') + kbDetails.setAttribute('id', 'keyboardDetails') + kbDetails.classList.add('hidden') + kbDetails.innerHTML = ` +
    +
  • + + + +
  • +
  • +
    +
    Version
    +
    ${item.version || "N/A"}
    +
    +
  • + +
  • +
    +
    Total downloads
    +
    ${item.totalDownloads || 0}
    +
    +
  • +
  • +
    +
    Supported Platforms
    +
    + ${platformSupport(item.platformSupport) || 'No platforms supported'} +
    +
    +
  • +
+ ` + return kbDetails +} + +function enableKbToType() { + // kbDiv.addEventListener('mouseenter', () => { + // kbDiv.style.cursor = "pointer" + // openKbDetails() + // }) + + kbDiv.addEventListener('click', async (e) => { + e.preventDefault() + + if (!data.id || !data || !item.helpLink) { + console.error("Missing Data or Item") + } + + let kbName = `Keyboard_${data.id}` + let keyboards = keyman.getKeyboards(); + let keyboard = keyboards.find(keyboard => keyboard.InternalName == kbName) + + // console.log("All keyboards: ", keyboards) + // console.log("My keyboard: " + keyboard) + if(keyboard) { + languageCode = keyboard.LanguageCode + changeKeyboard(data.id, languageCode, item.helpLink) + } else { + console.warn("Keyboard not found: ", kbName) + } + }) } /* - Behavior of the Selected Keyboard + Behavior of the Selected Keyboard menu */ const kbSelection = document.querySelector('#keyboardSelection') keyboardSelectionButton.addEventListener('mouseenter', () => { @@ -601,6 +654,7 @@ const worldMapBtn = document.querySelector('#worldMap') const kmwControls = document.querySelector('#KeymanWebControl') const langSearchDropdown = document.querySelector('#languageSearchDropdown') const caretRightIcon = keyboardSelectionButton.querySelector('.fa-caret-right') +const infoIcon = document.querySelector('#infoIcon') let mapIsOpen worldMapBtn.onclick = () => { @@ -618,7 +672,6 @@ function toggleMapAndKb() { function openMap() { mapIsOpen = true - searchBtn.style.display = "none" kmwControls.classList.remove('hidden') kmwControls.style.display = "block" @@ -630,14 +683,15 @@ function openMap() { function openSearch() { mapIsOpen = false - searchBtn.style.display = "block" kmwControls.classList.add('hidden') kmwControls.style.display = "none" langSearchDropdown.classList.remove('hidden') + infoIcon.classList.remove('hidden') searchBoxForm.innerHTML = '' searchBoxForm.appendChild(searchBtn) + searchBoxForm.appendChild(infoIcon) searchBoxForm.appendChild(langSearchDropdown) } diff --git a/index.php b/index.php index 4797c2c..ee0f9b6 100644 --- a/index.php +++ b/index.php @@ -21,10 +21,26 @@
World Map
+
+
+
+

Instruction

+
+
+
    +
  1. Search for any Keyman keyboard
  2. +
  3. Click on "+" to enable and store it in the keyboard selection menu
  4. +
  5. Switch between keyboards and start typing.
  6. +
+
+
-
- +
  • +
    +
    Source Path
    + +
    +
  • Supported Platforms
    @@ -599,11 +774,77 @@ function displayKbDetails(item) {
  • +
  • +
    +
    Last Updated
    +
    ${getOnlyDates(item.lastUpdated) || 0}
    +
    +
  • ` + kbDetails.appendChild(kbDetailsHead) + kbDetails.appendChild(kbDetailsContent) + return kbDetails } +// Get only the YYYY-mm-dd format +function getOnlyDates(dateData) { + const finalDateData = dateData.match(/^\d{4}-\d{2}-\d{2}/) + return finalDateData +} + +// Validate URLs +function validateURL(string) { + try { + const newUrl = new URL(string) + if (newUrl.protocol === 'https:') { + return newUrl + } else { + return false + } + } catch (error) { + console.error(error) + } +} +/* + == End of Keyboard Selection menu Section == +*/ + +// Change and type keyboard +const downloadBtn = document.getElementById('kbDownloadPage') +const textArea = document.getElementById('textArea') +async function changeKeyboard(kbdname, languageCode) { + + // selectedKbList.forEach(data => { + // let kbName = data.id + // let langCode = data.script + + // changeKeyboard(kbName, langCode) + // }) + console.log("kbdname: ", kbdname, " + ", "languageCode: ", languageCode) + if(kbdname == '') { + if (textArea) textArea.placeholder = 'Select a keyboard and start typing' + } + location.replace('#' + languageCode + ',Keyboard_' + kbdname); + + var kbd = keyman.getKeyboard(kbdname, languageCode); // Good + await keyman.setActiveKeyboard(kbdname, languageCode) // Good + console.log("kbd: ", kbd) + + if(kbd) { + textArea.placeholder = 'The ' + kbd.InternalName + ' keyboard is selected. Start typing...' + } + + const kbSpan = document.querySelector('#kbSpan') + const kbHelpDocATag = document.querySelector('#kbHelpdocLink') + textArea.placeholder = `The ${kbdname} keyboard is selected. Please start typing...` + kbSpan.innerHTML = `${kbdname}` + // kbHelpDocATag.href = `${kbdHelpLink}` + + if(typeof(KeyboardChange_EmbedFonts) != 'undefined') KeyboardChange_EmbedFonts(kbdname); +} + function enableKbToType() { // kbDiv.addEventListener('mouseenter', () => { // kbDiv.style.cursor = "pointer" @@ -629,22 +870,25 @@ function enableKbToType() { } else { console.warn("Keyboard not found: ", kbName) } - }) } -/* - Behavior of the Selected Keyboard menu +/* == Section == + UI interaction and manipulation */ + +/* UI Behavior of the Selected Keyboard menu */ const kbSelection = document.querySelector('#keyboardSelection') +const kbSelectionWrap = document.querySelector('.scroll-wrapper-keyboard-tab') +const keyboardSelectionButton = document.getElementById('keyboardSelectionButton') keyboardSelectionButton.addEventListener('mouseenter', () => { - kbSelection.style.width = "100%" + kbSelection.classList.add('open') }) keyboardSelectionButton.addEventListener('click', () => { - kbSelection.style.width = "0px" + kbSelection.classList.remove('open') }) kbSelection.addEventListener('mouseleave', () => { - kbSelection.style.width = "0px" + kbSelection.classList.remove('open') }) /* diff --git a/inc/head.php b/inc/head.php index 9d73cee..6d6cbe1 100644 --- a/inc/head.php +++ b/inc/head.php @@ -59,6 +59,7 @@ + " /> " /> diff --git a/index.php b/index.php index ee0f9b6..3e19382 100644 --- a/index.php +++ b/index.php @@ -56,11 +56,11 @@ -
    -
    - Open Search to get your keyboard - -
    +
    +
    +

    Open Search to get your keyboard

    + +
    From d7a0046877a9ec32c4c5ed41794412df34b595ed Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Wed, 23 Jul 2025 10:42:00 +0700 Subject: [PATCH 18/36] feat: keyboards, examples, styles, text dir, fix some bugs --- cdn/dev/css/kmw-body.css | 2 + cdn/dev/css/kmw-desktop.css | 752 +++--------------------------------- cdn/dev/css/kmw-header.css | 23 +- cdn/dev/js/kmwControls.js | 18 +- cdn/dev/js/kmwHeader.js | 485 +++++++++++++++-------- inc/head.php | 3 +- index.php | 25 +- prog/languageexample.php | 6 +- 8 files changed, 426 insertions(+), 888 deletions(-) diff --git a/cdn/dev/css/kmw-body.css b/cdn/dev/css/kmw-body.css index a632ac2..5e53260 100644 --- a/cdn/dev/css/kmw-body.css +++ b/cdn/dev/css/kmw-body.css @@ -101,6 +101,8 @@ i:hover { flex-direction: row; justify-content: center; align-items: center; + width: 1300px; + height: 500px; } .example-box { diff --git a/cdn/dev/css/kmw-desktop.css b/cdn/dev/css/kmw-desktop.css index c70ab66..09cc8af 100644 --- a/cdn/dev/css/kmw-desktop.css +++ b/cdn/dev/css/kmw-desktop.css @@ -6,162 +6,6 @@ ====================== */ -html { - overflow-y: auto; - overflow-x: hidden; - font-size: 14px; -} - -body { - width:100%; - font-family: Cabin, Arial, Helvetica, sans-serif; - color:#2D2C2C; - margin:0px; -} - -a { - text-decoration:none; - color: #2EADD3; - } - -a:hover { - text-decoration:underline; - } - -h3 { - font-size:18px; - } - -p { - font-size:13px; - line-height:1.5em; - } - -header, #content, footer { - /* width:960px; */ - margin:0px auto; - clear: both; - } - -.box { - -webkit-border-radius: 8px;-moz-border-radius: 8px; border-radius: 8px; - -moz-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -} - -/* -=================== -==Header Elements== -=================== -*/ -header { - position: fixed; - margin-left: auto; - margin-right: auto; - padding-bottom: 30px; - z-index: 1; -} - -header #headerBackground { - padding: 10px; -} - -header > div > img { - width: 100%; - display: block; - height: 8px; -} - -#headerBackground { - display: grid; - grid-template-columns: 5% 70% 25%; - justify-content: left; - align-items: center; - box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; - margin: 0px 0px; - background-color: white; -} - -#headerLeft { - margin-left: 10px; -} - -#headerLeft img { - display: block; /* default (inline) display inserts an unwanted bottom border */ - height: 50px; - /*-webkit-border-radius: 0px 0px 8px 8px; -moz-border-radius: 0px 0px 8px 8px; border-radius: 0px 0px 8px 8px;*/ -} - -#headerMiddle { - display: flex; - flex-direction: row; - justify-content: left; - align-items: center; - width: 100%; -} - -#headerMiddle div { - margin: 0px 15px; -} - -#headerMiddle div ul .row{ - margin: 0px !important; -} - -#headerMiddle div ul .row .col{ - margin: 0px !important; -} - -#headerRight { - display: grid; - grid-template-columns: 60% 20% 10% 10%; - justify-content: end; - align-items: center; - width: 100%; -} - -#headerRight div > * { - margin-right: 20px; -} - -#headerRight-beta { - display: block; - font-weight: bold; - color: red; - font-size: 16pt; - padding: 20px 12px 0; -} - -#headerRight-link { - padding: 0 12px 0; -} - -#headerBar { - width: 100%; -} -/* -==================== -==Content Elements== -==================== -*/ -#content { - min-height:375px; - } - - -/* KMW Main App */ -#app { - float:left; - /*height:330px;*/ - width:710px; - margin: 30px 15px 15px; - } -#KeymanWebControl { - width:710px; - height: 35px; - display:block; - -webkit-border-radius: 8px 8px 0px 0px; -moz-border-radius: 8px 8px 0px 0px; border-radius: 8px 8px 0px 0px; - } - #kmw_controls{ border-top-left-radius: 8px; border-top-right-radius: 8px; @@ -176,28 +20,6 @@ header > div > img { border-top-left-radius: 10px; } -#example,#help { - margin:8px 10px; - background-color:#95C6D6; - border:1px solid #2EADD3; - padding:2px; - text-align:center; - } - -#example { - visibility: hidden; - width:685px; - min-height: 45px; - display: flex; - justify-content: center; - align-items: center; - padding-top: 5px; -} - -#example a{ - padding-left: 10px; -} - textarea { height:260px; width:554px; @@ -215,520 +37,73 @@ form { #messageContainer { float:left; width:80%; - } - -/* KMW App Buttons */ - -#instructions { - margin:-1px 0px 2px; - } - -#buttons { - float:right; - padding-right:10px; - } - -#buttons div { - width:120px; - -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; - background-color: #eeeeee; - border: 1px solid #888888; - margin: 0px 10px; -/* -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -o-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - color: white; - font: bold 14px Helvetica, Verdana, Arial, sans-serif; - text-shadow: 0px -1px 1px #1E2D4D; */ - text-align:left; - margin: 0 auto 6px; - padding: 3px; - padding-top: 9px; - height: 26px; - background-repeat: no-repeat; - background-position: center left; - } -#buttons div:disabled { - cursor: default !important; - color: #eeeeee !important; - /* -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -o-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; */ -} - -#buttons p{ - margin-left: 41px; -} - -#search{ - background-image:url('../img/btn_google_small.png'); - -} - -#search.linksOff{ - background-image:url('../img/btn_google_small_white.png'); -} - -#copy{ - background-image:url('../img/btn_copy_small.png'); - -} - -#copy.linksOff{ - background-image:url('../img/btn_copy_small_white.png'); -} - -#font{ - display: none; -} - -#mobile-font{ - display: none; -} - -#font-size{ - float: right; - width: 120px; - margin-right: 10px; - margin-bottom: 8px; - padding: 0px 4px; - display: table; -} - -#font-small{ - font-size: 10pt; - padding-top: 7px; - text-align: left; -} - -#font-large{ - font-size: 16pt; - text-align: right; -} - -.ui-slider-handle{ - width: 10px !important; - height: 10px !important; - cursor: pointer !important; - outline: none !important; -} - -#slider{ - height: 4px; - width: 68px; - float: left; - position: relative; - top: 14px; -} - -.font-letter{ - float: left; - width: 25px; - text-align: center; - display: table-cell; -} - -#buttons div * { - display:inline; - } - -div.links { - cursor:pointer; - } - -div.linksOff { - cursor:default !important; - border: 1px solid #cccccc !important; - } - -div.linksOff * { - color: gray; - -moz-user-select:none; - } - -hr { - margin: 6px 4px 6px 4px; - } - - -/* Aside Elements */ -aside { - float:right; - width:200px; - margin-right:15px; - } -aside h3 { - background-color: rgba(181, 177, 176, 0.2); - padding:6px 10px 7px; - margin:0px; - -webkit-border-radius: 8px 8px 0px 0px; -moz-border-radius: 8px 8px 0px 0px; border-radius: 8px 8px 0px 0px; - -moz-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); - } -aside > div { - margin:30px 0px 0px; - } -aside p { - padding:10px; - margin:0px; - } -aside #learn { - font-size:13px; - text-align:center; - } - -#keymandesktop, #bookmarklet{ - display: none; } /* -=================== -==Footer Elements== -=================== +====================== +==Keyboard Examples== +====================== */ - -.button { - float: left; - width: 200px; - height: 40px; - line-height: 40px; - border-radius: 6px; - text-align: center; - margin: 20px; - cursor: pointer; - box-shadow: 1px 1px 2px #3e3e3e; -} - -.footer{ - bottom: 0; - left: 0; - float: left; - text-align: center; - width: 100%; - background: #A4A8AB; - line-height: 1; -} - -.footer .wrapper { - width: auto; - display: inline-block; - margin: 0; - text-align: left; -} - -.footer-third{ - float: left; - width: 320px; - margin-left: 4px; - margin-right: 4px; -} - -.footer-third-title{ - margin-top: 30px; - text-align: center; - font-size: 18pt; - font-weight: normal; - color: #fff; - margin-bottom: 25px; -} - -.footer-third form{ - width: 320px; -} - -.footer-third form input{ - -webkit-appearance: none; - padding: 0px; - float: left; - height: 38px; - width: 200px; - padding-left: 10px; - font-size: 14pt; - border-radius: 6px; - border-bottom-right-radius: 0px; - border-top-right-radius: 0px; - box-shadow: none; - border: 1px solid #FFFFFF; - margin-left: 10px; -} - -.footer-third form input:focus{ - outline: 0; -} - -#footer-mailchimp br { - clear: both; -} - -/* - social-logos font from https://github.com/Automattic/social-logos, GPLv2 - */ -@font-face { - font-family: "social-logos"; - src: url("../../fonts/social-logos.ttf"); - font-weight: normal; - font-style: normal; -} - -[data-icon]:before { - font-family: "social-logos" !important; - content: attr(data-icon); - font-style: normal !important; - font-weight: normal !important; - font-variant: normal !important; - text-transform: none !important; - line-height: 1; - speak: none; - padding-right: 4px; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; } - -#footer-social { - text-align: center; -} - -#footer-social a { - display: block; - text-decoration: none; - color: #666666; - font-size: 14pt; - padding: 4px; -} - -#footer-social a:hover { - color: #444444; -} - -#privacy-policy { - text-align: center; - margin-top: 16px; -} - -#privacy-policy a { - display: block; - text-decoration: none; - color: white; - font-size: 12pt; -} - -#privacy-policy a:hover { - color: #444444; -} - -#version { - color: #666666; - font-size: 10pt; - margin-top: 46px; +#example,#help { + margin: 5px 0px; text-align: center; } -#mobile-footer { - display: none; -} - -#footer-social div { - display: inline-block; - text-align: left; - margin-bottom: 24px; -} - -#footer-social a#footer-community { - padding-left: 27px; -} - -.subscribe{ - width: 90px; - margin: 0px; - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; - background: #666666; - box-shadow: none; -} - -.subscribe:hover{ - background: #888888; -} - -.subscribe h2{ - font-size: 16px; - margin: 0px; -} - -.sil-logo a, .sil-logo a:visited { - color: white; - text-decoration: none; +#example { + visibility: hidden; + width: 100%; + min-height: 45px; + display: flex; + justify-content: center; + align-items: center; + padding-top: 5px; } -.sil-logo a:hover { - color: white; - text-decoration: underline; +#example a { + padding-left: 10px; } -.sil-logo { - text-align: center; - margin-top: 20px; +.highlightKeys kbd { + border: solid 1px #808080; + border-radius: 4px; + background: #cccccf; + color: black; + font-family: Verdana; + font-weight: normal; + min-width: 16px; + display: inline-block; + box-shadow: 2px 2px 1px rgba(128, 128, 128, 0.3); + margin-right: 4px; } -.sil-logo p{ - color: #fff; - font-size: 12pt; - margin-top: 10px; +.highlightKeys kbd.space { + min-width: 64px; } /* -=================== -==Extras== -=================== +====================== +==Keyboard Styling== +====================== */ - -#fblike{ -position: absolute; -left: 50%; -margin-left: 320px; - } - -nav ul { - list-style: none outside none; - width:90%; - margin:0px auto; - padding:15px 0px; - } - -nav li { - display:inline; - padding:20px 39px; - } - -nav a { - color:#eee; - font-family:Tahoma; - font-weight:bold; - font-size:10.7px; - } - -.messageBox { - -webkit-border-radius: 8px;-moz-border-radius: 8px; border-radius: 8px; - -moz-box-shadow: 3px 3px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 3px 3px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 3px 3px 3px 0px rgba(0, 0, 0, 0.5); - background: #c4c4c4; - position: fixed; - left: 50%; - top: 25%; - z-index: 10002; - margin-left: -250px; - margin-top: -50px; - width: 500px; - height: 200px; +.desktop, .kmw-osk-frame { + display: block !important; + position: static !important; + width: 100% !important; + height: 264px !important; + max-width: 100% !important; + max-height: 264px !important; + border-radius: 0; } -.messageBox div { - width: 464px; - height: 134px; - left: 10px; - top: 10px; - padding: 8px; - font-size: 13px; - position: absolute; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 3px; - background: white; +.kmw-key-square { + z-index: 0 !important; } -.messageBox button { - width:83px; - position: absolute; - right: 10px; - bottom: 4px; - background: #414141; - border-top: 1px solid #383838; - border-right: 1px solid #1F1F1F; - border-bottom: 1px solid #151515; - border-left: 1px solid #1F1F1F; - -webkit-border-radius: 8px;-moz-border-radius: 8px; border-radius: 8px; - -moz-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); - color: white; - font: bold 12px Helvetica, Verdana, Arial, sans-serif; - text-shadow: 0px -1px 1px #1E2D4D; - text-align:center; - margin: 0 auto 6px; - padding: 3px; - } - -.messageBox button:disabled { - cursor: default !important; +.kmw-spacebar-caption { color: gray !important; - -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -o-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; -} - -.messageBox button:hover { --webkit-border-radius: 8px;-moz-border-radius: 8px; border-radius: 8px; - -moz-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); - cursor: pointer; -} - -.messageBox button:active { - -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - -o-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; -} - -.progressBox { --webkit-border-radius: 8px;-moz-border-radius: 8px; border-radius: 8px; - -moz-box-shadow: 3px 3px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 3px 3px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 3px 3px 3px 0px rgba(0, 0, 0, 0.5); - background: #c4c4c4; - position: fixed; - left: 50%; - top: 25%; - margin-left: -200px; - width: 400px; - height: 54px; -} - -.progressBox div { - width: 364px; - height: 18px; - left: 10px; - top: 10px; - padding: 8px; - background: url('../img/wait.gif') no-repeat 354px 8px white; - font-size: 13px; - position: absolute; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 3px; -} - -#footer-logo{ - margin-top: 10px; } -#content {width: 960px;} - -/* -====================== -==Keyboard Styling== -====================== -*/ - .desktop .kmw-osk-frame, .desktop .kmw-osk-inner-frame, .desktop .kmw-key-layer-group { background-color: #95C6D6 !important; } @@ -762,7 +137,7 @@ nav a { .desktop .kmw-key-label { top: 5%; } .desktop .kmw-key-label { left: 10%; } .desktop .kmw-key-default .kmw-key-text { top: 25%; } - .desktop .kmw-footer, .desktop .kmw-title-bar { background: #2EADD3 !important; } + .desktop .kmw-footer, .desktop .kmw-title-bar { background: #2EADD3 !important; display: none;} .desktop .kmw-title-bar div{min-height: 100%;} .desktop .kmw-footer-caption a { color: white !important; } .kmw-osk-frame, .kmw-osk-inner-frame { border-color: #2EADD3 !important; } @@ -785,47 +160,6 @@ nav a { text-align: center; } -#keyman-desktop-download { - display: block; - text-align: center; - margin-top: 8px; -} - -#free-open-source { - color: #606060; - font-size: 8pt; - font-weight: normal; - display: block; - text-align: center; - -} - -#close { - float: right; - cursor: pointer; - position: relative; - top: -10px; -} - -#bookmarklet.hidden { - display: none; -} - -#bookmarklet div { - text-align: center; - margin: 16px 0 2px; -} - -#bookmarklet p { - font-size: 9px; - text-align: justify; -} - -#learn div { - margin: 0; - padding-bottom: 12px; -} - @media all and (min-width: 1320px) { ins.adsbygoogle { display: inline-block !important; diff --git a/cdn/dev/css/kmw-header.css b/cdn/dev/css/kmw-header.css index 5cc7f18..eaca661 100644 --- a/cdn/dev/css/kmw-header.css +++ b/cdn/dev/css/kmw-header.css @@ -85,6 +85,7 @@ Language Search box border-radius: 15px; text-align: left; background-color: rgb(233, 228, 228); + font-family: inherit !important; } #mainSearchBtn:focus { @@ -333,7 +334,7 @@ Language Search box /* Selected Keyboard Menu */ #keyboardSelectionButton { - z-index: 1; + z-index: 3; } .scroll-wrapper-keyboard-tab { @@ -362,6 +363,7 @@ Language Search box } #keyboardSelection.open { + position: relative; width: 400px; height: fit-content; padding: 0 0 10px; @@ -371,18 +373,27 @@ Language Search box #keyboardSelection p { margin: 0; height: 25px; + width: 100%; } -.kb-item-header { +.kb-item-header, .kb-item-footer { display: flex; align-items: center; justify-content: center; height: 30px; - border-bottom: 1px solid gray; font-weight: 500; margin: 5px 0; } +.kb-item-header { + border-bottom: 1px solid gray; +} + +.kb-item-footer { + border-top: 1px solid gray; + cursor: pointer; +} + .kb-item { width: 100%; max-height: fit-content; @@ -395,7 +406,6 @@ Language Search box .kb-item:hover { cursor: pointer; - height: fit-content; background-color: var(--keyman-orange); color: white; } @@ -710,6 +720,10 @@ input[type="range"]::-webkit-slider-thumb { grid-template-rows: 1fr; } +.dropdown-item:active { + background-color: transparent !important; +} + #burgerMenu ul li { align-items: center; width: 300px; @@ -798,6 +812,7 @@ input[type="range"]::-webkit-slider-thumb { font-family: "social-logos" !important; content: attr(data-icon); padding-right: 4px; + font-size: 16px; } .kmw-version { diff --git a/cdn/dev/js/kmwControls.js b/cdn/dev/js/kmwControls.js index e1445f0..185a218 100644 --- a/cdn/dev/js/kmwControls.js +++ b/cdn/dev/js/kmwControls.js @@ -3,8 +3,16 @@ KeymanWebControls (Map, Examples, Keyboards...etc) */ -$(document).ready(function() { - $("#KeymanWebControls").show( function() { - alert("Show") - }) -}) \ No newline at end of file +function waitForElement(selector, callback) { + const interval = setInterval(() => { + const el = document.querySelector(selector) + if (el) { + clearInterval(interval) + callback(el) + } + }, 100) +} + +waitForElement(".kmw-osk-frame", function(oskDiv) { + document.querySelector('.keyboard-area').appendChild(oskDiv) +}) \ No newline at end of file diff --git a/cdn/dev/js/kmwHeader.js b/cdn/dev/js/kmwHeader.js index 531182a..ba21180 100644 --- a/cdn/dev/js/kmwHeader.js +++ b/cdn/dev/js/kmwHeader.js @@ -11,16 +11,290 @@ function getKeymanWeb() { let selectedKbList = [] let dataKbForRemoval +document.addEventListener('DOMContentLoaded', () => { + /* == Section == + UI interaction and manipulation + */ + + /* + Toggle between World Map and Search + */ + const elements = { + worldMapBtn: document.querySelector('#worldMap'), + kmwControls: document.querySelector('#KeymanWebControl'), + + kbSelection: document.querySelector('#keyboardSelection'), + keyboardSelectionButton: document.getElementById('keyboardSelectionButton'), + langSearchDropdown: document.querySelector('#languageSearchDropdown'), + caretRightIcon: keyboardSelectionButton.querySelector('.fa-caret-right'), + infoIcon: document.querySelector('#infoIcon'), + + searchBoxForm: document.querySelector('.form'), + searchBtn: document.querySelector('#mainSearchBtn') + } + + const state = { + mapIsOpen: true + } + + /* UI Behavior of the Selected Keyboard menu */ + if (exists(elements)) { + elements.keyboardSelectionButton.addEventListener('mouseenter', () => { + elements.kbSelection.classList.add('open') + }) + elements.keyboardSelectionButton.addEventListener('click', () => { + elements.kbSelection.classList.remove('open') + }) + elements.kbSelection.addEventListener('mouseleave', () => { + elements.kbSelection.classList.remove('open') + }) + } + + elements.worldMapBtn?.addEventListener('click', (e) => { + e.preventDefault() + toggleMapAndKb() + }) + + function toggleMapAndKb() { + if (state.mapIsOpen == false) { + // Open Search + hideEls( + elements.kmwControls, + ) + showEls( + elements.langSearchDropdown, + elements.infoIcon + ) + + if (selectedKbList.length > 0) { + elements.caretRightIcon.textContent = selectedKbList.length + } else { + elements.caretRightIcon.textContent = '' + elements.caretRightIcon.classList.add('fa-caret-right') + } + + elements.searchBoxForm.replaceChildren( + elements.searchBtn, + elements.infoIcon, + elements.langSearchDropdown + ) + + state.mapIsOpen = true + } else { + // Open Map + removeClass( + elements.kmwControls, 'hidden' + ) + hideEls( + elements.langSearchDropdown + ) + removeTextContent( + elements.caretRightIcon + ) + + elements.searchBoxForm.replaceChildren( + elements.kmwControls + ) + returnToSearchBtn() + + state.mapIsOpen = false + } + } + + function returnToSearchBtn() { + removeClass(elements.caretRightIcon, 'fa-caret-right') + elements.caretRightIcon.classList.add('fa-magnifying-glass') + elements.keyboardSelectionButton.style.backgroundColor = "var(--keyman-orange)" + elements.keyboardSelectionButton.style.border = '0px' + elements.kbSelection.style.display = "none" + + elements.keyboardSelectionButton.onclick = () => { + removeClass(elements.caretRightIcon, 'fa-magnifying-glass') + + if ((selectedKbList?.length || 0) < 1) { + elements.caretRightIcon.classList.add('fa-caret-right') + elements.caretRightIcon.textContent = '' + } + + elements.keyboardSelectionButton.style.backgroundColor = "" + elements.kbSelection.style.display = "block" + toggleMapAndKb() + } + } + + if (!typeof defaultKeyboard == 'function') { + console.warn('defaultKeyboard() is not defined.') + } + defaultKeyboard() +}) + +/* Utility functions */ +function hideEls(...elements) { + return elements.every(el => el.classList.add('hidden')) +} + +function showEls(...elements) { + return elements.every(el => el.classList.remove('hidden')) +} + +function removeClass(element, className) { + return element.classList.remove(className) +} + +function removeTextContent(...elements) { + return elements.every(el => el.textContent = '') +} + +/* Elements validation */ +function exists(...elements) { + return elements.every(el => el != null) +} + +/* + === Keyboard Execution === +*/ +const downloadBtn = document.getElementById('kbDownloadPage') +const textArea = document.getElementById('textArea') +let langExamples = []; + +function prepareSearchInputUI(dir = 'ltr', fontFamily = '') { + const searchTextBox = document.querySelector('#mainSearchBtn') + + searchTextBox.setAttribute('dir', dir) + searchTextBox.style.fontFamily = fontFamily + selectKb() +} + +function setTextDirection(targetEls, dir) { + const copyBtn = document.querySelector('#copyTool') + + targetEls.dir = dir + if (dir == 'rtl') { + copyBtn.style.right = '0' + copyBtn.style.left = '10px' + } else { + copyBtn.style.right = '' + copyBtn.style.left = '' + } +} + +function defaultKeyboard(kbdname = "basic_kbdus", languageCode = "en") { + if(!exists(kbdname, languageCode)) { + if (textArea) textArea.placeholder = 'A Keyboard name isn\'t specified. Select a keyboard and start typing' + return + } + setKeyboardWithDirection(kbdname, languageCode) +} + +function selectKb(kbdname, languageCode) { + if(!exists(kbdname, languageCode)) { + if (textArea) textArea.placeholder = 'A Keyboard name isn\'t specified. Select a keyboard and start typing' + return + } + setKeyboardWithDirection(kbdname, languageCode) +} + +// Change and type keyboard +async function setKeyboardWithDirection(kbdname, languageCode) { + const kbSpan = document.querySelector('#kbSpan') + const langTag = `#${languageCode}` + const kbTag = `Keyboard_${kbdname}` + + location.replace(`${langTag},${kbTag}`); + + await keyman.addKeyboards(kbdname) + const kbd = keyman.getKeyboard(kbdname, languageCode) + await keyman.setActiveKeyboard(kbdname, languageCode) + + if(kbd) { + textArea.placeholder = `The ${kbdname} keyboard is selected. Start typing...` + kbSpan.innerHTML = `${kbdname}` + + setTextDirection(textArea, textArea.dir) + } + updateExample(kbdname) + if(typeof(KeyboardChange_EmbedFonts) != 'undefined') KeyboardChange_EmbedFonts(kbdname) +} + +/* Language Examples AJAX */ +async function updateExample(kbdname) { + const keymanExample = document.getElementById("example") + const exampleBox = document.getElementById("exampleBox"); + + if (!keymanExample || !exampleBox) return false; + + if(kbdname == '') + { + keymanExample.textContent = `No example is available due to empty Keyboard name.` + return true; + } + + exampleBox.style.visibility='visible'; + keymanExample.style.visibility='visible'; + var activeLanguage = keyman.getActiveLanguage(); + + if(langExamples[activeLanguage + '_' + kbdname]) + { + keymanExample.innerHTML = langExamples[activeLanguage + '_' + kbdname]; + return true; + } + + langExamples[activeLanguage + '_' + kbdname] = 'Loading...'; + keymanExample.innerHTML = 'Loading...'; + + const link = `../../../prog/languageexample.php?keyboard=${kbdname}&language=${activeLanguage}`; + try { + const response = await fetch(link); + if(response.status == 200) { + const content = await response.text(); + + langExamples[activeLanguage + '_' + kbdname] = keymanExample.innerHTML = content; + } else { + throw new Error(`Unable to retrieve content, status was ${response.status}: ${response.statusText}`); + } + } catch(e) { + langExamples[activeLanguage + '_' + kbdname] = keymanExample.innerHTML = 'Error retrieving example: '+e.message; + throw e; + } +} + /* Search Box */ const searchBoxForm = document.querySelector('.form') searchBoxForm.addEventListener('click', function(e) { e.stopPropagation() + defaultKeyboard() }) /* Search */ const kbSearchCard = document.getElementById('kbSearchCardUI'); let debounceTimer +const searchBtn = document.querySelector('#mainSearchBtn') +const dropdown = new bootstrap.Dropdown(searchBtn, { + autoClose: 'outside' +}) + +searchBtn.addEventListener('focus', () => { + dropdown.show() +}) + +searchBtn.addEventListener('input', () => { + dropdown.show() +}) + +const dropdownMenu = document.querySelector('#languageSearchDropdown') +document.addEventListener('click', (e) => { + if (!searchBtn.contains(e.target) && !dropdownMenu.contains(e.target)) { + dropdown.hide() + } +}) + +// Hide Dropdown Search on Mouse leave +dropdownMenu.addEventListener('mouseleave', (e) => { + e.preventDefault() + dropdown.hide() +}) + /* Pagination */ prevBtn = document.getElementById('prevPage') nextBtn = document.getElementById('nextPage') @@ -57,8 +331,6 @@ function goNextPage() { } } -searchBtn = document.getElementById('mainSearchBtn') - const clearSearchIcon = document.querySelector('.clear-icon') const searchIcon = document.querySelector('.search-icon') @@ -210,7 +482,7 @@ function displaySearch(data, total = 0, query = '') { } // UI Search card -function searchKbCardUI(kb, marked = '', data) { +function searchKbCardUI(kb, marked = '', selectedKbList, data) { const kbFoundInList = selectedKbList.some(selected => selected.id == kb.id) // Keyboard card container let cardWrap = document.createElement('div') @@ -271,9 +543,14 @@ function searchKbCardUI(kb, marked = '', data) { cardWrap.appendChild(kbSpecs) // Choose keyboard to selection - kbIconPTag.onclick = () => {addKbToSelectionMenu(kbIconPTag, cardWrap, kb, data)} + kbIconPTag.onclick = (e) => { + e.stopPropagation() + addKbToSelectionMenu(kbIconPTag, cardWrap, kb, data) + textArea.focus() + selectKb() + } // console.log("Recent:", historyKbSelection.getHistory()); - + return cardWrap } @@ -355,6 +632,11 @@ function showMarkedContext(kb, matchField, matchValue) { } kbNameHeading.appendChild(kbHelpLink) kbNameHeading.appendChild(langNameSpan) + kbNameHeading.addEventListener('click', () => { + const checkedURL = validateURL(`https://help.keyman.com/keyboard/`) + const newURL = checkedURL + kb.id + window.open(newURL, '_blank') + }) return kbNameHeading } @@ -392,7 +674,7 @@ function truncateDesc(kb, matchField, marked) { toggleBtn.addEventListener('click', e => { e.preventDefault() const isExpanded = toggleBtn.textContent == "Show more" - kbDescHeading.innerHTML = !isExpanded ? shortText.replace(marked, '$&') : fullDesc + kbDescHeading.innerHTML = !isExpanded ? shortText.replace(marked, (m) => m ? `${m}` : m) : fullDesc if (matchField == 'description') { kbDescHeading.innerHTML = isExpanded ? fullDesc.replace(marked, '$&') : shortText } @@ -491,7 +773,6 @@ function addKbToSelection(kb) { "supportedLanguage": kb.languages, "lastUpdated": kb.lastModifiedDate } - console.log(kb) // historyKbSelection.add(kbInfo) selectedKbList.push(kbInfo) } @@ -510,6 +791,11 @@ function generateKbUI(selectedKbList) { const kbDivHeader = document.createElement('div') kbDivHeader.textContent = "Keyboard Selection menu" kbDivHeader.classList.add('kb-item-header') + + const kbDivFoot = document.createElement('div') + kbDivFoot.textContent = "US Basic Keyboard" + kbDivFoot.classList.add('kb-item-footer') + keyboardSelection.appendChild(kbDivHeader) selectedKbList.forEach(data => { @@ -550,12 +836,17 @@ function generateKbUI(selectedKbList) { ` const kbDetails = displayKbDetails(data) - + kbDiv.appendChild(kbName) kbDiv.appendChild(kbConfigList) kbDiv.appendChild(kbDetails) keyboardSelection.appendChild(kbDiv) + keyboardSelection.append(kbDivFoot) + + let kbdName = data.id + let langCode = Object.keys(data.supportedLanguage)[0] || "en" + selectKb(kbdName, langCode) kbConfigList.addEventListener('click', (e) => { const target = e.target if (target.tagName == 'I' && target.dataset.action) { @@ -565,6 +856,17 @@ function generateKbUI(selectedKbList) { kbConfigMenu(action, id, helpLink) } }) + + kbDiv.addEventListener('click', () => { + kbdName = data.id + langCode = Object.keys(data.supportedLanguage)[0] || "en" + textArea.focus() + selectKb(kbdName, langCode) + }) + + kbDivFoot.onclick = () => { + defaultKeyboard() + } }) triggerKbCount(selectedKbList) } @@ -591,10 +893,27 @@ function triggerKbCount(selectedKbList) { // Keyboard count default for Keyboard selection menu function resetKbSelectionMenu() { const keyboardSelection = document.querySelector("#keyboardSelection") - keyboardSelection.innerHTML = '' + + const kbDivHeader = document.createElement('div') + kbDivHeader.textContent = "Keyboard Selection menu" + kbDivHeader.classList.add('kb-item-header') + + const kbItem = document.createElement('div') + kbItem.classList.add('.kb-item') + const pTag = document.createElement('p') pTag.textContent = "Open Search to get your keyboard" - keyboardSelection.appendChild(pTag) + + const kbDivFoot = document.createElement('div') + kbDivFoot.textContent = "US Basic Keyboard" + kbDivFoot.classList.add('kb-item-footer') + + kbItem.appendChild(pTag) + + keyboardSelection.appendChild(kbDivHeader) + keyboardSelection.appendChild(kbItem) + keyboardSelection.appendChild(kbDivFoot) + } // Compare and remove keyboard @@ -606,9 +925,10 @@ function removeKbSelected(kbId) { } // Check 6th keyboard -function confirmAndAddKb(kbIconPTag, kb, onConfirmAdd) { +function confirmAndAddKb(onConfirmAdd) { const warningDialogUI = limitKbSelectionUI(() => { selectedKbList.shift() + console.log(selectedKbList) onConfirmAdd() generateKbUI(selectedKbList) }) @@ -810,146 +1130,3 @@ function validateURL(string) { /* == End of Keyboard Selection menu Section == */ - -// Change and type keyboard -const downloadBtn = document.getElementById('kbDownloadPage') -const textArea = document.getElementById('textArea') -async function changeKeyboard(kbdname, languageCode) { - - // selectedKbList.forEach(data => { - // let kbName = data.id - // let langCode = data.script - - // changeKeyboard(kbName, langCode) - // }) - console.log("kbdname: ", kbdname, " + ", "languageCode: ", languageCode) - if(kbdname == '') { - if (textArea) textArea.placeholder = 'Select a keyboard and start typing' - } - location.replace('#' + languageCode + ',Keyboard_' + kbdname); - - var kbd = keyman.getKeyboard(kbdname, languageCode); // Good - await keyman.setActiveKeyboard(kbdname, languageCode) // Good - console.log("kbd: ", kbd) - - if(kbd) { - textArea.placeholder = 'The ' + kbd.InternalName + ' keyboard is selected. Start typing...' - } - - const kbSpan = document.querySelector('#kbSpan') - const kbHelpDocATag = document.querySelector('#kbHelpdocLink') - textArea.placeholder = `The ${kbdname} keyboard is selected. Please start typing...` - kbSpan.innerHTML = `${kbdname}` - // kbHelpDocATag.href = `${kbdHelpLink}` - - if(typeof(KeyboardChange_EmbedFonts) != 'undefined') KeyboardChange_EmbedFonts(kbdname); -} - -function enableKbToType() { - // kbDiv.addEventListener('mouseenter', () => { - // kbDiv.style.cursor = "pointer" - // openKbDetails() - // }) - - kbDiv.addEventListener('click', async (e) => { - e.preventDefault() - - if (!data.id || !data || !item.helpLink) { - console.error("Missing Data or Item") - } - - let kbName = `Keyboard_${data.id}` - let keyboards = keyman.getKeyboards(); - let keyboard = keyboards.find(keyboard => keyboard.InternalName == kbName) - - // console.log("All keyboards: ", keyboards) - // console.log("My keyboard: " + keyboard) - if(keyboard) { - languageCode = keyboard.LanguageCode - changeKeyboard(data.id, languageCode, item.helpLink) - } else { - console.warn("Keyboard not found: ", kbName) - } - }) -} - -/* == Section == - UI interaction and manipulation -*/ - -/* UI Behavior of the Selected Keyboard menu */ -const kbSelection = document.querySelector('#keyboardSelection') -const kbSelectionWrap = document.querySelector('.scroll-wrapper-keyboard-tab') -const keyboardSelectionButton = document.getElementById('keyboardSelectionButton') -keyboardSelectionButton.addEventListener('mouseenter', () => { - kbSelection.classList.add('open') -}) -keyboardSelectionButton.addEventListener('click', () => { - kbSelection.classList.remove('open') -}) -kbSelection.addEventListener('mouseleave', () => { - kbSelection.classList.remove('open') -}) - -/* - Toggle between World Map and Search -*/ -const worldMapBtn = document.querySelector('#worldMap') -const kmwControls = document.querySelector('#KeymanWebControl') -const langSearchDropdown = document.querySelector('#languageSearchDropdown') -const caretRightIcon = keyboardSelectionButton.querySelector('.fa-caret-right') -const infoIcon = document.querySelector('#infoIcon') - -let mapIsOpen -worldMapBtn.onclick = () => { - toggleMapAndKb() -} - -function toggleMapAndKb() { - if (mapIsOpen == true) { - openSearch() - } else { - openMap() - returnToSearchBtn() - } -} - -function openMap() { - mapIsOpen = true - - kmwControls.classList.remove('hidden') - kmwControls.style.display = "block" - langSearchDropdown.classList.add('hidden') - - searchBoxForm.innerHTML = '' - searchBoxForm.appendChild(kmwControls) -} - -function openSearch() { - mapIsOpen = false - - kmwControls.classList.add('hidden') - kmwControls.style.display = "none" - langSearchDropdown.classList.remove('hidden') - infoIcon.classList.remove('hidden') - - searchBoxForm.innerHTML = '' - searchBoxForm.appendChild(searchBtn) - searchBoxForm.appendChild(infoIcon) - searchBoxForm.appendChild(langSearchDropdown) -} - -function returnToSearchBtn() { - caretRightIcon.classList.remove('fa-caret-right') - caretRightIcon.classList.add('fa-magnifying-glass') - keyboardSelectionButton.style.backgroundColor = "var(--keyman-orange)" - keyboardSelectionButton.style.border = '0px' - keyboardSelection.style.display = "none" - keyboardSelectionButton.onclick = () => { - caretRightIcon.classList.remove('fa-magnifying-glass') - caretRightIcon.classList.add('fa-caret-right') - keyboardSelectionButton.style.backgroundColor = "" - keyboardSelection.style.display = "block" - openSearch() - } -} diff --git a/inc/head.php b/inc/head.php index 6d6cbe1..2d7b71e 100644 --- a/inc/head.php +++ b/inc/head.php @@ -61,6 +61,7 @@ " /> +" /> " /> @@ -179,14 +180,12 @@ function loadKeyboardFromHash() { if(localKeyboard && localLanguage) { keyman.setActiveKeyboard(localKeyboard, localLanguage); } - document.getElementById('textArea').focus(); }); pageLoading = false; (function() { var css = { - // "desktop" : "", blue keyboard styles "desktop" : "", "tablet" : "", "mobile" : "" diff --git a/index.php b/index.php index 3e19382..2b11cef 100644 --- a/index.php +++ b/index.php @@ -11,7 +11,7 @@ KeymanWeb.com
    - + × @@ -58,7 +58,11 @@
    -

    Open Search to get your keyboard

    +
    Keyboard Selection menu
    +
    +

    Open Search to get your keyboard

    +
    +
    @@ -130,13 +134,13 @@
    - - +
    diff --git a/prog/languageexample.php b/prog/languageexample.php index 2bb4925..8340ee9 100644 --- a/prog/languageexample.php +++ b/prog/languageexample.php @@ -26,7 +26,7 @@ use \Keyman\Site\Common\KeymanHosts; if(isset($_REQUEST['keyboard'])) $keyboard = $_REQUEST['keyboard']; else $keyboard = ''; - if(isset($_REQUEST['language'])) $language = $_REQUEST['language']; else $language = ''; + if(isset($_REQUEST['language'])) $language = $_REQUEST['language']; else $language = ''; if(empty($keyboard) || empty($language)) { $data = FALSE; @@ -50,8 +50,8 @@ function renderHelpIcon($keyboard, $language) { if($data !== FALSE) { echo $data; } else { - echo "No example is available, please refer to keyboard help"; + echo "No example is available"; } - echo renderHelpIcon($keyboard, $language); + // echo renderHelpIcon($keyboard, $language); ?> From b1079919224466a0ed7fb335ee820ccfc2d422b0 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Mon, 18 Aug 2025 11:30:14 +0700 Subject: [PATCH 19/36] feats: modularize functions, add validation, and rename --- cdn/dev/css/kmw-body.css | 18 +- cdn/dev/css/kmw-header.css | 52 ++--- cdn/dev/js/kmwControls.js | 18 -- cdn/dev/js/kmwHeader.js | 402 ++++++++++++++++++++----------------- inc/head.php | 64 +++--- index.php | 23 +-- 6 files changed, 301 insertions(+), 276 deletions(-) delete mode 100644 cdn/dev/js/kmwControls.js diff --git a/cdn/dev/css/kmw-body.css b/cdn/dev/css/kmw-body.css index 5e53260..e874ebe 100644 --- a/cdn/dev/css/kmw-body.css +++ b/cdn/dev/css/kmw-body.css @@ -7,7 +7,6 @@ } body { - background-color: #F6F6F6; overflow: hidden; } @@ -50,6 +49,7 @@ i:hover { justify-content: center; align-items: center; width: 100%; + } .text-area { @@ -58,13 +58,19 @@ i:hover { width: 100%; box-shadow: var(--textarea-box); font-size: 16px; + border: none; + padding: 10px; +} + +.text-area::highlight { + border: red; } #copyTool { color: var(--keyman-blue); position: absolute; right: 10px; - top: 110px; + top: 97px; opacity: 50%; } @@ -118,6 +124,14 @@ i:hover { margin: 10px; } +#example { + visibility: visible !important; +} + +#exampleBox { + visibility: visible !important; +} + .keyboard-container { width: calc(100% - 40%); height: 100%; diff --git a/cdn/dev/css/kmw-header.css b/cdn/dev/css/kmw-header.css index eaca661..a3745a3 100644 --- a/cdn/dev/css/kmw-header.css +++ b/cdn/dev/css/kmw-header.css @@ -17,10 +17,10 @@ hr { header > div > img { width: 100%; display: block; - height: 8px; + height: 5px; } -#languageSearchDropdown { +#searchDropdownMenu { padding: 10px; margin: 0; } @@ -28,8 +28,7 @@ header > div > img { .main-header { display: grid; height: 75px; - padding: 10px; - background-color: white; + padding: 0 10px; box-shadow: var(--box-shadow); } @@ -43,63 +42,67 @@ header > div > img { align-items: center; } +.left-header img { + margin-right: 10px; +} + /* Language Search box */ -.form { +#searchBar { position: relative; width: 550px; margin-right: 10px; } -.info-icon-span { +#searchIcons { position: absolute; right: 5px; top: 12px; border-left: 1px solid gray; } -.info-icon-span > * { +#searchIcons > * { margin-right: 10px; padding-left: 15px; opacity: 50%; } -.info-icon-span > *:hover { +#searchIcons > *:hover { padding-left: 15px; opacity: 100%; } -.search-icon { +#magnifyingGlassIcon { display: inline; } -.clear-icon { +#clearSearchIcon { display: none; } -.form #mainSearchBtn { +#searchBar #searchInput { height: 50px; width: 100%; text-indent: 10px; border-radius: 15px; text-align: left; - background-color: rgb(233, 228, 228); font-family: inherit !important; + box-shadow: none; } -#mainSearchBtn:focus { - background-color: white; +#searchInput:hover, #searchInput:focus { + border: 1px solid var(--keyman-orange); } -#languageSearchDropdown { +#searchDropdownMenu { width: 100%; max-height: 600px; overflow: auto; scrollbar-width: thin; } -#languageSearchDropdown hr { +#searchDropdownMenu hr { margin: 15px 0; } @@ -315,7 +318,7 @@ Language Search box } /* Pagination */ -#languageSearchDropdown .bottom-row-search { +#searchDropdownMenu .bottom-row-search { background-color: white; align-items: center; justify-content: center; @@ -615,10 +618,11 @@ Language Search box .right-header { display: grid; - grid-template-columns: 90% 10%; - width: 350px; - justify-items: center; + grid-template-columns: 80% 20%; + width: 100%; + justify-items: right; align-items: center; + margin-right: 0; } .right-header i:hover { @@ -832,14 +836,14 @@ input[type="range"]::-webkit-slider-thumb { ================================ */ @media screen and (min-width: 1045px) { .main-header { - grid-template-columns: 3fr 1fr 1fr; + grid-template-columns: 3fr 1fr; } } /* Expanding the search box */ @media screen and (940px <= width <= 1045px) { .main-header { - grid-template-columns: 4fr 1fr 1fr; + grid-template-columns: 4fr 1fr; } } @@ -866,13 +870,13 @@ input[type="range"]::-webkit-slider-thumb { Language Search box */ - .form { + #searchBar { width: 50%; } } @media screen and (max-width: 565px) { - #languageSearchDropdown { + #searchDropdownMenu { width: 300px !important; } diff --git a/cdn/dev/js/kmwControls.js b/cdn/dev/js/kmwControls.js deleted file mode 100644 index 185a218..0000000 --- a/cdn/dev/js/kmwControls.js +++ /dev/null @@ -1,18 +0,0 @@ -/* - This is the code to modify the fetched - KeymanWebControls (Map, Examples, Keyboards...etc) -*/ - -function waitForElement(selector, callback) { - const interval = setInterval(() => { - const el = document.querySelector(selector) - if (el) { - clearInterval(interval) - callback(el) - } - }, 100) -} - -waitForElement(".kmw-osk-frame", function(oskDiv) { - document.querySelector('.keyboard-area').appendChild(oskDiv) -}) \ No newline at end of file diff --git a/cdn/dev/js/kmwHeader.js b/cdn/dev/js/kmwHeader.js index ba21180..5687861 100644 --- a/cdn/dev/js/kmwHeader.js +++ b/cdn/dev/js/kmwHeader.js @@ -6,129 +6,179 @@ function getKeymanWeb() { } return window.keyman; } - /* Global Variables */ -let selectedKbList = [] -let dataKbForRemoval +let selectedKbList = [] // Main array for the search, kb selection...etc. +let dataKbForRemoval // For History search +let kmwLang = keyman.getActiveLanguage() +let kmwKb = keyman.getActiveKeyboard() + +const clearSearchIcon = document.querySelector('#clearSearchIcon') +const magnifying = document.querySelector('#magnifyingGlassIcon') + +const elements = { + worldMapBtn: document.querySelector('#worldMap'), + kmwControls: document.querySelector('#KeymanWebControl'), + + kbSelection: document.querySelector('#keyboardSelection'), + keyboardSelectionButton: document.querySelector('#keyboardSelectionButton'), + caretRightIcon: keyboardSelectionButton.querySelector('.fa-caret-right'), + + searchBar: document.querySelector('#searchBar'), + searchInput: document.querySelector('#searchInput'), + searchDropdownMenu: document.querySelector('#searchDropdownMenu'), + searchIcons: document.querySelector('#searchIcons'), +} -document.addEventListener('DOMContentLoaded', () => { - /* == Section == - UI interaction and manipulation - */ - - /* - Toggle between World Map and Search - */ - const elements = { - worldMapBtn: document.querySelector('#worldMap'), - kmwControls: document.querySelector('#KeymanWebControl'), - - kbSelection: document.querySelector('#keyboardSelection'), - keyboardSelectionButton: document.getElementById('keyboardSelectionButton'), - langSearchDropdown: document.querySelector('#languageSearchDropdown'), - caretRightIcon: keyboardSelectionButton.querySelector('.fa-caret-right'), - infoIcon: document.querySelector('#infoIcon'), - - searchBoxForm: document.querySelector('.form'), - searchBtn: document.querySelector('#mainSearchBtn') +const state = { + mapIsOpen: false +} + +/* + ===================================== Default keyboard ========================================= +*/ + +function defaultKeyboard(kbdname = "basic_kbdus", languageCode = "en") { + if(!exists(kbdname, languageCode)) { + if (textArea) textArea.placeholder = 'A Keyboard name isn\'t specified. Select a keyboard and start typing' + return } + setKeyboardWithDirection(kbdname, languageCode) +} - const state = { - mapIsOpen: true +/* + ============================= Toggle between World Map and Search ============================== +*/ +elements.worldMapBtn?.addEventListener('click', (e) => { + e.preventDefault() + state.mapIsOpen = true + if (state.mapIsOpen == true) { + openMap() + keyman.addEventListener('keyboardchange', () => { + location.replace(`#${keyman.getActiveLanguage()},${keyman.getActiveKeyboard()}`) + updateExample(keyman.getActiveKeyboard()) + }) + } else { + openSearch() } +}) - /* UI Behavior of the Selected Keyboard menu */ - if (exists(elements)) { - elements.keyboardSelectionButton.addEventListener('mouseenter', () => { - elements.kbSelection.classList.add('open') - }) - elements.keyboardSelectionButton.addEventListener('click', () => { - elements.kbSelection.classList.remove('open') - }) - elements.kbSelection.addEventListener('mouseleave', () => { - elements.kbSelection.classList.remove('open') - }) +function openSearch() { + state.mapIsOpen = false + hideEls( + elements.kmwControls, + ) + showEls( + elements.searchDropdownMenu, + elements.searchIcons + ) + + if (selectedKbList.length > 0) { + elements.caretRightIcon.textContent = selectedKbList.length + removeClass(elements.caretRightIcon, 'fa-magnifying-glass') + } else { + elements.caretRightIcon.textContent = '' + elements.caretRightIcon.classList.add('fa-caret-right') } - elements.worldMapBtn?.addEventListener('click', (e) => { - e.preventDefault() - toggleMapAndKb() - }) - - function toggleMapAndKb() { - if (state.mapIsOpen == false) { - // Open Search - hideEls( - elements.kmwControls, - ) - showEls( - elements.langSearchDropdown, - elements.infoIcon - ) - - if (selectedKbList.length > 0) { - elements.caretRightIcon.textContent = selectedKbList.length - } else { - elements.caretRightIcon.textContent = '' - elements.caretRightIcon.classList.add('fa-caret-right') - } - - elements.searchBoxForm.replaceChildren( - elements.searchBtn, - elements.infoIcon, - elements.langSearchDropdown - ) + elements.searchBar.replaceChildren( + elements.searchInput, + elements.searchIcons, + elements.searchDropdownMenu + ) +} - state.mapIsOpen = true - } else { - // Open Map - removeClass( - elements.kmwControls, 'hidden' - ) - hideEls( - elements.langSearchDropdown - ) - removeTextContent( - elements.caretRightIcon - ) - - elements.searchBoxForm.replaceChildren( - elements.kmwControls - ) - returnToSearchBtn() - - state.mapIsOpen = false - } +function openMap() { + state.mapIsOpen = true + removeClass( + elements.kmwControls, 'hidden', + elements.caretRightIcon, 'fa-caret-right' + ) + hideEls( + elements.searchDropdownMenu + ) + removeTextContent( + elements.caretRightIcon + ) + elements.keyboardSelectionButton.removeAttribute('id', 'keyboardSelectionButton') + elements.keyboardSelectionButton.setAttribute('id', 'returnToSearchButton') + elements.caretRightIcon.classList.add('fa-magnifying-glass') + elements.keyboardSelectionButton.style.backgroundColor = "var(--keyman-orange)" + elements.keyboardSelectionButton.style.border = '0px' + elements.keyboardSelectionButton.classList.add('return-to-search') + elements.kbSelection.style.display = "none" + elements.searchBar.replaceChildren( + elements.kmwControls + ) +} + +function returnToSearch() { + elements.keyboardSelectionButton.removeAttribute('id', 'returnToSearchButton') + elements.keyboardSelectionButton.setAttribute('id', 'keyboardSelectionButton') + + if ((selectedKbList?.length || 0) < 1) { + elements.caretRightIcon.classList.add('fa-caret-right') + removeClass(elements.caretRightIcon, 'fa-magnifying-glass') + elements.caretRightIcon.textContent = '' } - function returnToSearchBtn() { - removeClass(elements.caretRightIcon, 'fa-caret-right') - elements.caretRightIcon.classList.add('fa-magnifying-glass') - elements.keyboardSelectionButton.style.backgroundColor = "var(--keyman-orange)" - elements.keyboardSelectionButton.style.border = '0px' - elements.kbSelection.style.display = "none" - - elements.keyboardSelectionButton.onclick = () => { - removeClass(elements.caretRightIcon, 'fa-magnifying-glass') + elements.keyboardSelectionButton.style.backgroundColor = "" + elements.kbSelection.style.display = "block" + openSearch() +} - if ((selectedKbList?.length || 0) < 1) { - elements.caretRightIcon.classList.add('fa-caret-right') - elements.caretRightIcon.textContent = '' +function waitForElement(selector) { + return new Promise((resolve) => { + const interval = setInterval(() => { + const element = document.querySelector(selector) + if (element) { + clearInterval(interval) + resolve(element) } + }, 100) + }) +} - elements.keyboardSelectionButton.style.backgroundColor = "" - elements.kbSelection.style.display = "block" - toggleMapAndKb() - } - } +waitForElement('#returnToSearchButton').then((element) => { + element.addEventListener('click', (e) => { + e.preventDefault() + returnToSearch() + }) +}) + +waitForElement(".kmw-osk-frame").then((oskDiv) => { + document.querySelector('.keyboard-area').appendChild(oskDiv) +}) - if (!typeof defaultKeyboard == 'function') { - console.warn('defaultKeyboard() is not defined.') +/* + ==================== Search Interaction =================== +*/ + +/* Search Input */ +const dropdown = new bootstrap.Dropdown(elements.searchInput, { + autoClose: 'outside' +}) + +document.addEventListener('click', (e) => { + if (!elements.searchInput.contains(e.target) && !elements.searchDropdownMenu.contains(e.target)) { + dropdown.hide() } - defaultKeyboard() }) -/* Utility functions */ +elements.searchInput.addEventListener('click', (e) => { + e.stopPropagation() + // defaultKeyboard() + dropdown.show() +}) + +// Hide Dropdown Search on Mouse leave +elements.searchDropdownMenu.addEventListener('mouseleave', (e) => { + e.preventDefault() + dropdown.hide() +}) + +/* + =========================== Utility functions ============================ +*/ function hideEls(...elements) { return elements.every(el => el.classList.add('hidden')) } @@ -150,6 +200,22 @@ function exists(...elements) { return elements.every(el => el != null) } +document.addEventListener('DOMContentLoaded', () => { + defaultKeyboard() + /* UI Behavior of the Selected Keyboard menu */ + if (exists(elements)) { + elements.keyboardSelectionButton.addEventListener('mouseenter', () => { + elements.kbSelection.classList.add('open') + }) + elements.keyboardSelectionButton.addEventListener('click', () => { + elements.kbSelection.classList.remove('open') + }) + elements.kbSelection.addEventListener('mouseleave', () => { + elements.kbSelection.classList.remove('open') + }) + } +}) + /* === Keyboard Execution === */ @@ -157,12 +223,12 @@ const downloadBtn = document.getElementById('kbDownloadPage') const textArea = document.getElementById('textArea') let langExamples = []; -function prepareSearchInputUI(dir = 'ltr', fontFamily = '') { - const searchTextBox = document.querySelector('#mainSearchBtn') - - searchTextBox.setAttribute('dir', dir) - searchTextBox.style.fontFamily = fontFamily - selectKb() +function selectKb(kbdname, languageCode) { + if(!exists(kbdname, languageCode)) { + if (textArea) textArea.placeholder = 'A Keyboard name isn\'t specified. Select a keyboard and start typing' + return + } + setKeyboardWithDirection(kbdname, languageCode) } function setTextDirection(targetEls, dir) { @@ -178,29 +244,19 @@ function setTextDirection(targetEls, dir) { } } -function defaultKeyboard(kbdname = "basic_kbdus", languageCode = "en") { - if(!exists(kbdname, languageCode)) { - if (textArea) textArea.placeholder = 'A Keyboard name isn\'t specified. Select a keyboard and start typing' - return - } - setKeyboardWithDirection(kbdname, languageCode) -} - -function selectKb(kbdname, languageCode) { - if(!exists(kbdname, languageCode)) { - if (textArea) textArea.placeholder = 'A Keyboard name isn\'t specified. Select a keyboard and start typing' - return - } - setKeyboardWithDirection(kbdname, languageCode) -} - // Change and type keyboard async function setKeyboardWithDirection(kbdname, languageCode) { const kbSpan = document.querySelector('#kbSpan') const langTag = `#${languageCode}` - const kbTag = `Keyboard_${kbdname}` + let kbTag = '' + + if (kbdname.match(/Keyboard_*/)) { + kbTag = `${kbdname}` + } else { + kbTag = `Keyboard_${kbdname}` + } - location.replace(`${langTag},${kbTag}`); + location.replace(`${langTag},${kbTag}`) await keyman.addKeyboards(kbdname) const kbd = keyman.getKeyboard(kbdname, languageCode) @@ -219,7 +275,7 @@ async function setKeyboardWithDirection(kbdname, languageCode) { /* Language Examples AJAX */ async function updateExample(kbdname) { const keymanExample = document.getElementById("example") - const exampleBox = document.getElementById("exampleBox"); + const exampleBox = document.getElementById("exampleBox") if (!keymanExample || !exampleBox) return false; @@ -229,9 +285,7 @@ async function updateExample(kbdname) { return true; } - exampleBox.style.visibility='visible'; - keymanExample.style.visibility='visible'; - var activeLanguage = keyman.getActiveLanguage(); + let activeLanguage = keyman.getActiveLanguage(); if(langExamples[activeLanguage + '_' + kbdname]) { @@ -242,7 +296,7 @@ async function updateExample(kbdname) { langExamples[activeLanguage + '_' + kbdname] = 'Loading...'; keymanExample.innerHTML = 'Loading...'; - const link = `../../../prog/languageexample.php?keyboard=${kbdname}&language=${activeLanguage}`; + const link = `/prog/languageexample.php?keyboard=${kbdname}&language=${activeLanguage}`; try { const response = await fetch(link); if(response.status == 200) { @@ -258,43 +312,10 @@ async function updateExample(kbdname) { } } -/* Search Box */ -const searchBoxForm = document.querySelector('.form') -searchBoxForm.addEventListener('click', function(e) { - e.stopPropagation() - defaultKeyboard() -}) - /* Search */ const kbSearchCard = document.getElementById('kbSearchCardUI'); let debounceTimer -const searchBtn = document.querySelector('#mainSearchBtn') -const dropdown = new bootstrap.Dropdown(searchBtn, { - autoClose: 'outside' -}) - -searchBtn.addEventListener('focus', () => { - dropdown.show() -}) - -searchBtn.addEventListener('input', () => { - dropdown.show() -}) - -const dropdownMenu = document.querySelector('#languageSearchDropdown') -document.addEventListener('click', (e) => { - if (!searchBtn.contains(e.target) && !dropdownMenu.contains(e.target)) { - dropdown.hide() - } -}) - -// Hide Dropdown Search on Mouse leave -dropdownMenu.addEventListener('mouseleave', (e) => { - e.preventDefault() - dropdown.hide() -}) - /* Pagination */ prevBtn = document.getElementById('prevPage') nextBtn = document.getElementById('nextPage') @@ -331,25 +352,25 @@ function goNextPage() { } } -const clearSearchIcon = document.querySelector('.clear-icon') -const searchIcon = document.querySelector('.search-icon') - /* Click: Open Search and Display search instructions */ -searchBtn.addEventListener('click', function(e) { - if (e.target.value.trim() == "") { +elements.searchInput.addEventListener('click', function(e) { + const query = e.target.value.trim() + if (query == "") { resetSearch() + } else { + searchKeyboard(query) } }) /* Input: Search and Display keyboards */ -searchBtn.addEventListener('input', function(e) { +elements.searchInput.addEventListener('input', function(e) { handleSearch(e.target.value) }) clearSearchIcon.addEventListener('click', () => { - searchBtn.value = '' + elements.searchInput.value = '' handleSearch() - searchBtn.focus() + elements.searchInput.focus() }) function handleSearch(value = "") { @@ -372,7 +393,7 @@ function resetSearch() { function updateSearchIcon(value) { const hasValue = value.length > 0 - searchIcon.style.display = hasValue ? 'none' : 'inline' + magnifying.style.display = hasValue ? 'none' : 'inline' clearSearchIcon.style.display = hasValue ? 'inline' : 'none' } @@ -742,7 +763,7 @@ function addKbToSelectionMenu(kbIconPTag, cardWrap, kb, data) { checkKbCardUI(kbIconPTag, cardWrap, kb) return } - confirmAndAddKb(kbIconPTag, kb, () => { + confirmAndAddKb(() => { addKbToSelection(kb) generateKbUI(selectedKbList) @@ -757,7 +778,6 @@ function addKbToSelectionMenu(kbIconPTag, cardWrap, kb, data) { }, 800) checkKbCardUI(kbIconPTag, cardWrap, kb) }) - } // Add keyboard for kb search and selection UI @@ -853,7 +873,7 @@ function generateKbUI(selectedKbList) { const action = target.dataset.action const id = target.dataset.id const helpLink = target.dataset.helplink - kbConfigMenu(action, id, helpLink) + kbConfigMenu(action, id, helpLink) } }) @@ -867,6 +887,11 @@ function generateKbUI(selectedKbList) { kbDivFoot.onclick = () => { defaultKeyboard() } + + const kbHelpLink = document.querySelector('#kbHelpdocLink') + kbHelpLink.addEventListener('click', (e) => { + kbConfigMenu('help', '', data.helpLink) + }) }) triggerKbCount(selectedKbList) } @@ -913,7 +938,6 @@ function resetKbSelectionMenu() { keyboardSelection.appendChild(kbDivHeader) keyboardSelection.appendChild(kbItem) keyboardSelection.appendChild(kbDivFoot) - } // Compare and remove keyboard @@ -921,15 +945,18 @@ function removeKbSelected(kbId) { if(kbId) { selectedKbList = selectedKbList.filter(kb => kb.id !== kbId) } - generateKbUI(selectedKbList) } // Check 6th keyboard function confirmAndAddKb(onConfirmAdd) { + if (typeof onConfirmAdd != 'function') { + console.log("Expected the onConfirmAdd a function, instead got: " + typeof onConfirmAdd) + alert("Click on the keyboard again to enable.") + } + const warningDialogUI = limitKbSelectionUI(() => { - selectedKbList.shift() - console.log(selectedKbList) onConfirmAdd() + selectedKbList.shift() generateKbUI(selectedKbList) }) @@ -999,8 +1026,13 @@ function limitKbSelectionUI(onAccept) { return dialogDiv } -let selectedKbData = [] +// Seperate list for History/Remember Search + +/* + ========================== To be continued ========================== +*/ function addDataKb(data) { + let selectedKbData = [] // console.log(data) const kbInfo = { "platformSupport": data.platformSupport, @@ -1010,6 +1042,8 @@ function addDataKb(data) { selectedKbData.push(kbInfo) } +// End of History search + // Keyboard selection menu's tools: help, download, and remove function kbConfigMenu(action, id, helplink) { if (action == "help") { diff --git a/inc/head.php b/inc/head.php index 2d7b71e..2050b3f 100644 --- a/inc/head.php +++ b/inc/head.php @@ -114,34 +114,6 @@ function bcp47ToISO6393(bcp) { var iso=mapBCP47_ISO6393[bcp]; return iso?iso:bcp; } - - var localKeyboard, localLanguage; - - function loadKeyboardFromHash() { - var locationHash = location.hash.match(/^#(.+),(Keyboard_.+)$/i); - if(locationHash) { - localKeyboard = locationHash[2]; - localLanguage = locationHash[1]; - - // Translate the language ID if necessary from ISO639-3 to BCP 47 - localLanguage = iso6393ToBCP47(localLanguage); - - document.cookie = 'KeymanWeb_Keyboard=current%3D'+localKeyboard+'%3A'+localLanguage+'%3B; path=/'; - document.cookie = 'KeymanWeb_Toolbar=recent0='+localLanguage+'%2C'+localKeyboard+'%3B; path=/'; - } else if(location.hash == '#') { - document.cookie = 'KeymanWeb_Keyboard=; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT'; - document.cookie = 'KeymanWeb_Toolbar=; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT'; - } else { - var cookie = keyman.util.loadCookie('KeymanWeb_Keyboard'); - if(cookie['current']) { - var cookieMatch = cookie['current'].match(/^(Keyboard_.+):(.+)$/); - if(cookieMatch) { - localKeyboard = cookieMatch[1]; - localLanguage = iso6393ToBCP47(cookieMatch[2]); - } - } - } - } @@ -154,8 +126,37 @@ function loadKeyboardFromHash() { + + + From 5fee5dc859a70c924c4bb63bb60998d87a30c75f Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Mon, 18 Aug 2025 11:38:03 +0700 Subject: [PATCH 20/36] feats: remove js references --- index.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/index.php b/index.php index 5ab1a6d..b6e1e8e 100644 --- a/index.php +++ b/index.php @@ -180,8 +180,6 @@ - - From ed07a5a5d4b0ef0448ab3be626aed913ca8e34fb Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Thu, 2 Oct 2025 13:27:10 +0700 Subject: [PATCH 21/36] feat: introduce and start devices styling, apply drag between kb and textarea, and more (note-to-self: these features are not finished but require this commit because of switching to macos) --- .github/multi-labeler.yml | 86 +- .github/workflows/add-to-keyman-project.yml | 38 +- .github/workflows/ci.yml | 146 +- .github/workflows/labeler.yml | 30 +- .gitignore | 28 +- .htaccess | 94 +- SPZITg5E.txt | 1 - _includes/2020/WebKeymanComSentry.php | 40 +- _includes/autoload.php | 48 +- cdn/dev/css/kmw-body.css | 529 ++-- cdn/dev/css/kmw-desktop.css | 393 +-- cdn/dev/css/kmw-header.css | 1793 +++++++------ cdn/dev/css/kmw-mobile.css | 586 ++--- cdn/dev/css/kmw-tablet.css | 1076 ++++---- cdn/dev/css/kmw.css | 156 +- cdn/dev/js/kmwBody.js | 289 +-- cdn/dev/js/kmwElements.js | 36 + cdn/dev/js/kmwHeader.js | 2522 ++++++++++--------- cdn/dev/js/kmwlive.js | 942 +++---- cdn/dev/src/bootstrap.bundle.min.js | 14 +- cdn/dev/src/bootstrap.min.css | 12 +- inc/head.php | 460 ++-- inc/servervars.php | 188 +- index.php | 368 ++- prog/languageexample.php | 114 +- prog/renderLanguageExample.php | 592 ++--- 26 files changed, 5246 insertions(+), 5335 deletions(-) delete mode 100644 SPZITg5E.txt create mode 100644 cdn/dev/js/kmwElements.js diff --git a/.github/multi-labeler.yml b/.github/multi-labeler.yml index a8d5e25..95ad40b 100644 --- a/.github/multi-labeler.yml +++ b/.github/multi-labeler.yml @@ -1,43 +1,43 @@ -version: v1 - -# This file adds labels based on the scopes in -# keymanapp/keyman:resources/scopes/commit-types.json -# Currently it must be manually kept up to date. Not all labels are added, only -# common ones. The others are commented out. - - -labels: - # - # conventional commit / semantic PR styles - # - - - label: 'auto' - matcher: - title: '^auto(\(|:)' - - label: 'change' - matcher: - title: '^change(\(|:)' - - label: 'chore' - matcher: - title: '^chore(\(|:)' - - label: 'docs' - matcher: - title: '^docs(\(|:)' - - label: 'feat' - matcher: - title: '^feat(\(|:)' - - label: 'fix' - matcher: - title: '^fix(\(|:)' - - label: 'maint' - matcher: - title: '^maint(\(|:)' - - label: 'refactor' - matcher: - title: '^refactor(\(|:)' - - label: 'style' - matcher: - title: '^style(\(|:)' - - label: 'test' - matcher: - title: '^test(\(|:)' +version: v1 + +# This file adds labels based on the scopes in +# keymanapp/keyman:resources/scopes/commit-types.json +# Currently it must be manually kept up to date. Not all labels are added, only +# common ones. The others are commented out. + + +labels: + # + # conventional commit / semantic PR styles + # + + - label: 'auto' + matcher: + title: '^auto(\(|:)' + - label: 'change' + matcher: + title: '^change(\(|:)' + - label: 'chore' + matcher: + title: '^chore(\(|:)' + - label: 'docs' + matcher: + title: '^docs(\(|:)' + - label: 'feat' + matcher: + title: '^feat(\(|:)' + - label: 'fix' + matcher: + title: '^fix(\(|:)' + - label: 'maint' + matcher: + title: '^maint(\(|:)' + - label: 'refactor' + matcher: + title: '^refactor(\(|:)' + - label: 'style' + matcher: + title: '^style(\(|:)' + - label: 'test' + matcher: + title: '^test(\(|:)' diff --git a/.github/workflows/add-to-keyman-project.yml b/.github/workflows/add-to-keyman-project.yml index c55d0b2..b8c5b74 100644 --- a/.github/workflows/add-to-keyman-project.yml +++ b/.github/workflows/add-to-keyman-project.yml @@ -1,19 +1,19 @@ -name: Add new issues and pull requests to projects - -on: - pull_request: - types: - - opened - issues: - types: - - opened - -jobs: - add-to-project: - name: Add new issues and pull requests to project - runs-on: ubuntu-latest - steps: - - uses: actions/add-to-project@v1.0.2 - with: - project-url: https://github.com/orgs/keymanapp/projects/1 - github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} +name: Add new issues and pull requests to projects + +on: + pull_request: + types: + - opened + issues: + types: + - opened + +jobs: + add-to-project: + name: Add new issues and pull requests to project + runs-on: ubuntu-latest + steps: + - uses: actions/add-to-project@v1.0.2 + with: + project-url: https://github.com/orgs/keymanapp/projects/1 + github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f53696..3f4abad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,73 +1,73 @@ -name: CI - -on: [pull_request] - -jobs: - - build-test: - runs-on: ubuntu-latest - env: - KEYMANHOSTS_TIER: TIER_TEST - # Composer started complaining about running as root, but we don't care in a GHA - COMPOSER_ALLOW_SUPERUSER: 1 - - steps: - - name: Checkout - uses: actions/checkout@v3.5.2 - - # Build the docker image and create link to vendor/ dependencies - - name: Build the Docker image - shell: bash - run: | - echo "TIER_TEST" > tier.txt - ./build.sh configure build start - env: - fail-fast: true - - # - # Finally, run the tests; note that this is almost all replicated in build.sh; here logging is reduced (TODO sync) - # - - name: PHP unit tests - shell: bash - run: | - docker exec web-keyman-com-app sh -c "vendor/bin/phpunit --testdox" - - - name: Lint - shell: bash - run: | - ( set +e; set +o pipefail; find . -name '*.php' | grep -v '/vendor/' | xargs -n 1 -d '\n' php -l | grep -v "No syntax errors detected"; exit ${PIPESTATUS[2]} ) - - - name: Check broken links - shell: bash - run: | - set +e; - set +o pipefail; - npx broken-link-checker http://localhost:8057 --ordered --recursive --requests 50 --host-requests 50 -e --filter-level 3 | \ - grep -E "BROKEN|Getting links from" | \ - grep -B 1 "BROKEN" - exit ${PIPESTATUS[0]} - - - name: Check PHP errors - shell: bash - run: | - CONTAINER=`docker container ls -l -q` - if docker container logs $CONTAINER 2>&1 | grep -q 'php7'; then - echo 'PHP reported errors or warnings:' - docker container logs $CONTAINER 2>&1 | grep 'php7' - exit 1 - else - echo 'No PHP errors found' - exit 0 - fi - # - # If any of the tests fail, let's grab a bit more detail on the environment - # - - name: Report errors - if: ${{ failure() }} - shell: bash - run: | - CONTAINER=`docker container ls -l -q` - echo "--- tier.txt ---" - cat tier.txt - echo "--- PHP errors in Docker log ---" - docker container logs $CONTAINER 2>&1 | grep 'php7' +name: CI + +on: [pull_request] + +jobs: + + build-test: + runs-on: ubuntu-latest + env: + KEYMANHOSTS_TIER: TIER_TEST + # Composer started complaining about running as root, but we don't care in a GHA + COMPOSER_ALLOW_SUPERUSER: 1 + + steps: + - name: Checkout + uses: actions/checkout@v3.5.2 + + # Build the docker image and create link to vendor/ dependencies + - name: Build the Docker image + shell: bash + run: | + echo "TIER_TEST" > tier.txt + ./build.sh configure build start + env: + fail-fast: true + + # + # Finally, run the tests; note that this is almost all replicated in build.sh; here logging is reduced (TODO sync) + # + - name: PHP unit tests + shell: bash + run: | + docker exec web-keyman-com-app sh -c "vendor/bin/phpunit --testdox" + + - name: Lint + shell: bash + run: | + ( set +e; set +o pipefail; find . -name '*.php' | grep -v '/vendor/' | xargs -n 1 -d '\n' php -l | grep -v "No syntax errors detected"; exit ${PIPESTATUS[2]} ) + + - name: Check broken links + shell: bash + run: | + set +e; + set +o pipefail; + npx broken-link-checker http://localhost:8057 --ordered --recursive --requests 50 --host-requests 50 -e --filter-level 3 | \ + grep -E "BROKEN|Getting links from" | \ + grep -B 1 "BROKEN" + exit ${PIPESTATUS[0]} + + - name: Check PHP errors + shell: bash + run: | + CONTAINER=`docker container ls -l -q` + if docker container logs $CONTAINER 2>&1 | grep -q 'php7'; then + echo 'PHP reported errors or warnings:' + docker container logs $CONTAINER 2>&1 | grep 'php7' + exit 1 + else + echo 'No PHP errors found' + exit 0 + fi + # + # If any of the tests fail, let's grab a bit more detail on the environment + # + - name: Report errors + if: ${{ failure() }} + shell: bash + run: | + CONTAINER=`docker container ls -l -q` + echo "--- tier.txt ---" + cat tier.txt + echo "--- PHP errors in Docker log ---" + docker container logs $CONTAINER 2>&1 | grep 'php7' diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index f0d4218..99a60dd 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -1,15 +1,15 @@ -name: "Pull Request Labeler" -on: -- pull_request - -jobs: - triage: - if: github.repository == 'keymanapp/keymanweb.com' - runs-on: ubuntu-latest - steps: - - name: Update labels based on PR title - id: labeler - uses: fuxingloh/multi-labeler@f5bd7323b53b0833c1e4ed8d7b797ae995ef75b4 # v2.0.1 - with: - github-token: ${{secrets.GITHUB_TOKEN}} - config-path: .github/multi-labeler.yml +name: "Pull Request Labeler" +on: +- pull_request + +jobs: + triage: + if: github.repository == 'keymanapp/keymanweb.com' + runs-on: ubuntu-latest + steps: + - name: Update labels based on PR title + id: labeler + uses: fuxingloh/multi-labeler@f5bd7323b53b0833c1e4ed8d7b797ae995ef75b4 # v2.0.1 + with: + github-token: ${{secrets.GITHUB_TOKEN}} + config-path: .github/multi-labeler.yml diff --git a/.gitignore b/.gitignore index bbdab99..bb83a5b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,14 @@ -.idea/** -cdn/deploy - -/vendor -.data/ - -# Shared files are bootstrapped: -resources/bootstrap.inc.sh -resources/.bootstrap-version -resources/.bootstrap-registry -_common/ - -# State files -_control/debug +.idea/** +cdn/deploy + +/vendor +.data/ + +# Shared files are bootstrapped: +resources/bootstrap.inc.sh +resources/.bootstrap-version +resources/.bootstrap-registry +_common/ + +# State files +_control/debug diff --git a/.htaccess b/.htaccess index 3605a73..ad75644 100644 --- a/.htaccess +++ b/.htaccess @@ -1,47 +1,47 @@ - -php_value display_errors off -php_value display_startup_errors off - - - php_value display_startup_errors on - php_value display_errors stderr - - - - - Header set Access-Control-Allow-Origin "*" - - - AddType font/ttf .ttf - AddType application/javascript .js - - AddCharset UTF-8 .js - - - RewriteEngine on - RewriteBase / - - - -# Keymanweb.com 2.0 rewrite rules for Keymanweb.com 1.0 /go/lang/kbd urls - -# Rewrite /go/lang/kbd/app[?...] to /?kmwlang=lang,kmwkbd=kbd -RewriteRule "^go/([^/]+)/([^/]+)/([^?]+)(\?)?(.+)?$" "/index.php?kmwlang=$1&kmwkbd=Keyboard_$2&$5" - -# Rewrite /go/lang/kbd[?...] to /?kmwlang=lang,kmwkbd=kbd -RewriteRule "^go/([^/]+)/([^?]+)(\?)?(.+)?$" "/index.php?kmwlang=$1&kmwkbd=Keyboard_$2&$4" - -# Keymanweb.com 2.0 rewrite rules for Keymanweb.com 1.0 /lang/app.php urls - -# Redirect /lang/app?kmwlang=lang,kmwkbd=kbd to /?kmwlang=lang,kmwkbd=kbd -RedirectMatch "^../[^?]+?kmwlang=(.+)&kmwkbd=(.+)(&(.+))?$" "/go/$1/$2" - -# Redirect /lang/app to / -RedirectMatch "^../[^?]+$" "/" - -# Redirect /mini/* to / -RedirectMatch "^mini/" "/" - -# Control rules -RewriteRule "^_control/info$" "_control/info.php" [END] -RewriteRule "^_control/ready$" "_control/ready.php" [END] + +php_value display_errors off +php_value display_startup_errors off + + + php_value display_startup_errors on + php_value display_errors stderr + + + + + Header set Access-Control-Allow-Origin "*" + + + AddType font/ttf .ttf + AddType application/javascript .js + + AddCharset UTF-8 .js + + + RewriteEngine on + RewriteBase / + + + +# Keymanweb.com 2.0 rewrite rules for Keymanweb.com 1.0 /go/lang/kbd urls + +# Rewrite /go/lang/kbd/app[?...] to /?kmwlang=lang,kmwkbd=kbd +RewriteRule "^go/([^/]+)/([^/]+)/([^?]+)(\?)?(.+)?$" "/index.php?kmwlang=$1&kmwkbd=Keyboard_$2&$5" + +# Rewrite /go/lang/kbd[?...] to /?kmwlang=lang,kmwkbd=kbd +RewriteRule "^go/([^/]+)/([^?]+)(\?)?(.+)?$" "/index.php?kmwlang=$1&kmwkbd=Keyboard_$2&$4" + +# Keymanweb.com 2.0 rewrite rules for Keymanweb.com 1.0 /lang/app.php urls + +# Redirect /lang/app?kmwlang=lang,kmwkbd=kbd to /?kmwlang=lang,kmwkbd=kbd +RedirectMatch "^../[^?]+?kmwlang=(.+)&kmwkbd=(.+)(&(.+))?$" "/go/$1/$2" + +# Redirect /lang/app to / +RedirectMatch "^../[^?]+$" "/" + +# Redirect /mini/* to / +RedirectMatch "^mini/" "/" + +# Control rules +RewriteRule "^_control/info$" "_control/info.php" [END] +RewriteRule "^_control/ready$" "_control/ready.php" [END] diff --git a/SPZITg5E.txt b/SPZITg5E.txt deleted file mode 100644 index b18c597..0000000 --- a/SPZITg5E.txt +++ /dev/null @@ -1 +0,0 @@ -1c30e207-a415-417b-9ee3-a73057e3add6 \ No newline at end of file diff --git a/_includes/2020/WebKeymanComSentry.php b/_includes/2020/WebKeymanComSentry.php index a898ee3..8b62d8a 100644 --- a/_includes/2020/WebKeymanComSentry.php +++ b/_includes/2020/WebKeymanComSentry.php @@ -1,21 +1,21 @@ -TierName(); - return KeymanSentry::GetBrowserHTML(SENTRY_DSN, $tier == 'stable' ? $kmwbuild : "$kmwbuild-$tier"); - } +TierName(); + return KeymanSentry::GetBrowserHTML(SENTRY_DSN, $tier == 'stable' ? $kmwbuild : "$kmwbuild-$tier"); + } } \ No newline at end of file diff --git a/_includes/autoload.php b/_includes/autoload.php index 5cfebed..83cf2ef 100644 --- a/_includes/autoload.php +++ b/_includes/autoload.php @@ -1,24 +1,24 @@ - *{ - margin: 0 5px; - } -} - -@media screen and (max-width: 400px) { - .example-box p { - font-size: 10px; - } -} - -/* Animation */ - -.textarea-animation { - animation: highlight 3s; -} - -@keyframes highlight { - from {box-shadow:#2EADD3 0px 0px 0px 3px;} - to {box-shadow: var(--textarea-box);} +* { + box-sizing: border-box; +} + +:root { + --textarea-box: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgb(209, 213, 219) 0px 0px 0px 1px inset +} + +body { + overflow: hidden; +} + +.container-flex { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; +} + +.hidden { + display: none !important; +} + +a { + margin: 0 !important; + padding: 0 !important; + text-decoration: none !important; +} + +/* Icons */ +i:hover { + transition: all 0.3s ease; +} + +.fa-grip-lines:hover { + cursor: grab; +} + +/* End of Icons */ + +/* Section Tag */ + +/* + Text area +*/ +.textarea-container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; +} + +.text-area { + padding: 10px; + resize: none; + width: 100%; + box-shadow: var(--textarea-box); + font-size: 16px; + border: none; + padding: 10px; +} + +.text-area::highlight { + border: red; +} + +#copyTool { + color: var(--keyman-blue); + position: absolute; + right: 10px; + top: 97px; + opacity: 50%; +} + +#copyTool:hover { + cursor: pointer; + opacity: 100%; +} + +/* Divider */ +.divider-container i { + opacity: 50%; +} + +.divider-container i:hover { + color: var(--keyman-blue); + opacity: 100%; +} + +/* Items at the middle of the divider */ +.middle-divider { + grid-area: middle; + justify-self: center; + height: fit-content; + z-index: 1; +} + +.font-size-mobile { + display: none; +} + +/* Keyboard */ +.keyboard-container { + width: 900px; + height: 500px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.keyboard-area { + user-select: none; + flex: 1; + width: 100%; + height: 50vh; + border: 1px solid var(--keyman-blue); +} + +.example-box { + background-color: var(--keyman-blue); + color: white; + width: 100%; + text-align: center; + padding: 5px; + border-bottom: 1px solid rgb(159, 159, 159); +} + +.desktop-keyboard { + width: 100%; +} + +.phone-keyboard { + display: none; +} + +.example-box p { + margin: 10px; +} + +#example { + visibility: visible !important; +} + +#exampleBox { + visibility: visible !important; +} + +/* End of Section Tag */ + +/* ================================ + Computer and Laptop screen sizes +================================ */ +@media screen and (min-width: 940px) { + .item, .section-items { + margin: 5px + } + + /* Divider */ + .divider-container { + user-select: none; + display: grid; + grid-template-columns: repeat(5, 20%); + grid-template-rows: 100%; + align-items: center; + grid-template-areas: ". left middle right ."; + width: 100%; + height: 15px; + } +} + +/* ================================ + Most Tablet to Phone sizes +================================ */ + +@media screen and (max-width: 940px) { + /* Divider */ + .divider-container { + user-select: none; + display: grid; + grid-template-columns: 1fr 1fr 1fr; + grid-template-rows: 100%; + align-items: center; + grid-template-areas: + "left middle right" + ; + width: 100%; + padding: 10px; + border-radius: 5px; + box-shadow: var(--box-shadow); + } + + /* Keyboard */ + .keyboard-container { + width: 100%; + height: 100%; + } + + .desktop-keyboard { + display: none; + } + + .phone-keyboard { + width: 100%; + display: block; + } + + .keyboard-download-box { + display: none; + } + + .spacing-purpose { + display: none; + } +} + +/* ================================ + Smallest Phone sizes +================================ */ +@media screen and (width < 565px) { + .font-size-desktop { + display: none; + } + + .font-size-mobile { + display: flex; + flex-direction: row; + align-items: center; + border-radius: 24px; + opacity: 50%; + } + + .font-size-mobile button { + border: 0; + background-color: #fff; + border-style: none; + } + + .font-size-mobile > *{ + margin: 0 5px; + } +} + +@media screen and (max-width: 400px) { + .example-box p { + font-size: 10px; + } +} + +/* Animation */ + +.textarea-animation { + animation: highlight 3s; +} + +@keyframes highlight { + from {box-shadow:#2EADD3 0px 0px 0px 3px;} + to {box-shadow: var(--textarea-box);} } \ No newline at end of file diff --git a/cdn/dev/css/kmw-desktop.css b/cdn/dev/css/kmw-desktop.css index 09cc8af..518796e 100644 --- a/cdn/dev/css/kmw-desktop.css +++ b/cdn/dev/css/kmw-desktop.css @@ -1,176 +1,217 @@ -/* Desktop browser CSS rules */ - -/* -====================== -==Universal Elements== -====================== -*/ - - #kmw_controls{ - border-top-left-radius: 8px; - border-top-right-radius: 8px; - -moz-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); - } - - #kmw_btn_osk{ - border-top-right-radius: 10px; - } - - #kmw_controls_start{ - border-top-left-radius: 10px; - } - -textarea { - height:260px; - width:554px; - float:left; - margin: 0px 10px 10px; - color:black; - font-size:16px; - font-family:SindhiWeb,Verdana,GeezWeb,LaoWeb,TibetanWeb,MyanmarWeb,SinhalaWeb,TamilWeb,KhmerWeb,LatinWeb,OriyaWeb,EgyptianWeb !important; - } - -form { - padding-right:10px; - float:left; - } -#messageContainer { - float:left; - width:80%; -} - -/* -====================== -==Keyboard Examples== -====================== -*/ - -#example,#help { - margin: 5px 0px; - text-align: center; -} - -#example { - visibility: hidden; - width: 100%; - min-height: 45px; - display: flex; - justify-content: center; - align-items: center; - padding-top: 5px; -} - -#example a { - padding-left: 10px; -} - -.highlightKeys kbd { - border: solid 1px #808080; - border-radius: 4px; - background: #cccccf; - color: black; - font-family: Verdana; - font-weight: normal; - min-width: 16px; - display: inline-block; - box-shadow: 2px 2px 1px rgba(128, 128, 128, 0.3); - margin-right: 4px; -} - -.highlightKeys kbd.space { - min-width: 64px; -} - -/* -====================== -==Keyboard Styling== -====================== -*/ -.desktop, .kmw-osk-frame { - display: block !important; - position: static !important; - width: 100% !important; - height: 264px !important; - max-width: 100% !important; - max-height: 264px !important; - border-radius: 0; -} - -.kmw-key-square { - z-index: 0 !important; -} - -.kmw-spacebar-caption { - color: gray !important; -} - -.desktop .kmw-osk-frame, .desktop .kmw-osk-inner-frame, .desktop .kmw-key-layer-group { - background-color: #95C6D6 !important; -} - -.desktop .kmw-key-default { - background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #EEEFF0), color-stop(100%, #D3D3D9)); - background-image: -moz-linear-gradient(#EEEFF0,#D3D3D9); - background-color: #E0E0E4; -} - -.desktop .kmw-key-touched { - background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #B5B5B5), color-stop(100%, #93969B)); - background-image: -moz-linear-gradient(#B5B5B5, #93969B) !important; - background-color: #B5B5B5; - } - -.desktop .kmw-key-shift{ - background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #DBDBDB), color-stop(100%, #C0C0C4)); - background-image: -moz-linear-gradient(#DBDBDB, #C0C0C4) !important; - background-color: #DBDBDB; -} - - .desktop .kmw-key-shift-on { - background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #B5B5B5), color-stop(100%, #93969B)); - background-image: -moz-linear-gradient(#B5B5B5, #93969B) !important; - background-color: #93969B; - } - - .desktop .kmw-key-shift .kmw-key-text, .desktop .kmw-key-shift-on .kmw-key-text { color: gray; font-size: 0.9em !important; text-shadow: 0 1px 1px #fff;} - .desktop .kmw-key-shift .kmw-key-text, .desktop .kmw-key-shift-on .kmw-key-text { top: 10%; } - .desktop .kmw-key-label { top: 5%; } - .desktop .kmw-key-label { left: 10%; } - .desktop .kmw-key-default .kmw-key-text { top: 25%; } - .desktop .kmw-footer, .desktop .kmw-title-bar { background: #2EADD3 !important; display: none;} - .desktop .kmw-title-bar div{min-height: 100%;} - .desktop .kmw-footer-caption a { color: white !important; } - .kmw-osk-frame, .kmw-osk-inner-frame { border-color: #2EADD3 !important; } - .kmw-key-shift, .kmw-key-shift-on { border-width: 2px !important; } - .kmw-key-shift, .kmw-key-shift-on { border-radius: 6px !important; } - .kmw-key-shift, .kmw-key-shift-on { border-color: #95C6D6 !important; } - .kmw-key-default { border-width: 2px !important; } - .kmw-key-default { border-radius: 6px !important; } - .kmw-key-default { border-color: #95C6D6 !important; } - .kmw-key-label { color: #2EADD3 !important; } - .kmw-key-label { top: 10% !important; } - .kmw-key-label { left: 15% !important; } - .kmw-key-default { - color: #313149; - } - -#keymandesktop p { - font-size: 11pt; - font-weight: bold; - text-align: center; -} - -@media all and (min-width: 1320px) { - ins.adsbygoogle { - display: inline-block !important; - height: 600px; - position: absolute; - right: 16px; - top: 120px; - width: 160px; - } -} - -.desktop .kmw-keyboard-dari_clra .kmw-key-default .kmw-key-text { - top: -33%; -} +/* Desktop browser CSS rules */ + +/* +====================== +==Universal Elements== +====================== +*/ + + #kmw_controls{ + border-top-left-radius: 8px; + border-top-right-radius: 8px; + -moz-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); + } + + #kmw_btn_osk{ + border-top-right-radius: 10px; + } + + #kmw_controls_start{ + border-top-left-radius: 10px; + } + +textarea { + height:260px; + width:554px; + float:left; + margin: 0px 10px 10px; + color:black; + font-size:16px; + font-family:SindhiWeb,Verdana,GeezWeb,LaoWeb,TibetanWeb,MyanmarWeb,SinhalaWeb,TamilWeb,KhmerWeb,LatinWeb,OriyaWeb,EgyptianWeb !important; + } + +form { + padding-right:10px; + float:left; + } +#messageContainer { + float:left; + width:80%; +} +/* +====================== +==Keyboard Examples== +====================== +*/ + +#example,#help { + margin: 5px 0px; + text-align: center; +} + +#example { + visibility: hidden; + width: 100%; + min-height: 10px; + max-height: 45px; + display: flex; + justify-content: center; + align-items: center; + padding-top: 5px; +} + +#example a { + padding-left: 10px; +} + +.highlightKeys kbd { + border: solid 1px #808080; + border-radius: 4px; + background: #cccccf; + color: black; + font-family: Verdana; + font-weight: normal; + min-width: 16px; + display: inline-block; + box-shadow: 2px 2px 1px rgba(128, 128, 128, 0.3); + margin-right: 4px; +} + +.highlightKeys kbd.space { + min-width: 64px; +} + +/* +====================== +==Keyboard Styling== +====================== +*/ +.desktop, .kmw-osk-frame { + display: block !important; + position: static !important; + width: 100% !important; + height: 100% !important; + max-width: 100% !important; + max-height: 100% !important; + border-radius: 0; +} + +.kmw-help-osk-frame { + height: 100% !important; + scroll-behavior: smooth !important; + scrollbar-width: thin; + overflow-x: hidden !important; + overflow-y: scroll !important; + text-align: center !important; +} + +.kmw-osk-static { + height: fit-content !important; + text-align: center !important; + border: solid 1px var(--keyman-blue) !important; +} + +.kmw-osk-static table { + display: flex !important; + flex-direction: row !important; + align-items: center !important; + justify-content: center !important; + width: 100% !important; +} + +#kmw-osk-help-page > table > tbody > tr > td > .row { + --bs-gutter-x: 0 !important; +} + +.kmw-title-bar { + background-color: #2EADD3 !important; + border-radius: 0 !important; + height: fit-content !important; +} + +#keyboard_europeanlatin_help p, .kmw-osk-static p { + display: flex !important; + justify-content: end !important; + position: relative !important; + right: 0 !important; + top: 0 !important; +} + +.kmw-key-square { + z-index: 0 !important; +} + +.kmw-spacebar-caption { + color: gray !important; +} + +.desktop .kmw-osk-frame, .desktop .kmw-osk-inner-frame, .desktop .kmw-key-layer-group { + background-color: #95C6D6 !important; +} + +.desktop .kmw-key-default { + background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #EEEFF0), color-stop(100%, #D3D3D9)); + background-image: -moz-linear-gradient(#EEEFF0,#D3D3D9); + background-color: #E0E0E4; +} + +.desktop .kmw-key-touched { + background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #B5B5B5), color-stop(100%, #93969B)); + background-image: -moz-linear-gradient(#B5B5B5, #93969B) !important; + background-color: #B5B5B5; + } + +.desktop .kmw-key-shift{ + background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #DBDBDB), color-stop(100%, #C0C0C4)); + background-image: -moz-linear-gradient(#DBDBDB, #C0C0C4) !important; + background-color: #DBDBDB; +} + + .desktop .kmw-key-shift-on { + background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #B5B5B5), color-stop(100%, #93969B)); + background-image: -moz-linear-gradient(#B5B5B5, #93969B) !important; + background-color: #93969B; + } + + .desktop .kmw-key-shift .kmw-key-text, .desktop .kmw-key-shift-on .kmw-key-text { color: gray; font-size: 0.9em !important; text-shadow: 0 1px 1px #fff;} + .desktop .kmw-key-shift .kmw-key-text, .desktop .kmw-key-shift-on .kmw-key-text { top: 10%; } + .desktop .kmw-key-label { top: 5%; } + .desktop .kmw-key-label { left: 10%; } + .desktop .kmw-key-default .kmw-key-text { top: 25%; } + .desktop .kmw-footer, .desktop .kmw-title-bar { background-color: #2EADD3 !important; display: none;} + .desktop .kmw-title-bar div{min-height: 100%;} + .desktop .kmw-footer-caption a { color: white !important; } + .kmw-osk-frame, .kmw-osk-inner-frame { border-color: #2EADD3 !important; } + .kmw-key-shift, .kmw-key-shift-on { border-width: 2px !important; } + .kmw-key-shift, .kmw-key-shift-on { border-radius: 6px !important; } + .kmw-key-shift, .kmw-key-shift-on { border-color: #95C6D6 !important; } + .kmw-key-default { border-width: 2px !important; } + .kmw-key-default { border-radius: 6px !important; } + .kmw-key-default { border-color: #95C6D6 !important; } + .kmw-key-label { color: #2EADD3 !important; } + .kmw-key-label { top: 10% !important; } + .kmw-key-label { left: 15% !important; } + .kmw-key-default { + color: #313149; + } + +#keymandesktop p { + font-size: 11pt; + font-weight: bold; + text-align: center; +} + +@media all and (min-width: 1320px) { + ins.adsbygoogle { + display: inline-block !important; + height: 600px; + position: absolute; + right: 16px; + top: 120px; + width: 160px; + } +} + +.desktop .kmw-keyboard-dari_clra .kmw-key-default .kmw-key-text { + top: -33%; +} diff --git a/cdn/dev/css/kmw-header.css b/cdn/dev/css/kmw-header.css index a3745a3..09bbb23 100644 --- a/cdn/dev/css/kmw-header.css +++ b/cdn/dev/css/kmw-header.css @@ -1,928 +1,867 @@ -:root { - --box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; - --keyman-orange: #FC7200; - --keyman-red: #B92034; - --keyman-blue: #2EADD3; -} - -* { - letter-spacing: .05rem; - font-weight: 400; -} - -hr { - margin: 0; -} - -header > div > img { - width: 100%; - display: block; - height: 5px; -} - -#searchDropdownMenu { - padding: 10px; - margin: 0; -} - -.main-header { - display: grid; - height: 75px; - padding: 0 10px; - box-shadow: var(--box-shadow); -} - -/* Left side of Header: - Search - Keyboard dropdown -*/ - -.left-header { - display: flex; - align-items: center; -} - -.left-header img { - margin-right: 10px; -} - -/* -Language Search box -*/ -#searchBar { - position: relative; - width: 550px; - margin-right: 10px; -} - -#searchIcons { - position: absolute; - right: 5px; - top: 12px; - border-left: 1px solid gray; -} - -#searchIcons > * { - margin-right: 10px; - padding-left: 15px; - opacity: 50%; -} - -#searchIcons > *:hover { - padding-left: 15px; - opacity: 100%; -} - -#magnifyingGlassIcon { - display: inline; -} - -#clearSearchIcon { - display: none; -} - -#searchBar #searchInput { - height: 50px; - width: 100%; - text-indent: 10px; - border-radius: 15px; - text-align: left; - font-family: inherit !important; - box-shadow: none; -} - -#searchInput:hover, #searchInput:focus { - border: 1px solid var(--keyman-orange); -} - -#searchDropdownMenu { - width: 100%; - max-height: 600px; - overflow: auto; - scrollbar-width: thin; -} - -#searchDropdownMenu hr { - margin: 15px 0; -} - -/* Enable keyboard Animation */ -.kb-icon-plus-animate { - animation: plustoTickToMinus 2s forwards; -} - -@keyframes plustoTickToMinus { - 0% { - content: "+"; - transform: scale(1); - } - 30% { - color: lime; - content: "โœ“"; - transform: scale(1.5); - } - 60% { - color: lime; - content: "โœ“"; - transform: scale(1.3); - } - 100% { - content: "-"; - transform: scale(1); - } -} - -/* Instruction on dropdown */ -.instruction-title, .keyboard-title { - width: 100%; -} - -.instruction-title p, .keyboard-title { - font-weight: 500; - font-size: 16px; - text-align: center; -} - -/* Map and Most download */ -.left-header .dropdown-menu .top-row #worldMap { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - margin: 10px 10px !important; -} - -#worldMap span { - opacity: 50%; -} - -#worldMap span:hover { - opacity: 100%; - cursor: pointer; -} - -#KeymanWebControl #kmw_controls -{ - display: flex !important; - flex-direction: row; - justify-content: space-evenly; - border-radius: 20px; - box-shadow: var(--box-shadow); - height: 35px; - padding: 5px; -} - -#KeymanWebControl .kmw_button, -#keymanWebControl .kmw_button_disabled, -#KeymanWebControl .kmw_button_selected -{ - width: fit-content !important; - background: none !important; - height: 0 !important; -} - -#KeymanWebControl #kmw_controls_start, -#KeymanWebControl #kmw_btn_osk, -.kmw_bar, #kmw_controls_end { - display: none; -} - -#KeymanWebControl .kmw_language { - padding: 3px; -} - -#kmw_control_keyboards { - width: fit-content; -} - -#kmw_selector_regions { - height: 100%; - overflow: hidden; - position: relative; -} - -.kmw_selector_region { - overflow-y: scroll; - overflow-x: hidden; - scrollbar-width: thin; - height: 600px; -} - -/* Search Dropdown cards */ -#languageSearchList > * { - margin-bottom: 5px; -} - -#languageSearchList > div:hover { - border: 1px solid var(--keyman-orange); - margin: 3px; -} - -.card-wrap { - box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;; - padding: 10px; - border-radius: 10px; - letter-spacing: .05rem; - overflow: hidden; - margin-bottom: 5px; -} - -.card-wrap.disabled { - opacity: 0.5; - pointer-events: none; - position: relative; -} - -.card-wrap.disabled .kb-icon-plus { - pointer-events: auto; - opacity: 1; - position: absolute; - right: 15px; - z-index: 1; -} - -.kb-icon-plus { - transition: 0.5s ease; -} - -.kb-icon-plus.animate { - color: green; -} - -.keyboard-id { - font-size: 12px; - margin-bottom: 10px; - color: #006622; -} - -.card-wrap h6 { - opacity: 75%; - font-size: 12px; - margin: 0 0 0.35rem; -} - -.keyboard-description { - color: gray; -} - -.keyboard-specs { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; -} - -.keyboard-specs .platform { - display: flex; - flex-direction: row; -} - -.keyboard-specs .platform span, -.keyboard-content .keyboard-platforms .platform span { - font-size: 0px; - width: 15px; - height: 20px; - margin: 0; -} - -.card-wrap .monthly-download { - opacity: 75%; -} - -.card-header { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - margin-bottom: 8px; -} - -.card-header h4 { - color: #0000EE; - font-weight: 400; - font-size: large; - margin: 0; -} - -.card-header h4 span { - color: black; -} - -.card-header p { - margin: 0; - position: relative; - float: right; - font-weight: 200; - font-size: medium; - color: var(--keyman-red); -} - -/* Pagination */ -#searchDropdownMenu .bottom-row-search { - background-color: white; - align-items: center; - justify-content: center; - width: fit-content; - border-radius: 10px; - width: 100%; - bottom: 0; - text-align: center; - box-shadow: rgba(9, 30, 66, 0.25) 0px 1px 1px, rgba(9, 30, 66, 0.13) 0px 0px 1px 1px; -} - -.bottom-row-search > * { - margin: 10px; - cursor: pointer; -} - -/* Selected Keyboard Menu */ -#keyboardSelectionButton { - z-index: 3; -} - -.scroll-wrapper-keyboard-tab { - width: 350px; - height: 35px; - position: relative; -} - -#keyboardSelection { - display: flex; - flex-direction: column; - text-align: center; - width: 0; - height: 100%; - background-color: white; - color: black; - box-shadow: var(--box-shadow); - overflow-y: scroll; - scrollbar-width: none; - transition: all 1s ease-in-out; - margin-left: -10px; - border-radius: 10px; - z-index: 0; - white-space: nowrap; - text-indent: 15px; -} - -#keyboardSelection.open { - position: relative; - width: 400px; - height: fit-content; - padding: 0 0 10px; - z-index: 2; -} - -#keyboardSelection p { - margin: 0; - height: 25px; - width: 100%; -} - -.kb-item-header, .kb-item-footer { - display: flex; - align-items: center; - justify-content: center; - height: 30px; - font-weight: 500; - margin: 5px 0; -} - -.kb-item-header { - border-bottom: 1px solid gray; -} - -.kb-item-footer { - border-top: 1px solid gray; - cursor: pointer; -} - -.kb-item { - width: 100%; - max-height: fit-content; - height: 38px; - display: flex; - flex-direction: row; - justify-content: space-between; - padding: 5px; -} - -.kb-item:hover { - cursor: pointer; - background-color: var(--keyman-orange); - color: white; -} - -.kb-item span { - width: 50%; - text-wrap: wrap; - align-self: center; -} - -.keyboard-configs { - width: 50%; - height: fit-content; - display: grid; - grid-template-columns: repeat(4, 1fr); - list-style-type: none; - padding: 2px 0 0; -} - -::-webkit-scrollbar:horizontal { - height: 5px; -} - -::-webkit-scrollbar-thumb:horizontal { - background: #2c7be5; - border-radius: 6px; -} - -::-webkit-scrollbar-track:horizontal { - background: #f1f1f1; -} - -.btn-keyman-orange { - background-color: var(--keyman-orange) !important; - color: white !important; -} - -.keyboard-details { - position: absolute; - width: 400px; - height: fit-content; - background-color: white; - color: black; - box-shadow: var(--box-shadow); - border-radius: 20px; - padding: 10px; - z-index: 2; -} - -.keyboard-content-wrapper { - margin-top: 10px; -} - -.keyboard-content { - width: max-content; - list-style-type: none; - padding: 0; - text-align: left; - display: flex; - flex-direction: column; -} - -.keyboard-content > * { - margin: 5px 0px; -} - -.keyboard-content .keyboard-platforms .platform { - display: flex; - flex-direction: row; -} - -.keyboard-content li .row .col:nth-child(2), -.keyboard-content li .row .col:nth-child(2) * { - text-align: center; - white-space: normal; - word-break: break-word; - width: 200px; - overflow: hidden; -} - -.keyboard-content li .row .col:nth-child(1) { - width: 200px; -} - -#removeLanguage { - cursor: pointer; -} - -.platform span { - background-repeat: no-repeat; - padding-left: 24px; - background-size: 18px; - display: block; - margin: 4px 0; -} - -.platform span:hover, .keyboard-configs li:hover{ - cursor: help; -} - -.platform .platform-windows { - background-image: url('/cdn/dev/img/platforms/icon-windows.png'); -} - -.platform .platform-macos { - background-image: url('/cdn/dev/img/platforms/icon-macos.png'); -} - -.platform .platform-linux { - background-image: url('/cdn/dev/img/platforms/icon-linux.png'); -} - -.platform .platform-android { - background-image: url('/cdn/dev/img/platforms/icon-android.png'); -} - -.platform .platform-ios { - background-image: url('/cdn/dev/img/platforms/icon-ios.png'); -} - -.platform .platform-desktopweb { - background-image: url('/cdn/dev/img/platforms/icon-desktopWeb.png'); -} - -.platform .platform-mobileweb { - background-image: url('/cdn/dev/img/platforms/icon-mobileWeb.png'); -} - -/* Limits of Keyboard Selection */ -.warning-container { - position: fixed; - height: 100vh; - width: 100%; - z-index: 1000; - top: 0; - left: 0; - display: flex; - justify-content: center; - align-items: center; -} - -.warning-content { - width: 500px; - display: flex; - flex-direction: column; - align-items: center; - background-color: white; - color: black; - text-align: center; - padding: 30px 30px 70px; - border-radius: 20px; - box-shadow: var(--box-shadow); -} - -.warning-cancel-btn { - width: 30px; - font-size: 20px; - opacity: 50%; - align-self: flex-end; - background-color: transparent; - border: none; - margin-bottom: 10px; -} - -.warning-keyman-image { - width: 82px; - margin-bottom: 15px; -} - -.warning-text { - margin-bottom: 40px; - font-size: 18px; -} - -.warning-accept-btn { - background-color: var(--keyman-orange); - border: none; - border-radius: 5px; - width: 200px; - padding: 14px; - color: white; - box-shadow: var(--box-shadow); -} - -/* Middle of the header */ -.middle-header { - display: flex; - justify-content: center; - align-items: center; -} - -.middle-header i, .right-header i { - font-size: 24px; - opacity: 50%; -} - -.middle-header i:hover { - opacity: 100%; - cursor: pointer; - color: var(--keyman-red); -} - -/* Right side of the header: - Tools - Hamburger menu -*/ - -.right-header { - display: grid; - grid-template-columns: 80% 20%; - width: 100%; - justify-items: right; - align-items: center; - margin-right: 0; -} - -.right-header i:hover { - opacity: 100%; - cursor: pointer; - color: var(--keyman-blue); -} - -/* Font size slider + Hide/show keyboard */ -.tool-container { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; -} - -.tool-container > * { - margin: 10px; -} - -.font-size-container { - display: flex; - flex-direction: row; - align-items: center; -} - -.font-size-slider { - display: flex; - flex-direction: column; - justify-content: end; - align-items: center; - height: 60px; -} - -#fontSizeRange[type=range] { - -webkit-appearance: none; - margin: 10px 0; - width: 100%; -} - - -.font-large { - font-size: 20px; -} - -input[type="range"] { - width: 100px; - background-color: transparent; -} - -input[type="range"]::-webkit-slider-runnable-track { - height: 3px; - background: rgb(107, 107, 107); - border-radius: 10px; -} - -input[type="range"]::-webkit-slider-thumb { - border-radius: 50%; - height: 20px; - width: 20px; - position: relative; - bottom: 6px; - background-size: 50%; - box-shadow: 0px 3px 5px 0px rgba(0, 0, 0, 0.4); - cursor: grab; -} - -#fontSizeRange[type=range]::-webkit-slider-runnable-track { - width: 100%; - cursor: pointer; - transform: 0.2s; - box-shadow: var(--box-shadow); - background: gray; - border-radius: 25px; -} - -#fontSizeRange[type=range]::-webkit-slider-thumb { - height: 10px; - width: 20px; - border-radius: 7px; - background: var(--keyman-blue); - cursor: pointer; - -webkit-appearance: none; - box-shadow: 0px 0px 5px rgb(143, 143, 143); - margin-top: 3px; -} - -#burgerMenu ul { - box-shadow: var(--box-shadow); -} - -#burgerMenu ul:hover { - cursor: pointer; -} - -.dropdown-grid-container { - display: grid; - grid-template-columns: 1fr 1fr; - grid-template-rows: 1fr; -} - -.dropdown-item:active { - background-color: transparent !important; -} - -#burgerMenu ul li { - align-items: center; - width: 300px; - border-bottom: 1px solid rgb(196, 196, 196); - margin-top: 10px; -} - -#burgerMenu ul li::after { - background-color: orange; -} - -#burgerMenu ul li p:hover { - opacity: 100%; -} - -#burgerMenu ul li p { - width: 90%; - white-space: normal; - position: relative; - left: 40px; - font-size: 14px; - opacity: 50%; - margin-top: 10px; -} - -#burgerMenu ul li a { - text-decoration: none; - color: black; - font-style: bold; - font-size: 16px; -} - -#burgerMenu ul li i, #burgerMenu ul li img { - margin: 0 10px; - font-size: 16px; - width: 18px; - opacity: 100%; - color: var(--keyman-orange) -} - -#burgerMenu button i:hover { - cursor: pointer; -} - -.kmw-socials, .kmw-version, .sil-logo { - font-size: 14px; -} - -.kmw-socials { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - padding: 10px; -} - -.kmw-socials-icons { - display: grid; - grid-template-columns: 1fr 1fr 1fr; - justify-content: center; - align-items: center; - gap: 10px; -} - -.kmw-socials-icons > a { - text-decoration: none; - color: black; - opacity: 50%; - position: relative; -} - -.kmw-socials-icons > a:hover { - opacity: 100%; -} - -@font-face { - font-family: "social-logos"; - src: url("../../fonts/social-logos.ttf"), - url("social-logos.woff2") format("woff2"), - url("social-logos.woff") format("woff"); - font-weight: normal; - font-style: normal; -} - -[data-icon]:before { - font-family: "social-logos" !important; - content: attr(data-icon); - padding-right: 4px; - font-size: 16px; -} - -.kmw-version { - display: flex; - flex-direction: row; - justify-content: center; -} - -.sil-logo { - display: flex; - flex-direction: column; - align-items: center; -} - -/* ================================ - Computer, Laptop, some Tablet screen sizes -================================ */ -@media screen and (min-width: 1045px) { - .main-header { - grid-template-columns: 3fr 1fr; - } -} - -/* Expanding the search box */ -@media screen and (940px <= width <= 1045px) { - .main-header { - grid-template-columns: 4fr 1fr; - } -} - -/* ================================ - Most Tablet to Phone sizes -================================ */ - -@media screen and (max-width: 940px) { - .main-header { - grid-template-columns: 4fr 1fr; - } - - .left-header { - align-items: center; - justify-content: left; - align-items: center; - } - - .left-header img { - display: none; - } - - /* - Language Search box - */ - - #searchBar { - width: 50%; - } -} - -@media screen and (max-width: 565px) { - #searchDropdownMenu { - width: 300px !important; - } - - #keyboardSelection { - max-width: 300px !important; - } - - #keyboardTab { - display: grid; - grid-template-columns: repeat(3, 1fr); - } - - #keyboardTab > * { - margin-bottom: 10px; - } -} - -/* Animation */ - -.keyboardTab-animation { - animation: keyboardTab 1s; -} -.keyboardSelection-animation { - animation: keyboardSelection 1s ease-in; -} - -@keyframes keyboardSelection { - 0% { - transform: translateY(-5px); - } - 50% { - transform: translateY(-3px); - } - 75% { - transform: translateY(-1px); - } - 100% { - transform: translateY(0); - } -} - -@keyframes keyboardTab { - from { - opacity: 50%; - } - to { - opacity: 100%; - } +:root { + --box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; + --keyman-orange: #FC7200; + --keyman-red: #B92034; + --keyman-blue: #2EADD3; +} + +* { + letter-spacing: .05rem; + font-weight: 400; +} + +hr { + margin: 0; +} + +header > div > img { + width: 100%; + display: block; + height: 5px; +} + +#searchDropdownMenu { + padding: 10px; + margin: 0; +} + +.main-header { + display: grid; + grid-template-columns: 1fr 1fr; + height: 75px; + padding: 0 10px; + box-shadow: var(--box-shadow); +} + +/* Left side of Header: + Search + Keyboard dropdown +*/ + +.left-header { + display: flex; + align-items: center; +} + +.left-header img { + margin-right: 10px; +} + +/* +Language Search box +*/ +#searchBar { + position: relative; + width: 550px; + margin-right: 10px; +} + +#searchIcons { + position: absolute; + right: 5px; + top: 12px; + border-left: 1px solid gray; + background-color: white; +} + +#searchIcons > * { + margin-right: 10px; + padding-left: 15px; + opacity: 50%; +} + +#searchIcons > *:hover { + padding-left: 15px; + opacity: 100%; +} + +#magnifyingGlassIcon { + display: inline; +} + +#clearSearchIcon { + display: none; +} + +#searchBar #searchInput { + height: 50px; + width: 100%; + text-indent: 10px; + border-radius: 15px; + text-align: left; + font-family: inherit !important; + box-shadow: none; +} + +#searchInput:hover, #searchInput:focus { + border: 1px solid var(--keyman-orange); +} + +#searchDropdownMenu { + width: 100%; + max-height: 600px; + overflow: auto; + scrollbar-width: thin; +} + +#searchDropdownMenu hr { + margin: 15px 0; +} + +/* Enable keyboard Animation */ +.kb-icon-plus-animate { + animation: plustoTickToMinus 2s forwards; +} + +@keyframes plustoTickToMinus { + 0% { + content: "+"; + transform: scale(1); + } + 30% { + color: lime; + content: "โœ“"; + transform: scale(1.5); + } + 60% { + color: lime; + content: "โœ“"; + transform: scale(1.3); + } + 100% { + content: "-"; + transform: scale(1); + } +} + +/* Instruction on dropdown */ +.instruction-title, .keyboard-title { + width: 100%; +} + +.instruction-title p, .keyboard-title { + font-weight: 500; + font-size: 16px; + text-align: center; +} + +/* Map and Most download */ +.left-header .dropdown-menu .top-row #worldMap { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + margin: 10px 10px !important; +} + +#worldMap span { + opacity: 50%; +} + +#worldMap span:hover { + opacity: 100%; + cursor: pointer; +} + +#KeymanWebControl #kmw_controls +{ + display: flex !important; + flex-direction: row; + justify-content: space-evenly; + border-radius: 20px; + box-shadow: var(--box-shadow); + height: 35px; + padding: 5px; +} + +#KeymanWebControl .kmw_button, +#keymanWebControl .kmw_button_disabled, +#KeymanWebControl .kmw_button_selected +{ + width: fit-content !important; + background: none !important; + height: 0 !important; +} + +#KeymanWebControl #kmw_controls_start, +#KeymanWebControl #kmw_btn_osk, +.kmw_bar, #kmw_controls_end { + display: none; +} + +#KeymanWebControl .kmw_language { + padding: 3px; +} + +#kmw_control_keyboards { + width: fit-content; +} + +#kmw_selector_regions { + height: 100%; + overflow: hidden; + position: relative; +} + +.kmw_selector_region { + overflow-y: scroll; + overflow-x: hidden; + scrollbar-width: thin; + height: 600px; +} + +/* Search Dropdown cards */ +#languageSearchList > * { + margin-bottom: 5px; +} + +#languageSearchList > div:hover { + border: 1px solid var(--keyman-orange); + margin: 3px; +} + +.card-wrap { + box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;; + padding: 10px; + border-radius: 10px; + letter-spacing: .05rem; + overflow: hidden; + margin-bottom: 5px; +} + +.card-wrap.disabled { + opacity: 0.5; + pointer-events: none; + position: relative; +} + +.card-wrap.disabled .kb-icon-plus { + pointer-events: auto; + opacity: 1; + position: absolute; + right: 15px; + z-index: 1; +} + +.kb-icon-plus { + transition: 0.5s ease; +} + +.kb-icon-plus.animate { + color: green; +} + +.keyboard-id { + font-size: 12px; + margin-bottom: 10px; + color: #006622; +} + +.card-wrap h6 { + opacity: 75%; + font-size: 12px; + margin: 0 0 0.35rem; +} + +.keyboard-description { + color: gray; +} + +.keyboard-specs { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; +} + +.keyboard-specs .platform { + display: flex; + flex-direction: row; +} + +.keyboard-specs .platform span, +.keyboard-content .keyboard-platforms .platform span { + font-size: 0px; + width: 15px; + height: 20px; + margin: 0; +} + +.card-wrap .monthly-download { + opacity: 75%; +} + +.card-header { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + margin-bottom: 8px; +} + +.card-header h4 { + color: #0000EE; + font-weight: 400; + font-size: large; + margin: 0; +} + +.card-header h4 span { + color: black; +} + +.card-header p { + margin: 0; + position: relative; + float: right; + font-weight: 200; + font-size: medium; + color: var(--keyman-red); +} + +/* Pagination */ +#searchDropdownMenu .bottom-row-search { + background-color: white; + align-items: center; + justify-content: center; + width: fit-content; + border-radius: 10px; + width: 100%; + bottom: 0; + text-align: center; + box-shadow: rgba(9, 30, 66, 0.25) 0px 1px 1px, rgba(9, 30, 66, 0.13) 0px 0px 1px 1px; +} + +.bottom-row-search > * { + margin: 10px; + cursor: pointer; +} + +/* Selected Keyboard Menu */ +#keyboardSelectionButton { + z-index: 3; +} + +.scroll-wrapper-keyboard-tab { + width: 350px; + height: 35px; + position: relative; +} + +#keyboardSelection { + display: flex; + flex-direction: column; + text-align: center; + width: 0; + height: 100%; + background-color: white; + color: black; + box-shadow: var(--box-shadow); + overflow-y: scroll; + scrollbar-width: none; + transition: all 1s ease-in-out; + margin-left: -10px; + border-radius: 10px; + z-index: 0; + white-space: nowrap; + text-indent: 15px; +} + +#keyboardSelection.open { + position: relative; + width: 400px; + height: fit-content; + padding: 0 0 10px; + z-index: 2; +} + +#keyboardSelection p { + margin: 0; + height: 25px; + width: 100%; +} + +.kb-item-header, .kb-item-footer { + display: flex; + align-items: center; + justify-content: center; + height: 30px; + font-weight: 500; + margin: 5px 0; +} + +.kb-item-header { + border-bottom: 1px solid gray; +} + +.kb-item-footer { + border-top: 1px solid gray; + cursor: pointer; +} + +.kb-item { + width: 100%; + max-height: fit-content; + height: 38px; + display: flex; + flex-direction: row; + justify-content: space-between; + padding: 5px; +} + +.kb-item:hover { + cursor: pointer; + background-color: var(--keyman-orange); + color: white; +} + +.kb-item span { + width: 50%; + text-wrap: wrap; + align-self: center; +} + +.keyboard-configs { + width: 50%; + height: fit-content; + display: grid; + grid-template-columns: repeat(4, 1fr); + list-style-type: none; + padding: 2px 0 0; +} + +::-webkit-scrollbar:horizontal { + height: 5px; +} + +::-webkit-scrollbar-thumb:horizontal { + background: #2c7be5; + border-radius: 6px; +} + +::-webkit-scrollbar-track:horizontal { + background: #f1f1f1; +} + +.btn-keyman-orange { + background-color: var(--keyman-orange) !important; + color: white !important; +} + +.keyboard-details { + position: absolute; + width: 400px; + height: fit-content; + background-color: white; + color: black; + box-shadow: var(--box-shadow); + border-radius: 20px; + padding: 10px; + z-index: 2; +} + +.keyboard-content-wrapper { + margin-top: 10px; +} + +.keyboard-content { + width: max-content; + list-style-type: none; + padding: 0; + text-align: left; + display: flex; + flex-direction: column; +} + +.keyboard-content > * { + margin: 5px 0px; +} + +.keyboard-content .keyboard-platforms .platform { + display: flex; + flex-direction: row; +} + +.keyboard-content li .row .col:nth-child(2), +.keyboard-content li .row .col:nth-child(2) * { + text-align: center; + white-space: normal; + word-break: break-word; + width: 200px; + overflow: hidden; +} + +.keyboard-content li .row .col:nth-child(1) { + width: 200px; +} + +#removeLanguage { + cursor: pointer; +} + +.platform span { + background-repeat: no-repeat; + padding-left: 24px; + background-size: 18px; + display: block; + margin: 4px 0; +} + +.platform span:hover, .keyboard-configs li:hover{ + cursor: help; +} + +.platform .platform-windows { + background-image: url('/cdn/dev/img/platforms/icon-windows.png'); +} + +.platform .platform-macos { + background-image: url('/cdn/dev/img/platforms/icon-macos.png'); +} + +.platform .platform-linux { + background-image: url('/cdn/dev/img/platforms/icon-linux.png'); +} + +.platform .platform-android { + background-image: url('/cdn/dev/img/platforms/icon-android.png'); +} + +.platform .platform-ios { + background-image: url('/cdn/dev/img/platforms/icon-ios.png'); +} + +.platform .platform-desktopweb { + background-image: url('/cdn/dev/img/platforms/icon-desktopWeb.png'); +} + +.platform .platform-mobileweb { + background-image: url('/cdn/dev/img/platforms/icon-mobileWeb.png'); +} + +/* Limits of Keyboard Selection */ +.warning-container { + position: fixed; + height: 100vh; + width: 100%; + z-index: 1000; + top: 0; + left: 0; + display: flex; + justify-content: center; + align-items: center; +} + +.warning-content { + width: 500px; + display: flex; + flex-direction: column; + align-items: center; + background-color: white; + color: black; + text-align: center; + padding: 30px 30px 70px; + border-radius: 20px; + box-shadow: var(--box-shadow); +} + +.warning-cancel-btn { + width: 30px; + font-size: 20px; + opacity: 50%; + align-self: flex-end; + background-color: transparent; + border: none; + margin-bottom: 10px; +} + +.warning-keyman-image { + width: 82px; + margin-bottom: 15px; +} + +.warning-text { + margin-bottom: 40px; + font-size: 18px; +} + +.warning-accept-btn { + background-color: var(--keyman-orange); + border: none; + border-radius: 5px; + width: 200px; + padding: 14px; + color: white; + box-shadow: var(--box-shadow); +} + +/* Middle of the header */ +.middle-header { + display: flex; + justify-content: center; + align-items: center; +} + +.middle-header i, .right-header i { + font-size: 24px; + opacity: 50%; +} + +.middle-header i:hover { + opacity: 100%; + cursor: pointer; + color: var(--keyman-red); +} + +/* Right side of the header: + Tools + Hamburger menu +*/ + +.right-header { + display: grid; + grid-template-columns: 80% 20%; + width: 100%; + justify-items: right; + align-items: center; + margin-right: 0; +} + +.right-header i:hover { + opacity: 100%; + cursor: pointer; + color: var(--keyman-blue); +} + +/* Font size slider + Hide/show keyboard */ +.tool-container { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; +} + +.tool-container > * { + margin: 10px; +} + +.font-size-container { + display: flex; + flex-direction: row; + align-items: center; +} + +.font-size-slider { + display: flex; + flex-direction: column; + justify-content: end; + align-items: center; + height: 60px; +} + +#fontSizeRange[type=range] { + -webkit-appearance: none; + margin: 10px 0; + width: 100%; +} + + +.font-large { + font-size: 20px; +} + +input[type="range"] { + width: 100px; + background-color: transparent; +} + +input[type="range"]::-webkit-slider-runnable-track { + height: 3px; + background: rgb(107, 107, 107); + border-radius: 10px; +} + +input[type="range"]::-webkit-slider-thumb { + border-radius: 50%; + height: 20px; + width: 20px; + position: relative; + bottom: 6px; + background-size: 50%; + box-shadow: 0px 3px 5px 0px rgba(0, 0, 0, 0.4); + cursor: grab; +} + +#fontSizeRange[type=range]::-webkit-slider-runnable-track { + width: 100%; + cursor: pointer; + transform: 0.2s; + box-shadow: var(--box-shadow); + background: gray; + border-radius: 25px; +} + +#fontSizeRange[type=range]::-webkit-slider-thumb { + height: 10px; + width: 20px; + border-radius: 7px; + background: var(--keyman-blue); + cursor: pointer; + -webkit-appearance: none; + box-shadow: 0px 0px 5px rgb(143, 143, 143); + margin-top: 3px; +} + +#burgerMenu ul { + box-shadow: var(--box-shadow); +} + +#burgerMenu ul:hover { + cursor: pointer; +} + +.dropdown-grid-container { + display: grid; + grid-template-columns: 1fr 1fr; + grid-template-rows: 1fr; +} + +.dropdown-item:active { + background-color: transparent !important; +} + +#burgerMenu ul li { + align-items: center; + width: 300px; + border-bottom: 1px solid rgb(196, 196, 196); + margin-top: 10px; +} + +#burgerMenu ul li::after { + background-color: orange; +} + +#burgerMenu ul li p:hover { + opacity: 100%; +} + +#burgerMenu ul li p { + width: 90%; + white-space: normal; + position: relative; + left: 40px; + font-size: 14px; + opacity: 50%; + margin-top: 10px; +} + +#burgerMenu ul li a { + text-decoration: none; + color: black; + font-style: bold; + font-size: 16px; +} + +#burgerMenu ul li i, #burgerMenu ul li img { + margin: 0 10px; + font-size: 16px; + width: 18px; + opacity: 100%; + color: var(--keyman-orange) +} + +#burgerMenu button i:hover { + cursor: pointer; +} + +.kmw-socials, .kmw-version, .sil-logo { + font-size: 14px; +} + +.kmw-socials { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 10px; +} + +.kmw-socials-icons { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + justify-content: center; + align-items: center; + gap: 10px; +} + +.kmw-socials-icons > a { + text-decoration: none; + color: black; + opacity: 50%; + position: relative; +} + +.kmw-socials-icons > a:hover { + opacity: 100%; +} + +@font-face { + font-family: "social-logos"; + src: url("../../fonts/social-logos.ttf"), + url("social-logos.woff2") format("woff2"), + url("social-logos.woff") format("woff"); + font-weight: normal; + font-style: normal; +} + +[data-icon]:before { + font-family: "social-logos" !important; + content: attr(data-icon); + padding-right: 4px; + font-size: 16px; +} + +.kmw-version { + display: flex; + flex-direction: row; + justify-content: center; +} + +.sil-logo { + display: flex; + flex-direction: column; + align-items: center; +} + +/* Animation */ + +.keyboardTab-animation { + animation: keyboardTab 1s; +} +.keyboardSelection-animation { + animation: keyboardSelection 1s ease-in; +} + +@keyframes keyboardSelection { + 0% { + transform: translateY(-5px); + } + 50% { + transform: translateY(-3px); + } + 75% { + transform: translateY(-1px); + } + 100% { + transform: translateY(0); + } +} + +@keyframes keyboardTab { + from { + opacity: 50%; + } + to { + opacity: 100%; + } } \ No newline at end of file diff --git a/cdn/dev/css/kmw-mobile.css b/cdn/dev/css/kmw-mobile.css index 95ce082..6c72d31 100644 --- a/cdn/dev/css/kmw-mobile.css +++ b/cdn/dev/css/kmw-mobile.css @@ -1,420 +1,166 @@ -/* KMW LIVE CSS for iPhone and other mobiles */ - -/* -====================== -==Universal Elements== -====================== -*/ - -html { - overflow-y: scroll; - overflow-x: hidden; -} - -body { - width:100%;height:100%; - font-family: Verdana, Arial, Helvetica, sans-serif; - color:#2D2C2C; - background-color: #eeeeee; - margin:0px; - } - -a { - text-decoration:none; - color: #AD4A28; - } - -a:hover { - text-decoration:underline; - } - -h3 { - font-size:18px; - } - -p { - font-size:13px; - line-height:1.5em; - } -/* -header, #content, footer { - margin:0px auto; - clear: both; - } -*/ - -hr { - display: none; - } - -/* -.box { - -webkit-border-radius: 8px;-moz-border-radius: 8px; border-radius: 8px; - -moz-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); - } -*/ -/* -=================== -==Header Elements== -=================== -*/ -header img, #headerLeft { - display: none; -} -header { - position: absolute; - top: 190px; - background: #776666; - font-size: 9pt; - padding: 6px 0; - color: white; - width: 100%; - text-align: center; -} -header a { - color: #c0c0ff; - text-decoration: underline; -} - -/* -==================== -==Content Elements== -==================== -*/ -#content { - width: 100%; /* specific for mobile and tablet */ - margin: 0px auto; - background-color: #eeeeee; - /* min-height:375px; */ - } - - -/* KMW Main App */ -#app { - width:100%; - margin: 0px; - } -#KeymanWebControl { - display: none; - } - -#exampleBox,#example { - display:none; - } - -#messageContainer { - width: 80%; - float:left; - height: 50%; - } - -#message { - height:144px; - width: 100%;/*554px;*/ - float:left; - margin: 4px; - color:black; - font-size:17px; - font-family:SindhiWeb,Verdana,GeezWeb,LaoWeb,TibetanWeb,MyanmarWeb,SinhalaWeb,TamilWeb,KhmerWeb,LatinWeb,OriyaWeb,EgyptianWeb !important; - } - - #font-size{ - display: none; - } - -/* KMW App Buttons */ - -#buttons { - float: right; - width: 40px; - margin: 8px 15px 8px 0px; - border: none; -} - -#buttons div { - /*width:50px;*/ - -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; - background: #eeeeee; - border: none; - margin: 0px 0px 4px 10px; - height:40px; - width: 41px; - padding: 0px; - padding-top: 2px; - background-repeat: no-repeat; - background-position: center center; - background-size: 34px 34px; - } - -#font{ - text-align: center; -} - -#font p{ - display: none; -} - -#buttons div:disabled { - cursor: default !important; - color: gray !important; - /*border-color: gray !important; */ - } - -#search,#search.links{ - background-image:url('../img/btn_google.png'); - -} - -#search.linksOff{ - background-image:url('../img/btn_google_white.png'); -} - -#copy,#copy.links{ - background-image:url('../img/btn_copy.png'); - -} - -#copy.linksOff{ - background-image:url('../img/btn_copy_white.png'); -} - -#buttons div * { - display:inline; - } - -#buttons p { /* buttons have no text label on mobiles */ - display:none; - } - -div.links { - cursor:pointer; - } - -div.linksOff { - cursor:default !important; - border:none; - /*border: 1px solid #cccccc !important; */ - } - -div.linksOff * { - color: gray; - -webkit-user-select:none; - } - -#mobile-font{ - display: none; - width: 40px; - border-radius: 4px; - position: absolute; - left: 100%; - top: 60px; - margin-left: -45px; - text-align: center; - font-size: 24pt; - background: #fff; -} - -#mobile-increase{ - height: 40px; - line-height: 40px; - border-bottom: solid 1px #000; -} - -#mobile-decrease{ - height: 40px; - line-height: 40px; -} - -/* Aside Elements */ -aside, aside div { - display:none; - } - -/* -=================== -==Footer Elements== -=================== -*/ -.footer,footer { - display:none; - } - -#mobile-footer { - position: fixed; - bottom: 0; - width: 100%; -} - -#mobile-footer #mobile-version { - font-size: 7pt; - text-align: center; - width: 100%; -} - -.messageBox { - box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -o-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -moz-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -khtml-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - background: #c4c4c4; - margin-left: 10%; - margin-top: 10%; - width: 80%; - height: 150px; - position: fixed; -} - -.messageBox div { - width: 85%; - height: 84px; - left: 5%; - top: 10px; - padding: 8px; - font-size: 13px; - position: absolute; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 3px; - background: white; -} - -.messageBox button { - width:83px; - position: absolute; - right: 10px; - bottom: 4px; - background: #414141; - border-top: 1px solid #383838; - border-right: 1px solid #1F1F1F; - border-bottom: 1px solid #151515; - border-left: 1px solid #1F1F1F; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -o-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - color: white; - font: bold 12px Helvetica, Verdana, Arial, sans-serif; - text-shadow: 0px -1px 1px #1E2D4D; - text-align:center; - margin: 0 auto 6px; - padding: 3px; - } - -.messageBox button:disabled { - cursor: default !important; - color: gray !important; - -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -o-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; -} - -.messageBox button:hover { - -webkit-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -moz-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -ms-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -o-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - cursor: pointer; -} - -.messageBox button:active { - -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - -o-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; -} - -.progressBox { - box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -o-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -moz-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -khtml-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - background: #c4c4c4; - top: 10%; - margin-left: 10%; - width: 80%; - height: 70px; - position: fixed; -} - -.progressBox div { - width: 85%; - height: 34px; - left: 5%; - top: 10px; - padding: 8px; - background: url('/img/wait.gif') no-repeat 354px 8px white; - font-size: 13px; - position: absolute; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 3px; -} - - /* Additional rules for portrait orientation */ -@media only screen and (orientation: portrait) { - - #message { - height: 170px; - } - - #messageContainer { - float: left; - width: 80%; - height: 40%; - } -} - - - /* Additional rules for landscape orientation */ -@media only screen and (orientation: landscape) { - - #messageContainer { - float: left; - width: 85%; - height: 50%; - } - #message { - height: 50%; - } - #buttons { - margin: 4px 15px 4px 0; - } - - #font{ - display: none; - } -} - -/* -====================== -==Keyboard Styling== -====================== -*/ - -#kmw-language-menu p { - color: #000 !important; -} - -#kmw-language-menu .selected { - background-color: gray !important; -} - - -.phone .kmw-keyboard-dari_clra .kmw-key-default .kmw-key-text { - top: -33%; - font-size: 0.8em !important; -} +/* KMW LIVE CSS for iPhone and other mobiles */ + +/* +====================== +==Universal Elements== +====================== +*/ + +:root { + --mobile-font-size: 12px; + --mobile-search-max-width: 250px; + --mobile-search-min-width: 50px; +} + +html { + overflow-y: scroll; + overflow-x: hidden; +} + +body { + width:100%;height:100%; + font-family: Verdana, Arial, Helvetica, sans-serif; + color:#2D2C2C; + background-color: #eeeeee; + margin:0px; + } + +a { + text-decoration:none; + color: #AD4A28; + } + +a:hover { + text-decoration:underline; + } + +h3 { + font-size:18px; + } + +p { + font-size:13px; + line-height:1.5em; + } + +/* +==================== +==Content Elements== +==================== +*/ + +/* KMW Main App */ +#app { + width: 100%; + margin: 0px; +} + +#KeymanWebControl { + display: none; +} + +#exampleBox, #example { + display: none; +} + +.main-header { + width: 100%; + grid-template-columns: 2fr 1fr; +} + +.left-header { + width: 70vw; +} + +.left-header img { + display: none; +} + +.right-header { + grid-template-columns: 50% 50%; +} + +.right-header { + width: 30vw; +} + +/* +Language Search box +*/ + +#searchBar { + width: 50%; +} + +#searchInput:focus, #searchDropdownMenu, #keyboardSelection:active { + width: var(--mobile-search-max-width) !important; +} + +#textArea { + height: 45vh !important; +} + +.mobile-font-size-container { + display: flex; + flex-direction: row; + position: absolute; + right: 50px; + top: 80px; + width: 150px; + background: white; + border: 1px solid black; + padding: 10px; + border-radius: 10px; +} + +/* Additional rules for portrait orientation */ +@media only screen and (orientation: portrait) { + + #message { + height: 170px; + } + + #messageContainer { + float: left; + width: 80%; + height: 40%; + } +} + +/* Additional rules for landscape orientation */ +@media only screen and (orientation: landscape) { + + #messageContainer { + float: left; + width: 85%; + height: 50%; + } + #message { + height: 50%; + } + #buttons { + margin: 4px 15px 4px 0; + } + #font { + display: none; + } +} + +/* +====================== +==Keyboard Styling== +====================== +*/ + +#kmw-language-menu p { + color: #000 !important; +} + +#kmw-language-menu .selected { + background-color: gray !important; +} + +.phone .kmw-keyboard-dari_clra .kmw-key-default .kmw-key-text { + top: -33%; + font-size: 0.8em !important; +} diff --git a/cdn/dev/css/kmw-tablet.css b/cdn/dev/css/kmw-tablet.css index d48202d..4b1c4da 100644 --- a/cdn/dev/css/kmw-tablet.css +++ b/cdn/dev/css/kmw-tablet.css @@ -1,526 +1,550 @@ -/* KMW LIVE CSS for iPad and other tablet devices */ - -/* -====================== -==Universal Elements== -====================== -*/ - -html { - overflow-y: scroll; - overflow-x: hidden; -} - -body { - width:100%; - font-family: Verdana, Arial, Helvetica, sans-serif; - color:#2D2C2C; - background-color: #eeeeee; - margin:0px; - } - -a { - text-decoration:none; - color: #AD4A28; - } - -a:hover { - text-decoration:underline; - } - -h3 { - font-size:18px; - } - -p { - font-size:13px; - line-height:1.5em; - } - -header, footer { - width:100%; - margin:0px auto; - /*clear: both;*/ - } - -hr { - display: none; - } - -.box { - -webkit-border-radius: 8px;-moz-border-radius: 8px; border-radius: 8px; - -moz-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); - } - -/* -=================== -==Header Elements== -=================== -*/ -header { - margin-top:0px; - } - -#headerLeft img { - display: block; /* default (inline) display inserts an unwanted bottom border */ - margin-top:0px; - height:60px; - /*-webkit-border-radius: 0px 0px 8px 8px; -moz-border-radius: 0px 0px 8px 8px; border-radius: 0px 0px 8px 8px;*/ - } - -header > div > img { - display: block; - width: 100%; - height: 8px; -} - -/* -==================== -==Content Elements== -==================== -*/ -#content { - width: 100%; /* specific for tablet and mobile */ - margin: 0px auto; - background-color: #eeeeee; - /*min-height:375px;*/ - } - - -/* KMW Main App */ -#app { - /*float:left;*/ - /*height:330px;*/ - width:100%; /*710px; */ - margin: 0px;/*30px 15px 15px;*/ - } - -#KeymanWebControl { - display: none; - } - -#exampleBox, #example { - display: none; - } - -#messageContainer { - width: 80%; - float:left; - } - -#message { - height:195px; - width: 100%;/*554px;*/ - float:left; - margin: 10px; - color:black; - font-size:17px; - font-family:SindhiWeb,Verdana,GeezWeb,LaoWeb,TibetanWeb,MyanmarWeb,SinhalaWeb,TamilWeb,KhmerWeb,LatinWeb,OriyaWeb,EgyptianWeb !important; - } - -/* KMW App Buttons */ - -#buttons { - float: right; - width:15%; - margin: 0px 20px; - margin-top: -6px; - } - -#buttons div { - width:140px; - -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; - background: #fff; - border: 1px solid #888888; - margin: 0px 10px; - padding: 3px; - padding-top: 9px; - height: 41px; - line-height: 36px; - background-repeat: no-repeat; - background-position: center left; - } - -#buttons div:disabled { - cursor: default !important; - color: gray !important; - border-color: gray !important; - } - -#buttons p{ - margin-left: 41px; -} - -#search.links, #search{ - background-image:url('../img/btn_google_small.png'); - -} - -#search.linksOff{ - background-image:url('../img/btn_google_small_white.png'); -} - -#copy.links, #copy{ - background-image:url('../img/btn_copy_small.png'); - -} - -#copy.linksOff{ - background-image:url('../img/btn_copy_small_white.png'); -} - -#buttons div * { - display:inline; - } - -div.links { - cursor:pointer; - } - -div.linksOff { - cursor:default !important; - border: 1px solid #cccccc !important; - } - -div.linksOff * { - color: gray; - -webkit-user-select:none; - } - -/* Aside Elements */ - -aside { - display:none; - } - -#font-size{ - display: none; -} - -/* - -#font, -=================== -==Footer Elements== -=================== -*/ -.footer, footer { - display: none; - background-color: #6A2915; - height:50px; - left:0px; - bottom:0px; - position: fixed; - /* -webkit-border-radius: 8px 8px 0px 0px; -moz-border-radius: 8px 8px 0px 0px; border-radius: 8px 8px 0px 0px; */ - } - -nav ul { - list-style: none outside none; - width:90%; - margin:0px auto; - padding:15px 0px; - } - -nav li { - display:inline; - padding:20px 39px; - } - -nav a { - color:#eee; - font-family:Tahoma; - font-weight:bold; - font-size:10.7px; - } - -.messageBox { - box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -o-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -moz-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -khtml-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - background: #c4c4c4; - position: fixed; - left: 50%; - top: 20%; - z-index: 999 !important; - margin-left: -250px; - margin-top: -100px; - width: 500px; - height: 200px; -} - -.messageBox div { - width: 464px; - height: 134px; - left: 10px; - top: 10px; - padding: 8px; - font-size: 13px; - position: absolute; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 3px; - background: white; -} - -.messageBox button { - width:83px; - position: absolute; - right: 10px; - bottom: 4px; - background: #414141; - border-top: 1px solid #383838; - border-right: 1px solid #1F1F1F; - border-bottom: 1px solid #151515; - border-left: 1px solid #1F1F1F; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -o-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - color: white; - font: bold 12px Helvetica, Verdana, Arial, sans-serif; - text-shadow: 0px -1px 1px #1E2D4D; - text-align:center; - margin: 0 auto 6px; - padding: 3px; - } - -.messageBox button:disabled { - cursor: default !important; - color: gray !important; - -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -o-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; -} - -.messageBox button:hover { - -webkit-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -moz-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -ms-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -o-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - cursor: pointer; -} - -.messageBox button:active { - -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - -o-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; -} - -.progressBox { - box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -o-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -moz-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -khtml-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - background: #c4c4c4; - position: fixed; - left: 50%; - top: 20%; - z-index: 999; - margin-left: -200px; - margin-top: -54px; - width: 400px; - height: 54px; -} - -.progressBox div { - width: 364px; - height: 18px; - left: 10px; - top: 10px; - padding: 8px; - background: url('../img/wait.gif') no-repeat 354px 8px white; - font-size: 13px; - position: absolute; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 3px; -} - -/* Elements modified for tablet */ -#headerBackground { - width: 100%; - background-color:white; -} - -#headerLeft { - float: left; - margin-left: 28px; -} - -#headerRight { - text-align: right; - height: 40px; - float: right; - padding-bottom: 33px; - padding-right: 10px; -} - -#headerRight-beta { - display: block; - font-weight: bold; - color: red; - font-size: 16pt; - padding: 16px 12px 0; -} - -#headerRight-link { - padding: 0 12px 0; -} - - -#instructions { - margin:10px; - font:12pt Helvetica,Verdana,Arial,sans-serif; - color: white; -} - -/* Additional rules for portrait orientation */ -@media only screen and (orientation: landscape) { - #buttons{ - padding-top: 11px; - } - #buttons div { - margin: 4px 20px 10px 0px; - padding: 0px; - } - #font span:first-child{ - margin-left: 3px; - } - #font p{ - margin-left: 8px; - position: relative; - top: -5px; - } - #mobile-font{ - display: none; - width: 136px; - border-radius: 4px; - position: absolute; - left: 100%; - top: 136px; - margin-left: -170px; - text-align: center; - font-size: 24pt; - background: #fff; - } - - #mobile-increase{ - height: 40px; - line-height: 40px; - border-bottom: solid 1px #000; - } - - #mobile-decrease{ - height: 40px; - line-height: 40px; - } -} - -/* Additional rules for portrait orientation */ -@media only screen and (orientation: portrait) { - - #app { - width: 97%; - } - - #message { - height: 350px; - } - - #messageContainer { - width: 100%; - } - - #buttons { - clear:both; - width: 90%; - } - - #buttons div { - display: inline-block; - margin: 10px 10px 0; - width: 130px; - height: 40px; - } - - #font{ - position: relative; - top: 4px; - } - - #font span:first-child{ - margin-left: 3px; - } - - #font p{ - margin-left: 8px; - position: relative; - top: -4px; - } - - #mobile-font{ - display: none; - width: 301px; - position: absolute; - left: 50%; - top: 452px; - margin-left: -155px; - text-align: center; - font-size: 24pt; - } - - #mobile-increase{ - float: right; - width: 136px; - height: 53px; - line-height: 53px; - background: #fff; - border: 1px solid #888888; - border-radius: 4px; - } - - #mobile-decrease{ - float: right; - width: 136px; - height: 53px; - line-height: 53px; - background: #fff; - border: 1px solid #888888; - margin-right: 25px; - border-radius: 4px; - } -} - -/* -====================== -==Keyboard Styling== -====================== -*/ - -#kmw-language-menu p { - color: #000 !important; -} - -#kmw-language-menu .selected { - background-color: gray !important; -} - -.tablet .kmw-keyboard-dari_clra .kmw-key-default .kmw-key-text { - top: -33%; -} +/* KMW LIVE CSS for iPad and other tablet devices */ + +/* +====================== +==Universal Elements== +====================== +*/ + +html { + overflow-y: scroll; + overflow-x: hidden; +} + +body { + width:100%; + font-family: Verdana, Arial, Helvetica, sans-serif; + color:#2D2C2C; + background-color: #eeeeee; + margin:0px; + } +section { + background-color: darkred; +} + +a { + text-decoration:none; + color: #AD4A28; + } + +a:hover { + text-decoration:underline; + } + +h3 { + font-size:18px; + } + +p { + font-size:13px; + line-height:1.5em; + } + +header, footer { + width:100%; + margin:0px auto; + /*clear: both;*/ + } + +hr { + display: none; + } + +.box { + -webkit-border-radius: 8px;-moz-border-radius: 8px; border-radius: 8px; + -moz-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); + } + +/* +=================== +==Header Elements== +=================== +*/ +header { + margin-top:0px; + } + +#headerLeft img { + display: block; /* default (inline) display inserts an unwanted bottom border */ + margin-top:0px; + height:60px; + /*-webkit-border-radius: 0px 0px 8px 8px; -moz-border-radius: 0px 0px 8px 8px; border-radius: 0px 0px 8px 8px;*/ + } + +header > div > img { + display: block; + width: 100%; + height: 8px; +} + + +/* Expanding the search box */ +/* @media screen and (940px <= width <= 1045px) { + .main-header { + grid-template-columns: 2fr 1fr 1fr; + } +} */ + +.main-header { + width: 100%; + grid-template-columns: 3fr 1fr; +} + +.left-header { + width: 70vw; +} + +.right-header { + width: 300px; +} + +/* +==================== +==Content Elements== +==================== +*/ +#content { + width: 100%; /* specific for tablet and mobile */ + margin: 0px auto; + background-color: #eeeeee; + /*min-height:375px;*/ + } + + +/* KMW Main App */ +#app { + /*float:left;*/ + /*height:330px;*/ + width:100%; /*710px; */ + margin: 0px;/*30px 15px 15px;*/ + } + +#KeymanWebControl { + display: none; + } + +#exampleBox, #example { + display: none; + } + +#messageContainer { + width: 80%; + float:left; + } + +#message { + height:195px; + width: 100%;/*554px;*/ + float:left; + margin: 10px; + color:black; + font-size:17px; + font-family:SindhiWeb,Verdana,GeezWeb,LaoWeb,TibetanWeb,MyanmarWeb,SinhalaWeb,TamilWeb,KhmerWeb,LatinWeb,OriyaWeb,EgyptianWeb !important; + } + +/* KMW App Buttons */ + +#buttons { + float: right; + width:15%; + margin: 0px 20px; + margin-top: -6px; + } + +#buttons div { + width:140px; + -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; + background: #fff; + border: 1px solid #888888; + margin: 0px 10px; + padding: 3px; + padding-top: 9px; + height: 41px; + line-height: 36px; + background-repeat: no-repeat; + background-position: center left; + } + +#buttons div:disabled { + cursor: default !important; + color: gray !important; + border-color: gray !important; + } + +#buttons p{ + margin-left: 41px; +} + +#search.links, #search{ + background-image:url('../img/btn_google_small.png'); + +} + +#search.linksOff{ + background-image:url('../img/btn_google_small_white.png'); +} + +#copy.links, #copy{ + background-image:url('../img/btn_copy_small.png'); + +} + +#copy.linksOff{ + background-image:url('../img/btn_copy_small_white.png'); +} + +#buttons div * { + display:inline; + } + +div.links { + cursor:pointer; + } + +div.linksOff { + cursor:default !important; + border: 1px solid #cccccc !important; + } + +div.linksOff * { + color: gray; + -webkit-user-select:none; + } + +/* Aside Elements */ + +aside { + display:none; + } + +#font-size{ + display: none; +} + +/* + +#font, +=================== +==Footer Elements== +=================== +*/ +.footer, footer { + display: none; + background-color: #6A2915; + height:50px; + left:0px; + bottom:0px; + position: fixed; + /* -webkit-border-radius: 8px 8px 0px 0px; -moz-border-radius: 8px 8px 0px 0px; border-radius: 8px 8px 0px 0px; */ + } + +nav ul { + list-style: none outside none; + width:90%; + margin:0px auto; + padding:15px 0px; + } + +nav li { + display:inline; + padding:20px 39px; + } + +nav a { + color:#eee; + font-family:Tahoma; + font-weight:bold; + font-size:10.7px; + } + +.messageBox { + box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); + -o-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); + -moz-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); + -khtml-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); + background: #c4c4c4; + position: fixed; + left: 50%; + top: 20%; + z-index: 999 !important; + margin-left: -250px; + margin-top: -100px; + width: 500px; + height: 200px; +} + +.messageBox div { + width: 464px; + height: 134px; + left: 10px; + top: 10px; + padding: 8px; + font-size: 13px; + position: absolute; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -ms-border-radius: 4px; + -o-border-radius: 4px; + border-radius: 3px; + background: white; +} + +.messageBox button { + width:83px; + position: absolute; + right: 10px; + bottom: 4px; + background: #414141; + border-top: 1px solid #383838; + border-right: 1px solid #1F1F1F; + border-bottom: 1px solid #151515; + border-left: 1px solid #1F1F1F; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -ms-border-radius: 4px; + -o-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + -o-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + color: white; + font: bold 12px Helvetica, Verdana, Arial, sans-serif; + text-shadow: 0px -1px 1px #1E2D4D; + text-align:center; + margin: 0 auto 6px; + padding: 3px; + } + +.messageBox button:disabled { + cursor: default !important; + color: gray !important; + -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; + -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; + -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; + -o-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; + box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; +} + +.messageBox button:hover { + -webkit-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + -moz-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + -ms-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + -o-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + cursor: pointer; +} + +.messageBox button:active { + -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; + -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; + -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; + -o-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; + box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; +} + +.progressBox { + box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); + -o-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); + -moz-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); + -khtml-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); + background: #c4c4c4; + position: fixed; + left: 50%; + top: 20%; + z-index: 999; + margin-left: -200px; + margin-top: -54px; + width: 400px; + height: 54px; +} + +.progressBox div { + width: 364px; + height: 18px; + left: 10px; + top: 10px; + padding: 8px; + background: url('../img/wait.gif') no-repeat 354px 8px white; + font-size: 13px; + position: absolute; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -ms-border-radius: 4px; + -o-border-radius: 4px; + border-radius: 3px; +} + +/* Elements modified for tablet */ +#headerBackground { + width: 100%; + background-color:white; +} + +#headerLeft { + float: left; + margin-left: 28px; +} + +#headerRight { + text-align: right; + height: 40px; + float: right; + padding-bottom: 33px; + padding-right: 10px; +} + +#headerRight-beta { + display: block; + font-weight: bold; + color: red; + font-size: 16pt; + padding: 16px 12px 0; +} + +#headerRight-link { + padding: 0 12px 0; +} + + +#instructions { + margin:10px; + font:12pt Helvetica,Verdana,Arial,sans-serif; + color: white; +} + +/* Additional rules for portrait orientation */ +@media only screen and (orientation: landscape) { + #buttons{ + padding-top: 11px; + } + #buttons div { + margin: 4px 20px 10px 0px; + padding: 0px; + } + #font span:first-child{ + margin-left: 3px; + } + #font p{ + margin-left: 8px; + position: relative; + top: -5px; + } + #mobile-font{ + display: none; + width: 136px; + border-radius: 4px; + position: absolute; + left: 100%; + top: 136px; + margin-left: -170px; + text-align: center; + font-size: 24pt; + background: #fff; + } + + #mobile-increase{ + height: 40px; + line-height: 40px; + border-bottom: solid 1px #000; + } + + #mobile-decrease{ + height: 40px; + line-height: 40px; + } +} + +/* Additional rules for portrait orientation */ +@media only screen and (orientation: portrait) { + + #app { + width: 97%; + } + + #message { + height: 350px; + } + + #messageContainer { + width: 100%; + } + + #buttons { + clear:both; + width: 90%; + } + + #buttons div { + display: inline-block; + margin: 10px 10px 0; + width: 130px; + height: 40px; + } + + #font{ + position: relative; + top: 4px; + } + + #font span:first-child{ + margin-left: 3px; + } + + #font p{ + margin-left: 8px; + position: relative; + top: -4px; + } + + #mobile-font{ + display: none; + width: 301px; + position: absolute; + left: 50%; + top: 452px; + margin-left: -155px; + text-align: center; + font-size: 24pt; + } + + #mobile-increase{ + float: right; + width: 136px; + height: 53px; + line-height: 53px; + background: #fff; + border: 1px solid #888888; + border-radius: 4px; + } + + #mobile-decrease{ + float: right; + width: 136px; + height: 53px; + line-height: 53px; + background: #fff; + border: 1px solid #888888; + margin-right: 25px; + border-radius: 4px; + } +} + +/* +====================== +==Keyboard Styling== +====================== +*/ + +#kmw-language-menu p { + color: #000 !important; +} + +#kmw-language-menu .selected { + background-color: gray !important; +} + +.tablet .kmw-keyboard-dari_clra .kmw-key-default .kmw-key-text { + top: -33%; +} diff --git a/cdn/dev/css/kmw.css b/cdn/dev/css/kmw.css index 02c9c07..8e80256 100644 --- a/cdn/dev/css/kmw.css +++ b/cdn/dev/css/kmw.css @@ -1,78 +1,78 @@ -/* -============= -==Reset CSS== -============= -*/ -html, body, div, span, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -abbr, address, cite, code, -del, dfn, em, img, ins, kbd, q, samp, -small, strong, sub, sup, var, -b, i, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, figcaption, figure, -footer, header, hgroup, menu, nav, section, summary, -time, mark, audio, video { - margin:0; - padding:0; - border:0; - outline:0; - vertical-align:baseline; - background:transparent; - } - -a { - margin:0; - padding:0; - vertical-align:baseline; - background:transparent; - } - -article,aside,details,figcaption,figure, -section,header,footer,hgroup,menu,nav { - display:block; - } - -ins { - background-color:#ff9; - text-decoration:none; - } - -mark { - background-color:#ff9; - font-weight:bold; - } - -del { - text-decoration: line-through; - } - -abbr[title], dfn[title] { - border-bottom:1px dotted; - cursor:help; - } - -table { - border-collapse:collapse; - border-spacing:0; - } - -hr { - display:block; - height:1px; - border:0; - border-top:1px solid #cccccc; - padding:0; -} - -button, input, select { - vertical-align:middle; -} - -/* === End of CSS reset rules === */ - -ins.adsbygoogle { - display: none !important; -} +/* +============= +==Reset CSS== +============= +*/ +html, body, div, span, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +abbr, address, cite, code, +del, dfn, em, img, ins, kbd, q, samp, +small, strong, sub, sup, var, +b, i, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, figcaption, figure, +footer, header, hgroup, menu, nav, section, summary, +time, mark, audio, video { + margin:0; + padding:0; + border:0; + outline:0; + vertical-align:baseline; + background:transparent; + } + +a { + margin:0; + padding:0; + vertical-align:baseline; + background:transparent; + } + +article,aside,details,figcaption,figure, +section,header,footer,hgroup,menu,nav { + display:block; + } + +ins { + background-color:#ff9; + text-decoration:none; + } + +mark { + background-color:#ff9; + font-weight:bold; + } + +del { + text-decoration: line-through; + } + +abbr[title], dfn[title] { + border-bottom:1px dotted; + cursor:help; + } + +table { + border-collapse:collapse; + border-spacing:0; + } + +hr { + display:block; + height:1px; + border:0; + border-top:1px solid #cccccc; + padding:0; +} + +button, input, select { + vertical-align:middle; +} + +/* === End of CSS reset rules === */ + +ins.adsbygoogle { + display: none !important; +} diff --git a/cdn/dev/js/kmwBody.js b/cdn/dev/js/kmwBody.js index 77c0f2b..d0f800a 100644 --- a/cdn/dev/js/kmwBody.js +++ b/cdn/dev/js/kmwBody.js @@ -1,173 +1,118 @@ -document.addEventListener('DOMContentLoaded', function() { - // Define the divider, text area and keyboard - const divider = document.getElementById('Divider') - const resizer = divider.querySelector('#resizeGrip') - let prevElement = divider.previousElementSibling.querySelector('.text-area'); - let nextElement = divider.nextElementSibling; - let isResizing = false; - - // Define the heights of text area, keyboard, and the vertical screen - let prevElementHeight = 0; - let prevElementWidth = 0; - let verticalViewport = 0; - - const mouseDownHandler = (e) => { - e.preventDefault(); - resizer.style.cursor = 'grabbing' - isResizing = true - - // Get the Y coordinate of mouse click & Text Area + Keyboard heights - prevElementHeight = prevElement.getBoundingClientRect().height; - prevElementWidth = prevElement.getBoundingClientRect().width; - verticalViewport = e.clientY; - - document.addEventListener('mousemove', mouseMoveHandler) - document.addEventListener('mouseup', mouseUpHandler) - } - const mouseUpHandler = () => { - resizer.style.removeProperty('cursor') - isResizing = false - } - - const mouseMoveHandler = function (e) { - if (!isResizing) return; - // Calculate the cursor movement - let value = e.clientY - verticalViewport - let clientX = e.clientX - calcElementSize(value, clientX) - } - - function calcElementSize(val, x) { - // Get the dynamic heights of both elements - let newPrevHeight = prevElementHeight + val; - let newNextWidth = (x / prevElementWidth) * 150; - - // Define minimum and maximum heights - const minPrevHeight = 150; - const maxPrevHeight = window.innerHeight * 0.8; - const minNextWidth = 50; - const maxNextWidth = 80; - - // Ensure the heights do need exceed the define heights - newPrevHeight = Math.max(minPrevHeight, Math.min(newPrevHeight, maxPrevHeight)); - newNextWidth = Math.max(minNextWidth, Math.min(newNextWidth, maxNextWidth)); - - // Update the heights of Prev and Next Elements - prevElement.style.height = `${newPrevHeight}px` - - if (newPrevHeight >= maxPrevHeight) { - fullScreenSize() - } else if (newPrevHeight < maxPrevHeight) { - divider.style.display = "grid" - nextElement.style.display = "flex" - } - } - - /* Hide-Show Keyboard */ - const hideKeyboardBtn = document.querySelector('#hideKeyboard') - - let isTextAreaFullHeight = true - const fullHeightTextArea = window.innerHeight * 0.9 - const defaultHeightTextArea = window.innerHeight * 0.3 - - function defaultSize() { - prevElement.style.height= `${defaultHeightTextArea}px` - isTextAreaFullHeight = true - } - - function fullScreenSize() { - prevElement.style.height = `${fullHeightTextArea}px` - isTextAreaFullHeight = false - } - - hideKeyboardBtn.addEventListener('click', () => { - if (!isTextAreaFullHeight) { - defaultSize() - } else { - fullScreenSize() - } - }) - window.onresize = updateSize - // Detect desktop browser height and modify css - function updateSize() { - // Set OSK size/position - p = new Object(); - - var height = $(window).height(); - var width = $(window).width(); - var appPos = $('#textAndKeyboardSection').position(); - var appLeft = appPos.left; - - // We can't proceed any further if KMW hasn't loaded yet. - // No point handling resizes until that's occurred. - if(!getKeymanWeb() || !getKeymanWeb().osk) { - return; - } - - // Adjust the message box height only if a desktop browser - if(!getKeymanWeb().util.isTouchDevice()) - { - if (height <= 768) { - $('#textArea').css('height', '209px'); - p['height'] = 264; - } - - if(height > 768) { - $('#textArea').css('height', '260px'); - if (height < 820) { - p['height'] = 246; - } - else if(height < 860) { - p['height'] = 246; - } - else{ - p['height'] = 264; - } - } - } - - p['top'] = $('#textAndKeyboardSection').offset().top + $('#textAndKeyboardSection').outerHeight() + 8; - p['left'] = appLeft + 15; - p['width'] = 710; - - // Update keyboard position and size - getKeymanWeb().osk.setRect(p); - } - - // Copy tool - const copyBtn = document.querySelector('#copyTool') - const textArea = document.querySelector('#textArea') - copyBtn.addEventListener('click', async function() { - try { - let textToCopy = textArea.value.trim() - - if(!textToCopy) { - copyBtn.classList.replace('fa-copy', 'fa-xmark') - // copyBtn.textContent = ' No characters to copy' - setTimeout(() => { - copyBtn.classList.replace('fa-xmark', 'fa-copy') - copyBtn.textContent = '' - }, 3000) - return; - } - - await navigator.clipboard.writeText(textToCopy) - - copyBtn.classList.replace('fa-copy', 'fa-check'); - - setTimeout(() => { - copyBtn.classList.replace('fa-check', 'fa-copy'); - }, 1000); - - } catch (error) { - console.error('Failed to copy: ', error) - } - }) - - const fontSliderBtn = document.querySelector('#fontSizeRange') - fontSliderBtn.addEventListener('input', function() { - textArea.style.fontSize = `${this.value}px` - }) - defaultSize() - resizer.addEventListener('mousedown', mouseDownHandler) +document.addEventListener('DOMContentLoaded', function() { + // Define the divider, text area and keyboard + const container = document.querySelector('.container-flex') + const divider = document.getElementById('Divider') + + const resizer = divider.querySelector('#resizeGrip') + const prevElementOfResizer = divider.previousElementSibling.querySelector('.text-area') + const nextElementOfResizer = divider.nextElementSibling + + let isResizing = false; + + let startY, startHeightTop, startHeightBottom = 0 + + const mouseDownHandler = (e) => { + e.preventDefault(); + resizer.style.cursor = 'grabbing' + isResizing = true + + startY = e.clientY + startHeightTop = prevElementOfResizer.offsetHeight + startHeightBottom = nextElementOfResizer.offsetHeight + + document.addEventListener('mousemove', mouseMoveHandler) + document.addEventListener('mouseup', mouseUpHandler) + } + + const mouseUpHandler = () => { + resizer.style.removeProperty('cursor') + isResizing = false + document.removeEventListener('mousemove', mouseMoveHandler) + } + + const mouseMoveHandler = function (e) { + if (!isResizing) return; + + let deltaY = e.clientY - startY // Get up or down direction + + let newTopHeight = startHeightTop + deltaY + let newBottomHeight = startHeightBottom - deltaY + + newTopHeight = Math.max(100, Math.min(newTopHeight, window.innerHeight * 0.8)) + newBottomHeight = Math.max(100, Math.min(newBottomHeight, window.innerHeight * 0.7)) + + prevElementOfResizer.style.height = `${newTopHeight}px` + nextElementOfResizer.style.height = `${newBottomHeight}px` + + if (newBottomHeight <= 200) { + fullScreenSize() + } + } + + /* Hide-Show Keyboard */ + const hideKeyboardBtn = document.querySelector('#hideKeyboard') + + let isTextAreaFullHeight = false + const fullHeightTextArea = window.innerHeight * 0.9 + const defaultHeightTextArea = window.innerHeight * 0.3 + + function defaultSize() { + prevElementOfResizer.style.height = `${defaultHeightTextArea}px` + nextElementOfResizer.style.height = `500px` + // nextElementOfResizer.style.width = `900px` + isTextAreaFullHeight = false + } + + function fullScreenSize() { + prevElementOfResizer.style.height = `${fullHeightTextArea}px` + isTextAreaFullHeight = true + } + + hideKeyboardBtn.addEventListener('click', () => { + if (isTextAreaFullHeight) { + defaultSize() + } else { + fullScreenSize() + } + }) + + // Copy tool + const copyBtn = document.querySelector('#copyTool') + const textArea = document.querySelector('#textArea') + copyBtn.addEventListener('click', async function() { + try { + let textToCopy = textArea.value.trim() + + if(!textToCopy) { + copyBtn.classList.replace('fa-copy', 'fa-xmark') + // copyBtn.textContent = ' No characters to copy' + setTimeout(() => { + copyBtn.classList.replace('fa-xmark', 'fa-copy') + copyBtn.textContent = '' + }, 3000) + return; + } + + await navigator.clipboard.writeText(textToCopy) + + copyBtn.classList.replace('fa-copy', 'fa-check'); + + setTimeout(() => { + copyBtn.classList.replace('fa-check', 'fa-copy'); + }, 1000); + + } catch (error) { + console.error('Failed to copy: ', error) + } + }) + + // Font slider + const fontSliderBtn = document.querySelector('#fontSizeRange') + fontSliderBtn.addEventListener('input', function() { + textArea.style.fontSize = `${this.value}px` + }) + + defaultSize() + + resizer.addEventListener('mousedown', mouseDownHandler) }) \ No newline at end of file diff --git a/cdn/dev/js/kmwElements.js b/cdn/dev/js/kmwElements.js new file mode 100644 index 0000000..849f8ae --- /dev/null +++ b/cdn/dev/js/kmwElements.js @@ -0,0 +1,36 @@ +const calcScreenSize = Math.min(screen.width, screen.height) > 720 ? 'tablet' : 'mobile' + +const searchBox = document.getElementById('searchInput') +const fontSizeContainer = document.getElementsByClassName('font-size-container') +const kbSelectionBtn = document.getElementById('keyboardSelectionButton') +const searchIcon = document.getElementById('searchIcons') + +const fontSizeElements = ` +
    + A + + A +
    ` + +if (calcScreenSize == 'tablet') { + +} + +if (calcScreenSize == 'mobile') { + const firstChild = fontSizeContainer[0].children[0] + const secondChild = fontSizeContainer[0].children[1] + firstChild.remove() + secondChild.remove() + + searchBox.addEventListener('click', () => { + kbSelectionBtn.style.display = 'none' + searchIcon.style.left = '200px' + }) +} + +const fontSizeChild = fontSizeContainer[0].children[0] +fontSizeChild.addEventListener('click', () => { + fontSizeChild.innerHTML = fontSizeElements +}) + + diff --git a/cdn/dev/js/kmwHeader.js b/cdn/dev/js/kmwHeader.js index 5687861..c9a76d4 100644 --- a/cdn/dev/js/kmwHeader.js +++ b/cdn/dev/js/kmwHeader.js @@ -1,1166 +1,1356 @@ -keyman = getKeymanWeb() - -function getKeymanWeb() { - if(window.tavultesoft) { - return window.tavultesoft.keymanweb; - } - return window.keyman; -} -/* Global Variables */ -let selectedKbList = [] // Main array for the search, kb selection...etc. -let dataKbForRemoval // For History search -let kmwLang = keyman.getActiveLanguage() -let kmwKb = keyman.getActiveKeyboard() - -const clearSearchIcon = document.querySelector('#clearSearchIcon') -const magnifying = document.querySelector('#magnifyingGlassIcon') - -const elements = { - worldMapBtn: document.querySelector('#worldMap'), - kmwControls: document.querySelector('#KeymanWebControl'), - - kbSelection: document.querySelector('#keyboardSelection'), - keyboardSelectionButton: document.querySelector('#keyboardSelectionButton'), - caretRightIcon: keyboardSelectionButton.querySelector('.fa-caret-right'), - - searchBar: document.querySelector('#searchBar'), - searchInput: document.querySelector('#searchInput'), - searchDropdownMenu: document.querySelector('#searchDropdownMenu'), - searchIcons: document.querySelector('#searchIcons'), -} - -const state = { - mapIsOpen: false -} - -/* - ===================================== Default keyboard ========================================= -*/ - -function defaultKeyboard(kbdname = "basic_kbdus", languageCode = "en") { - if(!exists(kbdname, languageCode)) { - if (textArea) textArea.placeholder = 'A Keyboard name isn\'t specified. Select a keyboard and start typing' - return - } - setKeyboardWithDirection(kbdname, languageCode) -} - -/* - ============================= Toggle between World Map and Search ============================== -*/ -elements.worldMapBtn?.addEventListener('click', (e) => { - e.preventDefault() - state.mapIsOpen = true - if (state.mapIsOpen == true) { - openMap() - keyman.addEventListener('keyboardchange', () => { - location.replace(`#${keyman.getActiveLanguage()},${keyman.getActiveKeyboard()}`) - updateExample(keyman.getActiveKeyboard()) - }) - } else { - openSearch() - } -}) - -function openSearch() { - state.mapIsOpen = false - hideEls( - elements.kmwControls, - ) - showEls( - elements.searchDropdownMenu, - elements.searchIcons - ) - - if (selectedKbList.length > 0) { - elements.caretRightIcon.textContent = selectedKbList.length - removeClass(elements.caretRightIcon, 'fa-magnifying-glass') - } else { - elements.caretRightIcon.textContent = '' - elements.caretRightIcon.classList.add('fa-caret-right') - } - - elements.searchBar.replaceChildren( - elements.searchInput, - elements.searchIcons, - elements.searchDropdownMenu - ) -} - -function openMap() { - state.mapIsOpen = true - removeClass( - elements.kmwControls, 'hidden', - elements.caretRightIcon, 'fa-caret-right' - ) - hideEls( - elements.searchDropdownMenu - ) - removeTextContent( - elements.caretRightIcon - ) - elements.keyboardSelectionButton.removeAttribute('id', 'keyboardSelectionButton') - elements.keyboardSelectionButton.setAttribute('id', 'returnToSearchButton') - elements.caretRightIcon.classList.add('fa-magnifying-glass') - elements.keyboardSelectionButton.style.backgroundColor = "var(--keyman-orange)" - elements.keyboardSelectionButton.style.border = '0px' - elements.keyboardSelectionButton.classList.add('return-to-search') - elements.kbSelection.style.display = "none" - elements.searchBar.replaceChildren( - elements.kmwControls - ) -} - -function returnToSearch() { - elements.keyboardSelectionButton.removeAttribute('id', 'returnToSearchButton') - elements.keyboardSelectionButton.setAttribute('id', 'keyboardSelectionButton') - - if ((selectedKbList?.length || 0) < 1) { - elements.caretRightIcon.classList.add('fa-caret-right') - removeClass(elements.caretRightIcon, 'fa-magnifying-glass') - elements.caretRightIcon.textContent = '' - } - - elements.keyboardSelectionButton.style.backgroundColor = "" - elements.kbSelection.style.display = "block" - openSearch() -} - -function waitForElement(selector) { - return new Promise((resolve) => { - const interval = setInterval(() => { - const element = document.querySelector(selector) - if (element) { - clearInterval(interval) - resolve(element) - } - }, 100) - }) -} - -waitForElement('#returnToSearchButton').then((element) => { - element.addEventListener('click', (e) => { - e.preventDefault() - returnToSearch() - }) -}) - -waitForElement(".kmw-osk-frame").then((oskDiv) => { - document.querySelector('.keyboard-area').appendChild(oskDiv) -}) - -/* - ==================== Search Interaction =================== -*/ - -/* Search Input */ -const dropdown = new bootstrap.Dropdown(elements.searchInput, { - autoClose: 'outside' -}) - -document.addEventListener('click', (e) => { - if (!elements.searchInput.contains(e.target) && !elements.searchDropdownMenu.contains(e.target)) { - dropdown.hide() - } -}) - -elements.searchInput.addEventListener('click', (e) => { - e.stopPropagation() - // defaultKeyboard() - dropdown.show() -}) - -// Hide Dropdown Search on Mouse leave -elements.searchDropdownMenu.addEventListener('mouseleave', (e) => { - e.preventDefault() - dropdown.hide() -}) - -/* - =========================== Utility functions ============================ -*/ -function hideEls(...elements) { - return elements.every(el => el.classList.add('hidden')) -} - -function showEls(...elements) { - return elements.every(el => el.classList.remove('hidden')) -} - -function removeClass(element, className) { - return element.classList.remove(className) -} - -function removeTextContent(...elements) { - return elements.every(el => el.textContent = '') -} - -/* Elements validation */ -function exists(...elements) { - return elements.every(el => el != null) -} - -document.addEventListener('DOMContentLoaded', () => { - defaultKeyboard() - /* UI Behavior of the Selected Keyboard menu */ - if (exists(elements)) { - elements.keyboardSelectionButton.addEventListener('mouseenter', () => { - elements.kbSelection.classList.add('open') - }) - elements.keyboardSelectionButton.addEventListener('click', () => { - elements.kbSelection.classList.remove('open') - }) - elements.kbSelection.addEventListener('mouseleave', () => { - elements.kbSelection.classList.remove('open') - }) - } -}) - -/* - === Keyboard Execution === -*/ -const downloadBtn = document.getElementById('kbDownloadPage') -const textArea = document.getElementById('textArea') -let langExamples = []; - -function selectKb(kbdname, languageCode) { - if(!exists(kbdname, languageCode)) { - if (textArea) textArea.placeholder = 'A Keyboard name isn\'t specified. Select a keyboard and start typing' - return - } - setKeyboardWithDirection(kbdname, languageCode) -} - -function setTextDirection(targetEls, dir) { - const copyBtn = document.querySelector('#copyTool') - - targetEls.dir = dir - if (dir == 'rtl') { - copyBtn.style.right = '0' - copyBtn.style.left = '10px' - } else { - copyBtn.style.right = '' - copyBtn.style.left = '' - } -} - -// Change and type keyboard -async function setKeyboardWithDirection(kbdname, languageCode) { - const kbSpan = document.querySelector('#kbSpan') - const langTag = `#${languageCode}` - let kbTag = '' - - if (kbdname.match(/Keyboard_*/)) { - kbTag = `${kbdname}` - } else { - kbTag = `Keyboard_${kbdname}` - } - - location.replace(`${langTag},${kbTag}`) - - await keyman.addKeyboards(kbdname) - const kbd = keyman.getKeyboard(kbdname, languageCode) - await keyman.setActiveKeyboard(kbdname, languageCode) - - if(kbd) { - textArea.placeholder = `The ${kbdname} keyboard is selected. Start typing...` - kbSpan.innerHTML = `${kbdname}` - - setTextDirection(textArea, textArea.dir) - } - updateExample(kbdname) - if(typeof(KeyboardChange_EmbedFonts) != 'undefined') KeyboardChange_EmbedFonts(kbdname) -} - -/* Language Examples AJAX */ -async function updateExample(kbdname) { - const keymanExample = document.getElementById("example") - const exampleBox = document.getElementById("exampleBox") - - if (!keymanExample || !exampleBox) return false; - - if(kbdname == '') - { - keymanExample.textContent = `No example is available due to empty Keyboard name.` - return true; - } - - let activeLanguage = keyman.getActiveLanguage(); - - if(langExamples[activeLanguage + '_' + kbdname]) - { - keymanExample.innerHTML = langExamples[activeLanguage + '_' + kbdname]; - return true; - } - - langExamples[activeLanguage + '_' + kbdname] = 'Loading...'; - keymanExample.innerHTML = 'Loading...'; - - const link = `/prog/languageexample.php?keyboard=${kbdname}&language=${activeLanguage}`; - try { - const response = await fetch(link); - if(response.status == 200) { - const content = await response.text(); - - langExamples[activeLanguage + '_' + kbdname] = keymanExample.innerHTML = content; - } else { - throw new Error(`Unable to retrieve content, status was ${response.status}: ${response.statusText}`); - } - } catch(e) { - langExamples[activeLanguage + '_' + kbdname] = keymanExample.innerHTML = 'Error retrieving example: '+e.message; - throw e; - } -} - -/* Search */ -const kbSearchCard = document.getElementById('kbSearchCardUI'); -let debounceTimer - -/* Pagination */ -prevBtn = document.getElementById('prevPage') -nextBtn = document.getElementById('nextPage') -pageInfo = document.getElementById('pageInfo') - -searchResultCount = document.getElementById('resultCount') -paginationCtrl = document.getElementById('paginationControls') - -let currentPage = 1 -let currentQuery = '' -let totalPage -const itemPerPage = 10 - -prevBtn.addEventListener('click', goPrevPage) -nextBtn.addEventListener('click', goNextPage) - -function updatePaginationCtrl() { - pageInfo.textContent = `${currentPage} of ${totalPage}` - nextBtn.disabled = currentPage >= totalPage - prevBtn.disabled = currentPage <= 1 -} - -function goPrevPage() { - if (currentPage > 1) { - currentPage-- - searchKeyboard(currentQuery, currentPage) - } -} - -function goNextPage() { - if (currentPage < totalPage) { - currentPage++ - searchKeyboard(currentQuery, currentPage) - } -} - -/* Click: Open Search and Display search instructions */ -elements.searchInput.addEventListener('click', function(e) { - const query = e.target.value.trim() - if (query == "") { - resetSearch() - } else { - searchKeyboard(query) - } -}) - -/* Input: Search and Display keyboards */ -elements.searchInput.addEventListener('input', function(e) { - handleSearch(e.target.value) -}) - -clearSearchIcon.addEventListener('click', () => { - elements.searchInput.value = '' - handleSearch() - elements.searchInput.focus() -}) - -function handleSearch(value = "") { - currentQuery = value.trim() - currentPage = 1 - - updateSearchIcon(value) - - if (!currentQuery) { - resetSearch() - return - } - debounceSearch(currentQuery, currentPage) -} - -function resetSearch() { - paginationCtrl.style.display = 'none' - defaultSearch() -} - -function updateSearchIcon(value) { - const hasValue = value.length > 0 - magnifying.style.display = hasValue ? 'none' : 'inline' - clearSearchIcon.style.display = hasValue ? 'inline' : 'none' -} - -function debounceSearch(query, page) { - clearTimeout(debounceTimer) - if (query.length > 1) { - debounceTimer = setTimeout(() => { - searchKeyboard(query, page) - }, 300) - } -} - -/* == Section == - Search -*/ - -/* Display top downloads with search Instruction */ -async function defaultSearch() { - kbSearchCard.innerHTML = `

    Loading...

    ` - try { - let response = await fetch(`https://api.keyman.com/search/2.0?q=p:popular`) - if (!response.ok) { - throw new Error(`API request failed with status ${response.status}`) - } - - let data = await response.json() - - let mostDownloadkb = data.keyboards - - if (!mostDownloadkb || !Array.isArray(mostDownloadkb)) { - throw new Error(`Invalid API response structure`) - } - displaySearch(mostDownloadkb) - } - catch(error) { - console.error(`Error fetching ${error}`) - kbSearchCard.innerHTML = `
    No keyboards are found.
    ` - paginationCtrl.style.display = 'none' - } -} - -/* Get query and return search */ -async function searchKeyboard(query = null, page) { - kbSearchCard.innerHTML = `
    Searching ${query}...
    ` - kbSearchCard.style.display = 'block' - - let response = await fetch(`https://api.keyman.com/search/2.0?q=${encodeURIComponent(query)}&p=${page}`) - if (!response.ok) { - throw new Error(`API request failed with status ${response.status}`) - } - - let data = await response.json() - // Found with Context: Setup pagination - if (data.context) { - totalPage = data.context.totalPages || 1; - currentPage = data.context.pageNumber || 1; - } else { - totalPage = Math.ceil(data.keyboards.length / itemPerPage); - } - - // Validate data.keyboards - let keyboardData = data.keyboards - if (!keyboardData || !Array.isArray(keyboardData)) { - throw new Error("Invalid API response structure") - } - - // Get total result - let totalFound = data.context.totalRows - - updatePaginationCtrl() - displaySearch(keyboardData, totalFound, query) -} - -/* Display items return from search */ -function displaySearch(data, total = 0, query = '') { - kbSearchCard.innerHTML = ''; - - if (!data || data.length == 0) { - kbSearchCard.innerHTML = 'No keyboards are found.' - paginationCtrl.style.display = 'none' - return - } - - if (total) { - searchResultCount.innerHTML = `${total} results` - searchResultCount.classList.remove('hidden') - } - - // Getting searched Word ready for highlight - const marked = getMarkedContext(query) - - const searchInstruction = document.querySelector('.search-instruction') - const kbHrTitle = document.querySelector('.keyboard-title') - if (!query) { - searchInstruction.classList.remove("hidden") - kbHrTitle.textContent = "Most Downloads" - } else { - searchInstruction.classList.add("hidden") - kbHrTitle.textContent = "" - } - data.forEach(kb => { - const card = searchKbCardUI(kb, marked, selectedKbList, data) - kbSearchCard.appendChild(card) - // dataKbForRemoval = selectedKbList - }) - paginationCtrl.style.display = 'flex'; -} - -// UI Search card -function searchKbCardUI(kb, marked = '', selectedKbList, data) { - const kbFoundInList = selectedKbList.some(selected => selected.id == kb.id) - // Keyboard card container - let cardWrap = document.createElement('div') - cardWrap.classList.add('card-wrap') - cardWrap.setAttribute('id', 'keyboardCardWrap') - - // Keyboard header container - let cardHeader = document.createElement('div') - cardHeader.classList.add('card-header') - - const {matchFound, matchField, matchValue} = highlightSearchContext(kb, marked) - - const kbNameHeading = matchFound ? showMarkedContext(kb, matchField, matchValue) - : (() => { - const heading = document.createElement('h4') - heading.innerHTML = kb.name - return heading - }) - - // Keyboard Plus (+) icon - const kbIconPTag = document.createElement('p') - kbIconPTag.textContent = kbFoundInList ? "-" : "+" - kbIconPTag.style.fontSize = '20px' - kbIconPTag.style.cursor = 'pointer' - kbIconPTag.classList.add('kb-icon-plus') - - checkKbCardUI(kbIconPTag, cardWrap, kb) - // Keyboard ID - const kbIdPTag = document.createElement('p') - kbIdPTag.classList.add('keyboard-id') - kbIdPTag.textContent = kb.id - - // Keyboard Description - const kbDescHeading = truncateDesc(kb, matchField, marked) - - // Keyboard monthly downloads and platform support - const kbSpecs = document.createElement('div') - kbSpecs.classList.add('keyboard-specs') - - const kbDownloadHeading = document.createElement('h6') - kbDownloadHeading.textContent = `${kb.match.downloads} monthly downloads` - kbDownloadHeading.classList.add('monthly-download') - - const kbPlatformSupport = document.createElement('div') - kbPlatformSupport.classList.add('platform') - kbPlatformSupport.innerHTML = platformSupport(kb.platformSupport) - - // Append children - cardHeader.appendChild(kbNameHeading) - cardHeader.appendChild(kbIconPTag) - - kbSpecs.appendChild(kbDownloadHeading) - kbSpecs.appendChild(kbPlatformSupport) - - cardWrap.appendChild(cardHeader) - cardWrap.appendChild(kbIdPTag) - cardWrap.appendChild(kbDescHeading) - cardWrap.appendChild(kbSpecs) - - // Choose keyboard to selection - kbIconPTag.onclick = (e) => { - e.stopPropagation() - addKbToSelectionMenu(kbIconPTag, cardWrap, kb, data) - textArea.focus() - selectKb() - } - // console.log("Recent:", historyKbSelection.getHistory()); - - return cardWrap -} - -// Disable or Enable search card -function checkKbCardUI(kbIconPTag, cardWrap, kb) { - // For checking if the keyboard exists in selected Kbs - let kbFoundInList = selectedKbList.some(selected => selected.id == kb.id) - if (kbFoundInList) { - cardWrap.classList.add('disabled') - } else { - cardWrap.classList.remove('disabled') - } -} - -// Highlight word searched -function getMarkedContext(query) { - let escapedTerm = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') - return new RegExp(escapedTerm, 'i') -} - -// Find a match between Search Context and Language, Keyboard name, Description -function highlightSearchContext(kb, marked) { - let matchFound = false - let matchField = "" - let matchValue = "" - - // Get and find language that matches the search - for (lang in kb.languages) { - let langData = kb.languages[lang] - for (key in langData) { - const value = langData[key] - if (typeof value == "string" && marked.test(value)) { - matchFound = true - matchValue = value.replace(marked, (m) => m ? `${m}` : m) - matchField = "language" - break - } - } - if (matchFound) break - } - - // Find a match for keyboard name if language is not a match - if (!matchFound && marked.test(kb.name)) { - matchFound = true - matchValue = kb.name.replace(marked, '$&') - matchField = "keyboard" - } - - // Find a match for keyboard description if name is not a match - if (!matchFound && marked.test(kb.description)) { - matchFound = true - matchField = "description" - } - - return {matchField, matchValue, matchFound} -} - -// Display Highlighted Search Context -function showMarkedContext(kb, matchField, matchValue) { - const kbNameHeading = document.createElement('h4') - - const kbHelpLink = document.createElement('a') - kbHelpLink.href = `https://help.keyman.com/keyboard/${kb.id}` - kbHelpLink.target = '_blank' - kbHelpLink.rel = 'noopener noreferrer' - - // Display matched language - const langNameSpan = document.createElement('span') - langNameSpan.style.fontSize = "14px" - if (matchField == "language") { - langNameSpan.innerHTML = matchField == "language" ? ` (${matchValue} language)` : "" - } - - // Display matched keyboard - if (matchField == "keyboard") { - kbHelpLink.innerHTML = matchValue - } else { - kbHelpLink.textContent = kb.name - } - kbNameHeading.appendChild(kbHelpLink) - kbNameHeading.appendChild(langNameSpan) - kbNameHeading.addEventListener('click', () => { - const checkedURL = validateURL(`https://help.keyman.com/keyboard/`) - const newURL = checkedURL + kb.id - window.open(newURL, '_blank') - }) - - return kbNameHeading -} - -// Truncated Keyboard Description -function truncateDesc(kb, matchField, marked) { - const kbDescHeading = document.createElement('h6') - kbDescHeading.classList.add("keyboard-description") - const word_limits = 90 - - let temp = document.createElement('div') - temp.innerHTML = kb.description - - let fullDesc = kb.description - let plainText = temp.textContent - let shortText = "" - - let isTruncated = false - - if (plainText.length >= word_limits) { - shortText = plainText.slice(0, word_limits) + "..." - kbDescHeading.innerHTML = shortText - isTruncated = true - } else { - kbDescHeading.innerHTML = fullDesc - isTruncated = false - } - - if (isTruncated) { - const toggleBtn = document.createElement('a') - toggleBtn.href = "#" - toggleBtn.style.marginLeft = "6px" - toggleBtn.textContent = "Show more" - - toggleBtn.addEventListener('click', e => { - e.preventDefault() - const isExpanded = toggleBtn.textContent == "Show more" - kbDescHeading.innerHTML = !isExpanded ? shortText.replace(marked, (m) => m ? `${m}` : m) : fullDesc - if (matchField == 'description') { - kbDescHeading.innerHTML = isExpanded ? fullDesc.replace(marked, '$&') : shortText - } - kbDescHeading.style.color = isExpanded ? 'black' : 'gray' - toggleBtn.textContent = isExpanded ? "Show less" : "Show more" - kbDescHeading.appendChild(toggleBtn) - }) - kbDescHeading.appendChild(toggleBtn) - } - - return kbDescHeading -} - -/* - == End of Search Section == -*/ - -// Platform Support -function platformSupport(data) { - const platformMap = { - android: "Android", - desktopWeb: "Web", - ios: "iPhone and iPad", - linux: "Linux", - macos: "macOS", - mobileWeb: "Mobile web", - windows: "Windows" - } - let platformSpan = Object.entries(data) - .filter(([_, supportLevel]) => supportLevel == 'full') - .map(([platform]) => `${platformMap[platform]}`).join('') - - return platformSpan -} - -/* == Section == - Keyboard Selection Menu -*/ -function addKbToSelectionMenu(kbIconPTag, cardWrap, kb, data) { - const keyboardSelectionButton = document.getElementById('keyboardSelectionButton') - let isSelected = selectedKbList.some(selected => selected.id == kb.id) - addDataKb(data) - // Remove keyboard - if (isSelected) { - removeKbSelected(kb.id) - kbIconPTag.textContent = '+' - generateKbUI(selectedKbList) - checkKbCardUI(kbIconPTag, cardWrap, kb) - - return - } - if(selectedKbList.length < 5) { - addKbToSelection(kb) - generateKbUI(selectedKbList) - kbIconPTag.textContent = 'โœ“' - kbIconPTag.classList.add('kb-icon-plus-animate') - - setTimeout(() => { - kbIconPTag.textContent = '-' - kbIconPTag.classList.remove('kb-icon-plus-animate') - keyboardSelectionButton.classList.remove('btn-secondary') - keyboardSelectionButton.classList.add('btn-keyman-orange') - }, 800) - - checkKbCardUI(kbIconPTag, cardWrap, kb) - return - } - confirmAndAddKb(() => { - addKbToSelection(kb) - generateKbUI(selectedKbList) - - kbIconPTag.textContent = 'โœ“' - kbIconPTag.classList.add('kb-icon-plus-animate') - - setTimeout(() => { - kbIconPTag.textContent = '-' - kbIconPTag.classList.remove('kb-icon-plus-animate') - keyboardSelectionButton.classList.remove('btn-secondary') - keyboardSelectionButton.classList.add('btn-keyman-orange') - }, 800) - checkKbCardUI(kbIconPTag, cardWrap, kb) - }) -} - -// Add keyboard for kb search and selection UI -function addKbToSelection(kb) { - const kbInfo = { - "id": kb.id, - "name": kb.name, - "version": kb.version, - "helpLink": kb.helpLink, - "platformSupport": kb.platformSupport, - "totalDownloads": kb.match.totalDownloads, - "sourcePath": kb.sourcePath, - "supportedLanguage": kb.languages, - "lastUpdated": kb.lastModifiedDate - } - // historyKbSelection.add(kbInfo) - selectedKbList.push(kbInfo) -} - -// UI for keyboard selection menu -function generateKbUI(selectedKbList) { - const keyboardSelection = document.getElementById("keyboardSelection") - keyboardSelection.innerHTML = '' - - if(selectedKbList.length < 1) { - triggerKbCount(selectedKbList) - resetKbSelectionMenu() - return - } - - const kbDivHeader = document.createElement('div') - kbDivHeader.textContent = "Keyboard Selection menu" - kbDivHeader.classList.add('kb-item-header') - - const kbDivFoot = document.createElement('div') - kbDivFoot.textContent = "US Basic Keyboard" - kbDivFoot.classList.add('kb-item-footer') - - keyboardSelection.appendChild(kbDivHeader) - - selectedKbList.forEach(data => { - const kbDiv = document.createElement('div') - kbDiv.classList.add("kb-item") - kbDiv.setAttribute('id', `${data.id}`) - - const kbName = document.createElement('span') - kbName.textContent = data.name - - const kbConfigList = document.createElement('ul') - kbConfigList.classList.add('keyboard-configs') - kbConfigList.innerHTML = ` -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • - ` - - const kbDetails = displayKbDetails(data) - - kbDiv.appendChild(kbName) - kbDiv.appendChild(kbConfigList) - kbDiv.appendChild(kbDetails) - keyboardSelection.appendChild(kbDiv) - keyboardSelection.append(kbDivFoot) - - let kbdName = data.id - let langCode = Object.keys(data.supportedLanguage)[0] || "en" - - selectKb(kbdName, langCode) - kbConfigList.addEventListener('click', (e) => { - const target = e.target - if (target.tagName == 'I' && target.dataset.action) { - const action = target.dataset.action - const id = target.dataset.id - const helpLink = target.dataset.helplink - kbConfigMenu(action, id, helpLink) - } - }) - - kbDiv.addEventListener('click', () => { - kbdName = data.id - langCode = Object.keys(data.supportedLanguage)[0] || "en" - textArea.focus() - selectKb(kbdName, langCode) - }) - - kbDivFoot.onclick = () => { - defaultKeyboard() - } - - const kbHelpLink = document.querySelector('#kbHelpdocLink') - kbHelpLink.addEventListener('click', (e) => { - kbConfigMenu('help', '', data.helpLink) - }) - }) - triggerKbCount(selectedKbList) -} - -// Keyboard count for Keyboard selection menu -function triggerKbCount(selectedKbList) { - const kbSelectedLength = selectedKbList.length - const keyboardSelectionButton = document.querySelector('#keyboardSelectionButton') - const keyboardCount = document.querySelector('#kbCount') - - if (kbSelectedLength >= 1) { - keyboardCount.classList.remove('fa-caret-right') - keyboardCount.textContent = `${kbSelectedLength}` - keyboardSelectionButton.classList.add('btn-keyman-orange') - keyboardSelectionButton.classList.remove('btn-secondary') - } else { - keyboardCount.classList.add('fa-caret-right') - keyboardCount.textContent = '' - keyboardSelectionButton.classList.remove('btn-keyman-orange') - keyboardSelectionButton.classList.add('btn-secondary') - } -} - -// Keyboard count default for Keyboard selection menu -function resetKbSelectionMenu() { - const keyboardSelection = document.querySelector("#keyboardSelection") - - const kbDivHeader = document.createElement('div') - kbDivHeader.textContent = "Keyboard Selection menu" - kbDivHeader.classList.add('kb-item-header') - - const kbItem = document.createElement('div') - kbItem.classList.add('.kb-item') - - const pTag = document.createElement('p') - pTag.textContent = "Open Search to get your keyboard" - - const kbDivFoot = document.createElement('div') - kbDivFoot.textContent = "US Basic Keyboard" - kbDivFoot.classList.add('kb-item-footer') - - kbItem.appendChild(pTag) - - keyboardSelection.appendChild(kbDivHeader) - keyboardSelection.appendChild(kbItem) - keyboardSelection.appendChild(kbDivFoot) -} - -// Compare and remove keyboard -function removeKbSelected(kbId) { - if(kbId) { - selectedKbList = selectedKbList.filter(kb => kb.id !== kbId) - } -} - -// Check 6th keyboard -function confirmAndAddKb(onConfirmAdd) { - if (typeof onConfirmAdd != 'function') { - console.log("Expected the onConfirmAdd a function, instead got: " + typeof onConfirmAdd) - alert("Click on the keyboard again to enable.") - } - - const warningDialogUI = limitKbSelectionUI(() => { - onConfirmAdd() - selectedKbList.shift() - generateKbUI(selectedKbList) - }) - - document.body.appendChild(warningDialogUI) -} - -// UI for Keyboard Selected Limitation -function limitKbSelectionUI(onAccept) { - const dialogDiv = document.createElement('div') - dialogDiv.classList.add('warning-container') - - const dialogContentDiv = document.createElement('div') - dialogContentDiv.classList.add('warning-content') - - const dialogCancel = document.createElement('button') - dialogCancel.classList.add('warning-cancel-btn') - dialogCancel.setAttribute('id', 'cancelWarningBtn') - dialogCancel.textContent = 'โœ–' - dialogCancel.onclick = () => { - dialogDiv.remove() - generateKbUI(selectedKbList) - } - - const dialogImgTag = document.createElement('img') - dialogImgTag.classList.add('warning-keyman-image') - dialogImgTag.src = `/cdn/dev/img/keymanweb-mini-logo-88.png` - dialogImgTag.alt = "Keyman Logo" - - const firstKeyboard = selectedKbList[0].name - - const dialogPTag = document.createElement('p') - dialogPTag.classList.add('warning-text') - dialogPTag.innerHTML = `The keyboards selected exceeds the limitation of 5 keyboards. Click 'Allow' to remove the
    ${firstKeyboard} keyboard.` - - const dialogUlTag = document.createElement('ol') - dialogUlTag.textContent = "Your keyboards selection:" - selectedKbList.forEach((kb, index) => { - const dialogLiTag = document.createElement('li') - if (index == 0) { - const markKeyboard = document.createElement('mark') - markKeyboard.textContent = kb.name - dialogLiTag.appendChild(markKeyboard) - } else { - dialogLiTag.textContent = kb.name - } - dialogUlTag.appendChild(dialogLiTag) - - }) - - const dialogAccept = document.createElement('button') - dialogAccept.classList.add('warning-accept-btn') - dialogAccept.setAttribute('id', 'acceptWarningBtn') - dialogAccept.textContent = "Allow" - dialogAccept.onclick = () => { - dialogDiv.remove() - onAccept() - } - - dialogContentDiv.appendChild(dialogCancel) - dialogContentDiv.appendChild(dialogImgTag) - dialogContentDiv.appendChild(dialogPTag) - dialogContentDiv.appendChild(dialogUlTag) - dialogContentDiv.appendChild(dialogAccept) - - dialogDiv.appendChild(dialogContentDiv) - - return dialogDiv -} - -// Seperate list for History/Remember Search - -/* - ========================== To be continued ========================== -*/ -function addDataKb(data) { - let selectedKbData = [] - // console.log(data) - const kbInfo = { - "platformSupport": data.platformSupport, - // "monthlyDownloads": data.match.downloads, - "sourceFile": data.sourcePath, - } - selectedKbData.push(kbInfo) -} - -// End of History search - -// Keyboard selection menu's tools: help, download, and remove -function kbConfigMenu(action, id, helplink) { - if (action == "help") { - window.open(helplink, '_blank') - } - - if (action == "download") { - const downloadUrl = `https://keyman.com/keyboards/install/${id}` - window.open(downloadUrl, '_blank') - } - - if (action == "remove") { - removeKbSelected(id) - generateKbUI(selectedKbList) - triggerKbCount(selectedKbList) - } - - if (action == "info") { - const kbDetails = document.querySelector(`#keyboard-${id}-details`) - - kbDetails.addEventListener('mouseleave', () => { - kbDetails.classList.add('hidden') - }) - kbDetails.classList.remove('hidden') - } -} - -// Keyboard details for Keyboard selection menu -function displayKbDetails(data) { - const item = selectedKbList.find(kb => kb.id == data.id) - if (!item) return; - - const kbDetails = document.createElement('div') - kbDetails.classList.add('keyboard-details') - kbDetails.setAttribute('id', `keyboard-${data.id}-details`) - kbDetails.classList.add('animate__animated', 'animate__fadeIn') - kbDetails.classList.add('hidden') - - const kbDetailsHead = document.createElement('div') - kbDetailsHead.textContent = 'Keyboard Details' - kbDetailsHead.classList.add('kb-item-header') - - const kbDetailsContent = document.createElement('div') - kbDetailsContent.classList.add('keyboard-content-wrapper') - kbDetailsContent.innerHTML = ` -
      -
    • -
      -
      Name
      -
      ${item.name || "N/A"}
      -
      -
    • -
    • -
      -
      Keyboard ID
      -
      ${item.id || "N/A"}
      -
      -
    • -
    • -
      -
      Version
      -
      ${item.version || "N/A"}
      -
      -
    • -
    • -
      -
      Total downloads
      -
      ${item.totalDownloads || 0}
      -
      -
    • -
    • -
      -
      Source Path
      - -
      -
    • -
    • -
      -
      Supported Platforms
      -
      - ${platformSupport(item.platformSupport) || 'No platforms supported'} -
      -
      -
    • -
    • -
      -
      Last Updated
      -
      ${getOnlyDates(item.lastUpdated) || 0}
      -
      -
    • -
    - ` - kbDetails.appendChild(kbDetailsHead) - kbDetails.appendChild(kbDetailsContent) - - return kbDetails -} - -// Get only the YYYY-mm-dd format -function getOnlyDates(dateData) { - const finalDateData = dateData.match(/^\d{4}-\d{2}-\d{2}/) - return finalDateData -} - -// Validate URLs -function validateURL(string) { - try { - const newUrl = new URL(string) - if (newUrl.protocol === 'https:') { - return newUrl - } else { - return false - } - } catch (error) { - console.error(error) - } -} -/* - == End of Keyboard Selection menu Section == -*/ +keyman = getKeymanWeb() + +function getKeymanWeb() { + if(window.tavultesoft) { + return window.tavultesoft.keymanweb; + } + return window.keyman; +} +/* Global Variables */ +let selectedKbList = [] // Main array for the search, kb selection...etc. +let kbSearchData = [] // For History search +let kmwLang = keyman.getActiveLanguage() +let kmwKb = keyman.getActiveKeyboard() + +const clearSearchIcon = document.querySelector('#clearSearchIcon') +const magnifying = document.querySelector('#magnifyingGlassIcon') + +const elements = { + worldMapBtn: document.querySelector('#worldMap'), + kmwControls: document.querySelector('#KeymanWebControl'), + + kbSelection: document.querySelector('#keyboardSelection'), + keyboardSelectionButton: document.querySelector('#keyboardSelectionButton'), + caretRightIcon: keyboardSelectionButton.querySelector('.fa-caret-right'), + + searchBar: document.querySelector('#searchBar'), + searchInput: document.querySelector('#searchInput'), + searchDropdownMenu: document.querySelector('#searchDropdownMenu'), + searchIcons: document.querySelector('#searchIcons'), +} + +const state = { + mapIsOpen: false +} + +/* + ===================================== Default keyboard ========================================= +*/ + +function defaultKeyboard(kbdname = "basic_kbdus", languageCode = "en") { + if(!exists(kbdname, languageCode)) { + if (textArea) textArea.placeholder = 'A Keyboard name isn\'t specified. Select a keyboard and start typing' + return + } + setKeyboardWithDirection(kbdname, languageCode) +} + +/* + ============================= Toggle between World Map and Search ============================== +*/ +elements.worldMapBtn?.addEventListener('click', (e) => { + e.preventDefault() + state.mapIsOpen = true + if (state.mapIsOpen == true) { + openMap() + keyman.addEventListener('keyboardchange', () => { + location.replace(`#${keyman.getActiveLanguage()},${keyman.getActiveKeyboard()}`) + updateExample(keyman.getActiveKeyboard()) + setTimeout(() => { + applyClassToKb(), 0 + }) + }) + } else { + openSearch() + } +}) + +function openSearch() { + state.mapIsOpen = false + hideEls( + elements.kmwControls, + ) + showEls( + elements.searchDropdownMenu, + elements.searchIcons + ) + + if (selectedKbList.length > 0) { + elements.caretRightIcon.textContent = selectedKbList.length + removeClass(elements.caretRightIcon, 'fa-magnifying-glass') + } else { + elements.caretRightIcon.textContent = '' + elements.caretRightIcon.classList.add('fa-caret-right') + } + + elements.searchBar.replaceChildren( + elements.searchInput, + elements.searchIcons, + elements.searchDropdownMenu + ) +} + +function openMap() { + state.mapIsOpen = true + removeClass( + elements.kmwControls, 'hidden', + elements.caretRightIcon, 'fa-caret-right' + ) + hideEls( + elements.searchDropdownMenu + ) + removeTextContent( + elements.caretRightIcon + ) + elements.keyboardSelectionButton.removeAttribute('id', 'keyboardSelectionButton') + elements.keyboardSelectionButton.setAttribute('id', 'returnToSearchButton') + elements.caretRightIcon.classList.add('fa-magnifying-glass') + elements.keyboardSelectionButton.style.backgroundColor = "var(--keyman-orange)" + elements.keyboardSelectionButton.style.border = '0px' + elements.keyboardSelectionButton.classList.add('return-to-search') + elements.kbSelection.style.display = "none" + elements.searchBar.replaceChildren( + elements.kmwControls + ) +} + +function returnToSearch() { + elements.keyboardSelectionButton.removeAttribute('id', 'returnToSearchButton') + elements.keyboardSelectionButton.setAttribute('id', 'keyboardSelectionButton') + + if ((selectedKbList?.length || 0) < 1) { + elements.caretRightIcon.classList.add('fa-caret-right') + removeClass(elements.caretRightIcon, 'fa-magnifying-glass') + elements.caretRightIcon.textContent = '' + } + + elements.keyboardSelectionButton.style.backgroundColor = "" + elements.kbSelection.style.display = "block" + openSearch() +} + +function waitForElement(selector) { + return new Promise((resolve) => { + const interval = setInterval(() => { + const element = document.querySelector(selector) + if (element) { + clearInterval(interval) + resolve(element) + } + }, 100) + }) +} + +waitForElement('#returnToSearchButton').then((element) => { + element.addEventListener('click', (e) => { + e.preventDefault() + returnToSearch() + }) +}) + +waitForElement(".kmw-osk-frame").then((oskDiv) => { + document.querySelector('.keyboard-area').appendChild(oskDiv) +}) + +/* + ==================== Search Interaction =================== +*/ + +/* Search Input */ +const dropdown = new bootstrap.Dropdown(elements.searchInput, { + autoClose: 'outside' +}) + +document.addEventListener('click', (e) => { + if (!elements.searchInput.contains(e.target) && !elements.searchDropdownMenu.contains(e.target)) { + dropdown.hide() + } +}) + +elements.searchInput.addEventListener('click', (e) => { + e.stopPropagation() + // defaultKeyboard() + dropdown.show() +}) + +// Hide Dropdown Search on Mouse leave +elements.searchDropdownMenu.addEventListener('mouseleave', (e) => { + e.preventDefault() + dropdown.hide() +}) + +/* + =========================== Utility functions ============================ +*/ +function hideEls(...elements) { + return elements.every(el => el.classList.add('hidden')) +} + +function showEls(...elements) { + return elements.every(el => el.classList.remove('hidden')) +} + +function removeClass(element, className) { + return element.classList.remove(className) +} + +function removeTextContent(...elements) { + return elements.every(el => el.textContent = '') +} + +/* Elements validation */ +function exists(...elements) { + return elements.every(el => el != null) +} + +document.addEventListener('DOMContentLoaded', () => { + /* UI Behavior of the Selected Keyboard menu */ + if (exists(elements)) { + elements.keyboardSelectionButton.addEventListener('mouseenter', () => { + elements.kbSelection.classList.add('open') + }) + elements.keyboardSelectionButton.addEventListener('click', () => { + elements.kbSelection.classList.remove('open') + }) + elements.kbSelection.addEventListener('mouseleave', () => { + elements.kbSelection.classList.remove('open') + }) + } +}) + +/* + === Keyboard Execution === +*/ +const downloadBtn = document.getElementById('kbDownloadPage') +const textArea = document.getElementById('textArea') +let langExamples = []; + +function selectKb(kbdname, languageCode) { + if(!exists(kbdname, languageCode)) { + if (textArea) textArea.placeholder = 'A Keyboard name isn\'t specified. Select a keyboard and start typing' + return + } + setKeyboardWithDirection(kbdname, languageCode) +} + +function setTextDirection(targetEls, dir) { + const copyBtn = document.querySelector('#copyTool') + + targetEls.dir = dir + if (dir == 'rtl') { + copyBtn.style.right = '0' + copyBtn.style.left = '10px' + } else { + copyBtn.style.right = '' + copyBtn.style.left = '' + } +} + +// Change and type keyboard +async function setKeyboardWithDirection(kbdname, languageCode) { + const kbSpan = document.querySelector('#kbSpan') + const langTag = `#${languageCode}` + let kbTag = '' + + if (kbdname.match(/Keyboard_*/)) { + kbTag = `${kbdname}` + } else { + kbTag = `Keyboard_${kbdname}` + } + + location.replace(`${langTag},${kbTag}`) + await keyman.addKeyboards(kbdname) + const kbd = keyman.getKeyboard(kbdname, languageCode) + await keyman.setActiveKeyboard(kbdname, languageCode) + + // setTimeout(() => { + // applyClassToKb(), 0 + // }) + + if(kbd) { + textArea.placeholder = `The ${kbdname} keyboard is selected. Start typing...` + kbSpan.innerHTML = `${kbdname}` + + setTextDirection(textArea, textArea.dir) + } + updateExample(kbdname) + if(typeof(KeyboardChange_EmbedFonts) != 'undefined') KeyboardChange_EmbedFonts(kbdname) +} + +/* Language Examples AJAX */ +async function updateExample(kbdname) { + const keymanExample = document.getElementById("example") + const exampleBox = document.getElementById("exampleBox") + + if (!keymanExample || !exampleBox) return false; + + if(kbdname == '') + { + keymanExample.textContent = `No example is available due to empty Keyboard name.` + return true; + } + + let activeLanguage = keyman.getActiveLanguage(); + + if(langExamples[activeLanguage + '_' + kbdname]) + { + keymanExample.innerHTML = langExamples[activeLanguage + '_' + kbdname]; + return true; + } + + langExamples[activeLanguage + '_' + kbdname] = 'Loading...'; + keymanExample.innerHTML = 'Loading...'; + + const link = `/prog/languageexample.php?keyboard=${kbdname}&language=${activeLanguage}`; + try { + const response = await fetch(link); + if(response.status == 200) { + const content = await response.text(); + + langExamples[activeLanguage + '_' + kbdname] = keymanExample.innerHTML = content; + } else { + throw new Error(`Unable to retrieve content, status was ${response.status}: ${response.statusText}`); + } + } catch(e) { + langExamples[activeLanguage + '_' + kbdname] = keymanExample.innerHTML = 'Error retrieving example: '+e.message; + throw e; + } +} + +function applyClassToKb() { + + const kbArea = document.querySelector('.keyboard-area') + if (!kbArea) return + + const apply = () => { + const child = kbArea.children + for (const c of child) { + if (!c.classList.contains('kmw-osk-frame')) { + c.classList.add('kmw-osk-frame') + c.classList.add('kmw-help-osk-frame') + } + } + } + + apply() + + // const observer = new MutationObserver(() => { + // for (const m of mutations) { + // if (m.type === 'childlist' && m.addedNodes.length) { + // apply() + // } + // } + // }) + // observer.observe(kbArea, {childList: true}) +} + +/* Search */ +const kbSearchCard = document.getElementById('kbSearchCardUI'); +let debounceTimer + +/* Pagination */ +prevBtn = document.getElementById('prevPage') +nextBtn = document.getElementById('nextPage') +pageInfo = document.getElementById('pageInfo') + +searchResultCount = document.getElementById('resultCount') +paginationCtrl = document.getElementById('paginationControls') + +let currentPage = 1 +let currentQuery = '' +let totalPage +const itemPerPage = 10 + +prevBtn.addEventListener('click', goPrevPage) +nextBtn.addEventListener('click', goNextPage) + +function updatePaginationCtrl() { + pageInfo.textContent = `${currentPage} of ${totalPage}` + nextBtn.disabled = currentPage >= totalPage + prevBtn.disabled = currentPage <= 1 +} + +function goPrevPage() { + if (currentPage > 1) { + currentPage-- + searchKeyboard(currentQuery, currentPage) + } +} + +function goNextPage() { + if (currentPage < totalPage) { + currentPage++ + searchKeyboard(currentQuery, currentPage) + } +} + +/* Click: Open Search and Display search instructions */ +elements.searchInput.addEventListener('click', function(e) { + const query = e.target.value.trim() + + defaultKeyboard() + if (query == "") { + resetSearch() + } else { + searchKeyboard(query) + } +}) + +/* Input: Search and Display keyboards */ +elements.searchInput.addEventListener('input', function(e) { + handleSearch(e.target.value) +}) + +clearSearchIcon.addEventListener('click', () => { + elements.searchInput.value = '' + handleSearch() + elements.searchInput.focus() +}) + +function handleSearch(value = "") { + currentQuery = value.trim() + currentPage = 1 + + updateSearchIcon(value) + + if (!currentQuery) { + resetSearch() + return + } + debounceSearch(currentQuery, currentPage) +} + +function resetSearch() { + paginationCtrl.style.display = 'none' + defaultSearch() +} + +function updateSearchIcon(value) { + const hasValue = value.length > 0 + magnifying.style.display = hasValue ? 'none' : 'inline' + clearSearchIcon.style.display = hasValue ? 'inline' : 'none' +} + +function debounceSearch(query, page) { + clearTimeout(debounceTimer) + if (query.length > 1) { + debounceTimer = setTimeout(() => { + searchKeyboard(query, page) + }, 300) + } +} + +/* == Section == + Search +*/ + +/* Display top downloads with search Instruction */ +async function defaultSearch() { + kbSearchCard.innerHTML = `

    Loading...

    ` + try { + let response = await fetch(`https://api.keyman.com/search/2.0?q=p:popular`) + if (!response.ok) { + throw new Error(`API request failed with status ${response.status}`) + } + + let data = await response.json() + + let mostDownloadkb = data.keyboards + + if (!mostDownloadkb || !Array.isArray(mostDownloadkb)) { + throw new Error(`Invalid API response structure`) + } + displaySearch(mostDownloadkb) + } + catch(error) { + console.error(`Error fetching ${error}`) + kbSearchCard.innerHTML = `
    No keyboards are found.
    ` + paginationCtrl.style.display = 'none' + } +} + +/* Get query and return search */ +async function searchKeyboard(query = null, page) { + kbSearchCard.innerHTML = `
    Searching ${query}...
    ` + kbSearchCard.style.display = 'block' + + let response = await fetch(`https://api.keyman.com/search/2.0?q=${encodeURIComponent(query)}&p=${page}`) + if (!response.ok) { + throw new Error(`API request failed with status ${response.status}`) + } + + searchHistory(query) + let data = await response.json() + // Found with Context: Setup pagination + if (data.context) { + totalPage = data.context.totalPages || 1; + currentPage = data.context.pageNumber || 1; + } else { + totalPage = Math.ceil(data.keyboards.length / itemPerPage); + } + + // Validate data.keyboards + let keyboardData = data.keyboards + if (!keyboardData || !Array.isArray(keyboardData)) { + throw new Error("Invalid API response structure") + } + + // Get total result + let totalFound = data.context.totalRows + + updatePaginationCtrl() + displaySearch(keyboardData, totalFound, query) +} + +/* Display items return from search */ +function displaySearch(data, total = 0, query = '') { + kbSearchCard.innerHTML = ''; + + if (!data || data.length == 0) { + kbSearchCard.innerHTML = 'No keyboards are found.' + paginationCtrl.style.display = 'none' + return + } + + if (total) { + searchResultCount.innerHTML = `${total} results` + searchResultCount.classList.remove('hidden') + } + + // Getting searched Word ready for highlight + const marked = getMarkedContext(query) + + const searchInstruction = document.querySelector('.search-instruction') + const kbHrTitle = document.querySelector('.keyboard-title') + if (!query) { + searchInstruction.classList.remove("hidden") + kbHrTitle.textContent = "Most Downloads" + } else { + searchInstruction.classList.add("hidden") + kbHrTitle.textContent = "" + } + data.forEach(kb => { + const card = searchKbCardUI(kb, marked, selectedKbList, data) + kbSearchCard.appendChild(card) + }) + paginationCtrl.style.display = 'flex'; +} + +// UI Search card +function searchKbCardUI(kb, marked = '', selectedKbList, data) { + const kbFoundInList = selectedKbList.some(selected => selected.id == kb.id) + // Keyboard card container + let cardWrap = document.createElement('div') + cardWrap.classList.add('card-wrap') + cardWrap.setAttribute('id', 'keyboardCardWrap') + + // Keyboard header container + let cardHeader = document.createElement('div') + cardHeader.classList.add('card-header') + + const {matchFound, matchField, matchValue} = highlightSearchContext(kb, marked) + + const kbNameHeading = matchFound ? showMarkedContext(kb, matchField, matchValue) + : (() => { + const heading = document.createElement('h4') + heading.innerHTML = kb.name + return heading + }) + + // Keyboard Plus (+) icon + const kbIconPTag = document.createElement('p') + kbIconPTag.textContent = kbFoundInList ? "-" : "+" + kbIconPTag.style.fontSize = '20px' + kbIconPTag.style.cursor = 'pointer' + kbIconPTag.classList.add('kb-icon-plus') + + checkKbCardUI(kbIconPTag, cardWrap, kb) + // Keyboard ID + const kbIdPTag = document.createElement('p') + kbIdPTag.classList.add('keyboard-id') + kbIdPTag.textContent = kb.id + + // Keyboard Description + const kbDescHeading = truncateDesc(kb, matchField, marked) + + // Keyboard monthly downloads and platform support + const kbSpecs = document.createElement('div') + kbSpecs.classList.add('keyboard-specs') + + const kbDownloadHeading = document.createElement('h6') + kbDownloadHeading.textContent = `${kb.match.downloads} monthly downloads` + kbDownloadHeading.classList.add('monthly-download') + + const kbPlatformSupport = document.createElement('div') + kbPlatformSupport.classList.add('platform') + kbPlatformSupport.innerHTML = platformSupport(kb.platformSupport) + + // Append children + cardHeader.appendChild(kbNameHeading) + cardHeader.appendChild(kbIconPTag) + + kbSpecs.appendChild(kbDownloadHeading) + kbSpecs.appendChild(kbPlatformSupport) + + cardWrap.appendChild(cardHeader) + cardWrap.appendChild(kbIdPTag) + cardWrap.appendChild(kbDescHeading) + cardWrap.appendChild(kbSpecs) + + // Choose keyboard to selection + kbIconPTag.onclick = (e) => { + e.stopPropagation() + addKbToSelectionMenu(kbIconPTag, cardWrap, kb, data) + textArea.focus() + selectKb() + } + // console.log("Recent:", historyKbSelection.getHistory()); + + return cardWrap +} + +// Disable or Enable search card +function checkKbCardUI(kbIconPTag, cardWrap, kb) { + // For checking if the keyboard exists in selected Kbs + let kbFoundInList = selectedKbList.some(selected => selected.id == kb.id) + if (kbFoundInList) { + cardWrap.classList.add('disabled') + } else { + cardWrap.classList.remove('disabled') + } +} + +// Highlight word searched +function getMarkedContext(query) { + let escapedTerm = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + return new RegExp(escapedTerm, 'i') +} + +// Find a match between Search Context and Language, Keyboard name, Description +function highlightSearchContext(kb, marked) { + let matchFound = false + let matchField = "" + let matchValue = "" + + // Get and find language that matches the search + for (lang in kb.languages) { + let langData = kb.languages[lang] + for (key in langData) { + const value = langData[key] + if (typeof value == "string" && marked.test(value)) { + matchFound = true + matchValue = value.replace(marked, (m) => m ? `${m}` : m) + matchField = "language" + break + } + } + if (matchFound) break + } + + // Find a match for keyboard name if language is not a match + if (!matchFound && marked.test(kb.name)) { + matchFound = true + matchValue = kb.name.replace(marked, '$&') + matchField = "keyboard" + } + + // Find a match for keyboard description if name is not a match + if (!matchFound && marked.test(kb.description)) { + matchFound = true + matchField = "description" + } + + return {matchField, matchValue, matchFound} +} + +// Display Highlighted Search Context +function showMarkedContext(kb, matchField, matchValue) { + const kbNameHeading = document.createElement('h4') + + const kbHelpLink = document.createElement('a') + kbHelpLink.href = `https://help.keyman.com/keyboard/${kb.id}` + kbHelpLink.target = '_blank' + kbHelpLink.rel = 'noopener noreferrer' + + // Display matched language + const langNameSpan = document.createElement('span') + langNameSpan.style.fontSize = "14px" + if (matchField == "language") { + langNameSpan.innerHTML = matchField == "language" ? ` (${matchValue} language)` : "" + } + + // Display matched keyboard + if (matchField == "keyboard") { + kbHelpLink.innerHTML = matchValue + } else { + kbHelpLink.textContent = kb.name + } + kbNameHeading.appendChild(kbHelpLink) + kbNameHeading.appendChild(langNameSpan) + kbNameHeading.addEventListener('click', () => { + const checkedURL = validateURL(`https://help.keyman.com/keyboard/`) + const newURL = checkedURL + kb.id + window.open(newURL, '_blank') + }) + + return kbNameHeading +} + +// Truncated Keyboard Description +function truncateDesc(kb, matchField, marked) { + const kbDescHeading = document.createElement('h6') + kbDescHeading.classList.add("keyboard-description") + const word_limits = 90 + + let temp = document.createElement('div') + temp.innerHTML = kb.description + + let fullDesc = kb.description + let plainText = temp.textContent + let shortText = "" + + let isTruncated = false + + if (plainText.length >= word_limits) { + shortText = plainText.slice(0, word_limits) + "..." + kbDescHeading.innerHTML = shortText + isTruncated = true + } else { + kbDescHeading.innerHTML = fullDesc + isTruncated = false + } + + if (isTruncated) { + const toggleBtn = document.createElement('a') + toggleBtn.href = "#" + toggleBtn.style.marginLeft = "6px" + toggleBtn.textContent = "Show more" + + toggleBtn.addEventListener('click', e => { + e.preventDefault() + const isExpanded = toggleBtn.textContent == "Show more" + kbDescHeading.innerHTML = !isExpanded ? shortText.replace(marked, (m) => m ? `${m}` : m) : fullDesc + if (matchField == 'description') { + kbDescHeading.innerHTML = isExpanded ? fullDesc.replace(marked, '$&') : shortText + } + kbDescHeading.style.color = isExpanded ? 'black' : 'gray' + toggleBtn.textContent = isExpanded ? "Show less" : "Show more" + kbDescHeading.appendChild(toggleBtn) + }) + kbDescHeading.appendChild(toggleBtn) + } + + return kbDescHeading +} + +/* + == End of Search Section == +*/ + +// Platform Support +function platformSupport(data) { + const platformMap = { + android: "Android", + desktopWeb: "Web", + ios: "iPhone and iPad", + linux: "Linux", + macos: "macOS", + mobileWeb: "Mobile web", + windows: "Windows" + } + let platformSpan = Object.entries(data) + .filter(([_, supportLevel]) => supportLevel == 'full') + .map(([platform]) => `${platformMap[platform]}`).join('') + + return platformSpan +} + +/* == Section == + Keyboard Selection Menu +*/ +function addKbToSelectionMenu(kbIconPTag, cardWrap, kb, data) { + const keyboardSelectionButton = document.getElementById('keyboardSelectionButton') + let isSelected = selectedKbList.some(selected => selected.id == kb.id) + addDataKb(data) + // Remove keyboard + if (isSelected) { + removeKbSelected(kb.id) + kbIconPTag.textContent = '+' + generateKbUI(selectedKbList) + checkKbCardUI(kbIconPTag, cardWrap, kb) + + return + } + if(selectedKbList.length < 5) { + addKbToSelection(kb) + generateKbUI(selectedKbList) + kbIconPTag.textContent = 'โœ“' + kbIconPTag.classList.add('kb-icon-plus-animate') + + setTimeout(() => { + kbIconPTag.textContent = '-' + kbIconPTag.classList.remove('kb-icon-plus-animate') + keyboardSelectionButton.classList.remove('btn-secondary') + keyboardSelectionButton.classList.add('btn-keyman-orange') + }, 800) + + checkKbCardUI(kbIconPTag, cardWrap, kb) + return + } + confirmAndAddKb(() => { + addKbToSelection(kb) + generateKbUI(selectedKbList) + + kbIconPTag.textContent = 'โœ“' + kbIconPTag.classList.add('kb-icon-plus-animate') + + setTimeout(() => { + kbIconPTag.textContent = '-' + kbIconPTag.classList.remove('kb-icon-plus-animate') + keyboardSelectionButton.classList.remove('btn-secondary') + keyboardSelectionButton.classList.add('btn-keyman-orange') + }, 800) + checkKbCardUI(kbIconPTag, cardWrap, kb) + }) +} + +// Add keyboard for kb search and selection UI +function addKbToSelection(kb) { + const kbInfo = { + "id": kb.id, + "name": kb.name, + "version": kb.version, + "helpLink": kb.helpLink, + "platformSupport": kb.platformSupport, + "totalDownloads": kb.match.totalDownloads, + "sourcePath": kb.sourcePath, + "supportedLanguage": kb.languages, + "lastUpdated": kb.lastModifiedDate + } + // historyKbSelection.add(kbInfo) + selectedKbList.push(kbInfo) +} + +// UI for keyboard selection menu +function generateKbUI(selectedKbList) { + const keyboardSelection = document.getElementById("keyboardSelection") + keyboardSelection.innerHTML = '' + + if(selectedKbList.length < 1) { + triggerKbCount(selectedKbList) + resetKbSelectionMenu() + return + } + + const kbDivHeader = document.createElement('div') + kbDivHeader.textContent = "Keyboard Selection menu" + kbDivHeader.classList.add('kb-item-header') + + const kbDivFoot = document.createElement('div') + kbDivFoot.textContent = "US Basic Keyboard" + kbDivFoot.classList.add('kb-item-footer') + + keyboardSelection.appendChild(kbDivHeader) + + selectedKbList.forEach(data => { + const kbDiv = document.createElement('div') + kbDiv.classList.add("kb-item") + kbDiv.setAttribute('id', `${data.id}`) + + const kbName = document.createElement('span') + kbName.textContent = data.name + + const kbConfigList = document.createElement('ul') + kbConfigList.classList.add('keyboard-configs') + kbConfigList.innerHTML = ` +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • + ` + + const kbDetails = displayKbDetails(data) + + kbDiv.appendChild(kbName) + kbDiv.appendChild(kbConfigList) + kbDiv.appendChild(kbDetails) + keyboardSelection.appendChild(kbDiv) + keyboardSelection.append(kbDivFoot) + + let kbdName = data.id + let langCode = Object.keys(data.supportedLanguage)[0] || "en" + + selectKb(kbdName, langCode) + kbConfigList.addEventListener('click', (e) => { + const target = e.target + if (target.tagName == 'I' && target.dataset.action) { + const action = target.dataset.action + const id = target.dataset.id + const helpLink = target.dataset.helplink + kbConfigMenu(action, id, helpLink) + } + }) + + kbDiv.addEventListener('click', () => { + kbdName = data.id + langCode = Object.keys(data.supportedLanguage)[0] || "en" + textArea.focus() + selectKb(kbdName, langCode) + }) + + kbDivFoot.onclick = () => { + defaultKeyboard() + } + + const kbHelpLink = document.querySelector('#kbHelpdocLink') + kbHelpLink.addEventListener('click', (e) => { + kbConfigMenu('help', '', data.helpLink) + }) + }) + triggerKbCount(selectedKbList) +} + +// Keyboard count for Keyboard selection menu +function triggerKbCount(selectedKbList) { + const kbSelectedLength = selectedKbList.length + const keyboardSelectionButton = document.querySelector('#keyboardSelectionButton') + const keyboardCount = document.querySelector('#kbCount') + + if (kbSelectedLength >= 1) { + keyboardCount.classList.remove('fa-caret-right') + keyboardCount.textContent = `${kbSelectedLength}` + keyboardSelectionButton.classList.add('btn-keyman-orange') + keyboardSelectionButton.classList.remove('btn-secondary') + } else { + keyboardCount.classList.add('fa-caret-right') + keyboardCount.textContent = '' + keyboardSelectionButton.classList.remove('btn-keyman-orange') + keyboardSelectionButton.classList.add('btn-secondary') + } +} + +// Keyboard count default for Keyboard selection menu +function resetKbSelectionMenu() { + const keyboardSelection = document.querySelector("#keyboardSelection") + + const kbDivHeader = document.createElement('div') + kbDivHeader.textContent = "Keyboard Selection menu" + kbDivHeader.classList.add('kb-item-header') + + const kbItem = document.createElement('div') + kbItem.classList.add('.kb-item') + + const pTag = document.createElement('p') + pTag.textContent = "Open Search to get your keyboard" + + const kbDivFoot = document.createElement('div') + kbDivFoot.textContent = "US Basic Keyboard" + kbDivFoot.classList.add('kb-item-footer') + + kbItem.appendChild(pTag) + + keyboardSelection.appendChild(kbDivHeader) + keyboardSelection.appendChild(kbItem) + keyboardSelection.appendChild(kbDivFoot) +} + +// Compare and remove keyboard +function removeKbSelected(kbId) { + if(kbId) { + selectedKbList = selectedKbList.filter(kb => kb.id !== kbId) + } +} + +// Check 6th keyboard +function confirmAndAddKb(onConfirmAdd) { + if (typeof onConfirmAdd != 'function') { + console.log("Expected the onConfirmAdd a function, instead got: " + typeof onConfirmAdd) + alert("Click on the keyboard again to enable.") + } + + const warningDialogUI = limitKbSelectionUI(() => { + onConfirmAdd() + selectedKbList.shift() + generateKbUI(selectedKbList) + }) + + document.body.appendChild(warningDialogUI) +} + +// UI for Keyboard Selected Limitation +function limitKbSelectionUI(onAccept) { + const dialogDiv = document.createElement('div') + dialogDiv.classList.add('warning-container') + + const dialogContentDiv = document.createElement('div') + dialogContentDiv.classList.add('warning-content') + + const dialogCancel = document.createElement('button') + dialogCancel.classList.add('warning-cancel-btn') + dialogCancel.setAttribute('id', 'cancelWarningBtn') + dialogCancel.textContent = 'โœ–' + dialogCancel.onclick = () => { + dialogDiv.remove() + generateKbUI(selectedKbList) + } + + const dialogImgTag = document.createElement('img') + dialogImgTag.classList.add('warning-keyman-image') + dialogImgTag.src = `/cdn/dev/img/keymanweb-mini-logo-88.png` + dialogImgTag.alt = "Keyman Logo" + + const firstKeyboard = selectedKbList[0].name + + const dialogPTag = document.createElement('p') + dialogPTag.classList.add('warning-text') + dialogPTag.innerHTML = `The keyboards selected exceeds the limitation of 5 keyboards. Click 'Allow' to remove the
    ${firstKeyboard} keyboard.` + + const dialogUlTag = document.createElement('ol') + dialogUlTag.textContent = "Your keyboards selection:" + selectedKbList.forEach((kb, index) => { + const dialogLiTag = document.createElement('li') + if (index == 0) { + const markKeyboard = document.createElement('mark') + markKeyboard.textContent = kb.name + dialogLiTag.appendChild(markKeyboard) + } else { + dialogLiTag.textContent = kb.name + } + dialogUlTag.appendChild(dialogLiTag) + + }) + + const dialogAccept = document.createElement('button') + dialogAccept.classList.add('warning-accept-btn') + dialogAccept.setAttribute('id', 'acceptWarningBtn') + dialogAccept.textContent = "Allow" + dialogAccept.onclick = () => { + dialogDiv.remove() + onAccept() + } + + dialogContentDiv.appendChild(dialogCancel) + dialogContentDiv.appendChild(dialogImgTag) + dialogContentDiv.appendChild(dialogPTag) + dialogContentDiv.appendChild(dialogUlTag) + dialogContentDiv.appendChild(dialogAccept) + + dialogDiv.appendChild(dialogContentDiv) + + return dialogDiv +} + +// Seperate list for History/Remember Search + +/* + ========================== To be continued ========================== +*/ +function addDataKb(data) { + let selectedKbData = [] + // console.log(data) + const kbInfo = { + "platformSupport": data.platformSupport, + // "monthlyDownloads": data.match.downloads, + "sourceFile": data.sourcePath, + } + selectedKbData.push(kbInfo) +} + +// End of History search + +// Keyboard selection menu's tools: help, download, and remove +function kbConfigMenu(action, id, helplink) { + if (action == "help") { + window.open(helplink, '_blank') + } + + if (action == "download") { + const downloadUrl = `https://keyman.com/keyboards/install/${id}` + window.open(downloadUrl, '_blank') + } + + if (action == "remove") { + removeKbSelected(id) + generateKbUI(selectedKbList) + triggerKbCount(selectedKbList) + } + + if (action == "info") { + const kbDetails = document.querySelector(`#keyboard-${id}-details`) + + kbDetails.addEventListener('mouseleave', () => { + kbDetails.classList.add('hidden') + }) + kbDetails.classList.remove('hidden') + } +} + +// Keyboard details for Keyboard selection menu +function displayKbDetails(data) { + const item = selectedKbList.find(kb => kb.id == data.id) + if (!item) return; + + const kbDetails = document.createElement('div') + kbDetails.classList.add('keyboard-details') + kbDetails.setAttribute('id', `keyboard-${data.id}-details`) + kbDetails.classList.add('animate__animated', 'animate__fadeIn') + kbDetails.classList.add('hidden') + + const kbDetailsHead = document.createElement('div') + kbDetailsHead.textContent = 'Keyboard Details' + kbDetailsHead.classList.add('kb-item-header') + + const kbDetailsContent = document.createElement('div') + kbDetailsContent.classList.add('keyboard-content-wrapper') + kbDetailsContent.innerHTML = ` +
      +
    • +
      +
      Name
      +
      ${item.name || "N/A"}
      +
      +
    • +
    • +
      +
      Keyboard ID
      +
      ${item.id || "N/A"}
      +
      +
    • +
    • +
      +
      Version
      +
      ${item.version || "N/A"}
      +
      +
    • +
    • +
      +
      Total downloads
      +
      ${item.totalDownloads || 0}
      +
      +
    • +
    • +
      +
      Source Path
      + +
      +
    • +
    • +
      +
      Supported Platforms
      +
      + ${platformSupport(item.platformSupport) || 'No platforms supported'} +
      +
      +
    • +
    • +
      +
      Last Updated
      +
      ${getOnlyDates(item.lastUpdated) || 0}
      +
      +
    • +
    + ` + kbDetails.appendChild(kbDetailsHead) + kbDetails.appendChild(kbDetailsContent) + + return kbDetails +} + +// Get only the YYYY-mm-dd format +function getOnlyDates(dateData) { + const finalDateData = dateData.match(/^\d{4}-\d{2}-\d{2}/) + return finalDateData +} + +// Validate URLs +function validateURL(string) { + try { + const newUrl = new URL(string) + if (newUrl.protocol === 'https:') { + return newUrl + } else { + return false + } + } catch (error) { + console.error(error) + } +} +/* + == End of Keyboard Selection menu Section == +*/ + +/* + == Store data in localStorage to use for reload == +*/ +let appState = { + fontSize: 16, + writtenText: "", + selectedKbList: [], + enabledKb: null, + keyboardSizes: null, + textAreaSizes: null +} +const keyboardContainer = document.querySelector('.keyboard-container') +const fontSizeRange = document.querySelector('#fontSizeRange') + +function getFontSize(element) { + let theFontSize + theFontSize = parseInt(window.getComputedStyle(element).fontSize) || "16" + + return theFontSize +} + +function getSelectedKb() { + return selectedKbList || [] +} + +function getEnabledKb() { + let hash = location.hash.match(/^#(.+),(Keyboard_.+)$/i)[0] + + let kbValues = hash.replace('#', '') + kbValues = hash.split(',') + + return [hash, kbValues] +} + +function getElementsSize(element) { + const rect = element.getBoundingClientRect() + return { + height: rect.height, + width: rect.width, + positionX: rect.x, + positionY: rect.y + } +} + +function getElementValue(element) { + return element.value +} + +function setFontSize(size) { + textArea.style.fontSize = size + "px" + fontSizeRange.value = size +} + +function setWrittenText(text) { + textArea.value = text +} + +function setElementsSize(element, sizes) { + element.style.height = sizes.height + "px" + element.style.left = sizes.positionX + "px" + element.style.top = sizes.positionY + "px" +} + +function setSelectedKb(savedKbList) { + selectedKbList = savedKbList +} + +function setEnabledKb(kb) { + if (kb) { + selectKb(kb) + } +} + +function buildAppState() { + appState = { + fontSize: getFontSize(textArea), + selectedKbList: getSelectedKb(), + enabledKb: getEnabledKb(), + textAreaSizes: getElementsSize(textArea), + keyboardSizes: getElementsSize(keyboardContainer), + writtenText: getElementValue(textArea) + } + saveSettings("keymanWebState", appState) +} + +function saveSettings(key, state) { + let recentTime = new Date() + const time = 5000 // equals to An hour + let item + + // console.log("recentTime: ", recentTime) + // console.log("recentTime.getTime(): ", recentTime.getTime()) + + if (state) { + item = { + value: state, + expiry: recentTime.getTime() + time + } + } + localStorage.setItem(key, JSON.stringify(item)) +} + +function loadSettings(key) { + const raw = localStorage.getItem(key) + if (raw) { + let appState = JSON.parse(raw) + const newTime = new Date() + + console.log("newTime: ", newTime, "appState.expiry: ", appState.expiry) + console.log(newTime.getTime() > appState.expiry) + if (newTime.getTime() > appState.expiry) { + localStorage.removeItem(key) + alert("Session expired!") + return null + } + + setFontSize(appState.value.fontSize) + setWrittenText(appState.value.writtenText) + setElementsSize(textArea, appState.value.textAreaSizes) + setElementsSize(keyboardContainer, appState.value.keyboardSizes) + setSelectedKb(appState.value.selectedKbList) + setEnabledKb(appState.value.enabledKb[0]) + + generateKbUI(appState.value.selectedKbList) + console.log(appState.value.enabledKb[1][1], appState.value.enabledKb[1][0]) + // selectKb(appState.value.enabledKb[1][1], appState.value.enabledKb[1][0]) + } +} + +window.addEventListener('load', () => { + loadSettings("keymanWebState") +}) + +window.addEventListener('beforeunload', () => { + buildAppState() +}) + +window.addEventListener('storage', (e) => { + if (e.key == "keymanWebState") { + appState = JSON.parse(e.newValue) + buildAppState() + } +}) + +function searchHistory(value) { + if (kbSearchData.length < 0) { + kbSearchData.push(value) + for (i=0; i<=kbSearchData.length; i++) { + if (value != kbSearchData[i] || kbSearchData.length >= 5) { + kbSearchData.shift() + } + } + } + // console.log(kbSearchData) +} \ No newline at end of file diff --git a/cdn/dev/js/kmwlive.js b/cdn/dev/js/kmwlive.js index 54051b4..46d806b 100644 --- a/cdn/dev/js/kmwlive.js +++ b/cdn/dev/js/kmwlive.js @@ -1,471 +1,471 @@ -$.urlParam = function(name){ - var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href); - if (!results) { return 0; } - return decodeURIComponent(results[1]).replace(/\+/g, ' ') || 0; -} - -function getKeymanWeb() { - if(window.tavultesoft) { - return window.tavultesoft.keymanweb; - } - return window.keyman; -} - -// -// If we detect a rewrite of /go//, remap that to the new #-based model. -// This will force a reload so the /return/ statement isn't really necessary... -// - -function setCookie(c_name,value,exdays){ - var exdate=new Date(); - exdate.setDate(exdate.getDate() + exdays); - var c_value=escape(value) + ((exdays==null) ? "" : "; expires="+exdate.toUTCString()); - document.cookie=c_name + "=" + c_value; -} - -var locationmatch = location.pathname.match(/^\/go\/([^/]+)\/([^/]+)/); -if(locationmatch) { - - location.href = '/#'+locationmatch[1]+',Keyboard_'+locationmatch[2]; -} - -// Perform all page-load init that is NOT dependent on KeymanWeb. -// That script may not load in time for this method. -$(document).ready(function() { - // Font size function - $( "#slider" ).slider({ - value:16, - min: 10, - max: 132, - step: 2, - slide: function( event, ui ) { - $('#message').css('font-size',ui.value); - $('#message').focus(); - } - }); - - var font = document.getElementById('font'); - var fontIncrease = document.getElementById('mobile-increase'); - var fontDecrease = document.getElementById('mobile-decrease'); - - font.addEventListener('touchstart', function(event) { - $('#mobile-font').show(); - $('#search').css('visibility','hidden'); - var r = setTimeout(function(){ - $('#mobile-font').hide(); - setTimeout(function(){ - $('#search').css('visibility','visible'); - },1000); - },3000); - var size = Number($('#mobile-font-size1').val()); - - fontIncrease.addEventListener('touchstart', function(event) { - clearInterval(r); - size = size * 1.2; - $('#mobile-font-size1').val(size); - $('textarea').css('font-size',size); - $('.keymanweb-input').css('font-size',size).focus(); - r = setTimeout(function(){ - $('#mobile-font').hide(); - setTimeout(function(){ - $('#search').css('visibility','visible'); - },600); - },2000); - }); - - fontDecrease.addEventListener('touchstart', function(event) { - clearInterval(r); - size = size / 1.2; - $('#mobile-font-size1').val(size); - $('textarea').css('font-size',size); - $('.keymanweb-input').css('font-size',size).focus(); - r = setTimeout(function(){ - $('#mobile-font').hide(); - setTimeout(function(){ - $('#search').css('visibility','visible'); - },600); - },2000); - }); - - }); - - setTimeout(function(){ - $('.kmw_button_a').click(function(){ - if ($(this).parent().attr('id') == 'kmw_btn_off') { - //$('body').removeClass('osk-always-visible'); - $('#message').blur(); - } else { - //$('body').addClass('osk-always-visible'); - } - }); - },5000); - - - /* Setup the bookmarklet */ - $('#bookmarklet div a').click( function() { - alert("Don't click this: drag it to your Bookmarks toolbar. Then you can click the '" + $(this).text() + "' bookmark on any web page to access your web keyboard on that page!") - return false; - }); - - // Detect desktop browser height and modify css - function updateSize(){ - // Set OSK size/position - p = new Object(); - - var height = $(window).height(); - var width = $(window).width(); - var appPos = $('#app').position(); - var appLeft = appPos.left; - - // We can't proceed any further if KMW hasn't loaded yet. - // No point handling resizes until that's occurred. - if(!getKeymanWeb() || !getKeymanWeb().osk) { - return; - } - - // Adjust the message box height only if a desktop browser - if(!getKeymanWeb().util.isTouchDevice()) - { - if (height <= 768) { - // Hide footer - $('footer').hide(); - $('#message').css('height', '209px'); - p['height'] = 264; - } - if(height > 768) { - $('#message').css('height', '260px'); - if (height < 820) { - p['height'] = 246; - $('footer').hide(); - }else if(height < 860){ - p['height'] = 246; - $('footer').show(); - }else{ - p['height'] = 264; - $('footer').show(); - } - } - } - p['top'] = $('#app').offset().top + $('#app').outerHeight() + 8; - p['left'] = appLeft + 15; - p['width'] = 710; - - // Update keyboard position and size - getKeymanWeb().osk.setRect(p); - } - - window.onresize = updateSize; - - //$('#example').css('height','50px'); - - /* Check for result for other modules in the query string */ - var result = $.urlParam('result'); - if(result) - { - var module = $.urlParam('module'); - var error = $.urlParam('error'); - var data = $.urlParam('data'); - if(result == 'error') - { - showError(module, error, redirectHome); - } - return; - } - - $('#search').click(function(event){ - event.preventDefault(); - if($('#search').attr('disabled') == 'disabled') return; - var newURL='https://www.google.com/search?q='+encodeURIComponent($('#message').val()); - window.open(newURL,'_blank'); - //location.href = 'http://www.google.com/search?q='+encodeURIComponent($('#message').val()); - }); - - var copy = document.getElementById('copy'); - var clipboard = new ClipboardJS(copy); - var isSupported = ClipboardJS.isSupported('copy'); - if (isSupported === false) { - $('#copy').attr('class', 'linksOff'); - $('#copy').attr('disabled', 'disabled'); - $('#copy').hide(); - } - - - clipboard.on('success', function(e) { - //console.log(e); - $('#copy').children('p').html('Copied'); - e.clearSelection(); - setTimeout(function(){ - $('#copy').children('p').html('Copy'); - },2000); - }); - - clipboard.on('error', function(e) { - //console.log(e); - $('#copy').children('p').html('Copy Failed'); - e.clearSelection(); - setTimeout(function(){ - $('#copy').children('p').html('Copy'); - },2000); - }); - - // Email subscribe form - $('.subscribe').click(function(){ - $('#mc-embedded-subscribe-form').submit(); - }); - - //Cannot detect change of content from KMW, so use a timer instead to refresh button state - //$('#message').bind("keypress keyup keydown change click focus blur", refreshButtons); - window.setInterval(refreshButtons,200); -}); - -var afterInitRun = false; -function afterInit() { - if(afterInitRun) { - return; - } - afterInitRun = true; - - // Focus on message box - if (!!$('.messageBox').length) { - getKeymanWeb().moveToElement('message'); - } - // On touch devices, this is necessary (but not sufficient) for ClipboardJS compatibility. - // Must take affect AFTER KMW has initialized. - $('#message').removeAttr('disabled'); - - getKeymanWeb().util.attachDOMEvent(window,'orientationchange', function() { - window.scrollTo(0,1); - },false); - - //getKeymanWeb().addEventListener('keyboardloaded',function(p){changeKeyboard(p['keyboardName']);}); - getKeymanWeb().addEventListener('keyboardchange',function(p){if(!pageLoading) changeKeyboard(p['internalName'],p['languageCode'],p);}); -} - -function refreshButtons() { - var len=getKMWInputLength('message'); // returns -1 for desktop page element - - if(len < 0) { - // refreshButtons runs via setInterval. It is possible for one call to persist through page reload, - // in which case the #message element is unavailable. - var message = $('#message').val(); - if(!message) { - return; - } - - len = message.length; - } - - // if message length is 0, use white SM buttons - if(len == 0) { - $('#buttons').children('div').attr('class','linksOff'); - $('#buttons div').attr('disabled', 'disabled'); - } else { - $('#buttons').children('div').attr('class','links'); - $('#buttons div').removeAttr('disabled'); - } -} - -function getKMWInputElement(id){ - var i,len; - try - { - var eList=document.getElementsByClassName('KMW_input'); - if(eList && eList.length > 0) - { - for(i=0; i
    '); - box.append($('
    ').append(message)); - $('body').append(box); - return box; -} - -var boxVisible = false; - -function showBox(module, message, callback) -{ - boxVisible = true; - var box = $('
    '); - box.append($('
    ').append(message)); - box.append($(' - 1 - - - - - - - -
    -
    -
    Keyboard Selection menu
    -
    -

    Open Search to get your keyboard

    -
    - - -
    -
    - - - - -
    - -
    - - -
    - -
    - - -
    -
    - -
    - -
    -
    -
    - -
    -
    -

    No example is available for this keyboard.

    -
    -
    -
    -
    -
    - -
    - - - - - - - - + + +
    +
    +
    + + KeymanWeb.com + + + + +
    +
    +
    Keyboard Selection menu
    +
    +

    Open Search to get your keyboard

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

    No example is available for this keyboard.

    +
    +
    +
    +
    + +
    + + + + + + diff --git a/prog/languageexample.php b/prog/languageexample.php index 8340ee9..4e687cc 100644 --- a/prog/languageexample.php +++ b/prog/languageexample.php @@ -1,57 +1,57 @@ -help_keyman_com; - $morehelp = - " "; - return $morehelp; - } - - if($data !== FALSE) { - echo $data; - } else { - echo "No example is available"; - } - - // echo renderHelpIcon($keyboard, $language); -?> +help_keyman_com; + $morehelp = + " "; + return $morehelp; + } + + if($data !== FALSE) { + echo $data; + } else { + echo "No example is available"; + } + + // echo renderHelpIcon($keyboard, $language); +?> diff --git a/prog/renderLanguageExample.php b/prog/renderLanguageExample.php index 1a0d9b3..a1ccd87 100644 --- a/prog/renderLanguageExample.php +++ b/prog/renderLanguageExample.php @@ -1,296 +1,296 @@ -SERVER_api_keyman_com . "/keyboard/" . rawurlencode($keyboard); - $json = @file_get_contents($string); - if($json === FALSE) { - return FALSE; - } - - $obj = @json_decode($json, true); - if($obj === NULL) { - return FALSE; - } - - if(!isset($obj['languages'][$language])) { - return false; - } - - $lang = $obj['languages'][$language]; - - if(isset($lang['examples'])) { - $result = DisplayExamples($lang['examples'], $language); - } else if(isset($lang['example'])) { - $result = DisplayExample($lang['example'], false, $language); - } else { - $result = FALSE; - } - - return $result ? ("Example: " . $result) : FALSE; - } - - function DisplayExample($x, $table = false, $language = '') - { - global $morehelp; - $result = ''; - - if(is_array($x)) - { - $keys = KeyRenderer::renderInternal($x['keys'], $table); - $out = $x['text']; - if(isset($x['note'])) $note = " ({$x['note']})"; else $note = ''; - - if($table) - $result .= "$out{$x['note']}$keys"; - else - $result .= - "To enter ". - "$out$note, ". - "type  ". - "$keys$morehelp"; - //" to get "; - //if(isset($x['note'])) echo " ({$x['note']})"; - //echo " $morehelp"; - } - else if(!$table) - $result .= "$x $morehelp"; - return $result; - } - - class KeyRenderer - { - public static function render($s) - { - return "".KeyRenderer::renderInternal($s, true).""; - } - - public static function renderInternal($s, $table = false) - { - $spkey = array("pgup","pgdn","left","right","up","down","ins","del","home","end","enter","tab","esc","caps","bksp","shift","ctrl","alt"); - $spkey2 = array("shift","ctrl","alt"); - - $i = 0; - $r = ''; - while($i < strlen($s)) - { - $endspan = false; - $ch = $s[$i]; - if($ch == '[' && $i < strlen($s)-1) - { - $i++; $ch = $s[$i]; - if($ch == '[') - { - $t = $ch; - } - else if($ch != '[') - { - /* Ctrl+Shift+Alt+key */ - $t = $ch; $i++; - while($i < strlen($s) && $s[$i] != ']') - { - $t .= $s[$i]; - $i++; - } - $ch = $t[strlen($t)-1]; $t1 = $t; - $t = substr($t, 0, strlen($t)-1); - $r .= ""; - - /* Special keys */ - $x = strpos($t1,'!'); $u = ""; - if($x !== FALSE) - { - $ks = strtolower(substr($t1,$x+1,strlen($t1)-$x-1)); - if(array_search($ks,$spkey) !== FALSE) - { - $u = $ks; - $kn = $ks; - if(array_search($ks,$spkey2) !== FALSE) $kn .= "2"; - $u = "" . $ks . ""; - $t = substr($t,0,$x); $ch = ''; - } - } - - if(strpos($t, 'C') !== FALSE) $r .= "Ctrl"; - if(strpos($t, 'S') !== FALSE) $r .= "Shift"; - if(strpos($t, 'A') !== FALSE) $r .= "Alt"; - $r .= $u; - $endspan = true; - } - } - if($ch <> '') - { - $chv = ord($ch); - $r .= "".htmlentities($ch, ENT_QUOTES).""; - } - if($endspan) $r .= ""; - $i++; - } - - if($table) - { - $r .= ""; - $i = 0; - while($i < strlen($s)) - { - $endspan = false; - $ch = $s[$i]; - if($ch == '[' && $i < strlen($s)-1) - { - $i++; $ch = $s[$i]; - $t = $ch; - if($ch != '[') - { - /* Ctrl+Shift+Alt+key */ - $i++; - while($i < strlen($s) && $s[$i] != ']') - { - $t .= $s[$i]; - $i++; - } - $ch = $t[strlen($t)-1]; $t1 = $t; - $t = substr($t, 0, strlen($t)-1); - $r .= ""; - - /* Special keys */ - $x = strpos($t1,'!'); $u = ""; - if($x !== FALSE) - { - $kn = substr($t1,$x+1,strlen($t1)-$x-1); - $ks = strtolower($kn); - if(array_search($ks,$spkey) !== FALSE) - { - $u = $kn; - $t = substr($t,0,$x); $ch = ''; - } - } - if(strpos($t, 'C') !== FALSE) $r .= "Ctrl+"; - if(strpos($t, 'S') !== FALSE) $r .= "Shift+"; - if(strpos($t, 'A') !== FALSE) $r .= "Alt+"; - $r .= $u; - $endspan = true; - } - } - - if($ch == ' ') $r .= "Space"; else if($ch <> '') $r .= htmlentities($ch, ENT_QUOTES); - if($endspan) $r .= " "; - $i++; - } - $r .= ""; - } - - return $r; - } - } - - $keyRenderer = new KeyRenderer(); // Can also be used statically - - //------------------------------------------------------------------------------------------ - - /** - * Render language example from kps 17.0 format examples - * - * Key format (from kmp-json-file.ts): - * - * A space-separated list of keys. - * - modifiers indicated with "+" - * - spacebar is "space" - * - plus key is "shift+=" or "plus" on US English (all other punctuation as per key cap). - * - Hardware modifiers are: "shift", "ctrl", "alt", "left-ctrl", - * "right-ctrl", "left-alt", "right-alt" - * - Key caps should generally be their character for desktop (Latin script - * case insensitive), or the actual key cap for touch - * - Caps Lock should be indicated with "caps-on", "caps-off" - * - * e.g. "shift+a b right-alt+c space plus z z z" represents something like: "Ab{AltGr+C} +zzz" - */ - function RenderExamplesKeys($keys) { - $modifiers = [ - 'left-alt' => 'Left Alt', - 'right-alt' => 'Right Alt', - 'left-ctrl' => 'Left Ctrl', - 'left-control' => 'Left Ctrl', - 'right-ctrl' => 'Right Ctrl', - 'right-control' => 'Right Ctrl', - 'shift' => 'Shift', - 'ctrl' => 'Ctrl', - 'control' => 'Ctrl', - 'alt' => 'Alt', - 'caps-on' => 'Caps (on)', - 'caps-off' => 'Caps (off)', - ]; - - // space separated - $keys = explode(' ', $keys); - foreach($keys as $chord) { - if(empty($chord)) { - continue; - } - $chord = explode('+', $chord); - $chord_keys = []; - foreach($chord as $key) { - $class=''; - $bkey = strtolower($key); - if($bkey == 'space') { - $key = ' '; $class=' class="space"'; - } else if($bkey == 'plus') { - $key = '+'; - } else if(array_key_exists($bkey, $modifiers)) { - $key = $modifiers[$bkey]; - $class=' class="modifier"'; - } else { - $key = htmlspecialchars($key); - } - array_push($chord_keys, "$key"); - } - $result .= implode('+', $chord_keys) . " "; - } - return trim($result); - } - - function DisplayExamples($examples, $language = '') - { - global $morehelp; - $result = ''; - - if(!is_array($examples) || count($examples) == 0) { - return FALSE; - } - - $example = $examples[0]; - if(empty($example['keys'])) { - return FALSE; - } - - $keys = RenderExamplesKeys($example['keys']); - $out = htmlspecialchars($example['text']); - $note = isset($example['note']) ? " (" . htmlspecialchars($example['note']) . ")" : ""; - - $result .= - "To enter ". - "$out$note, ". - "type  ". - "$keys$morehelp"; - - return $result; - } +SERVER_api_keyman_com . "/keyboard/" . rawurlencode($keyboard); + $json = @file_get_contents($string); + if($json === FALSE) { + return FALSE; + } + + $obj = @json_decode($json, true); + if($obj === NULL) { + return FALSE; + } + + if(!isset($obj['languages'][$language])) { + return false; + } + + $lang = $obj['languages'][$language]; + + if(isset($lang['examples'])) { + $result = DisplayExamples($lang['examples'], $language); + } else if(isset($lang['example'])) { + $result = DisplayExample($lang['example'], false, $language); + } else { + $result = FALSE; + } + + return $result ? ("Example: " . $result) : FALSE; + } + + function DisplayExample($x, $table = false, $language = '') + { + global $morehelp; + $result = ''; + + if(is_array($x)) + { + $keys = KeyRenderer::renderInternal($x['keys'], $table); + $out = $x['text']; + if(isset($x['note'])) $note = " ({$x['note']})"; else $note = ''; + + if($table) + $result .= "$out{$x['note']}$keys"; + else + $result .= + "To enter ". + "$out$note, ". + "type  ". + "$keys$morehelp"; + //" to get "; + //if(isset($x['note'])) echo " ({$x['note']})"; + //echo " $morehelp"; + } + else if(!$table) + $result .= "$x $morehelp"; + return $result; + } + + class KeyRenderer + { + public static function render($s) + { + return "".KeyRenderer::renderInternal($s, true).""; + } + + public static function renderInternal($s, $table = false) + { + $spkey = array("pgup","pgdn","left","right","up","down","ins","del","home","end","enter","tab","esc","caps","bksp","shift","ctrl","alt"); + $spkey2 = array("shift","ctrl","alt"); + + $i = 0; + $r = ''; + while($i < strlen($s)) + { + $endspan = false; + $ch = $s[$i]; + if($ch == '[' && $i < strlen($s)-1) + { + $i++; $ch = $s[$i]; + if($ch == '[') + { + $t = $ch; + } + else if($ch != '[') + { + /* Ctrl+Shift+Alt+key */ + $t = $ch; $i++; + while($i < strlen($s) && $s[$i] != ']') + { + $t .= $s[$i]; + $i++; + } + $ch = $t[strlen($t)-1]; $t1 = $t; + $t = substr($t, 0, strlen($t)-1); + $r .= ""; + + /* Special keys */ + $x = strpos($t1,'!'); $u = ""; + if($x !== FALSE) + { + $ks = strtolower(substr($t1,$x+1,strlen($t1)-$x-1)); + if(array_search($ks,$spkey) !== FALSE) + { + $u = $ks; + $kn = $ks; + if(array_search($ks,$spkey2) !== FALSE) $kn .= "2"; + $u = "" . $ks . ""; + $t = substr($t,0,$x); $ch = ''; + } + } + + if(strpos($t, 'C') !== FALSE) $r .= "Ctrl"; + if(strpos($t, 'S') !== FALSE) $r .= "Shift"; + if(strpos($t, 'A') !== FALSE) $r .= "Alt"; + $r .= $u; + $endspan = true; + } + } + if($ch <> '') + { + $chv = ord($ch); + $r .= "".htmlentities($ch, ENT_QUOTES).""; + } + if($endspan) $r .= ""; + $i++; + } + + if($table) + { + $r .= ""; + $i = 0; + while($i < strlen($s)) + { + $endspan = false; + $ch = $s[$i]; + if($ch == '[' && $i < strlen($s)-1) + { + $i++; $ch = $s[$i]; + $t = $ch; + if($ch != '[') + { + /* Ctrl+Shift+Alt+key */ + $i++; + while($i < strlen($s) && $s[$i] != ']') + { + $t .= $s[$i]; + $i++; + } + $ch = $t[strlen($t)-1]; $t1 = $t; + $t = substr($t, 0, strlen($t)-1); + $r .= ""; + + /* Special keys */ + $x = strpos($t1,'!'); $u = ""; + if($x !== FALSE) + { + $kn = substr($t1,$x+1,strlen($t1)-$x-1); + $ks = strtolower($kn); + if(array_search($ks,$spkey) !== FALSE) + { + $u = $kn; + $t = substr($t,0,$x); $ch = ''; + } + } + if(strpos($t, 'C') !== FALSE) $r .= "Ctrl+"; + if(strpos($t, 'S') !== FALSE) $r .= "Shift+"; + if(strpos($t, 'A') !== FALSE) $r .= "Alt+"; + $r .= $u; + $endspan = true; + } + } + + if($ch == ' ') $r .= "Space"; else if($ch <> '') $r .= htmlentities($ch, ENT_QUOTES); + if($endspan) $r .= " "; + $i++; + } + $r .= ""; + } + + return $r; + } + } + + $keyRenderer = new KeyRenderer(); // Can also be used statically + + //------------------------------------------------------------------------------------------ + + /** + * Render language example from kps 17.0 format examples + * + * Key format (from kmp-json-file.ts): + * + * A space-separated list of keys. + * - modifiers indicated with "+" + * - spacebar is "space" + * - plus key is "shift+=" or "plus" on US English (all other punctuation as per key cap). + * - Hardware modifiers are: "shift", "ctrl", "alt", "left-ctrl", + * "right-ctrl", "left-alt", "right-alt" + * - Key caps should generally be their character for desktop (Latin script + * case insensitive), or the actual key cap for touch + * - Caps Lock should be indicated with "caps-on", "caps-off" + * + * e.g. "shift+a b right-alt+c space plus z z z" represents something like: "Ab{AltGr+C} +zzz" + */ + function RenderExamplesKeys($keys) { + $modifiers = [ + 'left-alt' => 'Left Alt', + 'right-alt' => 'Right Alt', + 'left-ctrl' => 'Left Ctrl', + 'left-control' => 'Left Ctrl', + 'right-ctrl' => 'Right Ctrl', + 'right-control' => 'Right Ctrl', + 'shift' => 'Shift', + 'ctrl' => 'Ctrl', + 'control' => 'Ctrl', + 'alt' => 'Alt', + 'caps-on' => 'Caps (on)', + 'caps-off' => 'Caps (off)', + ]; + + // space separated + $keys = explode(' ', $keys); + foreach($keys as $chord) { + if(empty($chord)) { + continue; + } + $chord = explode('+', $chord); + $chord_keys = []; + foreach($chord as $key) { + $class=''; + $bkey = strtolower($key); + if($bkey == 'space') { + $key = ' '; $class=' class="space"'; + } else if($bkey == 'plus') { + $key = '+'; + } else if(array_key_exists($bkey, $modifiers)) { + $key = $modifiers[$bkey]; + $class=' class="modifier"'; + } else { + $key = htmlspecialchars($key); + } + array_push($chord_keys, "$key"); + } + $result .= implode('+', $chord_keys) . " "; + } + return trim($result); + } + + function DisplayExamples($examples, $language = '') + { + global $morehelp; + $result = ''; + + if(!is_array($examples) || count($examples) == 0) { + return FALSE; + } + + $example = $examples[0]; + if(empty($example['keys'])) { + return FALSE; + } + + $keys = RenderExamplesKeys($example['keys']); + $out = htmlspecialchars($example['text']); + $note = isset($example['note']) ? " (" . htmlspecialchars($example['note']) . ")" : ""; + + $result .= + "To enter ". + "$out$note, ". + "type  ". + "$keys$morehelp"; + + return $result; + } From 28d4ba080b7abf58fcd58e8a9c1188d847a7f9d4 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Mon, 6 Oct 2025 11:04:57 +0700 Subject: [PATCH 22/36] chore" remove `resources/.bootstrap-registry` --- resources/.bootstrap-registry | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 resources/.bootstrap-registry diff --git a/resources/.bootstrap-registry b/resources/.bootstrap-registry deleted file mode 100644 index 53924c3..0000000 --- a/resources/.bootstrap-registry +++ /dev/null @@ -1,22 +0,0 @@ -assets/img/gfm-limits-1.png assets/img/gfm-limits-1.324a4970ffdfdfb8e66e63df5d9d79d1725793c3.png -assets/img/gfm-limits-2.png assets/img/gfm-limits-2.3974f1a1df6cecf9a2b792fafa21f190214639f2.png -assets/img/gfm-limits-3.png assets/img/gfm-limits-3.4b6a74bee45225808fafb33733b171b917bef90b.png -assets/img/gfm-limits-4.png assets/img/gfm-limits-4.f871c142a8f9e023bb34cc656c0f67ef4e15e555.png -assets/img/gfmalerts.png assets/img/gfmalerts.1da0d82845f3f5d43dcbe509f1bdee3926b176e5.png -assets/js/sentry.js assets/js/sentry.98285d6b1fd4b5238be42da594ef71901b5d9217.js -assets/sil-logos-2024/sil-logo-abbysinica.png assets/sil-logos-2024/sil-logo-abbysinica.f1b63893af9963b15b643b033ae522b52f28134b.png -assets/sil-logos-2024/sil-logo-andika-v1.png assets/sil-logos-2024/sil-logo-andika-v1.e53568611d3460322856840078f18d507c7832a6.png -assets/sil-logos-2024/sil-logo-andika-v2.png assets/sil-logos-2024/sil-logo-andika-v2.d93c755ddb2056b304d6f8be5adff568ea86c00d.png -assets/sil-logos-2024/sil-logo-annapurna.png assets/sil-logos-2024/sil-logo-annapurna.c85665d2aa7ed9dd919a5f6044336a13d17e0c2a.png -assets/sil-logos-2024/sil-logo-tai-heritage-pro.png assets/sil-logos-2024/sil-logo-tai-heritage-pro.0cd269e5adefc991b75d32cb359c23b2fe10cc03.png -Assets.php -builder.inc.sh -docker.inc.sh -GFMAlerts.php -ImageRandomizer.php -JsonApiFailure.php -keyman-local-ports.inc.sh -KeymanHosts.php -KeymanSentry.php -KeymanVersion.php -MarkdownHost.php From 6ef0acafb99984899f9df8cde361ccd979bece7e Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Mon, 6 Oct 2025 12:27:53 +0700 Subject: [PATCH 23/36] Revert "feat: introduce and start devices styling, apply drag between kb and textarea, and more (note-to-self: these features are not finished but require this commit because of switching to macos)" This reverts commit ed07a5a5d4b0ef0448ab3be626aed913ca8e34fb. --- .github/multi-labeler.yml | 86 ++++----- .github/workflows/add-to-keyman-project.yml | 38 ++-- .github/workflows/ci.yml | 146 +++++++-------- .github/workflows/labeler.yml | 30 ++-- .gitignore | 28 +-- .htaccess | 94 +++++----- _includes/2020/WebKeymanComSentry.php | 40 ++--- _includes/autoload.php | 48 ++--- inc/servervars.php | 188 ++++++++++---------- 9 files changed, 349 insertions(+), 349 deletions(-) diff --git a/.github/multi-labeler.yml b/.github/multi-labeler.yml index 95ad40b..a8d5e25 100644 --- a/.github/multi-labeler.yml +++ b/.github/multi-labeler.yml @@ -1,43 +1,43 @@ -version: v1 - -# This file adds labels based on the scopes in -# keymanapp/keyman:resources/scopes/commit-types.json -# Currently it must be manually kept up to date. Not all labels are added, only -# common ones. The others are commented out. - - -labels: - # - # conventional commit / semantic PR styles - # - - - label: 'auto' - matcher: - title: '^auto(\(|:)' - - label: 'change' - matcher: - title: '^change(\(|:)' - - label: 'chore' - matcher: - title: '^chore(\(|:)' - - label: 'docs' - matcher: - title: '^docs(\(|:)' - - label: 'feat' - matcher: - title: '^feat(\(|:)' - - label: 'fix' - matcher: - title: '^fix(\(|:)' - - label: 'maint' - matcher: - title: '^maint(\(|:)' - - label: 'refactor' - matcher: - title: '^refactor(\(|:)' - - label: 'style' - matcher: - title: '^style(\(|:)' - - label: 'test' - matcher: - title: '^test(\(|:)' +version: v1 + +# This file adds labels based on the scopes in +# keymanapp/keyman:resources/scopes/commit-types.json +# Currently it must be manually kept up to date. Not all labels are added, only +# common ones. The others are commented out. + + +labels: + # + # conventional commit / semantic PR styles + # + + - label: 'auto' + matcher: + title: '^auto(\(|:)' + - label: 'change' + matcher: + title: '^change(\(|:)' + - label: 'chore' + matcher: + title: '^chore(\(|:)' + - label: 'docs' + matcher: + title: '^docs(\(|:)' + - label: 'feat' + matcher: + title: '^feat(\(|:)' + - label: 'fix' + matcher: + title: '^fix(\(|:)' + - label: 'maint' + matcher: + title: '^maint(\(|:)' + - label: 'refactor' + matcher: + title: '^refactor(\(|:)' + - label: 'style' + matcher: + title: '^style(\(|:)' + - label: 'test' + matcher: + title: '^test(\(|:)' diff --git a/.github/workflows/add-to-keyman-project.yml b/.github/workflows/add-to-keyman-project.yml index b8c5b74..c55d0b2 100644 --- a/.github/workflows/add-to-keyman-project.yml +++ b/.github/workflows/add-to-keyman-project.yml @@ -1,19 +1,19 @@ -name: Add new issues and pull requests to projects - -on: - pull_request: - types: - - opened - issues: - types: - - opened - -jobs: - add-to-project: - name: Add new issues and pull requests to project - runs-on: ubuntu-latest - steps: - - uses: actions/add-to-project@v1.0.2 - with: - project-url: https://github.com/orgs/keymanapp/projects/1 - github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} +name: Add new issues and pull requests to projects + +on: + pull_request: + types: + - opened + issues: + types: + - opened + +jobs: + add-to-project: + name: Add new issues and pull requests to project + runs-on: ubuntu-latest + steps: + - uses: actions/add-to-project@v1.0.2 + with: + project-url: https://github.com/orgs/keymanapp/projects/1 + github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f4abad..3f53696 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,73 +1,73 @@ -name: CI - -on: [pull_request] - -jobs: - - build-test: - runs-on: ubuntu-latest - env: - KEYMANHOSTS_TIER: TIER_TEST - # Composer started complaining about running as root, but we don't care in a GHA - COMPOSER_ALLOW_SUPERUSER: 1 - - steps: - - name: Checkout - uses: actions/checkout@v3.5.2 - - # Build the docker image and create link to vendor/ dependencies - - name: Build the Docker image - shell: bash - run: | - echo "TIER_TEST" > tier.txt - ./build.sh configure build start - env: - fail-fast: true - - # - # Finally, run the tests; note that this is almost all replicated in build.sh; here logging is reduced (TODO sync) - # - - name: PHP unit tests - shell: bash - run: | - docker exec web-keyman-com-app sh -c "vendor/bin/phpunit --testdox" - - - name: Lint - shell: bash - run: | - ( set +e; set +o pipefail; find . -name '*.php' | grep -v '/vendor/' | xargs -n 1 -d '\n' php -l | grep -v "No syntax errors detected"; exit ${PIPESTATUS[2]} ) - - - name: Check broken links - shell: bash - run: | - set +e; - set +o pipefail; - npx broken-link-checker http://localhost:8057 --ordered --recursive --requests 50 --host-requests 50 -e --filter-level 3 | \ - grep -E "BROKEN|Getting links from" | \ - grep -B 1 "BROKEN" - exit ${PIPESTATUS[0]} - - - name: Check PHP errors - shell: bash - run: | - CONTAINER=`docker container ls -l -q` - if docker container logs $CONTAINER 2>&1 | grep -q 'php7'; then - echo 'PHP reported errors or warnings:' - docker container logs $CONTAINER 2>&1 | grep 'php7' - exit 1 - else - echo 'No PHP errors found' - exit 0 - fi - # - # If any of the tests fail, let's grab a bit more detail on the environment - # - - name: Report errors - if: ${{ failure() }} - shell: bash - run: | - CONTAINER=`docker container ls -l -q` - echo "--- tier.txt ---" - cat tier.txt - echo "--- PHP errors in Docker log ---" - docker container logs $CONTAINER 2>&1 | grep 'php7' +name: CI + +on: [pull_request] + +jobs: + + build-test: + runs-on: ubuntu-latest + env: + KEYMANHOSTS_TIER: TIER_TEST + # Composer started complaining about running as root, but we don't care in a GHA + COMPOSER_ALLOW_SUPERUSER: 1 + + steps: + - name: Checkout + uses: actions/checkout@v3.5.2 + + # Build the docker image and create link to vendor/ dependencies + - name: Build the Docker image + shell: bash + run: | + echo "TIER_TEST" > tier.txt + ./build.sh configure build start + env: + fail-fast: true + + # + # Finally, run the tests; note that this is almost all replicated in build.sh; here logging is reduced (TODO sync) + # + - name: PHP unit tests + shell: bash + run: | + docker exec web-keyman-com-app sh -c "vendor/bin/phpunit --testdox" + + - name: Lint + shell: bash + run: | + ( set +e; set +o pipefail; find . -name '*.php' | grep -v '/vendor/' | xargs -n 1 -d '\n' php -l | grep -v "No syntax errors detected"; exit ${PIPESTATUS[2]} ) + + - name: Check broken links + shell: bash + run: | + set +e; + set +o pipefail; + npx broken-link-checker http://localhost:8057 --ordered --recursive --requests 50 --host-requests 50 -e --filter-level 3 | \ + grep -E "BROKEN|Getting links from" | \ + grep -B 1 "BROKEN" + exit ${PIPESTATUS[0]} + + - name: Check PHP errors + shell: bash + run: | + CONTAINER=`docker container ls -l -q` + if docker container logs $CONTAINER 2>&1 | grep -q 'php7'; then + echo 'PHP reported errors or warnings:' + docker container logs $CONTAINER 2>&1 | grep 'php7' + exit 1 + else + echo 'No PHP errors found' + exit 0 + fi + # + # If any of the tests fail, let's grab a bit more detail on the environment + # + - name: Report errors + if: ${{ failure() }} + shell: bash + run: | + CONTAINER=`docker container ls -l -q` + echo "--- tier.txt ---" + cat tier.txt + echo "--- PHP errors in Docker log ---" + docker container logs $CONTAINER 2>&1 | grep 'php7' diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 99a60dd..f0d4218 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -1,15 +1,15 @@ -name: "Pull Request Labeler" -on: -- pull_request - -jobs: - triage: - if: github.repository == 'keymanapp/keymanweb.com' - runs-on: ubuntu-latest - steps: - - name: Update labels based on PR title - id: labeler - uses: fuxingloh/multi-labeler@f5bd7323b53b0833c1e4ed8d7b797ae995ef75b4 # v2.0.1 - with: - github-token: ${{secrets.GITHUB_TOKEN}} - config-path: .github/multi-labeler.yml +name: "Pull Request Labeler" +on: +- pull_request + +jobs: + triage: + if: github.repository == 'keymanapp/keymanweb.com' + runs-on: ubuntu-latest + steps: + - name: Update labels based on PR title + id: labeler + uses: fuxingloh/multi-labeler@f5bd7323b53b0833c1e4ed8d7b797ae995ef75b4 # v2.0.1 + with: + github-token: ${{secrets.GITHUB_TOKEN}} + config-path: .github/multi-labeler.yml diff --git a/.gitignore b/.gitignore index bb83a5b..bbdab99 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,14 @@ -.idea/** -cdn/deploy - -/vendor -.data/ - -# Shared files are bootstrapped: -resources/bootstrap.inc.sh -resources/.bootstrap-version -resources/.bootstrap-registry -_common/ - -# State files -_control/debug +.idea/** +cdn/deploy + +/vendor +.data/ + +# Shared files are bootstrapped: +resources/bootstrap.inc.sh +resources/.bootstrap-version +resources/.bootstrap-registry +_common/ + +# State files +_control/debug diff --git a/.htaccess b/.htaccess index ad75644..3605a73 100644 --- a/.htaccess +++ b/.htaccess @@ -1,47 +1,47 @@ - -php_value display_errors off -php_value display_startup_errors off - - - php_value display_startup_errors on - php_value display_errors stderr - - - - - Header set Access-Control-Allow-Origin "*" - - - AddType font/ttf .ttf - AddType application/javascript .js - - AddCharset UTF-8 .js - - - RewriteEngine on - RewriteBase / - - - -# Keymanweb.com 2.0 rewrite rules for Keymanweb.com 1.0 /go/lang/kbd urls - -# Rewrite /go/lang/kbd/app[?...] to /?kmwlang=lang,kmwkbd=kbd -RewriteRule "^go/([^/]+)/([^/]+)/([^?]+)(\?)?(.+)?$" "/index.php?kmwlang=$1&kmwkbd=Keyboard_$2&$5" - -# Rewrite /go/lang/kbd[?...] to /?kmwlang=lang,kmwkbd=kbd -RewriteRule "^go/([^/]+)/([^?]+)(\?)?(.+)?$" "/index.php?kmwlang=$1&kmwkbd=Keyboard_$2&$4" - -# Keymanweb.com 2.0 rewrite rules for Keymanweb.com 1.0 /lang/app.php urls - -# Redirect /lang/app?kmwlang=lang,kmwkbd=kbd to /?kmwlang=lang,kmwkbd=kbd -RedirectMatch "^../[^?]+?kmwlang=(.+)&kmwkbd=(.+)(&(.+))?$" "/go/$1/$2" - -# Redirect /lang/app to / -RedirectMatch "^../[^?]+$" "/" - -# Redirect /mini/* to / -RedirectMatch "^mini/" "/" - -# Control rules -RewriteRule "^_control/info$" "_control/info.php" [END] -RewriteRule "^_control/ready$" "_control/ready.php" [END] + +php_value display_errors off +php_value display_startup_errors off + + + php_value display_startup_errors on + php_value display_errors stderr + + + + + Header set Access-Control-Allow-Origin "*" + + + AddType font/ttf .ttf + AddType application/javascript .js + + AddCharset UTF-8 .js + + + RewriteEngine on + RewriteBase / + + + +# Keymanweb.com 2.0 rewrite rules for Keymanweb.com 1.0 /go/lang/kbd urls + +# Rewrite /go/lang/kbd/app[?...] to /?kmwlang=lang,kmwkbd=kbd +RewriteRule "^go/([^/]+)/([^/]+)/([^?]+)(\?)?(.+)?$" "/index.php?kmwlang=$1&kmwkbd=Keyboard_$2&$5" + +# Rewrite /go/lang/kbd[?...] to /?kmwlang=lang,kmwkbd=kbd +RewriteRule "^go/([^/]+)/([^?]+)(\?)?(.+)?$" "/index.php?kmwlang=$1&kmwkbd=Keyboard_$2&$4" + +# Keymanweb.com 2.0 rewrite rules for Keymanweb.com 1.0 /lang/app.php urls + +# Redirect /lang/app?kmwlang=lang,kmwkbd=kbd to /?kmwlang=lang,kmwkbd=kbd +RedirectMatch "^../[^?]+?kmwlang=(.+)&kmwkbd=(.+)(&(.+))?$" "/go/$1/$2" + +# Redirect /lang/app to / +RedirectMatch "^../[^?]+$" "/" + +# Redirect /mini/* to / +RedirectMatch "^mini/" "/" + +# Control rules +RewriteRule "^_control/info$" "_control/info.php" [END] +RewriteRule "^_control/ready$" "_control/ready.php" [END] diff --git a/_includes/2020/WebKeymanComSentry.php b/_includes/2020/WebKeymanComSentry.php index 8b62d8a..a898ee3 100644 --- a/_includes/2020/WebKeymanComSentry.php +++ b/_includes/2020/WebKeymanComSentry.php @@ -1,21 +1,21 @@ -TierName(); - return KeymanSentry::GetBrowserHTML(SENTRY_DSN, $tier == 'stable' ? $kmwbuild : "$kmwbuild-$tier"); - } +TierName(); + return KeymanSentry::GetBrowserHTML(SENTRY_DSN, $tier == 'stable' ? $kmwbuild : "$kmwbuild-$tier"); + } } \ No newline at end of file diff --git a/_includes/autoload.php b/_includes/autoload.php index 83cf2ef..5cfebed 100644 --- a/_includes/autoload.php +++ b/_includes/autoload.php @@ -1,24 +1,24 @@ -r_keymanweb_com; - $staticDomainRoot= KeymanHosts::Instance()->s_keyman_com; - - - function cdn($file) { - global $cdn; - $use_cdn = - KeymanHosts::Instance()->Tier() == KeymanHosts::TIER_PRODUCTION || - KeymanHosts::Instance()->Tier() == KeymanHosts::TIER_STAGING || - (isset($_REQUEST['cdn']) && $_REQUEST['cdn'] == 'force'); - if($use_cdn && $cdn && array_key_exists('/'.$file, $cdn)) { - return "/cdn/deploy{$cdn['/'.$file]}"; - } - return "/cdn/dev/{$file}"; - } - - - function get_major_version($version) { - return preg_replace('/^(\\d+)\\.(\\d+).*$/', '$1.$2', $version); - } - - // Uses official API for version checking, but is not optimized for - // version-checking against multiple release tiers. - function get_keymanweb_version($tier) { - $json = @file_get_contents(KeymanHosts::Instance()->SERVER_api_keyman_com . "/version/web/$tier"); - if($json) { - $json = json_decode($json); - } - - if($json && property_exists($json, 'version')) { - $version = $json->version; - } else { - // If the get-version API fails, we'll use the latest known version - $version = FALLBACK_KMW_VERSION; - } - return $version; - } - - function get_keymanweb_versions() { - $json = @file_get_contents(KeymanHosts::Instance()->SERVER_api_keyman_com . "/version/web/all"); - if($json) { - $json = json_decode($json); - } - - $fallback_version = FALLBACK_KMW_VERSION; - - foreach(array('alpha', 'beta', 'stable') as $tier) { - if(!$json || !property_exists($json, $tier)) { - $version_map[$tier] = $fallback_version; - } else if(version_compare($json->{$tier}, "0.0.1") < 0) { - // The version string didn't properly validate. - $version_map[$tier] = $fallback_version; - } else { - $version_map[$tier] = $json->{$tier}; - } - } - - return $version_map; - } - -?> +r_keymanweb_com; + $staticDomainRoot= KeymanHosts::Instance()->s_keyman_com; + + + function cdn($file) { + global $cdn; + $use_cdn = + KeymanHosts::Instance()->Tier() == KeymanHosts::TIER_PRODUCTION || + KeymanHosts::Instance()->Tier() == KeymanHosts::TIER_STAGING || + (isset($_REQUEST['cdn']) && $_REQUEST['cdn'] == 'force'); + if($use_cdn && $cdn && array_key_exists('/'.$file, $cdn)) { + return "/cdn/deploy{$cdn['/'.$file]}"; + } + return "/cdn/dev/{$file}"; + } + + + function get_major_version($version) { + return preg_replace('/^(\\d+)\\.(\\d+).*$/', '$1.$2', $version); + } + + // Uses official API for version checking, but is not optimized for + // version-checking against multiple release tiers. + function get_keymanweb_version($tier) { + $json = @file_get_contents(KeymanHosts::Instance()->SERVER_api_keyman_com . "/version/web/$tier"); + if($json) { + $json = json_decode($json); + } + + if($json && property_exists($json, 'version')) { + $version = $json->version; + } else { + // If the get-version API fails, we'll use the latest known version + $version = FALLBACK_KMW_VERSION; + } + return $version; + } + + function get_keymanweb_versions() { + $json = @file_get_contents(KeymanHosts::Instance()->SERVER_api_keyman_com . "/version/web/all"); + if($json) { + $json = json_decode($json); + } + + $fallback_version = FALLBACK_KMW_VERSION; + + foreach(array('alpha', 'beta', 'stable') as $tier) { + if(!$json || !property_exists($json, $tier)) { + $version_map[$tier] = $fallback_version; + } else if(version_compare($json->{$tier}, "0.0.1") < 0) { + // The version string didn't properly validate. + $version_map[$tier] = $fallback_version; + } else { + $version_map[$tier] = $json->{$tier}; + } + } + + return $version_map; + } + +?> From d12447992fd6f04ec3ff4e4f6f47dce0386305fb Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Mon, 6 Oct 2025 15:05:40 +0700 Subject: [PATCH 24/36] chore: add files --- SPZITg5E.txt | 1 + cdn/dev/css/kmw.css | 156 ++++++++++++++++++++++---------------------- 2 files changed, 79 insertions(+), 78 deletions(-) create mode 100644 SPZITg5E.txt diff --git a/SPZITg5E.txt b/SPZITg5E.txt new file mode 100644 index 0000000..b18c597 --- /dev/null +++ b/SPZITg5E.txt @@ -0,0 +1 @@ +1c30e207-a415-417b-9ee3-a73057e3add6 \ No newline at end of file diff --git a/cdn/dev/css/kmw.css b/cdn/dev/css/kmw.css index 8e80256..02c9c07 100644 --- a/cdn/dev/css/kmw.css +++ b/cdn/dev/css/kmw.css @@ -1,78 +1,78 @@ -/* -============= -==Reset CSS== -============= -*/ -html, body, div, span, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -abbr, address, cite, code, -del, dfn, em, img, ins, kbd, q, samp, -small, strong, sub, sup, var, -b, i, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, figcaption, figure, -footer, header, hgroup, menu, nav, section, summary, -time, mark, audio, video { - margin:0; - padding:0; - border:0; - outline:0; - vertical-align:baseline; - background:transparent; - } - -a { - margin:0; - padding:0; - vertical-align:baseline; - background:transparent; - } - -article,aside,details,figcaption,figure, -section,header,footer,hgroup,menu,nav { - display:block; - } - -ins { - background-color:#ff9; - text-decoration:none; - } - -mark { - background-color:#ff9; - font-weight:bold; - } - -del { - text-decoration: line-through; - } - -abbr[title], dfn[title] { - border-bottom:1px dotted; - cursor:help; - } - -table { - border-collapse:collapse; - border-spacing:0; - } - -hr { - display:block; - height:1px; - border:0; - border-top:1px solid #cccccc; - padding:0; -} - -button, input, select { - vertical-align:middle; -} - -/* === End of CSS reset rules === */ - -ins.adsbygoogle { - display: none !important; -} +/* +============= +==Reset CSS== +============= +*/ +html, body, div, span, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +abbr, address, cite, code, +del, dfn, em, img, ins, kbd, q, samp, +small, strong, sub, sup, var, +b, i, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, figcaption, figure, +footer, header, hgroup, menu, nav, section, summary, +time, mark, audio, video { + margin:0; + padding:0; + border:0; + outline:0; + vertical-align:baseline; + background:transparent; + } + +a { + margin:0; + padding:0; + vertical-align:baseline; + background:transparent; + } + +article,aside,details,figcaption,figure, +section,header,footer,hgroup,menu,nav { + display:block; + } + +ins { + background-color:#ff9; + text-decoration:none; + } + +mark { + background-color:#ff9; + font-weight:bold; + } + +del { + text-decoration: line-through; + } + +abbr[title], dfn[title] { + border-bottom:1px dotted; + cursor:help; + } + +table { + border-collapse:collapse; + border-spacing:0; + } + +hr { + display:block; + height:1px; + border:0; + border-top:1px solid #cccccc; + padding:0; +} + +button, input, select { + vertical-align:middle; +} + +/* === End of CSS reset rules === */ + +ins.adsbygoogle { + display: none !important; +} From 8d3c477aa3003aecc70ede3fcabbd7387d719ea5 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Mon, 6 Oct 2025 15:25:28 +0700 Subject: [PATCH 25/36] chore: add languageexample.php --- prog/languageexample.php | 114 +++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/prog/languageexample.php b/prog/languageexample.php index 4e687cc..8340ee9 100644 --- a/prog/languageexample.php +++ b/prog/languageexample.php @@ -1,57 +1,57 @@ -help_keyman_com; - $morehelp = - " "; - return $morehelp; - } - - if($data !== FALSE) { - echo $data; - } else { - echo "No example is available"; - } - - // echo renderHelpIcon($keyboard, $language); -?> +help_keyman_com; + $morehelp = + " "; + return $morehelp; + } + + if($data !== FALSE) { + echo $data; + } else { + echo "No example is available"; + } + + // echo renderHelpIcon($keyboard, $language); +?> From e732fd0df6dcc51e38f50bd6f70dd1b6e41c31d9 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Mon, 6 Oct 2025 15:30:19 +0700 Subject: [PATCH 26/36] chore: add renderLanguageExample.php --- prog/renderLanguageExample.php | 592 ++++++++++++++++----------------- 1 file changed, 296 insertions(+), 296 deletions(-) diff --git a/prog/renderLanguageExample.php b/prog/renderLanguageExample.php index a1ccd87..1a0d9b3 100644 --- a/prog/renderLanguageExample.php +++ b/prog/renderLanguageExample.php @@ -1,296 +1,296 @@ -SERVER_api_keyman_com . "/keyboard/" . rawurlencode($keyboard); - $json = @file_get_contents($string); - if($json === FALSE) { - return FALSE; - } - - $obj = @json_decode($json, true); - if($obj === NULL) { - return FALSE; - } - - if(!isset($obj['languages'][$language])) { - return false; - } - - $lang = $obj['languages'][$language]; - - if(isset($lang['examples'])) { - $result = DisplayExamples($lang['examples'], $language); - } else if(isset($lang['example'])) { - $result = DisplayExample($lang['example'], false, $language); - } else { - $result = FALSE; - } - - return $result ? ("Example: " . $result) : FALSE; - } - - function DisplayExample($x, $table = false, $language = '') - { - global $morehelp; - $result = ''; - - if(is_array($x)) - { - $keys = KeyRenderer::renderInternal($x['keys'], $table); - $out = $x['text']; - if(isset($x['note'])) $note = " ({$x['note']})"; else $note = ''; - - if($table) - $result .= "$out{$x['note']}$keys"; - else - $result .= - "To enter ". - "$out$note, ". - "type  ". - "$keys$morehelp"; - //" to get "; - //if(isset($x['note'])) echo " ({$x['note']})"; - //echo " $morehelp"; - } - else if(!$table) - $result .= "$x $morehelp"; - return $result; - } - - class KeyRenderer - { - public static function render($s) - { - return "".KeyRenderer::renderInternal($s, true).""; - } - - public static function renderInternal($s, $table = false) - { - $spkey = array("pgup","pgdn","left","right","up","down","ins","del","home","end","enter","tab","esc","caps","bksp","shift","ctrl","alt"); - $spkey2 = array("shift","ctrl","alt"); - - $i = 0; - $r = ''; - while($i < strlen($s)) - { - $endspan = false; - $ch = $s[$i]; - if($ch == '[' && $i < strlen($s)-1) - { - $i++; $ch = $s[$i]; - if($ch == '[') - { - $t = $ch; - } - else if($ch != '[') - { - /* Ctrl+Shift+Alt+key */ - $t = $ch; $i++; - while($i < strlen($s) && $s[$i] != ']') - { - $t .= $s[$i]; - $i++; - } - $ch = $t[strlen($t)-1]; $t1 = $t; - $t = substr($t, 0, strlen($t)-1); - $r .= ""; - - /* Special keys */ - $x = strpos($t1,'!'); $u = ""; - if($x !== FALSE) - { - $ks = strtolower(substr($t1,$x+1,strlen($t1)-$x-1)); - if(array_search($ks,$spkey) !== FALSE) - { - $u = $ks; - $kn = $ks; - if(array_search($ks,$spkey2) !== FALSE) $kn .= "2"; - $u = "" . $ks . ""; - $t = substr($t,0,$x); $ch = ''; - } - } - - if(strpos($t, 'C') !== FALSE) $r .= "Ctrl"; - if(strpos($t, 'S') !== FALSE) $r .= "Shift"; - if(strpos($t, 'A') !== FALSE) $r .= "Alt"; - $r .= $u; - $endspan = true; - } - } - if($ch <> '') - { - $chv = ord($ch); - $r .= "".htmlentities($ch, ENT_QUOTES).""; - } - if($endspan) $r .= ""; - $i++; - } - - if($table) - { - $r .= ""; - $i = 0; - while($i < strlen($s)) - { - $endspan = false; - $ch = $s[$i]; - if($ch == '[' && $i < strlen($s)-1) - { - $i++; $ch = $s[$i]; - $t = $ch; - if($ch != '[') - { - /* Ctrl+Shift+Alt+key */ - $i++; - while($i < strlen($s) && $s[$i] != ']') - { - $t .= $s[$i]; - $i++; - } - $ch = $t[strlen($t)-1]; $t1 = $t; - $t = substr($t, 0, strlen($t)-1); - $r .= ""; - - /* Special keys */ - $x = strpos($t1,'!'); $u = ""; - if($x !== FALSE) - { - $kn = substr($t1,$x+1,strlen($t1)-$x-1); - $ks = strtolower($kn); - if(array_search($ks,$spkey) !== FALSE) - { - $u = $kn; - $t = substr($t,0,$x); $ch = ''; - } - } - if(strpos($t, 'C') !== FALSE) $r .= "Ctrl+"; - if(strpos($t, 'S') !== FALSE) $r .= "Shift+"; - if(strpos($t, 'A') !== FALSE) $r .= "Alt+"; - $r .= $u; - $endspan = true; - } - } - - if($ch == ' ') $r .= "Space"; else if($ch <> '') $r .= htmlentities($ch, ENT_QUOTES); - if($endspan) $r .= " "; - $i++; - } - $r .= ""; - } - - return $r; - } - } - - $keyRenderer = new KeyRenderer(); // Can also be used statically - - //------------------------------------------------------------------------------------------ - - /** - * Render language example from kps 17.0 format examples - * - * Key format (from kmp-json-file.ts): - * - * A space-separated list of keys. - * - modifiers indicated with "+" - * - spacebar is "space" - * - plus key is "shift+=" or "plus" on US English (all other punctuation as per key cap). - * - Hardware modifiers are: "shift", "ctrl", "alt", "left-ctrl", - * "right-ctrl", "left-alt", "right-alt" - * - Key caps should generally be their character for desktop (Latin script - * case insensitive), or the actual key cap for touch - * - Caps Lock should be indicated with "caps-on", "caps-off" - * - * e.g. "shift+a b right-alt+c space plus z z z" represents something like: "Ab{AltGr+C} +zzz" - */ - function RenderExamplesKeys($keys) { - $modifiers = [ - 'left-alt' => 'Left Alt', - 'right-alt' => 'Right Alt', - 'left-ctrl' => 'Left Ctrl', - 'left-control' => 'Left Ctrl', - 'right-ctrl' => 'Right Ctrl', - 'right-control' => 'Right Ctrl', - 'shift' => 'Shift', - 'ctrl' => 'Ctrl', - 'control' => 'Ctrl', - 'alt' => 'Alt', - 'caps-on' => 'Caps (on)', - 'caps-off' => 'Caps (off)', - ]; - - // space separated - $keys = explode(' ', $keys); - foreach($keys as $chord) { - if(empty($chord)) { - continue; - } - $chord = explode('+', $chord); - $chord_keys = []; - foreach($chord as $key) { - $class=''; - $bkey = strtolower($key); - if($bkey == 'space') { - $key = ' '; $class=' class="space"'; - } else if($bkey == 'plus') { - $key = '+'; - } else if(array_key_exists($bkey, $modifiers)) { - $key = $modifiers[$bkey]; - $class=' class="modifier"'; - } else { - $key = htmlspecialchars($key); - } - array_push($chord_keys, "$key"); - } - $result .= implode('+', $chord_keys) . " "; - } - return trim($result); - } - - function DisplayExamples($examples, $language = '') - { - global $morehelp; - $result = ''; - - if(!is_array($examples) || count($examples) == 0) { - return FALSE; - } - - $example = $examples[0]; - if(empty($example['keys'])) { - return FALSE; - } - - $keys = RenderExamplesKeys($example['keys']); - $out = htmlspecialchars($example['text']); - $note = isset($example['note']) ? " (" . htmlspecialchars($example['note']) . ")" : ""; - - $result .= - "To enter ". - "$out$note, ". - "type  ". - "$keys$morehelp"; - - return $result; - } +SERVER_api_keyman_com . "/keyboard/" . rawurlencode($keyboard); + $json = @file_get_contents($string); + if($json === FALSE) { + return FALSE; + } + + $obj = @json_decode($json, true); + if($obj === NULL) { + return FALSE; + } + + if(!isset($obj['languages'][$language])) { + return false; + } + + $lang = $obj['languages'][$language]; + + if(isset($lang['examples'])) { + $result = DisplayExamples($lang['examples'], $language); + } else if(isset($lang['example'])) { + $result = DisplayExample($lang['example'], false, $language); + } else { + $result = FALSE; + } + + return $result ? ("Example: " . $result) : FALSE; + } + + function DisplayExample($x, $table = false, $language = '') + { + global $morehelp; + $result = ''; + + if(is_array($x)) + { + $keys = KeyRenderer::renderInternal($x['keys'], $table); + $out = $x['text']; + if(isset($x['note'])) $note = " ({$x['note']})"; else $note = ''; + + if($table) + $result .= "$out{$x['note']}$keys"; + else + $result .= + "To enter ". + "$out$note, ". + "type  ". + "$keys$morehelp"; + //" to get "; + //if(isset($x['note'])) echo " ({$x['note']})"; + //echo " $morehelp"; + } + else if(!$table) + $result .= "$x $morehelp"; + return $result; + } + + class KeyRenderer + { + public static function render($s) + { + return "".KeyRenderer::renderInternal($s, true).""; + } + + public static function renderInternal($s, $table = false) + { + $spkey = array("pgup","pgdn","left","right","up","down","ins","del","home","end","enter","tab","esc","caps","bksp","shift","ctrl","alt"); + $spkey2 = array("shift","ctrl","alt"); + + $i = 0; + $r = ''; + while($i < strlen($s)) + { + $endspan = false; + $ch = $s[$i]; + if($ch == '[' && $i < strlen($s)-1) + { + $i++; $ch = $s[$i]; + if($ch == '[') + { + $t = $ch; + } + else if($ch != '[') + { + /* Ctrl+Shift+Alt+key */ + $t = $ch; $i++; + while($i < strlen($s) && $s[$i] != ']') + { + $t .= $s[$i]; + $i++; + } + $ch = $t[strlen($t)-1]; $t1 = $t; + $t = substr($t, 0, strlen($t)-1); + $r .= ""; + + /* Special keys */ + $x = strpos($t1,'!'); $u = ""; + if($x !== FALSE) + { + $ks = strtolower(substr($t1,$x+1,strlen($t1)-$x-1)); + if(array_search($ks,$spkey) !== FALSE) + { + $u = $ks; + $kn = $ks; + if(array_search($ks,$spkey2) !== FALSE) $kn .= "2"; + $u = "" . $ks . ""; + $t = substr($t,0,$x); $ch = ''; + } + } + + if(strpos($t, 'C') !== FALSE) $r .= "Ctrl"; + if(strpos($t, 'S') !== FALSE) $r .= "Shift"; + if(strpos($t, 'A') !== FALSE) $r .= "Alt"; + $r .= $u; + $endspan = true; + } + } + if($ch <> '') + { + $chv = ord($ch); + $r .= "".htmlentities($ch, ENT_QUOTES).""; + } + if($endspan) $r .= ""; + $i++; + } + + if($table) + { + $r .= ""; + $i = 0; + while($i < strlen($s)) + { + $endspan = false; + $ch = $s[$i]; + if($ch == '[' && $i < strlen($s)-1) + { + $i++; $ch = $s[$i]; + $t = $ch; + if($ch != '[') + { + /* Ctrl+Shift+Alt+key */ + $i++; + while($i < strlen($s) && $s[$i] != ']') + { + $t .= $s[$i]; + $i++; + } + $ch = $t[strlen($t)-1]; $t1 = $t; + $t = substr($t, 0, strlen($t)-1); + $r .= ""; + + /* Special keys */ + $x = strpos($t1,'!'); $u = ""; + if($x !== FALSE) + { + $kn = substr($t1,$x+1,strlen($t1)-$x-1); + $ks = strtolower($kn); + if(array_search($ks,$spkey) !== FALSE) + { + $u = $kn; + $t = substr($t,0,$x); $ch = ''; + } + } + if(strpos($t, 'C') !== FALSE) $r .= "Ctrl+"; + if(strpos($t, 'S') !== FALSE) $r .= "Shift+"; + if(strpos($t, 'A') !== FALSE) $r .= "Alt+"; + $r .= $u; + $endspan = true; + } + } + + if($ch == ' ') $r .= "Space"; else if($ch <> '') $r .= htmlentities($ch, ENT_QUOTES); + if($endspan) $r .= " "; + $i++; + } + $r .= ""; + } + + return $r; + } + } + + $keyRenderer = new KeyRenderer(); // Can also be used statically + + //------------------------------------------------------------------------------------------ + + /** + * Render language example from kps 17.0 format examples + * + * Key format (from kmp-json-file.ts): + * + * A space-separated list of keys. + * - modifiers indicated with "+" + * - spacebar is "space" + * - plus key is "shift+=" or "plus" on US English (all other punctuation as per key cap). + * - Hardware modifiers are: "shift", "ctrl", "alt", "left-ctrl", + * "right-ctrl", "left-alt", "right-alt" + * - Key caps should generally be their character for desktop (Latin script + * case insensitive), or the actual key cap for touch + * - Caps Lock should be indicated with "caps-on", "caps-off" + * + * e.g. "shift+a b right-alt+c space plus z z z" represents something like: "Ab{AltGr+C} +zzz" + */ + function RenderExamplesKeys($keys) { + $modifiers = [ + 'left-alt' => 'Left Alt', + 'right-alt' => 'Right Alt', + 'left-ctrl' => 'Left Ctrl', + 'left-control' => 'Left Ctrl', + 'right-ctrl' => 'Right Ctrl', + 'right-control' => 'Right Ctrl', + 'shift' => 'Shift', + 'ctrl' => 'Ctrl', + 'control' => 'Ctrl', + 'alt' => 'Alt', + 'caps-on' => 'Caps (on)', + 'caps-off' => 'Caps (off)', + ]; + + // space separated + $keys = explode(' ', $keys); + foreach($keys as $chord) { + if(empty($chord)) { + continue; + } + $chord = explode('+', $chord); + $chord_keys = []; + foreach($chord as $key) { + $class=''; + $bkey = strtolower($key); + if($bkey == 'space') { + $key = ' '; $class=' class="space"'; + } else if($bkey == 'plus') { + $key = '+'; + } else if(array_key_exists($bkey, $modifiers)) { + $key = $modifiers[$bkey]; + $class=' class="modifier"'; + } else { + $key = htmlspecialchars($key); + } + array_push($chord_keys, "$key"); + } + $result .= implode('+', $chord_keys) . " "; + } + return trim($result); + } + + function DisplayExamples($examples, $language = '') + { + global $morehelp; + $result = ''; + + if(!is_array($examples) || count($examples) == 0) { + return FALSE; + } + + $example = $examples[0]; + if(empty($example['keys'])) { + return FALSE; + } + + $keys = RenderExamplesKeys($example['keys']); + $out = htmlspecialchars($example['text']); + $note = isset($example['note']) ? " (" . htmlspecialchars($example['note']) . ")" : ""; + + $result .= + "To enter ". + "$out$note, ". + "type  ". + "$keys$morehelp"; + + return $result; + } From 06e5644328a73d1b01478dda1a3800e48c8af0aa Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Mon, 6 Oct 2025 15:31:11 +0700 Subject: [PATCH 27/36] chore: add bootstrap files --- cdn/dev/src/bootstrap.bundle.min.js | 14 +++++++------- cdn/dev/src/bootstrap.min.css | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/cdn/dev/src/bootstrap.bundle.min.js b/cdn/dev/src/bootstrap.bundle.min.js index ec2dde2..6c0869b 100644 --- a/cdn/dev/src/bootstrap.bundle.min.js +++ b/cdn/dev/src/bootstrap.bundle.min.js @@ -1,7 +1,7 @@ -/*! - * Bootstrap v5.1.3 (https://getbootstrap.com/) - * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t="transitionend",e=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return e},i=t=>{const i=e(t);return i&&document.querySelector(i)?i:null},n=t=>{const i=e(t);return i?document.querySelector(i):null},s=e=>{e.dispatchEvent(new Event(t))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(t):null,a=(t,e,i)=>{Object.keys(i).forEach((n=>{const s=i[n],r=e[n],a=r&&o(r)?"element":null==(l=r)?`${l}`:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();var l;if(!new RegExp(s).test(a))throw new TypeError(`${t.toUpperCase()}: Option "${n}" provided type "${a}" but expected type "${s}".`)}))},l=t=>!(!o(t)||0===t.getClientRects().length)&&"visible"===getComputedStyle(t).getPropertyValue("visibility"),c=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),h=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?h(t.parentNode):null},d=()=>{},u=t=>{t.offsetHeight},f=()=>{const{jQuery:t}=window;return t&&!document.body.hasAttribute("data-bs-no-jquery")?t:null},p=[],m=()=>"rtl"===document.documentElement.dir,g=t=>{var e;e=()=>{const e=f();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(p.length||document.addEventListener("DOMContentLoaded",(()=>{p.forEach((t=>t()))})),p.push(e)):e()},_=t=>{"function"==typeof t&&t()},b=(e,i,n=!0)=>{if(!n)return void _(e);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(i)+5;let r=!1;const a=({target:n})=>{n===i&&(r=!0,i.removeEventListener(t,a),_(e))};i.addEventListener(t,a),setTimeout((()=>{r||s(i)}),o)},v=(t,e,i,n)=>{let s=t.indexOf(e);if(-1===s)return t[!i&&n?t.length-1:0];const o=t.length;return s+=i?1:-1,n&&(s=(s+o)%o),t[Math.max(0,Math.min(s,o-1))]},y=/[^.]*(?=\..*)\.|.*/,w=/\..*/,E=/::\d+$/,A={};let T=1;const O={mouseenter:"mouseover",mouseleave:"mouseout"},C=/^(mouseenter|mouseleave)/i,k=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function L(t,e){return e&&`${e}::${T++}`||t.uidEvent||T++}function x(t){const e=L(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function D(t,e,i=null){const n=Object.keys(t);for(let s=0,o=n.length;sfunction(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};n?n=t(n):i=t(i)}const[o,r,a]=S(e,i,n),l=x(t),c=l[a]||(l[a]={}),h=D(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=L(r,e.replace(y,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(let a=o.length;a--;)if(o[a]===r)return s.delegateTarget=r,n.oneOff&&j.off(t,s.type,e,i),i.apply(r,[s]);return null}}(t,i,n):function(t,e){return function i(n){return n.delegateTarget=t,i.oneOff&&j.off(t,n.type,e),e.apply(t,[n])}}(t,i);u.delegationSelector=o?i:null,u.originalHandler=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function I(t,e,i,n,s){const o=D(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function P(t){return t=t.replace(w,""),O[t]||t}const j={on(t,e,i,n){N(t,e,i,n,!1)},one(t,e,i,n){N(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=S(e,i,n),a=r!==e,l=x(t),c=e.startsWith(".");if(void 0!==o){if(!l||!l[r])return;return void I(t,l,r,o,s?i:null)}c&&Object.keys(l).forEach((i=>{!function(t,e,i,n){const s=e[i]||{};Object.keys(s).forEach((o=>{if(o.includes(n)){const n=s[o];I(t,e,i,n.originalHandler,n.delegationSelector)}}))}(t,l,i,e.slice(1))}));const h=l[r]||{};Object.keys(h).forEach((i=>{const n=i.replace(E,"");if(!a||e.includes(n)){const e=h[i];I(t,l,r,e.originalHandler,e.delegationSelector)}}))},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=f(),s=P(e),o=e!==s,r=k.has(s);let a,l=!0,c=!0,h=!1,d=null;return o&&n&&(a=n.Event(e,i),n(t).trigger(a),l=!a.isPropagationStopped(),c=!a.isImmediatePropagationStopped(),h=a.isDefaultPrevented()),r?(d=document.createEvent("HTMLEvents"),d.initEvent(s,l,!0)):d=new CustomEvent(e,{bubbles:l,cancelable:!0}),void 0!==i&&Object.keys(i).forEach((t=>{Object.defineProperty(d,t,{get:()=>i[t]})})),h&&d.preventDefault(),c&&t.dispatchEvent(d),d.defaultPrevented&&void 0!==a&&a.preventDefault(),d}},M=new Map,H={set(t,e,i){M.has(t)||M.set(t,new Map);const n=M.get(t);n.has(e)||0===n.size?n.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>M.has(t)&&M.get(t).get(e)||null,remove(t,e){if(!M.has(t))return;const i=M.get(t);i.delete(e),0===i.size&&M.delete(t)}};class B{constructor(t){(t=r(t))&&(this._element=t,H.set(this._element,this.constructor.DATA_KEY,this))}dispose(){H.remove(this._element,this.constructor.DATA_KEY),j.off(this._element,this.constructor.EVENT_KEY),Object.getOwnPropertyNames(this).forEach((t=>{this[t]=null}))}_queueCallback(t,e,i=!0){b(t,e,i)}static getInstance(t){return H.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.1.3"}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}}const R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,s=t.NAME;j.on(document,i,`[data-bs-dismiss="${s}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),c(this))return;const o=n(this)||this.closest(`.${s}`);t.getOrCreateInstance(o)[e]()}))};class W extends B{static get NAME(){return"alert"}close(){if(j.trigger(this._element,"close.bs.alert").defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),j.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=W.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(W,"close"),g(W);const $='[data-bs-toggle="button"]';class z extends B{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=z.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}function q(t){return"true"===t||"false"!==t&&(t===Number(t).toString()?Number(t):""===t||"null"===t?null:t)}function F(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}j.on(document,"click.bs.button.data-api",$,(t=>{t.preventDefault();const e=t.target.closest($);z.getOrCreateInstance(e).toggle()})),g(z);const U={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${F(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${F(e)}`)},getDataAttributes(t){if(!t)return{};const e={};return Object.keys(t.dataset).filter((t=>t.startsWith("bs"))).forEach((i=>{let n=i.replace(/^bs/,"");n=n.charAt(0).toLowerCase()+n.slice(1,n.length),e[n]=q(t.dataset[i])})),e},getDataAttribute:(t,e)=>q(t.getAttribute(`data-bs-${F(e)}`)),offset(t){const e=t.getBoundingClientRect();return{top:e.top+window.pageYOffset,left:e.left+window.pageXOffset}},position:t=>({top:t.offsetTop,left:t.offsetLeft})},V={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode;for(;n&&n.nodeType===Node.ELEMENT_NODE&&3!==n.nodeType;)n.matches(e)&&i.push(n),n=n.parentNode;return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(", ");return this.find(e,t).filter((t=>!c(t)&&l(t)))}},K="carousel",X={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},Y={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},Q="next",G="prev",Z="left",J="right",tt={ArrowLeft:J,ArrowRight:Z},et="slid.bs.carousel",it="active",nt=".active.carousel-item";class st extends B{constructor(t,e){super(t),this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._indicatorsElement=V.findOne(".carousel-indicators",this._element),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent),this._addEventListeners()}static get Default(){return X}static get NAME(){return K}next(){this._slide(Q)}nextWhenVisible(){!document.hidden&&l(this._element)&&this.next()}prev(){this._slide(G)}pause(t){t||(this._isPaused=!0),V.findOne(".carousel-item-next, .carousel-item-prev",this._element)&&(s(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null}cycle(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))}to(t){this._activeElement=V.findOne(nt,this._element);const e=this._getItemIndex(this._activeElement);if(t>this._items.length-1||t<0)return;if(this._isSliding)return void j.one(this._element,et,(()=>this.to(t)));if(e===t)return this.pause(),void this.cycle();const i=t>e?Q:G;this._slide(i,this._items[t])}_getConfig(t){return t={...X,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(K,t,Y),t}_handleSwipe(){const t=Math.abs(this.touchDeltaX);if(t<=40)return;const e=t/this.touchDeltaX;this.touchDeltaX=0,e&&this._slide(e>0?J:Z)}_addEventListeners(){this._config.keyboard&&j.on(this._element,"keydown.bs.carousel",(t=>this._keydown(t))),"hover"===this._config.pause&&(j.on(this._element,"mouseenter.bs.carousel",(t=>this.pause(t))),j.on(this._element,"mouseleave.bs.carousel",(t=>this.cycle(t)))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()}_addTouchEventListeners(){const t=t=>this._pointerEvent&&("pen"===t.pointerType||"touch"===t.pointerType),e=e=>{t(e)?this.touchStartX=e.clientX:this._pointerEvent||(this.touchStartX=e.touches[0].clientX)},i=t=>{this.touchDeltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this.touchStartX},n=e=>{t(e)&&(this.touchDeltaX=e.clientX-this.touchStartX),this._handleSwipe(),"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((t=>this.cycle(t)),500+this._config.interval))};V.find(".carousel-item img",this._element).forEach((t=>{j.on(t,"dragstart.bs.carousel",(t=>t.preventDefault()))})),this._pointerEvent?(j.on(this._element,"pointerdown.bs.carousel",(t=>e(t))),j.on(this._element,"pointerup.bs.carousel",(t=>n(t))),this._element.classList.add("pointer-event")):(j.on(this._element,"touchstart.bs.carousel",(t=>e(t))),j.on(this._element,"touchmove.bs.carousel",(t=>i(t))),j.on(this._element,"touchend.bs.carousel",(t=>n(t))))}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=tt[t.key];e&&(t.preventDefault(),this._slide(e))}_getItemIndex(t){return this._items=t&&t.parentNode?V.find(".carousel-item",t.parentNode):[],this._items.indexOf(t)}_getItemByOrder(t,e){const i=t===Q;return v(this._items,e,i,this._config.wrap)}_triggerSlideEvent(t,e){const i=this._getItemIndex(t),n=this._getItemIndex(V.findOne(nt,this._element));return j.trigger(this._element,"slide.bs.carousel",{relatedTarget:t,direction:e,from:n,to:i})}_setActiveIndicatorElement(t){if(this._indicatorsElement){const e=V.findOne(".active",this._indicatorsElement);e.classList.remove(it),e.removeAttribute("aria-current");const i=V.find("[data-bs-target]",this._indicatorsElement);for(let e=0;e{j.trigger(this._element,et,{relatedTarget:o,direction:d,from:s,to:r})};if(this._element.classList.contains("slide")){o.classList.add(h),u(o),n.classList.add(c),o.classList.add(c);const t=()=>{o.classList.remove(c,h),o.classList.add(it),n.classList.remove(it,h,c),this._isSliding=!1,setTimeout(f,0)};this._queueCallback(t,n,!0)}else n.classList.remove(it),o.classList.add(it),this._isSliding=!1,f();a&&this.cycle()}_directionToOrder(t){return[J,Z].includes(t)?m()?t===Z?G:Q:t===Z?Q:G:t}_orderToDirection(t){return[Q,G].includes(t)?m()?t===G?Z:J:t===G?J:Z:t}static carouselInterface(t,e){const i=st.getOrCreateInstance(t,e);let{_config:n}=i;"object"==typeof e&&(n={...n,...e});const s="string"==typeof e?e:n.slide;if("number"==typeof e)i.to(e);else if("string"==typeof s){if(void 0===i[s])throw new TypeError(`No method named "${s}"`);i[s]()}else n.interval&&n.ride&&(i.pause(),i.cycle())}static jQueryInterface(t){return this.each((function(){st.carouselInterface(this,t)}))}static dataApiClickHandler(t){const e=n(this);if(!e||!e.classList.contains("carousel"))return;const i={...U.getDataAttributes(e),...U.getDataAttributes(this)},s=this.getAttribute("data-bs-slide-to");s&&(i.interval=!1),st.carouselInterface(e,i),s&&st.getInstance(e).to(s),t.preventDefault()}}j.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",st.dataApiClickHandler),j.on(window,"load.bs.carousel.data-api",(()=>{const t=V.find('[data-bs-ride="carousel"]');for(let e=0,i=t.length;et===this._element));null!==s&&o.length&&(this._selector=s,this._triggerArray.push(e))}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return rt}static get NAME(){return ot}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t,e=[];if(this._config.parent){const t=V.find(ut,this._config.parent);e=V.find(".collapse.show, .collapse.collapsing",this._config.parent).filter((e=>!t.includes(e)))}const i=V.findOne(this._selector);if(e.length){const n=e.find((t=>i!==t));if(t=n?pt.getInstance(n):null,t&&t._isTransitioning)return}if(j.trigger(this._element,"show.bs.collapse").defaultPrevented)return;e.forEach((e=>{i!==e&&pt.getOrCreateInstance(e,{toggle:!1}).hide(),t||H.set(e,"bs.collapse",null)}));const n=this._getDimension();this._element.classList.remove(ct),this._element.classList.add(ht),this._element.style[n]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const s=`scroll${n[0].toUpperCase()+n.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct,lt),this._element.style[n]="",j.trigger(this._element,"shown.bs.collapse")}),this._element,!0),this._element.style[n]=`${this._element[s]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(j.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,u(this._element),this._element.classList.add(ht),this._element.classList.remove(ct,lt);const e=this._triggerArray.length;for(let t=0;t{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct),j.trigger(this._element,"hidden.bs.collapse")}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(lt)}_getConfig(t){return(t={...rt,...U.getDataAttributes(this._element),...t}).toggle=Boolean(t.toggle),t.parent=r(t.parent),a(ot,t,at),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=V.find(ut,this._config.parent);V.find(ft,this._config.parent).filter((e=>!t.includes(e))).forEach((t=>{const e=n(t);e&&this._addAriaAndCollapsedClass([t],this._isShown(e))}))}_addAriaAndCollapsedClass(t,e){t.length&&t.forEach((t=>{e?t.classList.remove(dt):t.classList.add(dt),t.setAttribute("aria-expanded",e)}))}static jQueryInterface(t){return this.each((function(){const e={};"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1);const i=pt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}j.on(document,"click.bs.collapse.data-api",ft,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();const e=i(this);V.find(e).forEach((t=>{pt.getOrCreateInstance(t,{toggle:!1}).toggle()}))})),g(pt);var mt="top",gt="bottom",_t="right",bt="left",vt="auto",yt=[mt,gt,_t,bt],wt="start",Et="end",At="clippingParents",Tt="viewport",Ot="popper",Ct="reference",kt=yt.reduce((function(t,e){return t.concat([e+"-"+wt,e+"-"+Et])}),[]),Lt=[].concat(yt,[vt]).reduce((function(t,e){return t.concat([e,e+"-"+wt,e+"-"+Et])}),[]),xt="beforeRead",Dt="read",St="afterRead",Nt="beforeMain",It="main",Pt="afterMain",jt="beforeWrite",Mt="write",Ht="afterWrite",Bt=[xt,Dt,St,Nt,It,Pt,jt,Mt,Ht];function Rt(t){return t?(t.nodeName||"").toLowerCase():null}function Wt(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function $t(t){return t instanceof Wt(t).Element||t instanceof Element}function zt(t){return t instanceof Wt(t).HTMLElement||t instanceof HTMLElement}function qt(t){return"undefined"!=typeof ShadowRoot&&(t instanceof Wt(t).ShadowRoot||t instanceof ShadowRoot)}const Ft={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];zt(s)&&Rt(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});zt(n)&&Rt(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function Ut(t){return t.split("-")[0]}function Vt(t,e){var i=t.getBoundingClientRect();return{width:i.width/1,height:i.height/1,top:i.top/1,right:i.right/1,bottom:i.bottom/1,left:i.left/1,x:i.left/1,y:i.top/1}}function Kt(t){var e=Vt(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Xt(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&qt(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Yt(t){return Wt(t).getComputedStyle(t)}function Qt(t){return["table","td","th"].indexOf(Rt(t))>=0}function Gt(t){return(($t(t)?t.ownerDocument:t.document)||window.document).documentElement}function Zt(t){return"html"===Rt(t)?t:t.assignedSlot||t.parentNode||(qt(t)?t.host:null)||Gt(t)}function Jt(t){return zt(t)&&"fixed"!==Yt(t).position?t.offsetParent:null}function te(t){for(var e=Wt(t),i=Jt(t);i&&Qt(i)&&"static"===Yt(i).position;)i=Jt(i);return i&&("html"===Rt(i)||"body"===Rt(i)&&"static"===Yt(i).position)?e:i||function(t){var e=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&zt(t)&&"fixed"===Yt(t).position)return null;for(var i=Zt(t);zt(i)&&["html","body"].indexOf(Rt(i))<0;){var n=Yt(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function ee(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}var ie=Math.max,ne=Math.min,se=Math.round;function oe(t,e,i){return ie(t,ne(e,i))}function re(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function ae(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const le={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=Ut(i.placement),l=ee(a),c=[bt,_t].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return re("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:ae(t,yt))}(s.padding,i),d=Kt(o),u="y"===l?mt:bt,f="y"===l?gt:_t,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=te(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,E=oe(v,w,y),A=l;i.modifiersData[n]=((e={})[A]=E,e.centerOffset=E-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Xt(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function ce(t){return t.split("-")[1]}var he={top:"auto",right:"auto",bottom:"auto",left:"auto"};function de(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=!0===h?function(t){var e=t.x,i=t.y,n=window.devicePixelRatio||1;return{x:se(se(e*n)/n)||0,y:se(se(i*n)/n)||0}}(r):"function"==typeof h?h(r):r,u=d.x,f=void 0===u?0:u,p=d.y,m=void 0===p?0:p,g=r.hasOwnProperty("x"),_=r.hasOwnProperty("y"),b=bt,v=mt,y=window;if(c){var w=te(i),E="clientHeight",A="clientWidth";w===Wt(i)&&"static"!==Yt(w=Gt(i)).position&&"absolute"===a&&(E="scrollHeight",A="scrollWidth"),w=w,s!==mt&&(s!==bt&&s!==_t||o!==Et)||(v=gt,m-=w[E]-n.height,m*=l?1:-1),s!==bt&&(s!==mt&&s!==gt||o!==Et)||(b=_t,f-=w[A]-n.width,f*=l?1:-1)}var T,O=Object.assign({position:a},c&&he);return l?Object.assign({},O,((T={})[v]=_?"0":"",T[b]=g?"0":"",T.transform=(y.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",T)):Object.assign({},O,((e={})[v]=_?m+"px":"",e[b]=g?f+"px":"",e.transform="",e))}const ue={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:Ut(e.placement),variation:ce(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,de(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,de(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var fe={passive:!0};const pe={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=Wt(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,fe)})),a&&l.addEventListener("resize",i.update,fe),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,fe)})),a&&l.removeEventListener("resize",i.update,fe)}},data:{}};var me={left:"right",right:"left",bottom:"top",top:"bottom"};function ge(t){return t.replace(/left|right|bottom|top/g,(function(t){return me[t]}))}var _e={start:"end",end:"start"};function be(t){return t.replace(/start|end/g,(function(t){return _e[t]}))}function ve(t){var e=Wt(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function ye(t){return Vt(Gt(t)).left+ve(t).scrollLeft}function we(t){var e=Yt(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ee(t){return["html","body","#document"].indexOf(Rt(t))>=0?t.ownerDocument.body:zt(t)&&we(t)?t:Ee(Zt(t))}function Ae(t,e){var i;void 0===e&&(e=[]);var n=Ee(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=Wt(n),r=s?[o].concat(o.visualViewport||[],we(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Ae(Zt(r)))}function Te(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Oe(t,e){return e===Tt?Te(function(t){var e=Wt(t),i=Gt(t),n=e.visualViewport,s=i.clientWidth,o=i.clientHeight,r=0,a=0;return n&&(s=n.width,o=n.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(r=n.offsetLeft,a=n.offsetTop)),{width:s,height:o,x:r+ye(t),y:a}}(t)):zt(e)?function(t){var e=Vt(t);return e.top=e.top+t.clientTop,e.left=e.left+t.clientLeft,e.bottom=e.top+t.clientHeight,e.right=e.left+t.clientWidth,e.width=t.clientWidth,e.height=t.clientHeight,e.x=e.left,e.y=e.top,e}(e):Te(function(t){var e,i=Gt(t),n=ve(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=ie(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=ie(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+ye(t),l=-n.scrollTop;return"rtl"===Yt(s||i).direction&&(a+=ie(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(Gt(t)))}function Ce(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?Ut(s):null,r=s?ce(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case mt:e={x:a,y:i.y-n.height};break;case gt:e={x:a,y:i.y+i.height};break;case _t:e={x:i.x+i.width,y:l};break;case bt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?ee(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case wt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Et:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ke(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.boundary,r=void 0===o?At:o,a=i.rootBoundary,l=void 0===a?Tt:a,c=i.elementContext,h=void 0===c?Ot:c,d=i.altBoundary,u=void 0!==d&&d,f=i.padding,p=void 0===f?0:f,m=re("number"!=typeof p?p:ae(p,yt)),g=h===Ot?Ct:Ot,_=t.rects.popper,b=t.elements[u?g:h],v=function(t,e,i){var n="clippingParents"===e?function(t){var e=Ae(Zt(t)),i=["absolute","fixed"].indexOf(Yt(t).position)>=0&&zt(t)?te(t):t;return $t(i)?e.filter((function(t){return $t(t)&&Xt(t,i)&&"body"!==Rt(t)})):[]}(t):[].concat(e),s=[].concat(n,[i]),o=s[0],r=s.reduce((function(e,i){var n=Oe(t,i);return e.top=ie(n.top,e.top),e.right=ne(n.right,e.right),e.bottom=ne(n.bottom,e.bottom),e.left=ie(n.left,e.left),e}),Oe(t,o));return r.width=r.right-r.left,r.height=r.bottom-r.top,r.x=r.left,r.y=r.top,r}($t(b)?b:b.contextElement||Gt(t.elements.popper),r,l),y=Vt(t.elements.reference),w=Ce({reference:y,element:_,strategy:"absolute",placement:s}),E=Te(Object.assign({},_,w)),A=h===Ot?E:y,T={top:v.top-A.top+m.top,bottom:A.bottom-v.bottom+m.bottom,left:v.left-A.left+m.left,right:A.right-v.right+m.right},O=t.modifiersData.offset;if(h===Ot&&O){var C=O[s];Object.keys(T).forEach((function(t){var e=[_t,gt].indexOf(t)>=0?1:-1,i=[mt,gt].indexOf(t)>=0?"y":"x";T[t]+=C[i]*e}))}return T}function Le(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?Lt:l,h=ce(n),d=h?a?kt:kt.filter((function(t){return ce(t)===h})):yt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=ke(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[Ut(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const xe={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=Ut(g),b=l||(_!==g&&p?function(t){if(Ut(t)===vt)return[];var e=ge(t);return[be(t),e,be(e)]}(g):[ge(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(Ut(i)===vt?Le(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,E=new Map,A=!0,T=v[0],O=0;O=0,D=x?"width":"height",S=ke(e,{placement:C,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),N=x?L?_t:bt:L?gt:mt;y[D]>w[D]&&(N=ge(N));var I=ge(N),P=[];if(o&&P.push(S[k]<=0),a&&P.push(S[N]<=0,S[I]<=0),P.every((function(t){return t}))){T=C,A=!1;break}E.set(C,P)}if(A)for(var j=function(t){var e=v.find((function(e){var i=E.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==j(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function De(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function Se(t){return[mt,_t,gt,bt].some((function(e){return t[e]>=0}))}const Ne={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=ke(e,{elementContext:"reference"}),a=ke(e,{altBoundary:!0}),l=De(r,n),c=De(a,s,o),h=Se(l),d=Se(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},Ie={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=Lt.reduce((function(t,i){return t[i]=function(t,e,i){var n=Ut(t),s=[bt,mt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[bt,_t].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},Pe={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=Ce({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},je={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=ke(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=Ut(e.placement),b=ce(e.placement),v=!b,y=ee(_),w="x"===y?"y":"x",E=e.modifiersData.popperOffsets,A=e.rects.reference,T=e.rects.popper,O="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,C={x:0,y:0};if(E){if(o||a){var k="y"===y?mt:bt,L="y"===y?gt:_t,x="y"===y?"height":"width",D=E[y],S=E[y]+g[k],N=E[y]-g[L],I=f?-T[x]/2:0,P=b===wt?A[x]:T[x],j=b===wt?-T[x]:-A[x],M=e.elements.arrow,H=f&&M?Kt(M):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},R=B[k],W=B[L],$=oe(0,A[x],H[x]),z=v?A[x]/2-I-$-R-O:P-$-R-O,q=v?-A[x]/2+I+$+W+O:j+$+W+O,F=e.elements.arrow&&te(e.elements.arrow),U=F?"y"===y?F.clientTop||0:F.clientLeft||0:0,V=e.modifiersData.offset?e.modifiersData.offset[e.placement][y]:0,K=E[y]+z-V-U,X=E[y]+q-V;if(o){var Y=oe(f?ne(S,K):S,D,f?ie(N,X):N);E[y]=Y,C[y]=Y-D}if(a){var Q="x"===y?mt:bt,G="x"===y?gt:_t,Z=E[w],J=Z+g[Q],tt=Z-g[G],et=oe(f?ne(J,K):J,Z,f?ie(tt,X):tt);E[w]=et,C[w]=et-Z}}e.modifiersData[n]=C}},requiresIfExists:["offset"]};function Me(t,e,i){void 0===i&&(i=!1);var n=zt(e);zt(e)&&function(t){var e=t.getBoundingClientRect();e.width,t.offsetWidth,e.height,t.offsetHeight}(e);var s,o,r=Gt(e),a=Vt(t),l={scrollLeft:0,scrollTop:0},c={x:0,y:0};return(n||!n&&!i)&&(("body"!==Rt(e)||we(r))&&(l=(s=e)!==Wt(s)&&zt(s)?{scrollLeft:(o=s).scrollLeft,scrollTop:o.scrollTop}:ve(s)),zt(e)?((c=Vt(e)).x+=e.clientLeft,c.y+=e.clientTop):r&&(c.x=ye(r))),{x:a.left+l.scrollLeft-c.x,y:a.top+l.scrollTop-c.y,width:a.width,height:a.height}}function He(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var Be={placement:"bottom",modifiers:[],strategy:"absolute"};function Re(){for(var t=arguments.length,e=new Array(t),i=0;ij.on(t,"mouseover",d))),this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add(Je),this._element.classList.add(Je),j.trigger(this._element,"shown.bs.dropdown",t)}hide(){if(c(this._element)||!this._isShown(this._menu))return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(t){j.trigger(this._element,"hide.bs.dropdown",t).defaultPrevented||("ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>j.off(t,"mouseover",d))),this._popper&&this._popper.destroy(),this._menu.classList.remove(Je),this._element.classList.remove(Je),this._element.setAttribute("aria-expanded","false"),U.removeDataAttribute(this._menu,"popper"),j.trigger(this._element,"hidden.bs.dropdown",t))}_getConfig(t){if(t={...this.constructor.Default,...U.getDataAttributes(this._element),...t},a(Ue,t,this.constructor.DefaultType),"object"==typeof t.reference&&!o(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError(`${Ue.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return t}_createPopper(t){if(void 0===Fe)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let e=this._element;"parent"===this._config.reference?e=t:o(this._config.reference)?e=r(this._config.reference):"object"==typeof this._config.reference&&(e=this._config.reference);const i=this._getPopperConfig(),n=i.modifiers.find((t=>"applyStyles"===t.name&&!1===t.enabled));this._popper=qe(e,this._menu,i),n&&U.setDataAttribute(this._menu,"popper","static")}_isShown(t=this._element){return t.classList.contains(Je)}_getMenuElement(){return V.next(this._element,ei)[0]}_getPlacement(){const t=this._element.parentNode;if(t.classList.contains("dropend"))return ri;if(t.classList.contains("dropstart"))return ai;const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?ni:ii:e?oi:si}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return"static"===this._config.display&&(t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}_selectMenuItem({key:t,target:e}){const i=V.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter(l);i.length&&v(i,e,t===Ye,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=hi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(t&&(2===t.button||"keyup"===t.type&&"Tab"!==t.key))return;const e=V.find(ti);for(let i=0,n=e.length;ie+t)),this._setElementAttributes(di,"paddingRight",(e=>e+t)),this._setElementAttributes(ui,"marginRight",(e=>e-t))}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t)[e];t.style[e]=`${i(Number.parseFloat(s))}px`}))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,"paddingRight"),this._resetElementAttributes(di,"paddingRight"),this._resetElementAttributes(ui,"marginRight")}_saveInitialAttribute(t,e){const i=t.style[e];i&&U.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=U.getDataAttribute(t,e);void 0===i?t.style.removeProperty(e):(U.removeDataAttribute(t,e),t.style[e]=i)}))}_applyManipulationCallback(t,e){o(t)?e(t):V.find(t,this._element).forEach(e)}isOverflowing(){return this.getWidth()>0}}const pi={className:"modal-backdrop",isVisible:!0,isAnimated:!1,rootElement:"body",clickCallback:null},mi={className:"string",isVisible:"boolean",isAnimated:"boolean",rootElement:"(element|string)",clickCallback:"(function|null)"},gi="show",_i="mousedown.bs.backdrop";class bi{constructor(t){this._config=this._getConfig(t),this._isAppended=!1,this._element=null}show(t){this._config.isVisible?(this._append(),this._config.isAnimated&&u(this._getElement()),this._getElement().classList.add(gi),this._emulateAnimation((()=>{_(t)}))):_(t)}hide(t){this._config.isVisible?(this._getElement().classList.remove(gi),this._emulateAnimation((()=>{this.dispose(),_(t)}))):_(t)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_getConfig(t){return(t={...pi,..."object"==typeof t?t:{}}).rootElement=r(t.rootElement),a("backdrop",t,mi),t}_append(){this._isAppended||(this._config.rootElement.append(this._getElement()),j.on(this._getElement(),_i,(()=>{_(this._config.clickCallback)})),this._isAppended=!0)}dispose(){this._isAppended&&(j.off(this._element,_i),this._element.remove(),this._isAppended=!1)}_emulateAnimation(t){b(t,this._getElement(),this._config.isAnimated)}}const vi={trapElement:null,autofocus:!0},yi={trapElement:"element",autofocus:"boolean"},wi=".bs.focustrap",Ei="backward";class Ai{constructor(t){this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}activate(){const{trapElement:t,autofocus:e}=this._config;this._isActive||(e&&t.focus(),j.off(document,wi),j.on(document,"focusin.bs.focustrap",(t=>this._handleFocusin(t))),j.on(document,"keydown.tab.bs.focustrap",(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,j.off(document,wi))}_handleFocusin(t){const{target:e}=t,{trapElement:i}=this._config;if(e===document||e===i||i.contains(e))return;const n=V.focusableChildren(i);0===n.length?i.focus():this._lastTabNavDirection===Ei?n[n.length-1].focus():n[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?Ei:"forward")}_getConfig(t){return t={...vi,..."object"==typeof t?t:{}},a("focustrap",t,yi),t}}const Ti="modal",Oi="Escape",Ci={backdrop:!0,keyboard:!0,focus:!0},ki={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean"},Li="hidden.bs.modal",xi="show.bs.modal",Di="resize.bs.modal",Si="click.dismiss.bs.modal",Ni="keydown.dismiss.bs.modal",Ii="mousedown.dismiss.bs.modal",Pi="modal-open",ji="show",Mi="modal-static";class Hi extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._dialog=V.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollBar=new fi}static get Default(){return Ci}static get NAME(){return Ti}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||j.trigger(this._element,xi,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isAnimated()&&(this._isTransitioning=!0),this._scrollBar.hide(),document.body.classList.add(Pi),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),j.on(this._dialog,Ii,(()=>{j.one(this._element,"mouseup.dismiss.bs.modal",(t=>{t.target===this._element&&(this._ignoreBackdropClick=!0)}))})),this._showBackdrop((()=>this._showElement(t))))}hide(){if(!this._isShown||this._isTransitioning)return;if(j.trigger(this._element,"hide.bs.modal").defaultPrevented)return;this._isShown=!1;const t=this._isAnimated();t&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),this._focustrap.deactivate(),this._element.classList.remove(ji),j.off(this._element,Si),j.off(this._dialog,Ii),this._queueCallback((()=>this._hideModal()),this._element,t)}dispose(){[window,this._dialog].forEach((t=>j.off(t,".bs.modal"))),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new bi({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Ai({trapElement:this._element})}_getConfig(t){return t={...Ci,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(Ti,t,ki),t}_showElement(t){const e=this._isAnimated(),i=V.findOne(".modal-body",this._dialog);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0,i&&(i.scrollTop=0),e&&u(this._element),this._element.classList.add(ji),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,j.trigger(this._element,"shown.bs.modal",{relatedTarget:t})}),this._dialog,e)}_setEscapeEvent(){this._isShown?j.on(this._element,Ni,(t=>{this._config.keyboard&&t.key===Oi?(t.preventDefault(),this.hide()):this._config.keyboard||t.key!==Oi||this._triggerBackdropTransition()})):j.off(this._element,Ni)}_setResizeEvent(){this._isShown?j.on(window,Di,(()=>this._adjustDialog())):j.off(window,Di)}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(Pi),this._resetAdjustments(),this._scrollBar.reset(),j.trigger(this._element,Li)}))}_showBackdrop(t){j.on(this._element,Si,(t=>{this._ignoreBackdropClick?this._ignoreBackdropClick=!1:t.target===t.currentTarget&&(!0===this._config.backdrop?this.hide():"static"===this._config.backdrop&&this._triggerBackdropTransition())})),this._backdrop.show(t)}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(j.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const{classList:t,scrollHeight:e,style:i}=this._element,n=e>document.documentElement.clientHeight;!n&&"hidden"===i.overflowY||t.contains(Mi)||(n||(i.overflowY="hidden"),t.add(Mi),this._queueCallback((()=>{t.remove(Mi),n||this._queueCallback((()=>{i.overflowY=""}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;(!i&&t&&!m()||i&&!t&&m())&&(this._element.style.paddingLeft=`${e}px`),(i&&!t&&!m()||!i&&t&&m())&&(this._element.style.paddingRight=`${e}px`)}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=Hi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}j.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=n(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),j.one(e,xi,(t=>{t.defaultPrevented||j.one(e,Li,(()=>{l(this)&&this.focus()}))}));const i=V.findOne(".modal.show");i&&Hi.getInstance(i).hide(),Hi.getOrCreateInstance(e).toggle(this)})),R(Hi),g(Hi);const Bi="offcanvas",Ri={backdrop:!0,keyboard:!0,scroll:!1},Wi={backdrop:"boolean",keyboard:"boolean",scroll:"boolean"},$i="show",zi=".offcanvas.show",qi="hidden.bs.offcanvas";class Fi extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get NAME(){return Bi}static get Default(){return Ri}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||j.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._element.style.visibility="visible",this._backdrop.show(),this._config.scroll||(new fi).hide(),this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add($i),this._queueCallback((()=>{this._config.scroll||this._focustrap.activate(),j.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(j.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.remove($i),this._backdrop.hide(),this._queueCallback((()=>{this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._element.style.visibility="hidden",this._config.scroll||(new fi).reset(),j.trigger(this._element,qi)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_getConfig(t){return t={...Ri,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(Bi,t,Wi),t}_initializeBackDrop(){return new bi({className:"offcanvas-backdrop",isVisible:this._config.backdrop,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:()=>this.hide()})}_initializeFocusTrap(){return new Ai({trapElement:this._element})}_addEventListeners(){j.on(this._element,"keydown.dismiss.bs.offcanvas",(t=>{this._config.keyboard&&"Escape"===t.key&&this.hide()}))}static jQueryInterface(t){return this.each((function(){const e=Fi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}j.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=n(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),c(this))return;j.one(e,qi,(()=>{l(this)&&this.focus()}));const i=V.findOne(zi);i&&i!==e&&Fi.getInstance(i).hide(),Fi.getOrCreateInstance(e).toggle(this)})),j.on(window,"load.bs.offcanvas.data-api",(()=>V.find(zi).forEach((t=>Fi.getOrCreateInstance(t).show())))),R(Fi),g(Fi);const Ui=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Vi=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,Ki=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,Xi=(t,e)=>{const i=t.nodeName.toLowerCase();if(e.includes(i))return!Ui.has(i)||Boolean(Vi.test(t.nodeValue)||Ki.test(t.nodeValue));const n=e.filter((t=>t instanceof RegExp));for(let t=0,e=n.length;t{Xi(t,r)||i.removeAttribute(t.nodeName)}))}return n.body.innerHTML}const Qi="tooltip",Gi=new Set(["sanitize","allowList","sanitizeFn"]),Zi={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(array|string|function)",container:"(string|element|boolean)",fallbackPlacements:"array",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",allowList:"object",popperConfig:"(null|object|function)"},Ji={AUTO:"auto",TOP:"top",RIGHT:m()?"left":"right",BOTTOM:"bottom",LEFT:m()?"right":"left"},tn={animation:!0,template:'',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:[0,0],container:!1,fallbackPlacements:["top","right","bottom","left"],boundary:"clippingParents",customClass:"",sanitize:!0,sanitizeFn:null,allowList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},en={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},nn="fade",sn="show",on="show",rn="out",an=".tooltip-inner",ln=".modal",cn="hide.bs.modal",hn="hover",dn="focus";class un extends B{constructor(t,e){if(void 0===Fe)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t),this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this._config=this._getConfig(e),this.tip=null,this._setListeners()}static get Default(){return tn}static get NAME(){return Qi}static get Event(){return en}static get DefaultType(){return Zi}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(t){if(this._isEnabled)if(t){const e=this._initializeOnDelegatedTarget(t);e._activeTrigger.click=!e._activeTrigger.click,e._isWithActiveTrigger()?e._enter(null,e):e._leave(null,e)}else{if(this.getTipElement().classList.contains(sn))return void this._leave(null,this);this._enter(null,this)}}dispose(){clearTimeout(this._timeout),j.off(this._element.closest(ln),cn,this._hideModalHandler),this.tip&&this.tip.remove(),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this.isWithContent()||!this._isEnabled)return;const t=j.trigger(this._element,this.constructor.Event.SHOW),e=h(this._element),i=null===e?this._element.ownerDocument.documentElement.contains(this._element):e.contains(this._element);if(t.defaultPrevented||!i)return;"tooltip"===this.constructor.NAME&&this.tip&&this.getTitle()!==this.tip.querySelector(an).innerHTML&&(this._disposePopper(),this.tip.remove(),this.tip=null);const n=this.getTipElement(),s=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME);n.setAttribute("id",s),this._element.setAttribute("aria-describedby",s),this._config.animation&&n.classList.add(nn);const o="function"==typeof this._config.placement?this._config.placement.call(this,n,this._element):this._config.placement,r=this._getAttachment(o);this._addAttachmentClass(r);const{container:a}=this._config;H.set(n,this.constructor.DATA_KEY,this),this._element.ownerDocument.documentElement.contains(this.tip)||(a.append(n),j.trigger(this._element,this.constructor.Event.INSERTED)),this._popper?this._popper.update():this._popper=qe(this._element,n,this._getPopperConfig(r)),n.classList.add(sn);const l=this._resolvePossibleFunction(this._config.customClass);l&&n.classList.add(...l.split(" ")),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>{j.on(t,"mouseover",d)}));const c=this.tip.classList.contains(nn);this._queueCallback((()=>{const t=this._hoverState;this._hoverState=null,j.trigger(this._element,this.constructor.Event.SHOWN),t===rn&&this._leave(null,this)}),this.tip,c)}hide(){if(!this._popper)return;const t=this.getTipElement();if(j.trigger(this._element,this.constructor.Event.HIDE).defaultPrevented)return;t.classList.remove(sn),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>j.off(t,"mouseover",d))),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1;const e=this.tip.classList.contains(nn);this._queueCallback((()=>{this._isWithActiveTrigger()||(this._hoverState!==on&&t.remove(),this._cleanTipClass(),this._element.removeAttribute("aria-describedby"),j.trigger(this._element,this.constructor.Event.HIDDEN),this._disposePopper())}),this.tip,e),this._hoverState=""}update(){null!==this._popper&&this._popper.update()}isWithContent(){return Boolean(this.getTitle())}getTipElement(){if(this.tip)return this.tip;const t=document.createElement("div");t.innerHTML=this._config.template;const e=t.children[0];return this.setContent(e),e.classList.remove(nn,sn),this.tip=e,this.tip}setContent(t){this._sanitizeAndSetContent(t,this.getTitle(),an)}_sanitizeAndSetContent(t,e,i){const n=V.findOne(i,t);e||!n?this.setElementContent(n,e):n.remove()}setElementContent(t,e){if(null!==t)return o(e)?(e=r(e),void(this._config.html?e.parentNode!==t&&(t.innerHTML="",t.append(e)):t.textContent=e.textContent)):void(this._config.html?(this._config.sanitize&&(e=Yi(e,this._config.allowList,this._config.sanitizeFn)),t.innerHTML=e):t.textContent=e)}getTitle(){const t=this._element.getAttribute("data-bs-original-title")||this._config.title;return this._resolvePossibleFunction(t)}updateAttachment(t){return"right"===t?"end":"left"===t?"start":t}_initializeOnDelegatedTarget(t,e){return e||this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return"function"==typeof t?t.call(this._element):t}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"onChange",enabled:!0,phase:"afterWrite",fn:t=>this._handlePopperPlacementChange(t)}],onFirstUpdate:t=>{t.options.placement!==t.placement&&this._handlePopperPlacementChange(t)}};return{...e,..."function"==typeof this._config.popperConfig?this._config.popperConfig(e):this._config.popperConfig}}_addAttachmentClass(t){this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(t)}`)}_getAttachment(t){return Ji[t.toUpperCase()]}_setListeners(){this._config.trigger.split(" ").forEach((t=>{if("click"===t)j.on(this._element,this.constructor.Event.CLICK,this._config.selector,(t=>this.toggle(t)));else if("manual"!==t){const e=t===hn?this.constructor.Event.MOUSEENTER:this.constructor.Event.FOCUSIN,i=t===hn?this.constructor.Event.MOUSELEAVE:this.constructor.Event.FOCUSOUT;j.on(this._element,e,this._config.selector,(t=>this._enter(t))),j.on(this._element,i,this._config.selector,(t=>this._leave(t)))}})),this._hideModalHandler=()=>{this._element&&this.hide()},j.on(this._element.closest(ln),cn,this._hideModalHandler),this._config.selector?this._config={...this._config,trigger:"manual",selector:""}:this._fixTitle()}_fixTitle(){const t=this._element.getAttribute("title"),e=typeof this._element.getAttribute("data-bs-original-title");(t||"string"!==e)&&(this._element.setAttribute("data-bs-original-title",t||""),!t||this._element.getAttribute("aria-label")||this._element.textContent||this._element.setAttribute("aria-label",t),this._element.setAttribute("title",""))}_enter(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusin"===t.type?dn:hn]=!0),e.getTipElement().classList.contains(sn)||e._hoverState===on?e._hoverState=on:(clearTimeout(e._timeout),e._hoverState=on,e._config.delay&&e._config.delay.show?e._timeout=setTimeout((()=>{e._hoverState===on&&e.show()}),e._config.delay.show):e.show())}_leave(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusout"===t.type?dn:hn]=e._element.contains(t.relatedTarget)),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=rn,e._config.delay&&e._config.delay.hide?e._timeout=setTimeout((()=>{e._hoverState===rn&&e.hide()}),e._config.delay.hide):e.hide())}_isWithActiveTrigger(){for(const t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1}_getConfig(t){const e=U.getDataAttributes(this._element);return Object.keys(e).forEach((t=>{Gi.has(t)&&delete e[t]})),(t={...this.constructor.Default,...e,..."object"==typeof t&&t?t:{}}).container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),a(Qi,t,this.constructor.DefaultType),t.sanitize&&(t.template=Yi(t.template,t.allowList,t.sanitizeFn)),t}_getDelegateConfig(){const t={};for(const e in this._config)this.constructor.Default[e]!==this._config[e]&&(t[e]=this._config[e]);return t}_cleanTipClass(){const t=this.getTipElement(),e=new RegExp(`(^|\\s)${this._getBasicClassPrefix()}\\S+`,"g"),i=t.getAttribute("class").match(e);null!==i&&i.length>0&&i.map((t=>t.trim())).forEach((e=>t.classList.remove(e)))}_getBasicClassPrefix(){return"bs-tooltip"}_handlePopperPlacementChange(t){const{state:e}=t;e&&(this.tip=e.elements.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(e.placement)))}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null)}static jQueryInterface(t){return this.each((function(){const e=un.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(un);const fn={...un.Default,placement:"right",offset:[0,8],trigger:"click",content:"",template:''},pn={...un.DefaultType,content:"(string|element|function)"},mn={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"};class gn extends un{static get Default(){return fn}static get NAME(){return"popover"}static get Event(){return mn}static get DefaultType(){return pn}isWithContent(){return this.getTitle()||this._getContent()}setContent(t){this._sanitizeAndSetContent(t,this.getTitle(),".popover-header"),this._sanitizeAndSetContent(t,this._getContent(),".popover-body")}_getContent(){return this._resolvePossibleFunction(this._config.content)}_getBasicClassPrefix(){return"bs-popover"}static jQueryInterface(t){return this.each((function(){const e=gn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(gn);const _n="scrollspy",bn={offset:10,method:"auto",target:""},vn={offset:"number",method:"string",target:"(string|element)"},yn="active",wn=".nav-link, .list-group-item, .dropdown-item",En="position";class An extends B{constructor(t,e){super(t),this._scrollElement="BODY"===this._element.tagName?window:this._element,this._config=this._getConfig(e),this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,j.on(this._scrollElement,"scroll.bs.scrollspy",(()=>this._process())),this.refresh(),this._process()}static get Default(){return bn}static get NAME(){return _n}refresh(){const t=this._scrollElement===this._scrollElement.window?"offset":En,e="auto"===this._config.method?t:this._config.method,n=e===En?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),V.find(wn,this._config.target).map((t=>{const s=i(t),o=s?V.findOne(s):null;if(o){const t=o.getBoundingClientRect();if(t.width||t.height)return[U[e](o).top+n,s]}return null})).filter((t=>t)).sort(((t,e)=>t[0]-e[0])).forEach((t=>{this._offsets.push(t[0]),this._targets.push(t[1])}))}dispose(){j.off(this._scrollElement,".bs.scrollspy"),super.dispose()}_getConfig(t){return(t={...bn,...U.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}}).target=r(t.target)||document.documentElement,a(_n,t,vn),t}_getScrollTop(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop}_getScrollHeight(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}_getOffsetHeight(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height}_process(){const t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),i=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=i){const t=this._targets[this._targets.length-1];this._activeTarget!==t&&this._activate(t)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(let e=this._offsets.length;e--;)this._activeTarget!==this._targets[e]&&t>=this._offsets[e]&&(void 0===this._offsets[e+1]||t`${e}[data-bs-target="${t}"],${e}[href="${t}"]`)),i=V.findOne(e.join(","),this._config.target);i.classList.add(yn),i.classList.contains("dropdown-item")?V.findOne(".dropdown-toggle",i.closest(".dropdown")).classList.add(yn):V.parents(i,".nav, .list-group").forEach((t=>{V.prev(t,".nav-link, .list-group-item").forEach((t=>t.classList.add(yn))),V.prev(t,".nav-item").forEach((t=>{V.children(t,".nav-link").forEach((t=>t.classList.add(yn)))}))})),j.trigger(this._scrollElement,"activate.bs.scrollspy",{relatedTarget:t})}_clear(){V.find(wn,this._config.target).filter((t=>t.classList.contains(yn))).forEach((t=>t.classList.remove(yn)))}static jQueryInterface(t){return this.each((function(){const e=An.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}j.on(window,"load.bs.scrollspy.data-api",(()=>{V.find('[data-bs-spy="scroll"]').forEach((t=>new An(t)))})),g(An);const Tn="active",On="fade",Cn="show",kn=".active",Ln=":scope > li > .active";class xn extends B{static get NAME(){return"tab"}show(){if(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains(Tn))return;let t;const e=n(this._element),i=this._element.closest(".nav, .list-group");if(i){const e="UL"===i.nodeName||"OL"===i.nodeName?Ln:kn;t=V.find(e,i),t=t[t.length-1]}const s=t?j.trigger(t,"hide.bs.tab",{relatedTarget:this._element}):null;if(j.trigger(this._element,"show.bs.tab",{relatedTarget:t}).defaultPrevented||null!==s&&s.defaultPrevented)return;this._activate(this._element,i);const o=()=>{j.trigger(t,"hidden.bs.tab",{relatedTarget:this._element}),j.trigger(this._element,"shown.bs.tab",{relatedTarget:t})};e?this._activate(e,e.parentNode,o):o()}_activate(t,e,i){const n=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?V.children(e,kn):V.find(Ln,e))[0],s=i&&n&&n.classList.contains(On),o=()=>this._transitionComplete(t,n,i);n&&s?(n.classList.remove(Cn),this._queueCallback(o,t,!0)):o()}_transitionComplete(t,e,i){if(e){e.classList.remove(Tn);const t=V.findOne(":scope > .dropdown-menu .active",e.parentNode);t&&t.classList.remove(Tn),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}t.classList.add(Tn),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),u(t),t.classList.contains(On)&&t.classList.add(Cn);let n=t.parentNode;if(n&&"LI"===n.nodeName&&(n=n.parentNode),n&&n.classList.contains("dropdown-menu")){const e=t.closest(".dropdown");e&&V.find(".dropdown-toggle",e).forEach((t=>t.classList.add(Tn))),t.setAttribute("aria-expanded",!0)}i&&i()}static jQueryInterface(t){return this.each((function(){const e=xn.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}j.on(document,"click.bs.tab.data-api",'[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),c(this)||xn.getOrCreateInstance(this).show()})),g(xn);const Dn="toast",Sn="hide",Nn="show",In="showing",Pn={animation:"boolean",autohide:"boolean",delay:"number"},jn={animation:!0,autohide:!0,delay:5e3};class Mn extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get DefaultType(){return Pn}static get Default(){return jn}static get NAME(){return Dn}show(){j.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(Sn),u(this._element),this._element.classList.add(Nn),this._element.classList.add(In),this._queueCallback((()=>{this._element.classList.remove(In),j.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this._element.classList.contains(Nn)&&(j.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.add(In),this._queueCallback((()=>{this._element.classList.add(Sn),this._element.classList.remove(In),this._element.classList.remove(Nn),j.trigger(this._element,"hidden.bs.toast")}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this._element.classList.contains(Nn)&&this._element.classList.remove(Nn),super.dispose()}_getConfig(t){return t={...jn,...U.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}},a(Dn,t,this.constructor.DefaultType),t}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){j.on(this._element,"mouseover.bs.toast",(t=>this._onInteraction(t,!0))),j.on(this._element,"mouseout.bs.toast",(t=>this._onInteraction(t,!1))),j.on(this._element,"focusin.bs.toast",(t=>this._onInteraction(t,!0))),j.on(this._element,"focusout.bs.toast",(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=Mn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(Mn),g(Mn),{Alert:W,Button:z,Carousel:st,Collapse:pt,Dropdown:hi,Modal:Hi,Offcanvas:Fi,Popover:gn,ScrollSpy:An,Tab:xn,Toast:Mn,Tooltip:un}})); -//# sourceMappingURL=bootstrap.bundle.min.js.map +/*! + * Bootstrap v5.1.3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t="transitionend",e=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return e},i=t=>{const i=e(t);return i&&document.querySelector(i)?i:null},n=t=>{const i=e(t);return i?document.querySelector(i):null},s=e=>{e.dispatchEvent(new Event(t))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(t):null,a=(t,e,i)=>{Object.keys(i).forEach((n=>{const s=i[n],r=e[n],a=r&&o(r)?"element":null==(l=r)?`${l}`:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();var l;if(!new RegExp(s).test(a))throw new TypeError(`${t.toUpperCase()}: Option "${n}" provided type "${a}" but expected type "${s}".`)}))},l=t=>!(!o(t)||0===t.getClientRects().length)&&"visible"===getComputedStyle(t).getPropertyValue("visibility"),c=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),h=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?h(t.parentNode):null},d=()=>{},u=t=>{t.offsetHeight},f=()=>{const{jQuery:t}=window;return t&&!document.body.hasAttribute("data-bs-no-jquery")?t:null},p=[],m=()=>"rtl"===document.documentElement.dir,g=t=>{var e;e=()=>{const e=f();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(p.length||document.addEventListener("DOMContentLoaded",(()=>{p.forEach((t=>t()))})),p.push(e)):e()},_=t=>{"function"==typeof t&&t()},b=(e,i,n=!0)=>{if(!n)return void _(e);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(i)+5;let r=!1;const a=({target:n})=>{n===i&&(r=!0,i.removeEventListener(t,a),_(e))};i.addEventListener(t,a),setTimeout((()=>{r||s(i)}),o)},v=(t,e,i,n)=>{let s=t.indexOf(e);if(-1===s)return t[!i&&n?t.length-1:0];const o=t.length;return s+=i?1:-1,n&&(s=(s+o)%o),t[Math.max(0,Math.min(s,o-1))]},y=/[^.]*(?=\..*)\.|.*/,w=/\..*/,E=/::\d+$/,A={};let T=1;const O={mouseenter:"mouseover",mouseleave:"mouseout"},C=/^(mouseenter|mouseleave)/i,k=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function L(t,e){return e&&`${e}::${T++}`||t.uidEvent||T++}function x(t){const e=L(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function D(t,e,i=null){const n=Object.keys(t);for(let s=0,o=n.length;sfunction(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};n?n=t(n):i=t(i)}const[o,r,a]=S(e,i,n),l=x(t),c=l[a]||(l[a]={}),h=D(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=L(r,e.replace(y,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(let a=o.length;a--;)if(o[a]===r)return s.delegateTarget=r,n.oneOff&&j.off(t,s.type,e,i),i.apply(r,[s]);return null}}(t,i,n):function(t,e){return function i(n){return n.delegateTarget=t,i.oneOff&&j.off(t,n.type,e),e.apply(t,[n])}}(t,i);u.delegationSelector=o?i:null,u.originalHandler=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function I(t,e,i,n,s){const o=D(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function P(t){return t=t.replace(w,""),O[t]||t}const j={on(t,e,i,n){N(t,e,i,n,!1)},one(t,e,i,n){N(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=S(e,i,n),a=r!==e,l=x(t),c=e.startsWith(".");if(void 0!==o){if(!l||!l[r])return;return void I(t,l,r,o,s?i:null)}c&&Object.keys(l).forEach((i=>{!function(t,e,i,n){const s=e[i]||{};Object.keys(s).forEach((o=>{if(o.includes(n)){const n=s[o];I(t,e,i,n.originalHandler,n.delegationSelector)}}))}(t,l,i,e.slice(1))}));const h=l[r]||{};Object.keys(h).forEach((i=>{const n=i.replace(E,"");if(!a||e.includes(n)){const e=h[i];I(t,l,r,e.originalHandler,e.delegationSelector)}}))},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=f(),s=P(e),o=e!==s,r=k.has(s);let a,l=!0,c=!0,h=!1,d=null;return o&&n&&(a=n.Event(e,i),n(t).trigger(a),l=!a.isPropagationStopped(),c=!a.isImmediatePropagationStopped(),h=a.isDefaultPrevented()),r?(d=document.createEvent("HTMLEvents"),d.initEvent(s,l,!0)):d=new CustomEvent(e,{bubbles:l,cancelable:!0}),void 0!==i&&Object.keys(i).forEach((t=>{Object.defineProperty(d,t,{get:()=>i[t]})})),h&&d.preventDefault(),c&&t.dispatchEvent(d),d.defaultPrevented&&void 0!==a&&a.preventDefault(),d}},M=new Map,H={set(t,e,i){M.has(t)||M.set(t,new Map);const n=M.get(t);n.has(e)||0===n.size?n.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>M.has(t)&&M.get(t).get(e)||null,remove(t,e){if(!M.has(t))return;const i=M.get(t);i.delete(e),0===i.size&&M.delete(t)}};class B{constructor(t){(t=r(t))&&(this._element=t,H.set(this._element,this.constructor.DATA_KEY,this))}dispose(){H.remove(this._element,this.constructor.DATA_KEY),j.off(this._element,this.constructor.EVENT_KEY),Object.getOwnPropertyNames(this).forEach((t=>{this[t]=null}))}_queueCallback(t,e,i=!0){b(t,e,i)}static getInstance(t){return H.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.1.3"}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}}const R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,s=t.NAME;j.on(document,i,`[data-bs-dismiss="${s}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),c(this))return;const o=n(this)||this.closest(`.${s}`);t.getOrCreateInstance(o)[e]()}))};class W extends B{static get NAME(){return"alert"}close(){if(j.trigger(this._element,"close.bs.alert").defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),j.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=W.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(W,"close"),g(W);const $='[data-bs-toggle="button"]';class z extends B{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=z.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}function q(t){return"true"===t||"false"!==t&&(t===Number(t).toString()?Number(t):""===t||"null"===t?null:t)}function F(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}j.on(document,"click.bs.button.data-api",$,(t=>{t.preventDefault();const e=t.target.closest($);z.getOrCreateInstance(e).toggle()})),g(z);const U={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${F(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${F(e)}`)},getDataAttributes(t){if(!t)return{};const e={};return Object.keys(t.dataset).filter((t=>t.startsWith("bs"))).forEach((i=>{let n=i.replace(/^bs/,"");n=n.charAt(0).toLowerCase()+n.slice(1,n.length),e[n]=q(t.dataset[i])})),e},getDataAttribute:(t,e)=>q(t.getAttribute(`data-bs-${F(e)}`)),offset(t){const e=t.getBoundingClientRect();return{top:e.top+window.pageYOffset,left:e.left+window.pageXOffset}},position:t=>({top:t.offsetTop,left:t.offsetLeft})},V={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode;for(;n&&n.nodeType===Node.ELEMENT_NODE&&3!==n.nodeType;)n.matches(e)&&i.push(n),n=n.parentNode;return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(", ");return this.find(e,t).filter((t=>!c(t)&&l(t)))}},K="carousel",X={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},Y={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},Q="next",G="prev",Z="left",J="right",tt={ArrowLeft:J,ArrowRight:Z},et="slid.bs.carousel",it="active",nt=".active.carousel-item";class st extends B{constructor(t,e){super(t),this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._indicatorsElement=V.findOne(".carousel-indicators",this._element),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent),this._addEventListeners()}static get Default(){return X}static get NAME(){return K}next(){this._slide(Q)}nextWhenVisible(){!document.hidden&&l(this._element)&&this.next()}prev(){this._slide(G)}pause(t){t||(this._isPaused=!0),V.findOne(".carousel-item-next, .carousel-item-prev",this._element)&&(s(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null}cycle(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))}to(t){this._activeElement=V.findOne(nt,this._element);const e=this._getItemIndex(this._activeElement);if(t>this._items.length-1||t<0)return;if(this._isSliding)return void j.one(this._element,et,(()=>this.to(t)));if(e===t)return this.pause(),void this.cycle();const i=t>e?Q:G;this._slide(i,this._items[t])}_getConfig(t){return t={...X,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(K,t,Y),t}_handleSwipe(){const t=Math.abs(this.touchDeltaX);if(t<=40)return;const e=t/this.touchDeltaX;this.touchDeltaX=0,e&&this._slide(e>0?J:Z)}_addEventListeners(){this._config.keyboard&&j.on(this._element,"keydown.bs.carousel",(t=>this._keydown(t))),"hover"===this._config.pause&&(j.on(this._element,"mouseenter.bs.carousel",(t=>this.pause(t))),j.on(this._element,"mouseleave.bs.carousel",(t=>this.cycle(t)))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()}_addTouchEventListeners(){const t=t=>this._pointerEvent&&("pen"===t.pointerType||"touch"===t.pointerType),e=e=>{t(e)?this.touchStartX=e.clientX:this._pointerEvent||(this.touchStartX=e.touches[0].clientX)},i=t=>{this.touchDeltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this.touchStartX},n=e=>{t(e)&&(this.touchDeltaX=e.clientX-this.touchStartX),this._handleSwipe(),"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((t=>this.cycle(t)),500+this._config.interval))};V.find(".carousel-item img",this._element).forEach((t=>{j.on(t,"dragstart.bs.carousel",(t=>t.preventDefault()))})),this._pointerEvent?(j.on(this._element,"pointerdown.bs.carousel",(t=>e(t))),j.on(this._element,"pointerup.bs.carousel",(t=>n(t))),this._element.classList.add("pointer-event")):(j.on(this._element,"touchstart.bs.carousel",(t=>e(t))),j.on(this._element,"touchmove.bs.carousel",(t=>i(t))),j.on(this._element,"touchend.bs.carousel",(t=>n(t))))}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=tt[t.key];e&&(t.preventDefault(),this._slide(e))}_getItemIndex(t){return this._items=t&&t.parentNode?V.find(".carousel-item",t.parentNode):[],this._items.indexOf(t)}_getItemByOrder(t,e){const i=t===Q;return v(this._items,e,i,this._config.wrap)}_triggerSlideEvent(t,e){const i=this._getItemIndex(t),n=this._getItemIndex(V.findOne(nt,this._element));return j.trigger(this._element,"slide.bs.carousel",{relatedTarget:t,direction:e,from:n,to:i})}_setActiveIndicatorElement(t){if(this._indicatorsElement){const e=V.findOne(".active",this._indicatorsElement);e.classList.remove(it),e.removeAttribute("aria-current");const i=V.find("[data-bs-target]",this._indicatorsElement);for(let e=0;e{j.trigger(this._element,et,{relatedTarget:o,direction:d,from:s,to:r})};if(this._element.classList.contains("slide")){o.classList.add(h),u(o),n.classList.add(c),o.classList.add(c);const t=()=>{o.classList.remove(c,h),o.classList.add(it),n.classList.remove(it,h,c),this._isSliding=!1,setTimeout(f,0)};this._queueCallback(t,n,!0)}else n.classList.remove(it),o.classList.add(it),this._isSliding=!1,f();a&&this.cycle()}_directionToOrder(t){return[J,Z].includes(t)?m()?t===Z?G:Q:t===Z?Q:G:t}_orderToDirection(t){return[Q,G].includes(t)?m()?t===G?Z:J:t===G?J:Z:t}static carouselInterface(t,e){const i=st.getOrCreateInstance(t,e);let{_config:n}=i;"object"==typeof e&&(n={...n,...e});const s="string"==typeof e?e:n.slide;if("number"==typeof e)i.to(e);else if("string"==typeof s){if(void 0===i[s])throw new TypeError(`No method named "${s}"`);i[s]()}else n.interval&&n.ride&&(i.pause(),i.cycle())}static jQueryInterface(t){return this.each((function(){st.carouselInterface(this,t)}))}static dataApiClickHandler(t){const e=n(this);if(!e||!e.classList.contains("carousel"))return;const i={...U.getDataAttributes(e),...U.getDataAttributes(this)},s=this.getAttribute("data-bs-slide-to");s&&(i.interval=!1),st.carouselInterface(e,i),s&&st.getInstance(e).to(s),t.preventDefault()}}j.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",st.dataApiClickHandler),j.on(window,"load.bs.carousel.data-api",(()=>{const t=V.find('[data-bs-ride="carousel"]');for(let e=0,i=t.length;et===this._element));null!==s&&o.length&&(this._selector=s,this._triggerArray.push(e))}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return rt}static get NAME(){return ot}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t,e=[];if(this._config.parent){const t=V.find(ut,this._config.parent);e=V.find(".collapse.show, .collapse.collapsing",this._config.parent).filter((e=>!t.includes(e)))}const i=V.findOne(this._selector);if(e.length){const n=e.find((t=>i!==t));if(t=n?pt.getInstance(n):null,t&&t._isTransitioning)return}if(j.trigger(this._element,"show.bs.collapse").defaultPrevented)return;e.forEach((e=>{i!==e&&pt.getOrCreateInstance(e,{toggle:!1}).hide(),t||H.set(e,"bs.collapse",null)}));const n=this._getDimension();this._element.classList.remove(ct),this._element.classList.add(ht),this._element.style[n]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const s=`scroll${n[0].toUpperCase()+n.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct,lt),this._element.style[n]="",j.trigger(this._element,"shown.bs.collapse")}),this._element,!0),this._element.style[n]=`${this._element[s]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(j.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,u(this._element),this._element.classList.add(ht),this._element.classList.remove(ct,lt);const e=this._triggerArray.length;for(let t=0;t{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct),j.trigger(this._element,"hidden.bs.collapse")}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(lt)}_getConfig(t){return(t={...rt,...U.getDataAttributes(this._element),...t}).toggle=Boolean(t.toggle),t.parent=r(t.parent),a(ot,t,at),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=V.find(ut,this._config.parent);V.find(ft,this._config.parent).filter((e=>!t.includes(e))).forEach((t=>{const e=n(t);e&&this._addAriaAndCollapsedClass([t],this._isShown(e))}))}_addAriaAndCollapsedClass(t,e){t.length&&t.forEach((t=>{e?t.classList.remove(dt):t.classList.add(dt),t.setAttribute("aria-expanded",e)}))}static jQueryInterface(t){return this.each((function(){const e={};"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1);const i=pt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}j.on(document,"click.bs.collapse.data-api",ft,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();const e=i(this);V.find(e).forEach((t=>{pt.getOrCreateInstance(t,{toggle:!1}).toggle()}))})),g(pt);var mt="top",gt="bottom",_t="right",bt="left",vt="auto",yt=[mt,gt,_t,bt],wt="start",Et="end",At="clippingParents",Tt="viewport",Ot="popper",Ct="reference",kt=yt.reduce((function(t,e){return t.concat([e+"-"+wt,e+"-"+Et])}),[]),Lt=[].concat(yt,[vt]).reduce((function(t,e){return t.concat([e,e+"-"+wt,e+"-"+Et])}),[]),xt="beforeRead",Dt="read",St="afterRead",Nt="beforeMain",It="main",Pt="afterMain",jt="beforeWrite",Mt="write",Ht="afterWrite",Bt=[xt,Dt,St,Nt,It,Pt,jt,Mt,Ht];function Rt(t){return t?(t.nodeName||"").toLowerCase():null}function Wt(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function $t(t){return t instanceof Wt(t).Element||t instanceof Element}function zt(t){return t instanceof Wt(t).HTMLElement||t instanceof HTMLElement}function qt(t){return"undefined"!=typeof ShadowRoot&&(t instanceof Wt(t).ShadowRoot||t instanceof ShadowRoot)}const Ft={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];zt(s)&&Rt(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});zt(n)&&Rt(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function Ut(t){return t.split("-")[0]}function Vt(t,e){var i=t.getBoundingClientRect();return{width:i.width/1,height:i.height/1,top:i.top/1,right:i.right/1,bottom:i.bottom/1,left:i.left/1,x:i.left/1,y:i.top/1}}function Kt(t){var e=Vt(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Xt(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&qt(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Yt(t){return Wt(t).getComputedStyle(t)}function Qt(t){return["table","td","th"].indexOf(Rt(t))>=0}function Gt(t){return(($t(t)?t.ownerDocument:t.document)||window.document).documentElement}function Zt(t){return"html"===Rt(t)?t:t.assignedSlot||t.parentNode||(qt(t)?t.host:null)||Gt(t)}function Jt(t){return zt(t)&&"fixed"!==Yt(t).position?t.offsetParent:null}function te(t){for(var e=Wt(t),i=Jt(t);i&&Qt(i)&&"static"===Yt(i).position;)i=Jt(i);return i&&("html"===Rt(i)||"body"===Rt(i)&&"static"===Yt(i).position)?e:i||function(t){var e=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&zt(t)&&"fixed"===Yt(t).position)return null;for(var i=Zt(t);zt(i)&&["html","body"].indexOf(Rt(i))<0;){var n=Yt(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function ee(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}var ie=Math.max,ne=Math.min,se=Math.round;function oe(t,e,i){return ie(t,ne(e,i))}function re(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function ae(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const le={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=Ut(i.placement),l=ee(a),c=[bt,_t].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return re("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:ae(t,yt))}(s.padding,i),d=Kt(o),u="y"===l?mt:bt,f="y"===l?gt:_t,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=te(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,E=oe(v,w,y),A=l;i.modifiersData[n]=((e={})[A]=E,e.centerOffset=E-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Xt(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function ce(t){return t.split("-")[1]}var he={top:"auto",right:"auto",bottom:"auto",left:"auto"};function de(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=!0===h?function(t){var e=t.x,i=t.y,n=window.devicePixelRatio||1;return{x:se(se(e*n)/n)||0,y:se(se(i*n)/n)||0}}(r):"function"==typeof h?h(r):r,u=d.x,f=void 0===u?0:u,p=d.y,m=void 0===p?0:p,g=r.hasOwnProperty("x"),_=r.hasOwnProperty("y"),b=bt,v=mt,y=window;if(c){var w=te(i),E="clientHeight",A="clientWidth";w===Wt(i)&&"static"!==Yt(w=Gt(i)).position&&"absolute"===a&&(E="scrollHeight",A="scrollWidth"),w=w,s!==mt&&(s!==bt&&s!==_t||o!==Et)||(v=gt,m-=w[E]-n.height,m*=l?1:-1),s!==bt&&(s!==mt&&s!==gt||o!==Et)||(b=_t,f-=w[A]-n.width,f*=l?1:-1)}var T,O=Object.assign({position:a},c&&he);return l?Object.assign({},O,((T={})[v]=_?"0":"",T[b]=g?"0":"",T.transform=(y.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",T)):Object.assign({},O,((e={})[v]=_?m+"px":"",e[b]=g?f+"px":"",e.transform="",e))}const ue={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:Ut(e.placement),variation:ce(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,de(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,de(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var fe={passive:!0};const pe={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=Wt(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,fe)})),a&&l.addEventListener("resize",i.update,fe),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,fe)})),a&&l.removeEventListener("resize",i.update,fe)}},data:{}};var me={left:"right",right:"left",bottom:"top",top:"bottom"};function ge(t){return t.replace(/left|right|bottom|top/g,(function(t){return me[t]}))}var _e={start:"end",end:"start"};function be(t){return t.replace(/start|end/g,(function(t){return _e[t]}))}function ve(t){var e=Wt(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function ye(t){return Vt(Gt(t)).left+ve(t).scrollLeft}function we(t){var e=Yt(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ee(t){return["html","body","#document"].indexOf(Rt(t))>=0?t.ownerDocument.body:zt(t)&&we(t)?t:Ee(Zt(t))}function Ae(t,e){var i;void 0===e&&(e=[]);var n=Ee(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=Wt(n),r=s?[o].concat(o.visualViewport||[],we(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Ae(Zt(r)))}function Te(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Oe(t,e){return e===Tt?Te(function(t){var e=Wt(t),i=Gt(t),n=e.visualViewport,s=i.clientWidth,o=i.clientHeight,r=0,a=0;return n&&(s=n.width,o=n.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(r=n.offsetLeft,a=n.offsetTop)),{width:s,height:o,x:r+ye(t),y:a}}(t)):zt(e)?function(t){var e=Vt(t);return e.top=e.top+t.clientTop,e.left=e.left+t.clientLeft,e.bottom=e.top+t.clientHeight,e.right=e.left+t.clientWidth,e.width=t.clientWidth,e.height=t.clientHeight,e.x=e.left,e.y=e.top,e}(e):Te(function(t){var e,i=Gt(t),n=ve(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=ie(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=ie(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+ye(t),l=-n.scrollTop;return"rtl"===Yt(s||i).direction&&(a+=ie(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(Gt(t)))}function Ce(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?Ut(s):null,r=s?ce(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case mt:e={x:a,y:i.y-n.height};break;case gt:e={x:a,y:i.y+i.height};break;case _t:e={x:i.x+i.width,y:l};break;case bt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?ee(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case wt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Et:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ke(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.boundary,r=void 0===o?At:o,a=i.rootBoundary,l=void 0===a?Tt:a,c=i.elementContext,h=void 0===c?Ot:c,d=i.altBoundary,u=void 0!==d&&d,f=i.padding,p=void 0===f?0:f,m=re("number"!=typeof p?p:ae(p,yt)),g=h===Ot?Ct:Ot,_=t.rects.popper,b=t.elements[u?g:h],v=function(t,e,i){var n="clippingParents"===e?function(t){var e=Ae(Zt(t)),i=["absolute","fixed"].indexOf(Yt(t).position)>=0&&zt(t)?te(t):t;return $t(i)?e.filter((function(t){return $t(t)&&Xt(t,i)&&"body"!==Rt(t)})):[]}(t):[].concat(e),s=[].concat(n,[i]),o=s[0],r=s.reduce((function(e,i){var n=Oe(t,i);return e.top=ie(n.top,e.top),e.right=ne(n.right,e.right),e.bottom=ne(n.bottom,e.bottom),e.left=ie(n.left,e.left),e}),Oe(t,o));return r.width=r.right-r.left,r.height=r.bottom-r.top,r.x=r.left,r.y=r.top,r}($t(b)?b:b.contextElement||Gt(t.elements.popper),r,l),y=Vt(t.elements.reference),w=Ce({reference:y,element:_,strategy:"absolute",placement:s}),E=Te(Object.assign({},_,w)),A=h===Ot?E:y,T={top:v.top-A.top+m.top,bottom:A.bottom-v.bottom+m.bottom,left:v.left-A.left+m.left,right:A.right-v.right+m.right},O=t.modifiersData.offset;if(h===Ot&&O){var C=O[s];Object.keys(T).forEach((function(t){var e=[_t,gt].indexOf(t)>=0?1:-1,i=[mt,gt].indexOf(t)>=0?"y":"x";T[t]+=C[i]*e}))}return T}function Le(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?Lt:l,h=ce(n),d=h?a?kt:kt.filter((function(t){return ce(t)===h})):yt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=ke(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[Ut(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const xe={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=Ut(g),b=l||(_!==g&&p?function(t){if(Ut(t)===vt)return[];var e=ge(t);return[be(t),e,be(e)]}(g):[ge(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(Ut(i)===vt?Le(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,E=new Map,A=!0,T=v[0],O=0;O=0,D=x?"width":"height",S=ke(e,{placement:C,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),N=x?L?_t:bt:L?gt:mt;y[D]>w[D]&&(N=ge(N));var I=ge(N),P=[];if(o&&P.push(S[k]<=0),a&&P.push(S[N]<=0,S[I]<=0),P.every((function(t){return t}))){T=C,A=!1;break}E.set(C,P)}if(A)for(var j=function(t){var e=v.find((function(e){var i=E.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==j(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function De(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function Se(t){return[mt,_t,gt,bt].some((function(e){return t[e]>=0}))}const Ne={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=ke(e,{elementContext:"reference"}),a=ke(e,{altBoundary:!0}),l=De(r,n),c=De(a,s,o),h=Se(l),d=Se(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},Ie={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=Lt.reduce((function(t,i){return t[i]=function(t,e,i){var n=Ut(t),s=[bt,mt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[bt,_t].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},Pe={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=Ce({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},je={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=ke(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=Ut(e.placement),b=ce(e.placement),v=!b,y=ee(_),w="x"===y?"y":"x",E=e.modifiersData.popperOffsets,A=e.rects.reference,T=e.rects.popper,O="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,C={x:0,y:0};if(E){if(o||a){var k="y"===y?mt:bt,L="y"===y?gt:_t,x="y"===y?"height":"width",D=E[y],S=E[y]+g[k],N=E[y]-g[L],I=f?-T[x]/2:0,P=b===wt?A[x]:T[x],j=b===wt?-T[x]:-A[x],M=e.elements.arrow,H=f&&M?Kt(M):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},R=B[k],W=B[L],$=oe(0,A[x],H[x]),z=v?A[x]/2-I-$-R-O:P-$-R-O,q=v?-A[x]/2+I+$+W+O:j+$+W+O,F=e.elements.arrow&&te(e.elements.arrow),U=F?"y"===y?F.clientTop||0:F.clientLeft||0:0,V=e.modifiersData.offset?e.modifiersData.offset[e.placement][y]:0,K=E[y]+z-V-U,X=E[y]+q-V;if(o){var Y=oe(f?ne(S,K):S,D,f?ie(N,X):N);E[y]=Y,C[y]=Y-D}if(a){var Q="x"===y?mt:bt,G="x"===y?gt:_t,Z=E[w],J=Z+g[Q],tt=Z-g[G],et=oe(f?ne(J,K):J,Z,f?ie(tt,X):tt);E[w]=et,C[w]=et-Z}}e.modifiersData[n]=C}},requiresIfExists:["offset"]};function Me(t,e,i){void 0===i&&(i=!1);var n=zt(e);zt(e)&&function(t){var e=t.getBoundingClientRect();e.width,t.offsetWidth,e.height,t.offsetHeight}(e);var s,o,r=Gt(e),a=Vt(t),l={scrollLeft:0,scrollTop:0},c={x:0,y:0};return(n||!n&&!i)&&(("body"!==Rt(e)||we(r))&&(l=(s=e)!==Wt(s)&&zt(s)?{scrollLeft:(o=s).scrollLeft,scrollTop:o.scrollTop}:ve(s)),zt(e)?((c=Vt(e)).x+=e.clientLeft,c.y+=e.clientTop):r&&(c.x=ye(r))),{x:a.left+l.scrollLeft-c.x,y:a.top+l.scrollTop-c.y,width:a.width,height:a.height}}function He(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var Be={placement:"bottom",modifiers:[],strategy:"absolute"};function Re(){for(var t=arguments.length,e=new Array(t),i=0;ij.on(t,"mouseover",d))),this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add(Je),this._element.classList.add(Je),j.trigger(this._element,"shown.bs.dropdown",t)}hide(){if(c(this._element)||!this._isShown(this._menu))return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(t){j.trigger(this._element,"hide.bs.dropdown",t).defaultPrevented||("ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>j.off(t,"mouseover",d))),this._popper&&this._popper.destroy(),this._menu.classList.remove(Je),this._element.classList.remove(Je),this._element.setAttribute("aria-expanded","false"),U.removeDataAttribute(this._menu,"popper"),j.trigger(this._element,"hidden.bs.dropdown",t))}_getConfig(t){if(t={...this.constructor.Default,...U.getDataAttributes(this._element),...t},a(Ue,t,this.constructor.DefaultType),"object"==typeof t.reference&&!o(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError(`${Ue.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return t}_createPopper(t){if(void 0===Fe)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let e=this._element;"parent"===this._config.reference?e=t:o(this._config.reference)?e=r(this._config.reference):"object"==typeof this._config.reference&&(e=this._config.reference);const i=this._getPopperConfig(),n=i.modifiers.find((t=>"applyStyles"===t.name&&!1===t.enabled));this._popper=qe(e,this._menu,i),n&&U.setDataAttribute(this._menu,"popper","static")}_isShown(t=this._element){return t.classList.contains(Je)}_getMenuElement(){return V.next(this._element,ei)[0]}_getPlacement(){const t=this._element.parentNode;if(t.classList.contains("dropend"))return ri;if(t.classList.contains("dropstart"))return ai;const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?ni:ii:e?oi:si}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return"static"===this._config.display&&(t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}_selectMenuItem({key:t,target:e}){const i=V.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter(l);i.length&&v(i,e,t===Ye,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=hi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(t&&(2===t.button||"keyup"===t.type&&"Tab"!==t.key))return;const e=V.find(ti);for(let i=0,n=e.length;ie+t)),this._setElementAttributes(di,"paddingRight",(e=>e+t)),this._setElementAttributes(ui,"marginRight",(e=>e-t))}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t)[e];t.style[e]=`${i(Number.parseFloat(s))}px`}))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,"paddingRight"),this._resetElementAttributes(di,"paddingRight"),this._resetElementAttributes(ui,"marginRight")}_saveInitialAttribute(t,e){const i=t.style[e];i&&U.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=U.getDataAttribute(t,e);void 0===i?t.style.removeProperty(e):(U.removeDataAttribute(t,e),t.style[e]=i)}))}_applyManipulationCallback(t,e){o(t)?e(t):V.find(t,this._element).forEach(e)}isOverflowing(){return this.getWidth()>0}}const pi={className:"modal-backdrop",isVisible:!0,isAnimated:!1,rootElement:"body",clickCallback:null},mi={className:"string",isVisible:"boolean",isAnimated:"boolean",rootElement:"(element|string)",clickCallback:"(function|null)"},gi="show",_i="mousedown.bs.backdrop";class bi{constructor(t){this._config=this._getConfig(t),this._isAppended=!1,this._element=null}show(t){this._config.isVisible?(this._append(),this._config.isAnimated&&u(this._getElement()),this._getElement().classList.add(gi),this._emulateAnimation((()=>{_(t)}))):_(t)}hide(t){this._config.isVisible?(this._getElement().classList.remove(gi),this._emulateAnimation((()=>{this.dispose(),_(t)}))):_(t)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_getConfig(t){return(t={...pi,..."object"==typeof t?t:{}}).rootElement=r(t.rootElement),a("backdrop",t,mi),t}_append(){this._isAppended||(this._config.rootElement.append(this._getElement()),j.on(this._getElement(),_i,(()=>{_(this._config.clickCallback)})),this._isAppended=!0)}dispose(){this._isAppended&&(j.off(this._element,_i),this._element.remove(),this._isAppended=!1)}_emulateAnimation(t){b(t,this._getElement(),this._config.isAnimated)}}const vi={trapElement:null,autofocus:!0},yi={trapElement:"element",autofocus:"boolean"},wi=".bs.focustrap",Ei="backward";class Ai{constructor(t){this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}activate(){const{trapElement:t,autofocus:e}=this._config;this._isActive||(e&&t.focus(),j.off(document,wi),j.on(document,"focusin.bs.focustrap",(t=>this._handleFocusin(t))),j.on(document,"keydown.tab.bs.focustrap",(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,j.off(document,wi))}_handleFocusin(t){const{target:e}=t,{trapElement:i}=this._config;if(e===document||e===i||i.contains(e))return;const n=V.focusableChildren(i);0===n.length?i.focus():this._lastTabNavDirection===Ei?n[n.length-1].focus():n[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?Ei:"forward")}_getConfig(t){return t={...vi,..."object"==typeof t?t:{}},a("focustrap",t,yi),t}}const Ti="modal",Oi="Escape",Ci={backdrop:!0,keyboard:!0,focus:!0},ki={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean"},Li="hidden.bs.modal",xi="show.bs.modal",Di="resize.bs.modal",Si="click.dismiss.bs.modal",Ni="keydown.dismiss.bs.modal",Ii="mousedown.dismiss.bs.modal",Pi="modal-open",ji="show",Mi="modal-static";class Hi extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._dialog=V.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollBar=new fi}static get Default(){return Ci}static get NAME(){return Ti}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||j.trigger(this._element,xi,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isAnimated()&&(this._isTransitioning=!0),this._scrollBar.hide(),document.body.classList.add(Pi),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),j.on(this._dialog,Ii,(()=>{j.one(this._element,"mouseup.dismiss.bs.modal",(t=>{t.target===this._element&&(this._ignoreBackdropClick=!0)}))})),this._showBackdrop((()=>this._showElement(t))))}hide(){if(!this._isShown||this._isTransitioning)return;if(j.trigger(this._element,"hide.bs.modal").defaultPrevented)return;this._isShown=!1;const t=this._isAnimated();t&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),this._focustrap.deactivate(),this._element.classList.remove(ji),j.off(this._element,Si),j.off(this._dialog,Ii),this._queueCallback((()=>this._hideModal()),this._element,t)}dispose(){[window,this._dialog].forEach((t=>j.off(t,".bs.modal"))),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new bi({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Ai({trapElement:this._element})}_getConfig(t){return t={...Ci,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(Ti,t,ki),t}_showElement(t){const e=this._isAnimated(),i=V.findOne(".modal-body",this._dialog);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0,i&&(i.scrollTop=0),e&&u(this._element),this._element.classList.add(ji),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,j.trigger(this._element,"shown.bs.modal",{relatedTarget:t})}),this._dialog,e)}_setEscapeEvent(){this._isShown?j.on(this._element,Ni,(t=>{this._config.keyboard&&t.key===Oi?(t.preventDefault(),this.hide()):this._config.keyboard||t.key!==Oi||this._triggerBackdropTransition()})):j.off(this._element,Ni)}_setResizeEvent(){this._isShown?j.on(window,Di,(()=>this._adjustDialog())):j.off(window,Di)}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(Pi),this._resetAdjustments(),this._scrollBar.reset(),j.trigger(this._element,Li)}))}_showBackdrop(t){j.on(this._element,Si,(t=>{this._ignoreBackdropClick?this._ignoreBackdropClick=!1:t.target===t.currentTarget&&(!0===this._config.backdrop?this.hide():"static"===this._config.backdrop&&this._triggerBackdropTransition())})),this._backdrop.show(t)}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(j.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const{classList:t,scrollHeight:e,style:i}=this._element,n=e>document.documentElement.clientHeight;!n&&"hidden"===i.overflowY||t.contains(Mi)||(n||(i.overflowY="hidden"),t.add(Mi),this._queueCallback((()=>{t.remove(Mi),n||this._queueCallback((()=>{i.overflowY=""}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;(!i&&t&&!m()||i&&!t&&m())&&(this._element.style.paddingLeft=`${e}px`),(i&&!t&&!m()||!i&&t&&m())&&(this._element.style.paddingRight=`${e}px`)}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=Hi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}j.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=n(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),j.one(e,xi,(t=>{t.defaultPrevented||j.one(e,Li,(()=>{l(this)&&this.focus()}))}));const i=V.findOne(".modal.show");i&&Hi.getInstance(i).hide(),Hi.getOrCreateInstance(e).toggle(this)})),R(Hi),g(Hi);const Bi="offcanvas",Ri={backdrop:!0,keyboard:!0,scroll:!1},Wi={backdrop:"boolean",keyboard:"boolean",scroll:"boolean"},$i="show",zi=".offcanvas.show",qi="hidden.bs.offcanvas";class Fi extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get NAME(){return Bi}static get Default(){return Ri}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||j.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._element.style.visibility="visible",this._backdrop.show(),this._config.scroll||(new fi).hide(),this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add($i),this._queueCallback((()=>{this._config.scroll||this._focustrap.activate(),j.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(j.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.remove($i),this._backdrop.hide(),this._queueCallback((()=>{this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._element.style.visibility="hidden",this._config.scroll||(new fi).reset(),j.trigger(this._element,qi)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_getConfig(t){return t={...Ri,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(Bi,t,Wi),t}_initializeBackDrop(){return new bi({className:"offcanvas-backdrop",isVisible:this._config.backdrop,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:()=>this.hide()})}_initializeFocusTrap(){return new Ai({trapElement:this._element})}_addEventListeners(){j.on(this._element,"keydown.dismiss.bs.offcanvas",(t=>{this._config.keyboard&&"Escape"===t.key&&this.hide()}))}static jQueryInterface(t){return this.each((function(){const e=Fi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}j.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=n(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),c(this))return;j.one(e,qi,(()=>{l(this)&&this.focus()}));const i=V.findOne(zi);i&&i!==e&&Fi.getInstance(i).hide(),Fi.getOrCreateInstance(e).toggle(this)})),j.on(window,"load.bs.offcanvas.data-api",(()=>V.find(zi).forEach((t=>Fi.getOrCreateInstance(t).show())))),R(Fi),g(Fi);const Ui=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Vi=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,Ki=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,Xi=(t,e)=>{const i=t.nodeName.toLowerCase();if(e.includes(i))return!Ui.has(i)||Boolean(Vi.test(t.nodeValue)||Ki.test(t.nodeValue));const n=e.filter((t=>t instanceof RegExp));for(let t=0,e=n.length;t{Xi(t,r)||i.removeAttribute(t.nodeName)}))}return n.body.innerHTML}const Qi="tooltip",Gi=new Set(["sanitize","allowList","sanitizeFn"]),Zi={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(array|string|function)",container:"(string|element|boolean)",fallbackPlacements:"array",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",allowList:"object",popperConfig:"(null|object|function)"},Ji={AUTO:"auto",TOP:"top",RIGHT:m()?"left":"right",BOTTOM:"bottom",LEFT:m()?"right":"left"},tn={animation:!0,template:'',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:[0,0],container:!1,fallbackPlacements:["top","right","bottom","left"],boundary:"clippingParents",customClass:"",sanitize:!0,sanitizeFn:null,allowList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},en={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},nn="fade",sn="show",on="show",rn="out",an=".tooltip-inner",ln=".modal",cn="hide.bs.modal",hn="hover",dn="focus";class un extends B{constructor(t,e){if(void 0===Fe)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t),this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this._config=this._getConfig(e),this.tip=null,this._setListeners()}static get Default(){return tn}static get NAME(){return Qi}static get Event(){return en}static get DefaultType(){return Zi}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(t){if(this._isEnabled)if(t){const e=this._initializeOnDelegatedTarget(t);e._activeTrigger.click=!e._activeTrigger.click,e._isWithActiveTrigger()?e._enter(null,e):e._leave(null,e)}else{if(this.getTipElement().classList.contains(sn))return void this._leave(null,this);this._enter(null,this)}}dispose(){clearTimeout(this._timeout),j.off(this._element.closest(ln),cn,this._hideModalHandler),this.tip&&this.tip.remove(),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this.isWithContent()||!this._isEnabled)return;const t=j.trigger(this._element,this.constructor.Event.SHOW),e=h(this._element),i=null===e?this._element.ownerDocument.documentElement.contains(this._element):e.contains(this._element);if(t.defaultPrevented||!i)return;"tooltip"===this.constructor.NAME&&this.tip&&this.getTitle()!==this.tip.querySelector(an).innerHTML&&(this._disposePopper(),this.tip.remove(),this.tip=null);const n=this.getTipElement(),s=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME);n.setAttribute("id",s),this._element.setAttribute("aria-describedby",s),this._config.animation&&n.classList.add(nn);const o="function"==typeof this._config.placement?this._config.placement.call(this,n,this._element):this._config.placement,r=this._getAttachment(o);this._addAttachmentClass(r);const{container:a}=this._config;H.set(n,this.constructor.DATA_KEY,this),this._element.ownerDocument.documentElement.contains(this.tip)||(a.append(n),j.trigger(this._element,this.constructor.Event.INSERTED)),this._popper?this._popper.update():this._popper=qe(this._element,n,this._getPopperConfig(r)),n.classList.add(sn);const l=this._resolvePossibleFunction(this._config.customClass);l&&n.classList.add(...l.split(" ")),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>{j.on(t,"mouseover",d)}));const c=this.tip.classList.contains(nn);this._queueCallback((()=>{const t=this._hoverState;this._hoverState=null,j.trigger(this._element,this.constructor.Event.SHOWN),t===rn&&this._leave(null,this)}),this.tip,c)}hide(){if(!this._popper)return;const t=this.getTipElement();if(j.trigger(this._element,this.constructor.Event.HIDE).defaultPrevented)return;t.classList.remove(sn),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>j.off(t,"mouseover",d))),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1;const e=this.tip.classList.contains(nn);this._queueCallback((()=>{this._isWithActiveTrigger()||(this._hoverState!==on&&t.remove(),this._cleanTipClass(),this._element.removeAttribute("aria-describedby"),j.trigger(this._element,this.constructor.Event.HIDDEN),this._disposePopper())}),this.tip,e),this._hoverState=""}update(){null!==this._popper&&this._popper.update()}isWithContent(){return Boolean(this.getTitle())}getTipElement(){if(this.tip)return this.tip;const t=document.createElement("div");t.innerHTML=this._config.template;const e=t.children[0];return this.setContent(e),e.classList.remove(nn,sn),this.tip=e,this.tip}setContent(t){this._sanitizeAndSetContent(t,this.getTitle(),an)}_sanitizeAndSetContent(t,e,i){const n=V.findOne(i,t);e||!n?this.setElementContent(n,e):n.remove()}setElementContent(t,e){if(null!==t)return o(e)?(e=r(e),void(this._config.html?e.parentNode!==t&&(t.innerHTML="",t.append(e)):t.textContent=e.textContent)):void(this._config.html?(this._config.sanitize&&(e=Yi(e,this._config.allowList,this._config.sanitizeFn)),t.innerHTML=e):t.textContent=e)}getTitle(){const t=this._element.getAttribute("data-bs-original-title")||this._config.title;return this._resolvePossibleFunction(t)}updateAttachment(t){return"right"===t?"end":"left"===t?"start":t}_initializeOnDelegatedTarget(t,e){return e||this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return"function"==typeof t?t.call(this._element):t}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"onChange",enabled:!0,phase:"afterWrite",fn:t=>this._handlePopperPlacementChange(t)}],onFirstUpdate:t=>{t.options.placement!==t.placement&&this._handlePopperPlacementChange(t)}};return{...e,..."function"==typeof this._config.popperConfig?this._config.popperConfig(e):this._config.popperConfig}}_addAttachmentClass(t){this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(t)}`)}_getAttachment(t){return Ji[t.toUpperCase()]}_setListeners(){this._config.trigger.split(" ").forEach((t=>{if("click"===t)j.on(this._element,this.constructor.Event.CLICK,this._config.selector,(t=>this.toggle(t)));else if("manual"!==t){const e=t===hn?this.constructor.Event.MOUSEENTER:this.constructor.Event.FOCUSIN,i=t===hn?this.constructor.Event.MOUSELEAVE:this.constructor.Event.FOCUSOUT;j.on(this._element,e,this._config.selector,(t=>this._enter(t))),j.on(this._element,i,this._config.selector,(t=>this._leave(t)))}})),this._hideModalHandler=()=>{this._element&&this.hide()},j.on(this._element.closest(ln),cn,this._hideModalHandler),this._config.selector?this._config={...this._config,trigger:"manual",selector:""}:this._fixTitle()}_fixTitle(){const t=this._element.getAttribute("title"),e=typeof this._element.getAttribute("data-bs-original-title");(t||"string"!==e)&&(this._element.setAttribute("data-bs-original-title",t||""),!t||this._element.getAttribute("aria-label")||this._element.textContent||this._element.setAttribute("aria-label",t),this._element.setAttribute("title",""))}_enter(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusin"===t.type?dn:hn]=!0),e.getTipElement().classList.contains(sn)||e._hoverState===on?e._hoverState=on:(clearTimeout(e._timeout),e._hoverState=on,e._config.delay&&e._config.delay.show?e._timeout=setTimeout((()=>{e._hoverState===on&&e.show()}),e._config.delay.show):e.show())}_leave(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusout"===t.type?dn:hn]=e._element.contains(t.relatedTarget)),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=rn,e._config.delay&&e._config.delay.hide?e._timeout=setTimeout((()=>{e._hoverState===rn&&e.hide()}),e._config.delay.hide):e.hide())}_isWithActiveTrigger(){for(const t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1}_getConfig(t){const e=U.getDataAttributes(this._element);return Object.keys(e).forEach((t=>{Gi.has(t)&&delete e[t]})),(t={...this.constructor.Default,...e,..."object"==typeof t&&t?t:{}}).container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),a(Qi,t,this.constructor.DefaultType),t.sanitize&&(t.template=Yi(t.template,t.allowList,t.sanitizeFn)),t}_getDelegateConfig(){const t={};for(const e in this._config)this.constructor.Default[e]!==this._config[e]&&(t[e]=this._config[e]);return t}_cleanTipClass(){const t=this.getTipElement(),e=new RegExp(`(^|\\s)${this._getBasicClassPrefix()}\\S+`,"g"),i=t.getAttribute("class").match(e);null!==i&&i.length>0&&i.map((t=>t.trim())).forEach((e=>t.classList.remove(e)))}_getBasicClassPrefix(){return"bs-tooltip"}_handlePopperPlacementChange(t){const{state:e}=t;e&&(this.tip=e.elements.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(e.placement)))}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null)}static jQueryInterface(t){return this.each((function(){const e=un.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(un);const fn={...un.Default,placement:"right",offset:[0,8],trigger:"click",content:"",template:''},pn={...un.DefaultType,content:"(string|element|function)"},mn={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"};class gn extends un{static get Default(){return fn}static get NAME(){return"popover"}static get Event(){return mn}static get DefaultType(){return pn}isWithContent(){return this.getTitle()||this._getContent()}setContent(t){this._sanitizeAndSetContent(t,this.getTitle(),".popover-header"),this._sanitizeAndSetContent(t,this._getContent(),".popover-body")}_getContent(){return this._resolvePossibleFunction(this._config.content)}_getBasicClassPrefix(){return"bs-popover"}static jQueryInterface(t){return this.each((function(){const e=gn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(gn);const _n="scrollspy",bn={offset:10,method:"auto",target:""},vn={offset:"number",method:"string",target:"(string|element)"},yn="active",wn=".nav-link, .list-group-item, .dropdown-item",En="position";class An extends B{constructor(t,e){super(t),this._scrollElement="BODY"===this._element.tagName?window:this._element,this._config=this._getConfig(e),this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,j.on(this._scrollElement,"scroll.bs.scrollspy",(()=>this._process())),this.refresh(),this._process()}static get Default(){return bn}static get NAME(){return _n}refresh(){const t=this._scrollElement===this._scrollElement.window?"offset":En,e="auto"===this._config.method?t:this._config.method,n=e===En?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),V.find(wn,this._config.target).map((t=>{const s=i(t),o=s?V.findOne(s):null;if(o){const t=o.getBoundingClientRect();if(t.width||t.height)return[U[e](o).top+n,s]}return null})).filter((t=>t)).sort(((t,e)=>t[0]-e[0])).forEach((t=>{this._offsets.push(t[0]),this._targets.push(t[1])}))}dispose(){j.off(this._scrollElement,".bs.scrollspy"),super.dispose()}_getConfig(t){return(t={...bn,...U.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}}).target=r(t.target)||document.documentElement,a(_n,t,vn),t}_getScrollTop(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop}_getScrollHeight(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}_getOffsetHeight(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height}_process(){const t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),i=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=i){const t=this._targets[this._targets.length-1];this._activeTarget!==t&&this._activate(t)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(let e=this._offsets.length;e--;)this._activeTarget!==this._targets[e]&&t>=this._offsets[e]&&(void 0===this._offsets[e+1]||t`${e}[data-bs-target="${t}"],${e}[href="${t}"]`)),i=V.findOne(e.join(","),this._config.target);i.classList.add(yn),i.classList.contains("dropdown-item")?V.findOne(".dropdown-toggle",i.closest(".dropdown")).classList.add(yn):V.parents(i,".nav, .list-group").forEach((t=>{V.prev(t,".nav-link, .list-group-item").forEach((t=>t.classList.add(yn))),V.prev(t,".nav-item").forEach((t=>{V.children(t,".nav-link").forEach((t=>t.classList.add(yn)))}))})),j.trigger(this._scrollElement,"activate.bs.scrollspy",{relatedTarget:t})}_clear(){V.find(wn,this._config.target).filter((t=>t.classList.contains(yn))).forEach((t=>t.classList.remove(yn)))}static jQueryInterface(t){return this.each((function(){const e=An.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}j.on(window,"load.bs.scrollspy.data-api",(()=>{V.find('[data-bs-spy="scroll"]').forEach((t=>new An(t)))})),g(An);const Tn="active",On="fade",Cn="show",kn=".active",Ln=":scope > li > .active";class xn extends B{static get NAME(){return"tab"}show(){if(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains(Tn))return;let t;const e=n(this._element),i=this._element.closest(".nav, .list-group");if(i){const e="UL"===i.nodeName||"OL"===i.nodeName?Ln:kn;t=V.find(e,i),t=t[t.length-1]}const s=t?j.trigger(t,"hide.bs.tab",{relatedTarget:this._element}):null;if(j.trigger(this._element,"show.bs.tab",{relatedTarget:t}).defaultPrevented||null!==s&&s.defaultPrevented)return;this._activate(this._element,i);const o=()=>{j.trigger(t,"hidden.bs.tab",{relatedTarget:this._element}),j.trigger(this._element,"shown.bs.tab",{relatedTarget:t})};e?this._activate(e,e.parentNode,o):o()}_activate(t,e,i){const n=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?V.children(e,kn):V.find(Ln,e))[0],s=i&&n&&n.classList.contains(On),o=()=>this._transitionComplete(t,n,i);n&&s?(n.classList.remove(Cn),this._queueCallback(o,t,!0)):o()}_transitionComplete(t,e,i){if(e){e.classList.remove(Tn);const t=V.findOne(":scope > .dropdown-menu .active",e.parentNode);t&&t.classList.remove(Tn),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}t.classList.add(Tn),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),u(t),t.classList.contains(On)&&t.classList.add(Cn);let n=t.parentNode;if(n&&"LI"===n.nodeName&&(n=n.parentNode),n&&n.classList.contains("dropdown-menu")){const e=t.closest(".dropdown");e&&V.find(".dropdown-toggle",e).forEach((t=>t.classList.add(Tn))),t.setAttribute("aria-expanded",!0)}i&&i()}static jQueryInterface(t){return this.each((function(){const e=xn.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}j.on(document,"click.bs.tab.data-api",'[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),c(this)||xn.getOrCreateInstance(this).show()})),g(xn);const Dn="toast",Sn="hide",Nn="show",In="showing",Pn={animation:"boolean",autohide:"boolean",delay:"number"},jn={animation:!0,autohide:!0,delay:5e3};class Mn extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get DefaultType(){return Pn}static get Default(){return jn}static get NAME(){return Dn}show(){j.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(Sn),u(this._element),this._element.classList.add(Nn),this._element.classList.add(In),this._queueCallback((()=>{this._element.classList.remove(In),j.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this._element.classList.contains(Nn)&&(j.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.add(In),this._queueCallback((()=>{this._element.classList.add(Sn),this._element.classList.remove(In),this._element.classList.remove(Nn),j.trigger(this._element,"hidden.bs.toast")}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this._element.classList.contains(Nn)&&this._element.classList.remove(Nn),super.dispose()}_getConfig(t){return t={...jn,...U.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}},a(Dn,t,this.constructor.DefaultType),t}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){j.on(this._element,"mouseover.bs.toast",(t=>this._onInteraction(t,!0))),j.on(this._element,"mouseout.bs.toast",(t=>this._onInteraction(t,!1))),j.on(this._element,"focusin.bs.toast",(t=>this._onInteraction(t,!0))),j.on(this._element,"focusout.bs.toast",(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=Mn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(Mn),g(Mn),{Alert:W,Button:z,Carousel:st,Collapse:pt,Dropdown:hi,Modal:Hi,Offcanvas:Fi,Popover:gn,ScrollSpy:An,Tab:xn,Toast:Mn,Tooltip:un}})); +//# sourceMappingURL=bootstrap.bundle.min.js.map diff --git a/cdn/dev/src/bootstrap.min.css b/cdn/dev/src/bootstrap.min.css index 016a33a..aac8bee 100644 --- a/cdn/dev/src/bootstrap.min.css +++ b/cdn/dev/src/bootstrap.min.css @@ -1,6 +1,6 @@ -@charset "UTF-8";/*! - * Bootstrap v5.3.3 (https://getbootstrap.com/) - * Copyright 2011-2024 The Bootstrap Authors - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-color:#212529;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13, 110, 253, 0.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#dee2e6;--bs-body-color-rgb:222,226,230;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb:222,226,230;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb:222,226,230;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#41464b;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#087990;--bs-warning-border-subtle:#997404;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:inherit;--bs-link-color:#6ea8fe;--bs-link-hover-color:#8bb9fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:139,185,254;--bs-code-color:#e685b5;--bs-highlight-color:#dee2e6;--bs-highlight-bg:#664d03;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, 0.15);--bs-form-valid-color:#75b798;--bs-form-valid-border-color:#75b798;--bs-form-invalid-color:#ea868f;--bs-form-invalid-border-color:#ea868f}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width) solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color)}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;color:var(--bs-highlight-color);background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-secondary-color);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"โ€” "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:var(--bs-body-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:var(--bs-secondary-color)}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}:root{--bs-breakpoint-xs:0;--bs-breakpoint-sm:576px;--bs-breakpoint-md:768px;--bs-breakpoint-lg:992px;--bs-breakpoint-xl:1200px;--bs-breakpoint-xxl:1400px}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color-type:initial;--bs-table-bg-type:initial;--bs-table-color-state:initial;--bs-table-bg-state:initial;--bs-table-color:var(--bs-emphasis-color);--bs-table-bg:var(--bs-body-bg);--bs-table-border-color:var(--bs-border-color);--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-emphasis-color);--bs-table-striped-bg:rgba(var(--bs-emphasis-color-rgb), 0.05);--bs-table-active-color:var(--bs-emphasis-color);--bs-table-active-bg:rgba(var(--bs-emphasis-color-rgb), 0.1);--bs-table-hover-color:var(--bs-emphasis-color);--bs-table-hover-bg:rgba(var(--bs-emphasis-color-rgb), 0.075);width:100%;margin-bottom:1rem;vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;color:var(--bs-table-color-state,var(--bs-table-color-type,var(--bs-table-color)));background-color:var(--bs-table-bg);border-bottom-width:var(--bs-border-width);box-shadow:inset 0 0 0 9999px var(--bs-table-bg-state,var(--bs-table-bg-type,var(--bs-table-accent-bg)))}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:calc(var(--bs-border-width) * 2) solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:var(--bs-border-width) 0}.table-bordered>:not(caption)>*>*{border-width:0 var(--bs-border-width)}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-striped-columns>:not(caption)>tr>:nth-child(2n){--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-active{--bs-table-color-state:var(--bs-table-active-color);--bs-table-bg-state:var(--bs-table-active-bg)}.table-hover>tbody>tr:hover>*{--bs-table-color-state:var(--bs-table-hover-color);--bs-table-bg-state:var(--bs-table-hover-bg)}.table-primary{--bs-table-color:#000;--bs-table-bg:#cfe2ff;--bs-table-border-color:#a6b5cc;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#000;--bs-table-bg:#e2e3e5;--bs-table-border-color:#b5b6b7;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#000;--bs-table-bg:#d1e7dd;--bs-table-border-color:#a7b9b1;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#000;--bs-table-bg:#cff4fc;--bs-table-border-color:#a6c3ca;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#000;--bs-table-bg:#fff3cd;--bs-table-border-color:#ccc2a4;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#000;--bs-table-bg:#f8d7da;--bs-table-border-color:#c6acae;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#000;--bs-table-bg:#f8f9fa;--bs-table-border-color:#c6c7c8;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#212529;--bs-table-border-color:#4d5154;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + var(--bs-border-width));padding-bottom:calc(.375rem + var(--bs-border-width));margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + var(--bs-border-width));padding-bottom:calc(.5rem + var(--bs-border-width));font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + var(--bs-border-width));padding-bottom:calc(.25rem + var(--bs-border-width));font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--bs-secondary-color)}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-clip:padding-box;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--bs-body-color);background-color:var(--bs-body-bg);border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{min-width:85px;height:1.5em;margin:0}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::-moz-placeholder{color:var(--bs-secondary-color);opacity:1}.form-control::placeholder{color:var(--bs-secondary-color);opacity:1}.form-control:disabled{background-color:var(--bs-secondary-bg);opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:var(--bs-secondary-bg)}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:var(--bs-secondary-bg)}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:var(--bs-body-color);background-color:transparent;border:solid transparent;border-width:var(--bs-border-width) 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2));padding:.25rem .5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));padding:.5rem 1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2))}textarea.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}textarea.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-control-color{width:3rem;height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2));padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color::-webkit-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon,none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:var(--bs-secondary-bg)}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--bs-body-color)}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}[data-bs-theme=dark] .form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23dee2e6' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e")}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{--bs-form-check-bg:var(--bs-body-bg);flex-shrink:0;width:1em;height:1em;margin-top:.25em;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:center;background-size:contain;border:var(--bs-border-width) solid var(--bs-border-color);-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");width:2em;margin-left:-2.5em;background-image:var(--bs-form-switch-bg);background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus){--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e")}.form-range{width:100%;height:1.5rem;padding:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;-webkit-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;-moz-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:var(--bs-secondary-color)}.form-range:disabled::-moz-range-thumb{background-color:var(--bs-secondary-color)}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + calc(var(--bs-border-width) * 2));min-height:calc(3.5rem + calc(var(--bs-border-width) * 2));line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;z-index:2;height:100%;padding:1rem .75rem;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:var(--bs-border-width) solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::-moz-placeholder,.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:not(:-moz-placeholder-shown),.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{color:rgba(var(--bs-body-color-rgb),.65);transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{color:rgba(var(--bs-body-color-rgb),.65);transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:not(:-moz-placeholder-shown)~label::after{position:absolute;inset:1rem 0.375rem;z-index:-1;height:1.5em;content:"";background-color:var(--bs-body-bg);border-radius:var(--bs-border-radius)}.form-floating>.form-control-plaintext~label::after,.form-floating>.form-control:focus~label::after,.form-floating>.form-control:not(:placeholder-shown)~label::after,.form-floating>.form-select~label::after{position:absolute;inset:1rem 0.375rem;z-index:-1;height:1.5em;content:"";background-color:var(--bs-body-bg);border-radius:var(--bs-border-radius)}.form-floating>.form-control:-webkit-autofill~label{color:rgba(var(--bs-body-color-rgb),.65);transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:var(--bs-border-width) 0}.form-floating>.form-control:disabled~label,.form-floating>:disabled~label{color:#6c757d}.form-floating>.form-control:disabled~label::after,.form-floating>:disabled~label::after{background-color:var(--bs-secondary-bg)}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);text-align:center;white-space:nowrap;background-color:var(--bs-tertiary-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius)}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:calc(var(--bs-border-width) * -1);border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-valid-color)}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-success);border-radius:var(--bs-border-radius)}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:var(--bs-form-valid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:var(--bs-form-valid-border-color)}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:var(--bs-form-valid-border-color)}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:var(--bs-form-valid-color)}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:var(--bs-form-valid-color)}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-invalid-color)}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-danger);border-radius:var(--bs-border-radius)}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:var(--bs-form-invalid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:var(--bs-form-invalid-border-color)}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:var(--bs-form-invalid-border-color)}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:var(--bs-form-invalid-color)}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:var(--bs-form-invalid-color)}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:var(--bs-body-color);--bs-btn-bg:transparent;--bs-btn-border-width:var(--bs-border-width);--bs-btn-border-color:transparent;--bs-btn-border-radius:var(--bs-border-radius);--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked:focus-visible+.btn{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:0 0 0 #000;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:var(--bs-border-radius-lg)}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:var(--bs-border-radius-sm)}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:var(--bs-body-color);--bs-dropdown-bg:var(--bs-body-bg);--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-border-radius:var(--bs-border-radius);--bs-dropdown-border-width:var(--bs-border-width);--bs-dropdown-inner-border-radius:calc(var(--bs-border-radius) - var(--bs-border-width));--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:var(--bs-box-shadow);--bs-dropdown-link-color:var(--bs-body-color);--bs-dropdown-link-hover-color:var(--bs-body-color);--bs-dropdown-link-hover-bg:var(--bs-tertiary-bg);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:var(--bs-tertiary-color);--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#6c757d;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0;border-radius:var(--bs-dropdown-item-border-radius,0)}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#343a40;--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:var(--bs-border-radius)}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:calc(var(--bs-border-width) * -1)}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:calc(var(--bs-border-width) * -1)}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;background:0 0;border:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link:focus-visible{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:var(--bs-border-width);--bs-nav-tabs-border-color:var(--bs-border-color);--bs-nav-tabs-border-radius:var(--bs-border-radius);--bs-nav-tabs-link-hover-border-color:var(--bs-secondary-bg) var(--bs-secondary-bg) var(--bs-border-color);--bs-nav-tabs-link-active-color:var(--bs-emphasis-color);--bs-nav-tabs-link-active-bg:var(--bs-body-bg);--bs-nav-tabs-link-active-border-color:var(--bs-border-color) var(--bs-border-color) var(--bs-body-bg);border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:var(--bs-border-radius);--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0d6efd}.nav-pills .nav-link{border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-underline{--bs-nav-underline-gap:1rem;--bs-nav-underline-border-width:0.125rem;--bs-nav-underline-link-active-color:var(--bs-emphasis-color);gap:var(--bs-nav-underline-gap)}.nav-underline .nav-link{padding-right:0;padding-left:0;border-bottom:var(--bs-nav-underline-border-width) solid transparent}.nav-underline .nav-link:focus,.nav-underline .nav-link:hover{border-bottom-color:currentcolor}.nav-underline .nav-link.active,.nav-underline .show>.nav-link{font-weight:700;color:var(--bs-nav-underline-link-active-color);border-bottom-color:currentcolor}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:0.5rem;--bs-navbar-color:rgba(var(--bs-emphasis-color-rgb), 0.65);--bs-navbar-hover-color:rgba(var(--bs-emphasis-color-rgb), 0.8);--bs-navbar-disabled-color:rgba(var(--bs-emphasis-color-rgb), 0.3);--bs-navbar-active-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-hover-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2833, 37, 41, 0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(var(--bs-emphasis-color-rgb), 0.15);--bs-navbar-toggler-border-radius:var(--bs-border-radius);--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark,.navbar[data-bs-theme=dark]{--bs-navbar-color:rgba(255, 255, 255, 0.55);--bs-navbar-hover-color:rgba(255, 255, 255, 0.75);--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}[data-bs-theme=dark] .navbar-toggler-icon{--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width:var(--bs-border-width);--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:rgba(var(--bs-body-color-rgb), 0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:var(--bs-body-bg);--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);color:var(--bs-body-color);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y);color:var(--bs-card-title-color)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0;color:var(--bs-card-subtitle-color)}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:var(--bs-body-color);--bs-accordion-bg:var(--bs-body-bg);--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:var(--bs-border-width);--bs-accordion-border-radius:var(--bs-border-radius);--bs-accordion-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23212529' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M2 5L8 11L14 5'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23052c65' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M2 5L8 11L14 5'/%3e%3c/svg%3e");--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:var(--bs-primary-text-emphasis);--bs-accordion-active-bg:var(--bs-primary-bg-subtle)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type>.accordion-header .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type>.accordion-header .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type>.accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush>.accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush>.accordion-item:first-child{border-top:0}.accordion-flush>.accordion-item:last-child{border-bottom:0}.accordion-flush>.accordion-item>.accordion-header .accordion-button,.accordion-flush>.accordion-item>.accordion-header .accordion-button.collapsed{border-radius:0}.accordion-flush>.accordion-item>.accordion-collapse{border-radius:0}[data-bs-theme=dark] .accordion-button::after{--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.breadcrumb{--bs-breadcrumb-padding-x:0;--bs-breadcrumb-padding-y:0;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color:var(--bs-secondary-color);--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:var(--bs-link-color);--bs-pagination-bg:var(--bs-body-bg);--bs-pagination-border-width:var(--bs-border-width);--bs-pagination-border-color:var(--bs-border-color);--bs-pagination-border-radius:var(--bs-border-radius);--bs-pagination-hover-color:var(--bs-link-hover-color);--bs-pagination-hover-bg:var(--bs-tertiary-bg);--bs-pagination-hover-border-color:var(--bs-border-color);--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:var(--bs-secondary-bg);--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#0d6efd;--bs-pagination-active-border-color:#0d6efd;--bs-pagination-disabled-color:var(--bs-secondary-color);--bs-pagination-disabled-bg:var(--bs-secondary-bg);--bs-pagination-disabled-border-color:var(--bs-border-color);display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(var(--bs-border-width) * -1)}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:var(--bs-border-radius-lg)}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:var(--bs-border-radius-sm)}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:var(--bs-border-radius);display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:var(--bs-border-width) solid var(--bs-alert-border-color);--bs-alert-border-radius:var(--bs-border-radius);--bs-alert-link-color:inherit;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700;color:var(--bs-alert-link-color)}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:var(--bs-primary-text-emphasis);--bs-alert-bg:var(--bs-primary-bg-subtle);--bs-alert-border-color:var(--bs-primary-border-subtle);--bs-alert-link-color:var(--bs-primary-text-emphasis)}.alert-secondary{--bs-alert-color:var(--bs-secondary-text-emphasis);--bs-alert-bg:var(--bs-secondary-bg-subtle);--bs-alert-border-color:var(--bs-secondary-border-subtle);--bs-alert-link-color:var(--bs-secondary-text-emphasis)}.alert-success{--bs-alert-color:var(--bs-success-text-emphasis);--bs-alert-bg:var(--bs-success-bg-subtle);--bs-alert-border-color:var(--bs-success-border-subtle);--bs-alert-link-color:var(--bs-success-text-emphasis)}.alert-info{--bs-alert-color:var(--bs-info-text-emphasis);--bs-alert-bg:var(--bs-info-bg-subtle);--bs-alert-border-color:var(--bs-info-border-subtle);--bs-alert-link-color:var(--bs-info-text-emphasis)}.alert-warning{--bs-alert-color:var(--bs-warning-text-emphasis);--bs-alert-bg:var(--bs-warning-bg-subtle);--bs-alert-border-color:var(--bs-warning-border-subtle);--bs-alert-link-color:var(--bs-warning-text-emphasis)}.alert-danger{--bs-alert-color:var(--bs-danger-text-emphasis);--bs-alert-bg:var(--bs-danger-bg-subtle);--bs-alert-border-color:var(--bs-danger-border-subtle);--bs-alert-link-color:var(--bs-danger-text-emphasis)}.alert-light{--bs-alert-color:var(--bs-light-text-emphasis);--bs-alert-bg:var(--bs-light-bg-subtle);--bs-alert-border-color:var(--bs-light-border-subtle);--bs-alert-link-color:var(--bs-light-text-emphasis)}.alert-dark{--bs-alert-color:var(--bs-dark-text-emphasis);--bs-alert-bg:var(--bs-dark-bg-subtle);--bs-alert-border-color:var(--bs-dark-border-subtle);--bs-alert-link-color:var(--bs-dark-text-emphasis)}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress,.progress-stacked{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:var(--bs-secondary-bg);--bs-progress-border-radius:var(--bs-border-radius);--bs-progress-box-shadow:var(--bs-box-shadow-inset);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#0d6efd;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-stacked>.progress{overflow:visible}.progress-stacked>.progress>.progress-bar{width:100%}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color:var(--bs-body-color);--bs-list-group-bg:var(--bs-body-bg);--bs-list-group-border-color:var(--bs-border-color);--bs-list-group-border-width:var(--bs-border-width);--bs-list-group-border-radius:var(--bs-border-radius);--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:var(--bs-secondary-color);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-tertiary-bg);--bs-list-group-action-active-color:var(--bs-body-color);--bs-list-group-action-active-bg:var(--bs-secondary-bg);--bs-list-group-disabled-color:var(--bs-secondary-color);--bs-list-group-disabled-bg:var(--bs-body-bg);--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#0d6efd;--bs-list-group-active-border-color:#0d6efd;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{--bs-list-group-color:var(--bs-primary-text-emphasis);--bs-list-group-bg:var(--bs-primary-bg-subtle);--bs-list-group-border-color:var(--bs-primary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-primary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-primary-border-subtle);--bs-list-group-active-color:var(--bs-primary-bg-subtle);--bs-list-group-active-bg:var(--bs-primary-text-emphasis);--bs-list-group-active-border-color:var(--bs-primary-text-emphasis)}.list-group-item-secondary{--bs-list-group-color:var(--bs-secondary-text-emphasis);--bs-list-group-bg:var(--bs-secondary-bg-subtle);--bs-list-group-border-color:var(--bs-secondary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-secondary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-secondary-border-subtle);--bs-list-group-active-color:var(--bs-secondary-bg-subtle);--bs-list-group-active-bg:var(--bs-secondary-text-emphasis);--bs-list-group-active-border-color:var(--bs-secondary-text-emphasis)}.list-group-item-success{--bs-list-group-color:var(--bs-success-text-emphasis);--bs-list-group-bg:var(--bs-success-bg-subtle);--bs-list-group-border-color:var(--bs-success-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-success-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-success-border-subtle);--bs-list-group-active-color:var(--bs-success-bg-subtle);--bs-list-group-active-bg:var(--bs-success-text-emphasis);--bs-list-group-active-border-color:var(--bs-success-text-emphasis)}.list-group-item-info{--bs-list-group-color:var(--bs-info-text-emphasis);--bs-list-group-bg:var(--bs-info-bg-subtle);--bs-list-group-border-color:var(--bs-info-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-info-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-info-border-subtle);--bs-list-group-active-color:var(--bs-info-bg-subtle);--bs-list-group-active-bg:var(--bs-info-text-emphasis);--bs-list-group-active-border-color:var(--bs-info-text-emphasis)}.list-group-item-warning{--bs-list-group-color:var(--bs-warning-text-emphasis);--bs-list-group-bg:var(--bs-warning-bg-subtle);--bs-list-group-border-color:var(--bs-warning-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-warning-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-warning-border-subtle);--bs-list-group-active-color:var(--bs-warning-bg-subtle);--bs-list-group-active-bg:var(--bs-warning-text-emphasis);--bs-list-group-active-border-color:var(--bs-warning-text-emphasis)}.list-group-item-danger{--bs-list-group-color:var(--bs-danger-text-emphasis);--bs-list-group-bg:var(--bs-danger-bg-subtle);--bs-list-group-border-color:var(--bs-danger-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-danger-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-danger-border-subtle);--bs-list-group-active-color:var(--bs-danger-bg-subtle);--bs-list-group-active-bg:var(--bs-danger-text-emphasis);--bs-list-group-active-border-color:var(--bs-danger-text-emphasis)}.list-group-item-light{--bs-list-group-color:var(--bs-light-text-emphasis);--bs-list-group-bg:var(--bs-light-bg-subtle);--bs-list-group-border-color:var(--bs-light-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-light-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-light-border-subtle);--bs-list-group-active-color:var(--bs-light-bg-subtle);--bs-list-group-active-bg:var(--bs-light-text-emphasis);--bs-list-group-active-border-color:var(--bs-light-text-emphasis)}.list-group-item-dark{--bs-list-group-color:var(--bs-dark-text-emphasis);--bs-list-group-bg:var(--bs-dark-bg-subtle);--bs-list-group-border-color:var(--bs-dark-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-dark-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-dark-border-subtle);--bs-list-group-active-color:var(--bs-dark-bg-subtle);--bs-list-group-active-bg:var(--bs-dark-text-emphasis);--bs-list-group-active-border-color:var(--bs-dark-text-emphasis)}.btn-close{--bs-btn-close-color:#000;--bs-btn-close-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e");--bs-btn-close-opacity:0.5;--bs-btn-close-hover-opacity:0.75;--bs-btn-close-focus-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-btn-close-focus-opacity:1;--bs-btn-close-disabled-opacity:0.25;--bs-btn-close-white-filter:invert(1) grayscale(100%) brightness(200%);box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:var(--bs-btn-close-color);background:transparent var(--bs-btn-close-bg) center/1em auto no-repeat;border:0;border-radius:.375rem;opacity:var(--bs-btn-close-opacity)}.btn-close:hover{color:var(--bs-btn-close-color);text-decoration:none;opacity:var(--bs-btn-close-hover-opacity)}.btn-close:focus{outline:0;box-shadow:var(--bs-btn-close-focus-shadow);opacity:var(--bs-btn-close-focus-opacity)}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:var(--bs-btn-close-disabled-opacity)}.btn-close-white{filter:var(--bs-btn-close-white-filter)}[data-bs-theme=dark] .btn-close{filter:var(--bs-btn-close-white-filter)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-border-width:var(--bs-border-width);--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:var(--bs-border-radius);--bs-toast-box-shadow:var(--bs-box-shadow);--bs-toast-header-color:var(--bs-secondary-color);--bs-toast-header-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-header-border-color:var(--bs-border-color-translucent);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex:1090;position:absolute;z-index:var(--bs-toast-zindex);width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:var(--bs-body-bg);--bs-modal-border-color:var(--bs-border-color-translucent);--bs-modal-border-width:var(--bs-border-width);--bs-modal-border-radius:var(--bs-border-radius-lg);--bs-modal-box-shadow:var(--bs-box-shadow-sm);--bs-modal-inner-border-radius:calc(var(--bs-border-radius-lg) - (var(--bs-border-width)));--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:var(--bs-border-color);--bs-modal-header-border-width:var(--bs-border-width);--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:var(--bs-border-color);--bs-modal-footer-border-width:var(--bs-border-width);position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin:calc(-.5 * var(--bs-modal-header-padding-y)) calc(-.5 * var(--bs-modal-header-padding-x)) calc(-.5 * var(--bs-modal-header-padding-y)) auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:var(--bs-box-shadow)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:var(--bs-body-bg);--bs-tooltip-bg:var(--bs-emphasis-color);--bs-tooltip-border-radius:var(--bs-border-radius);--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:calc(-1 * var(--bs-tooltip-arrow-height))}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:calc(-1 * var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:calc(-1 * var(--bs-tooltip-arrow-height))}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:calc(-1 * var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:var(--bs-body-bg);--bs-popover-border-width:var(--bs-border-width);--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:var(--bs-border-radius-lg);--bs-popover-inner-border-radius:calc(var(--bs-border-radius-lg) - var(--bs-border-width));--bs-popover-box-shadow:var(--bs-box-shadow);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color:inherit;--bs-popover-header-bg:var(--bs-secondary-bg);--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:var(--bs-body-color);--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-.5 * var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}[data-bs-theme=dark] .carousel .carousel-control-next-icon,[data-bs-theme=dark] .carousel .carousel-control-prev-icon,[data-bs-theme=dark].carousel .carousel-control-next-icon,[data-bs-theme=dark].carousel .carousel-control-prev-icon{filter:invert(1) grayscale(100)}[data-bs-theme=dark] .carousel .carousel-indicators [data-bs-target],[data-bs-theme=dark].carousel .carousel-indicators [data-bs-target]{background-color:#000}[data-bs-theme=dark] .carousel .carousel-caption,[data-bs-theme=dark].carousel .carousel-caption{color:#000}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color:var(--bs-body-color);--bs-offcanvas-bg:var(--bs-body-bg);--bs-offcanvas-border-width:var(--bs-border-width);--bs-offcanvas-border-color:var(--bs-border-color-translucent);--bs-offcanvas-box-shadow:var(--bs-box-shadow-sm);--bs-offcanvas-transition:transform 0.3s ease-in-out;--bs-offcanvas-title-line-height:1.5}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin:calc(-.5 * var(--bs-offcanvas-padding-y)) calc(-.5 * var(--bs-offcanvas-padding-x)) calc(-.5 * var(--bs-offcanvas-padding-y)) auto}.offcanvas-title{margin-bottom:0;line-height:var(--bs-offcanvas-title-line-height)}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(var(--bs-primary-rgb),var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(var(--bs-secondary-rgb),var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(var(--bs-success-rgb),var(--bs-bg-opacity,1))!important}.text-bg-info{color:#000!important;background-color:RGBA(var(--bs-info-rgb),var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#000!important;background-color:RGBA(var(--bs-warning-rgb),var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(var(--bs-danger-rgb),var(--bs-bg-opacity,1))!important}.text-bg-light{color:#000!important;background-color:RGBA(var(--bs-light-rgb),var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(var(--bs-dark-rgb),var(--bs-bg-opacity,1))!important}.link-primary{color:RGBA(var(--bs-primary-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-primary-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-primary-rgb),var(--bs-link-underline-opacity,1))!important}.link-primary:focus,.link-primary:hover{color:RGBA(10,88,202,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(10,88,202,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(10,88,202,var(--bs-link-underline-opacity,1))!important}.link-secondary{color:RGBA(var(--bs-secondary-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-secondary-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-secondary-rgb),var(--bs-link-underline-opacity,1))!important}.link-secondary:focus,.link-secondary:hover{color:RGBA(86,94,100,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(86,94,100,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(86,94,100,var(--bs-link-underline-opacity,1))!important}.link-success{color:RGBA(var(--bs-success-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-success-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-success-rgb),var(--bs-link-underline-opacity,1))!important}.link-success:focus,.link-success:hover{color:RGBA(20,108,67,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(20,108,67,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(20,108,67,var(--bs-link-underline-opacity,1))!important}.link-info{color:RGBA(var(--bs-info-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-info-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-info-rgb),var(--bs-link-underline-opacity,1))!important}.link-info:focus,.link-info:hover{color:RGBA(61,213,243,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(61,213,243,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(61,213,243,var(--bs-link-underline-opacity,1))!important}.link-warning{color:RGBA(var(--bs-warning-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-warning-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-warning-rgb),var(--bs-link-underline-opacity,1))!important}.link-warning:focus,.link-warning:hover{color:RGBA(255,205,57,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(255,205,57,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(255,205,57,var(--bs-link-underline-opacity,1))!important}.link-danger{color:RGBA(var(--bs-danger-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-danger-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-danger-rgb),var(--bs-link-underline-opacity,1))!important}.link-danger:focus,.link-danger:hover{color:RGBA(176,42,55,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(176,42,55,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(176,42,55,var(--bs-link-underline-opacity,1))!important}.link-light{color:RGBA(var(--bs-light-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-light-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-light-rgb),var(--bs-link-underline-opacity,1))!important}.link-light:focus,.link-light:hover{color:RGBA(249,250,251,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(249,250,251,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(249,250,251,var(--bs-link-underline-opacity,1))!important}.link-dark{color:RGBA(var(--bs-dark-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-dark-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-dark-rgb),var(--bs-link-underline-opacity,1))!important}.link-dark:focus,.link-dark:hover{color:RGBA(26,30,33,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(26,30,33,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(26,30,33,var(--bs-link-underline-opacity,1))!important}.link-body-emphasis{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-body-emphasis:focus,.link-body-emphasis:hover{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,.75))!important;-webkit-text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,0.75))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,0.75))!important}.focus-ring:focus{outline:0;box-shadow:var(--bs-focus-ring-x,0) var(--bs-focus-ring-y,0) var(--bs-focus-ring-blur,0) var(--bs-focus-ring-width) var(--bs-focus-ring-color)}.icon-link{display:inline-flex;gap:.375rem;align-items:center;-webkit-text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,0.5));text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,0.5));text-underline-offset:0.25em;-webkit-backface-visibility:hidden;backface-visibility:hidden}.icon-link>.bi{flex-shrink:0;width:1em;height:1em;fill:currentcolor;transition:.2s ease-in-out transform}@media (prefers-reduced-motion:reduce){.icon-link>.bi{transition:none}}.icon-link-hover:focus-visible>.bi,.icon-link-hover:hover>.bi{transform:var(--bs-icon-link-transform,translate3d(.25em,0,0))}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.visually-hidden-focusable:not(:focus):not(:focus-within):not(caption),.visually-hidden:not(caption){position:absolute!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:var(--bs-border-width);min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.object-fit-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-none{-o-object-fit:none!important;object-fit:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.overflow-x-auto{overflow-x:auto!important}.overflow-x-hidden{overflow-x:hidden!important}.overflow-x-visible{overflow-x:visible!important}.overflow-x-scroll{overflow-x:scroll!important}.overflow-y-auto{overflow-y:auto!important}.overflow-y-hidden{overflow-y:hidden!important}.overflow-y-visible{overflow-y:visible!important}.overflow-y-scroll{overflow-y:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-inline-grid{display:inline-grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:var(--bs-box-shadow)!important}.shadow-sm{box-shadow:var(--bs-box-shadow-sm)!important}.shadow-lg{box-shadow:var(--bs-box-shadow-lg)!important}.shadow-none{box-shadow:none!important}.focus-ring-primary{--bs-focus-ring-color:rgba(var(--bs-primary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-secondary{--bs-focus-ring-color:rgba(var(--bs-secondary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-success{--bs-focus-ring-color:rgba(var(--bs-success-rgb), var(--bs-focus-ring-opacity))}.focus-ring-info{--bs-focus-ring-color:rgba(var(--bs-info-rgb), var(--bs-focus-ring-opacity))}.focus-ring-warning{--bs-focus-ring-color:rgba(var(--bs-warning-rgb), var(--bs-focus-ring-opacity))}.focus-ring-danger{--bs-focus-ring-color:rgba(var(--bs-danger-rgb), var(--bs-focus-ring-opacity))}.focus-ring-light{--bs-focus-ring-color:rgba(var(--bs-light-rgb), var(--bs-focus-ring-opacity))}.focus-ring-dark{--bs-focus-ring-color:rgba(var(--bs-dark-rgb), var(--bs-focus-ring-opacity))}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-black{--bs-border-opacity:1;border-color:rgba(var(--bs-black-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-primary-subtle{border-color:var(--bs-primary-border-subtle)!important}.border-secondary-subtle{border-color:var(--bs-secondary-border-subtle)!important}.border-success-subtle{border-color:var(--bs-success-border-subtle)!important}.border-info-subtle{border-color:var(--bs-info-border-subtle)!important}.border-warning-subtle{border-color:var(--bs-warning-border-subtle)!important}.border-danger-subtle{border-color:var(--bs-danger-border-subtle)!important}.border-light-subtle{border-color:var(--bs-light-border-subtle)!important}.border-dark-subtle{border-color:var(--bs-dark-border-subtle)!important}.border-1{border-width:1px!important}.border-2{border-width:2px!important}.border-3{border-width:3px!important}.border-4{border-width:4px!important}.border-5{border-width:5px!important}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.row-gap-0{row-gap:0!important}.row-gap-1{row-gap:.25rem!important}.row-gap-2{row-gap:.5rem!important}.row-gap-3{row-gap:1rem!important}.row-gap-4{row-gap:1.5rem!important}.row-gap-5{row-gap:3rem!important}.column-gap-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-lighter{font-weight:lighter!important}.fw-light{font-weight:300!important}.fw-normal{font-weight:400!important}.fw-medium{font-weight:500!important}.fw-semibold{font-weight:600!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-body-secondary{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-body-tertiary{--bs-text-opacity:1;color:var(--bs-tertiary-color)!important}.text-body-emphasis{--bs-text-opacity:1;color:var(--bs-emphasis-color)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.text-primary-emphasis{color:var(--bs-primary-text-emphasis)!important}.text-secondary-emphasis{color:var(--bs-secondary-text-emphasis)!important}.text-success-emphasis{color:var(--bs-success-text-emphasis)!important}.text-info-emphasis{color:var(--bs-info-text-emphasis)!important}.text-warning-emphasis{color:var(--bs-warning-text-emphasis)!important}.text-danger-emphasis{color:var(--bs-danger-text-emphasis)!important}.text-light-emphasis{color:var(--bs-light-text-emphasis)!important}.text-dark-emphasis{color:var(--bs-dark-text-emphasis)!important}.link-opacity-10{--bs-link-opacity:0.1}.link-opacity-10-hover:hover{--bs-link-opacity:0.1}.link-opacity-25{--bs-link-opacity:0.25}.link-opacity-25-hover:hover{--bs-link-opacity:0.25}.link-opacity-50{--bs-link-opacity:0.5}.link-opacity-50-hover:hover{--bs-link-opacity:0.5}.link-opacity-75{--bs-link-opacity:0.75}.link-opacity-75-hover:hover{--bs-link-opacity:0.75}.link-opacity-100{--bs-link-opacity:1}.link-opacity-100-hover:hover{--bs-link-opacity:1}.link-offset-1{text-underline-offset:0.125em!important}.link-offset-1-hover:hover{text-underline-offset:0.125em!important}.link-offset-2{text-underline-offset:0.25em!important}.link-offset-2-hover:hover{text-underline-offset:0.25em!important}.link-offset-3{text-underline-offset:0.375em!important}.link-offset-3-hover:hover{text-underline-offset:0.375em!important}.link-underline-primary{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-primary-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-primary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-secondary{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-secondary-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-secondary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-success{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-success-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-success-rgb),var(--bs-link-underline-opacity))!important}.link-underline-info{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-info-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-info-rgb),var(--bs-link-underline-opacity))!important}.link-underline-warning{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-warning-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-warning-rgb),var(--bs-link-underline-opacity))!important}.link-underline-danger{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-danger-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-danger-rgb),var(--bs-link-underline-opacity))!important}.link-underline-light{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-light-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-light-rgb),var(--bs-link-underline-opacity))!important}.link-underline-dark{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-dark-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-dark-rgb),var(--bs-link-underline-opacity))!important}.link-underline{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-underline-opacity-0{--bs-link-underline-opacity:0}.link-underline-opacity-0-hover:hover{--bs-link-underline-opacity:0}.link-underline-opacity-10{--bs-link-underline-opacity:0.1}.link-underline-opacity-10-hover:hover{--bs-link-underline-opacity:0.1}.link-underline-opacity-25{--bs-link-underline-opacity:0.25}.link-underline-opacity-25-hover:hover{--bs-link-underline-opacity:0.25}.link-underline-opacity-50{--bs-link-underline-opacity:0.5}.link-underline-opacity-50-hover:hover{--bs-link-underline-opacity:0.5}.link-underline-opacity-75{--bs-link-underline-opacity:0.75}.link-underline-opacity-75-hover:hover{--bs-link-underline-opacity:0.75}.link-underline-opacity-100{--bs-link-underline-opacity:1}.link-underline-opacity-100-hover:hover{--bs-link-underline-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-body-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-bg-rgb),var(--bs-bg-opacity))!important}.bg-body-tertiary{--bs-bg-opacity:1;background-color:rgba(var(--bs-tertiary-bg-rgb),var(--bs-bg-opacity))!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-primary-subtle{background-color:var(--bs-primary-bg-subtle)!important}.bg-secondary-subtle{background-color:var(--bs-secondary-bg-subtle)!important}.bg-success-subtle{background-color:var(--bs-success-bg-subtle)!important}.bg-info-subtle{background-color:var(--bs-info-bg-subtle)!important}.bg-warning-subtle{background-color:var(--bs-warning-bg-subtle)!important}.bg-danger-subtle{background-color:var(--bs-danger-bg-subtle)!important}.bg-light-subtle{background-color:var(--bs-light-bg-subtle)!important}.bg-dark-subtle{background-color:var(--bs-dark-bg-subtle)!important}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-xxl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-0{border-top-left-radius:0!important;border-top-right-radius:0!important}.rounded-top-1{border-top-left-radius:var(--bs-border-radius-sm)!important;border-top-right-radius:var(--bs-border-radius-sm)!important}.rounded-top-2{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-3{border-top-left-radius:var(--bs-border-radius-lg)!important;border-top-right-radius:var(--bs-border-radius-lg)!important}.rounded-top-4{border-top-left-radius:var(--bs-border-radius-xl)!important;border-top-right-radius:var(--bs-border-radius-xl)!important}.rounded-top-5{border-top-left-radius:var(--bs-border-radius-xxl)!important;border-top-right-radius:var(--bs-border-radius-xxl)!important}.rounded-top-circle{border-top-left-radius:50%!important;border-top-right-radius:50%!important}.rounded-top-pill{border-top-left-radius:var(--bs-border-radius-pill)!important;border-top-right-radius:var(--bs-border-radius-pill)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-0{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.rounded-end-1{border-top-right-radius:var(--bs-border-radius-sm)!important;border-bottom-right-radius:var(--bs-border-radius-sm)!important}.rounded-end-2{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-3{border-top-right-radius:var(--bs-border-radius-lg)!important;border-bottom-right-radius:var(--bs-border-radius-lg)!important}.rounded-end-4{border-top-right-radius:var(--bs-border-radius-xl)!important;border-bottom-right-radius:var(--bs-border-radius-xl)!important}.rounded-end-5{border-top-right-radius:var(--bs-border-radius-xxl)!important;border-bottom-right-radius:var(--bs-border-radius-xxl)!important}.rounded-end-circle{border-top-right-radius:50%!important;border-bottom-right-radius:50%!important}.rounded-end-pill{border-top-right-radius:var(--bs-border-radius-pill)!important;border-bottom-right-radius:var(--bs-border-radius-pill)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-0{border-bottom-right-radius:0!important;border-bottom-left-radius:0!important}.rounded-bottom-1{border-bottom-right-radius:var(--bs-border-radius-sm)!important;border-bottom-left-radius:var(--bs-border-radius-sm)!important}.rounded-bottom-2{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-3{border-bottom-right-radius:var(--bs-border-radius-lg)!important;border-bottom-left-radius:var(--bs-border-radius-lg)!important}.rounded-bottom-4{border-bottom-right-radius:var(--bs-border-radius-xl)!important;border-bottom-left-radius:var(--bs-border-radius-xl)!important}.rounded-bottom-5{border-bottom-right-radius:var(--bs-border-radius-xxl)!important;border-bottom-left-radius:var(--bs-border-radius-xxl)!important}.rounded-bottom-circle{border-bottom-right-radius:50%!important;border-bottom-left-radius:50%!important}.rounded-bottom-pill{border-bottom-right-radius:var(--bs-border-radius-pill)!important;border-bottom-left-radius:var(--bs-border-radius-pill)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-0{border-bottom-left-radius:0!important;border-top-left-radius:0!important}.rounded-start-1{border-bottom-left-radius:var(--bs-border-radius-sm)!important;border-top-left-radius:var(--bs-border-radius-sm)!important}.rounded-start-2{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-3{border-bottom-left-radius:var(--bs-border-radius-lg)!important;border-top-left-radius:var(--bs-border-radius-lg)!important}.rounded-start-4{border-bottom-left-radius:var(--bs-border-radius-xl)!important;border-top-left-radius:var(--bs-border-radius-xl)!important}.rounded-start-5{border-bottom-left-radius:var(--bs-border-radius-xxl)!important;border-top-left-radius:var(--bs-border-radius-xxl)!important}.rounded-start-circle{border-bottom-left-radius:50%!important;border-top-left-radius:50%!important}.rounded-start-pill{border-bottom-left-radius:var(--bs-border-radius-pill)!important;border-top-left-radius:var(--bs-border-radius-pill)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}.z-n1{z-index:-1!important}.z-0{z-index:0!important}.z-1{z-index:1!important}.z-2{z-index:2!important}.z-3{z-index:3!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.object-fit-sm-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-sm-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-sm-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-sm-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-sm-none{-o-object-fit:none!important;object-fit:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-inline-grid{display:inline-grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.row-gap-sm-0{row-gap:0!important}.row-gap-sm-1{row-gap:.25rem!important}.row-gap-sm-2{row-gap:.5rem!important}.row-gap-sm-3{row-gap:1rem!important}.row-gap-sm-4{row-gap:1.5rem!important}.row-gap-sm-5{row-gap:3rem!important}.column-gap-sm-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-sm-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-sm-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-sm-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-sm-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-sm-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.object-fit-md-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-md-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-md-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-md-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-md-none{-o-object-fit:none!important;object-fit:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-inline-grid{display:inline-grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.row-gap-md-0{row-gap:0!important}.row-gap-md-1{row-gap:.25rem!important}.row-gap-md-2{row-gap:.5rem!important}.row-gap-md-3{row-gap:1rem!important}.row-gap-md-4{row-gap:1.5rem!important}.row-gap-md-5{row-gap:3rem!important}.column-gap-md-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-md-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-md-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-md-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-md-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-md-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.object-fit-lg-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-lg-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-lg-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-lg-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-lg-none{-o-object-fit:none!important;object-fit:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-inline-grid{display:inline-grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.row-gap-lg-0{row-gap:0!important}.row-gap-lg-1{row-gap:.25rem!important}.row-gap-lg-2{row-gap:.5rem!important}.row-gap-lg-3{row-gap:1rem!important}.row-gap-lg-4{row-gap:1.5rem!important}.row-gap-lg-5{row-gap:3rem!important}.column-gap-lg-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-lg-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-lg-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-lg-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-lg-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-lg-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.object-fit-xl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xl-none{-o-object-fit:none!important;object-fit:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-inline-grid{display:inline-grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.row-gap-xl-0{row-gap:0!important}.row-gap-xl-1{row-gap:.25rem!important}.row-gap-xl-2{row-gap:.5rem!important}.row-gap-xl-3{row-gap:1rem!important}.row-gap-xl-4{row-gap:1.5rem!important}.row-gap-xl-5{row-gap:3rem!important}.column-gap-xl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.object-fit-xxl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xxl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xxl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xxl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xxl-none{-o-object-fit:none!important;object-fit:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-inline-grid{display:inline-grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.row-gap-xxl-0{row-gap:0!important}.row-gap-xxl-1{row-gap:.25rem!important}.row-gap-xxl-2{row-gap:.5rem!important}.row-gap-xxl-3{row-gap:1rem!important}.row-gap-xxl-4{row-gap:1.5rem!important}.row-gap-xxl-5{row-gap:3rem!important}.column-gap-xxl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xxl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xxl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xxl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xxl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xxl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-inline-grid{display:inline-grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} -/*# sourceMappingURL=bootstrap.min.css.map */ +@charset "UTF-8";/*! + * Bootstrap v5.3.3 (https://getbootstrap.com/) + * Copyright 2011-2024 The Bootstrap Authors + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-color:#212529;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13, 110, 253, 0.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#dee2e6;--bs-body-color-rgb:222,226,230;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb:222,226,230;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb:222,226,230;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#41464b;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#087990;--bs-warning-border-subtle:#997404;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:inherit;--bs-link-color:#6ea8fe;--bs-link-hover-color:#8bb9fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:139,185,254;--bs-code-color:#e685b5;--bs-highlight-color:#dee2e6;--bs-highlight-bg:#664d03;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, 0.15);--bs-form-valid-color:#75b798;--bs-form-valid-border-color:#75b798;--bs-form-invalid-color:#ea868f;--bs-form-invalid-border-color:#ea868f}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width) solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color)}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;color:var(--bs-highlight-color);background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-secondary-color);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"โ€” "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:var(--bs-body-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:var(--bs-secondary-color)}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}:root{--bs-breakpoint-xs:0;--bs-breakpoint-sm:576px;--bs-breakpoint-md:768px;--bs-breakpoint-lg:992px;--bs-breakpoint-xl:1200px;--bs-breakpoint-xxl:1400px}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color-type:initial;--bs-table-bg-type:initial;--bs-table-color-state:initial;--bs-table-bg-state:initial;--bs-table-color:var(--bs-emphasis-color);--bs-table-bg:var(--bs-body-bg);--bs-table-border-color:var(--bs-border-color);--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-emphasis-color);--bs-table-striped-bg:rgba(var(--bs-emphasis-color-rgb), 0.05);--bs-table-active-color:var(--bs-emphasis-color);--bs-table-active-bg:rgba(var(--bs-emphasis-color-rgb), 0.1);--bs-table-hover-color:var(--bs-emphasis-color);--bs-table-hover-bg:rgba(var(--bs-emphasis-color-rgb), 0.075);width:100%;margin-bottom:1rem;vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;color:var(--bs-table-color-state,var(--bs-table-color-type,var(--bs-table-color)));background-color:var(--bs-table-bg);border-bottom-width:var(--bs-border-width);box-shadow:inset 0 0 0 9999px var(--bs-table-bg-state,var(--bs-table-bg-type,var(--bs-table-accent-bg)))}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:calc(var(--bs-border-width) * 2) solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:var(--bs-border-width) 0}.table-bordered>:not(caption)>*>*{border-width:0 var(--bs-border-width)}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-striped-columns>:not(caption)>tr>:nth-child(2n){--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-active{--bs-table-color-state:var(--bs-table-active-color);--bs-table-bg-state:var(--bs-table-active-bg)}.table-hover>tbody>tr:hover>*{--bs-table-color-state:var(--bs-table-hover-color);--bs-table-bg-state:var(--bs-table-hover-bg)}.table-primary{--bs-table-color:#000;--bs-table-bg:#cfe2ff;--bs-table-border-color:#a6b5cc;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#000;--bs-table-bg:#e2e3e5;--bs-table-border-color:#b5b6b7;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#000;--bs-table-bg:#d1e7dd;--bs-table-border-color:#a7b9b1;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#000;--bs-table-bg:#cff4fc;--bs-table-border-color:#a6c3ca;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#000;--bs-table-bg:#fff3cd;--bs-table-border-color:#ccc2a4;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#000;--bs-table-bg:#f8d7da;--bs-table-border-color:#c6acae;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#000;--bs-table-bg:#f8f9fa;--bs-table-border-color:#c6c7c8;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#212529;--bs-table-border-color:#4d5154;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + var(--bs-border-width));padding-bottom:calc(.375rem + var(--bs-border-width));margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + var(--bs-border-width));padding-bottom:calc(.5rem + var(--bs-border-width));font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + var(--bs-border-width));padding-bottom:calc(.25rem + var(--bs-border-width));font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--bs-secondary-color)}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-clip:padding-box;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--bs-body-color);background-color:var(--bs-body-bg);border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{min-width:85px;height:1.5em;margin:0}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::-moz-placeholder{color:var(--bs-secondary-color);opacity:1}.form-control::placeholder{color:var(--bs-secondary-color);opacity:1}.form-control:disabled{background-color:var(--bs-secondary-bg);opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:var(--bs-secondary-bg)}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:var(--bs-secondary-bg)}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:var(--bs-body-color);background-color:transparent;border:solid transparent;border-width:var(--bs-border-width) 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2));padding:.25rem .5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));padding:.5rem 1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2))}textarea.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}textarea.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-control-color{width:3rem;height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2));padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color::-webkit-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon,none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:var(--bs-secondary-bg)}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--bs-body-color)}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}[data-bs-theme=dark] .form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23dee2e6' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e")}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{--bs-form-check-bg:var(--bs-body-bg);flex-shrink:0;width:1em;height:1em;margin-top:.25em;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:center;background-size:contain;border:var(--bs-border-width) solid var(--bs-border-color);-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");width:2em;margin-left:-2.5em;background-image:var(--bs-form-switch-bg);background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus){--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e")}.form-range{width:100%;height:1.5rem;padding:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;-webkit-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;-moz-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:var(--bs-secondary-color)}.form-range:disabled::-moz-range-thumb{background-color:var(--bs-secondary-color)}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + calc(var(--bs-border-width) * 2));min-height:calc(3.5rem + calc(var(--bs-border-width) * 2));line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;z-index:2;height:100%;padding:1rem .75rem;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:var(--bs-border-width) solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::-moz-placeholder,.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:not(:-moz-placeholder-shown),.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{color:rgba(var(--bs-body-color-rgb),.65);transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{color:rgba(var(--bs-body-color-rgb),.65);transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:not(:-moz-placeholder-shown)~label::after{position:absolute;inset:1rem 0.375rem;z-index:-1;height:1.5em;content:"";background-color:var(--bs-body-bg);border-radius:var(--bs-border-radius)}.form-floating>.form-control-plaintext~label::after,.form-floating>.form-control:focus~label::after,.form-floating>.form-control:not(:placeholder-shown)~label::after,.form-floating>.form-select~label::after{position:absolute;inset:1rem 0.375rem;z-index:-1;height:1.5em;content:"";background-color:var(--bs-body-bg);border-radius:var(--bs-border-radius)}.form-floating>.form-control:-webkit-autofill~label{color:rgba(var(--bs-body-color-rgb),.65);transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:var(--bs-border-width) 0}.form-floating>.form-control:disabled~label,.form-floating>:disabled~label{color:#6c757d}.form-floating>.form-control:disabled~label::after,.form-floating>:disabled~label::after{background-color:var(--bs-secondary-bg)}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);text-align:center;white-space:nowrap;background-color:var(--bs-tertiary-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius)}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:calc(var(--bs-border-width) * -1);border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-valid-color)}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-success);border-radius:var(--bs-border-radius)}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:var(--bs-form-valid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:var(--bs-form-valid-border-color)}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:var(--bs-form-valid-border-color)}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:var(--bs-form-valid-color)}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:var(--bs-form-valid-color)}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-invalid-color)}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-danger);border-radius:var(--bs-border-radius)}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:var(--bs-form-invalid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:var(--bs-form-invalid-border-color)}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:var(--bs-form-invalid-border-color)}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:var(--bs-form-invalid-color)}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:var(--bs-form-invalid-color)}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:var(--bs-body-color);--bs-btn-bg:transparent;--bs-btn-border-width:var(--bs-border-width);--bs-btn-border-color:transparent;--bs-btn-border-radius:var(--bs-border-radius);--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked:focus-visible+.btn{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:0 0 0 #000;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:var(--bs-border-radius-lg)}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:var(--bs-border-radius-sm)}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:var(--bs-body-color);--bs-dropdown-bg:var(--bs-body-bg);--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-border-radius:var(--bs-border-radius);--bs-dropdown-border-width:var(--bs-border-width);--bs-dropdown-inner-border-radius:calc(var(--bs-border-radius) - var(--bs-border-width));--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:var(--bs-box-shadow);--bs-dropdown-link-color:var(--bs-body-color);--bs-dropdown-link-hover-color:var(--bs-body-color);--bs-dropdown-link-hover-bg:var(--bs-tertiary-bg);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:var(--bs-tertiary-color);--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#6c757d;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0;border-radius:var(--bs-dropdown-item-border-radius,0)}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#343a40;--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:var(--bs-border-radius)}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:calc(var(--bs-border-width) * -1)}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:calc(var(--bs-border-width) * -1)}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;background:0 0;border:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link:focus-visible{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:var(--bs-border-width);--bs-nav-tabs-border-color:var(--bs-border-color);--bs-nav-tabs-border-radius:var(--bs-border-radius);--bs-nav-tabs-link-hover-border-color:var(--bs-secondary-bg) var(--bs-secondary-bg) var(--bs-border-color);--bs-nav-tabs-link-active-color:var(--bs-emphasis-color);--bs-nav-tabs-link-active-bg:var(--bs-body-bg);--bs-nav-tabs-link-active-border-color:var(--bs-border-color) var(--bs-border-color) var(--bs-body-bg);border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:var(--bs-border-radius);--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0d6efd}.nav-pills .nav-link{border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-underline{--bs-nav-underline-gap:1rem;--bs-nav-underline-border-width:0.125rem;--bs-nav-underline-link-active-color:var(--bs-emphasis-color);gap:var(--bs-nav-underline-gap)}.nav-underline .nav-link{padding-right:0;padding-left:0;border-bottom:var(--bs-nav-underline-border-width) solid transparent}.nav-underline .nav-link:focus,.nav-underline .nav-link:hover{border-bottom-color:currentcolor}.nav-underline .nav-link.active,.nav-underline .show>.nav-link{font-weight:700;color:var(--bs-nav-underline-link-active-color);border-bottom-color:currentcolor}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:0.5rem;--bs-navbar-color:rgba(var(--bs-emphasis-color-rgb), 0.65);--bs-navbar-hover-color:rgba(var(--bs-emphasis-color-rgb), 0.8);--bs-navbar-disabled-color:rgba(var(--bs-emphasis-color-rgb), 0.3);--bs-navbar-active-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-hover-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2833, 37, 41, 0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(var(--bs-emphasis-color-rgb), 0.15);--bs-navbar-toggler-border-radius:var(--bs-border-radius);--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark,.navbar[data-bs-theme=dark]{--bs-navbar-color:rgba(255, 255, 255, 0.55);--bs-navbar-hover-color:rgba(255, 255, 255, 0.75);--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}[data-bs-theme=dark] .navbar-toggler-icon{--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width:var(--bs-border-width);--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:rgba(var(--bs-body-color-rgb), 0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:var(--bs-body-bg);--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);color:var(--bs-body-color);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y);color:var(--bs-card-title-color)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0;color:var(--bs-card-subtitle-color)}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:var(--bs-body-color);--bs-accordion-bg:var(--bs-body-bg);--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:var(--bs-border-width);--bs-accordion-border-radius:var(--bs-border-radius);--bs-accordion-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23212529' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M2 5L8 11L14 5'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23052c65' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M2 5L8 11L14 5'/%3e%3c/svg%3e");--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:var(--bs-primary-text-emphasis);--bs-accordion-active-bg:var(--bs-primary-bg-subtle)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type>.accordion-header .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type>.accordion-header .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type>.accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush>.accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush>.accordion-item:first-child{border-top:0}.accordion-flush>.accordion-item:last-child{border-bottom:0}.accordion-flush>.accordion-item>.accordion-header .accordion-button,.accordion-flush>.accordion-item>.accordion-header .accordion-button.collapsed{border-radius:0}.accordion-flush>.accordion-item>.accordion-collapse{border-radius:0}[data-bs-theme=dark] .accordion-button::after{--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.breadcrumb{--bs-breadcrumb-padding-x:0;--bs-breadcrumb-padding-y:0;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color:var(--bs-secondary-color);--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:var(--bs-link-color);--bs-pagination-bg:var(--bs-body-bg);--bs-pagination-border-width:var(--bs-border-width);--bs-pagination-border-color:var(--bs-border-color);--bs-pagination-border-radius:var(--bs-border-radius);--bs-pagination-hover-color:var(--bs-link-hover-color);--bs-pagination-hover-bg:var(--bs-tertiary-bg);--bs-pagination-hover-border-color:var(--bs-border-color);--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:var(--bs-secondary-bg);--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#0d6efd;--bs-pagination-active-border-color:#0d6efd;--bs-pagination-disabled-color:var(--bs-secondary-color);--bs-pagination-disabled-bg:var(--bs-secondary-bg);--bs-pagination-disabled-border-color:var(--bs-border-color);display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(var(--bs-border-width) * -1)}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:var(--bs-border-radius-lg)}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:var(--bs-border-radius-sm)}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:var(--bs-border-radius);display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:var(--bs-border-width) solid var(--bs-alert-border-color);--bs-alert-border-radius:var(--bs-border-radius);--bs-alert-link-color:inherit;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700;color:var(--bs-alert-link-color)}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:var(--bs-primary-text-emphasis);--bs-alert-bg:var(--bs-primary-bg-subtle);--bs-alert-border-color:var(--bs-primary-border-subtle);--bs-alert-link-color:var(--bs-primary-text-emphasis)}.alert-secondary{--bs-alert-color:var(--bs-secondary-text-emphasis);--bs-alert-bg:var(--bs-secondary-bg-subtle);--bs-alert-border-color:var(--bs-secondary-border-subtle);--bs-alert-link-color:var(--bs-secondary-text-emphasis)}.alert-success{--bs-alert-color:var(--bs-success-text-emphasis);--bs-alert-bg:var(--bs-success-bg-subtle);--bs-alert-border-color:var(--bs-success-border-subtle);--bs-alert-link-color:var(--bs-success-text-emphasis)}.alert-info{--bs-alert-color:var(--bs-info-text-emphasis);--bs-alert-bg:var(--bs-info-bg-subtle);--bs-alert-border-color:var(--bs-info-border-subtle);--bs-alert-link-color:var(--bs-info-text-emphasis)}.alert-warning{--bs-alert-color:var(--bs-warning-text-emphasis);--bs-alert-bg:var(--bs-warning-bg-subtle);--bs-alert-border-color:var(--bs-warning-border-subtle);--bs-alert-link-color:var(--bs-warning-text-emphasis)}.alert-danger{--bs-alert-color:var(--bs-danger-text-emphasis);--bs-alert-bg:var(--bs-danger-bg-subtle);--bs-alert-border-color:var(--bs-danger-border-subtle);--bs-alert-link-color:var(--bs-danger-text-emphasis)}.alert-light{--bs-alert-color:var(--bs-light-text-emphasis);--bs-alert-bg:var(--bs-light-bg-subtle);--bs-alert-border-color:var(--bs-light-border-subtle);--bs-alert-link-color:var(--bs-light-text-emphasis)}.alert-dark{--bs-alert-color:var(--bs-dark-text-emphasis);--bs-alert-bg:var(--bs-dark-bg-subtle);--bs-alert-border-color:var(--bs-dark-border-subtle);--bs-alert-link-color:var(--bs-dark-text-emphasis)}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress,.progress-stacked{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:var(--bs-secondary-bg);--bs-progress-border-radius:var(--bs-border-radius);--bs-progress-box-shadow:var(--bs-box-shadow-inset);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#0d6efd;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-stacked>.progress{overflow:visible}.progress-stacked>.progress>.progress-bar{width:100%}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color:var(--bs-body-color);--bs-list-group-bg:var(--bs-body-bg);--bs-list-group-border-color:var(--bs-border-color);--bs-list-group-border-width:var(--bs-border-width);--bs-list-group-border-radius:var(--bs-border-radius);--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:var(--bs-secondary-color);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-tertiary-bg);--bs-list-group-action-active-color:var(--bs-body-color);--bs-list-group-action-active-bg:var(--bs-secondary-bg);--bs-list-group-disabled-color:var(--bs-secondary-color);--bs-list-group-disabled-bg:var(--bs-body-bg);--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#0d6efd;--bs-list-group-active-border-color:#0d6efd;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{--bs-list-group-color:var(--bs-primary-text-emphasis);--bs-list-group-bg:var(--bs-primary-bg-subtle);--bs-list-group-border-color:var(--bs-primary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-primary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-primary-border-subtle);--bs-list-group-active-color:var(--bs-primary-bg-subtle);--bs-list-group-active-bg:var(--bs-primary-text-emphasis);--bs-list-group-active-border-color:var(--bs-primary-text-emphasis)}.list-group-item-secondary{--bs-list-group-color:var(--bs-secondary-text-emphasis);--bs-list-group-bg:var(--bs-secondary-bg-subtle);--bs-list-group-border-color:var(--bs-secondary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-secondary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-secondary-border-subtle);--bs-list-group-active-color:var(--bs-secondary-bg-subtle);--bs-list-group-active-bg:var(--bs-secondary-text-emphasis);--bs-list-group-active-border-color:var(--bs-secondary-text-emphasis)}.list-group-item-success{--bs-list-group-color:var(--bs-success-text-emphasis);--bs-list-group-bg:var(--bs-success-bg-subtle);--bs-list-group-border-color:var(--bs-success-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-success-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-success-border-subtle);--bs-list-group-active-color:var(--bs-success-bg-subtle);--bs-list-group-active-bg:var(--bs-success-text-emphasis);--bs-list-group-active-border-color:var(--bs-success-text-emphasis)}.list-group-item-info{--bs-list-group-color:var(--bs-info-text-emphasis);--bs-list-group-bg:var(--bs-info-bg-subtle);--bs-list-group-border-color:var(--bs-info-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-info-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-info-border-subtle);--bs-list-group-active-color:var(--bs-info-bg-subtle);--bs-list-group-active-bg:var(--bs-info-text-emphasis);--bs-list-group-active-border-color:var(--bs-info-text-emphasis)}.list-group-item-warning{--bs-list-group-color:var(--bs-warning-text-emphasis);--bs-list-group-bg:var(--bs-warning-bg-subtle);--bs-list-group-border-color:var(--bs-warning-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-warning-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-warning-border-subtle);--bs-list-group-active-color:var(--bs-warning-bg-subtle);--bs-list-group-active-bg:var(--bs-warning-text-emphasis);--bs-list-group-active-border-color:var(--bs-warning-text-emphasis)}.list-group-item-danger{--bs-list-group-color:var(--bs-danger-text-emphasis);--bs-list-group-bg:var(--bs-danger-bg-subtle);--bs-list-group-border-color:var(--bs-danger-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-danger-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-danger-border-subtle);--bs-list-group-active-color:var(--bs-danger-bg-subtle);--bs-list-group-active-bg:var(--bs-danger-text-emphasis);--bs-list-group-active-border-color:var(--bs-danger-text-emphasis)}.list-group-item-light{--bs-list-group-color:var(--bs-light-text-emphasis);--bs-list-group-bg:var(--bs-light-bg-subtle);--bs-list-group-border-color:var(--bs-light-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-light-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-light-border-subtle);--bs-list-group-active-color:var(--bs-light-bg-subtle);--bs-list-group-active-bg:var(--bs-light-text-emphasis);--bs-list-group-active-border-color:var(--bs-light-text-emphasis)}.list-group-item-dark{--bs-list-group-color:var(--bs-dark-text-emphasis);--bs-list-group-bg:var(--bs-dark-bg-subtle);--bs-list-group-border-color:var(--bs-dark-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-dark-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-dark-border-subtle);--bs-list-group-active-color:var(--bs-dark-bg-subtle);--bs-list-group-active-bg:var(--bs-dark-text-emphasis);--bs-list-group-active-border-color:var(--bs-dark-text-emphasis)}.btn-close{--bs-btn-close-color:#000;--bs-btn-close-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e");--bs-btn-close-opacity:0.5;--bs-btn-close-hover-opacity:0.75;--bs-btn-close-focus-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-btn-close-focus-opacity:1;--bs-btn-close-disabled-opacity:0.25;--bs-btn-close-white-filter:invert(1) grayscale(100%) brightness(200%);box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:var(--bs-btn-close-color);background:transparent var(--bs-btn-close-bg) center/1em auto no-repeat;border:0;border-radius:.375rem;opacity:var(--bs-btn-close-opacity)}.btn-close:hover{color:var(--bs-btn-close-color);text-decoration:none;opacity:var(--bs-btn-close-hover-opacity)}.btn-close:focus{outline:0;box-shadow:var(--bs-btn-close-focus-shadow);opacity:var(--bs-btn-close-focus-opacity)}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:var(--bs-btn-close-disabled-opacity)}.btn-close-white{filter:var(--bs-btn-close-white-filter)}[data-bs-theme=dark] .btn-close{filter:var(--bs-btn-close-white-filter)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-border-width:var(--bs-border-width);--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:var(--bs-border-radius);--bs-toast-box-shadow:var(--bs-box-shadow);--bs-toast-header-color:var(--bs-secondary-color);--bs-toast-header-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-header-border-color:var(--bs-border-color-translucent);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex:1090;position:absolute;z-index:var(--bs-toast-zindex);width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:var(--bs-body-bg);--bs-modal-border-color:var(--bs-border-color-translucent);--bs-modal-border-width:var(--bs-border-width);--bs-modal-border-radius:var(--bs-border-radius-lg);--bs-modal-box-shadow:var(--bs-box-shadow-sm);--bs-modal-inner-border-radius:calc(var(--bs-border-radius-lg) - (var(--bs-border-width)));--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:var(--bs-border-color);--bs-modal-header-border-width:var(--bs-border-width);--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:var(--bs-border-color);--bs-modal-footer-border-width:var(--bs-border-width);position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin:calc(-.5 * var(--bs-modal-header-padding-y)) calc(-.5 * var(--bs-modal-header-padding-x)) calc(-.5 * var(--bs-modal-header-padding-y)) auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:var(--bs-box-shadow)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:var(--bs-body-bg);--bs-tooltip-bg:var(--bs-emphasis-color);--bs-tooltip-border-radius:var(--bs-border-radius);--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:calc(-1 * var(--bs-tooltip-arrow-height))}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:calc(-1 * var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:calc(-1 * var(--bs-tooltip-arrow-height))}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:calc(-1 * var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:var(--bs-body-bg);--bs-popover-border-width:var(--bs-border-width);--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:var(--bs-border-radius-lg);--bs-popover-inner-border-radius:calc(var(--bs-border-radius-lg) - var(--bs-border-width));--bs-popover-box-shadow:var(--bs-box-shadow);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color:inherit;--bs-popover-header-bg:var(--bs-secondary-bg);--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:var(--bs-body-color);--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-.5 * var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}[data-bs-theme=dark] .carousel .carousel-control-next-icon,[data-bs-theme=dark] .carousel .carousel-control-prev-icon,[data-bs-theme=dark].carousel .carousel-control-next-icon,[data-bs-theme=dark].carousel .carousel-control-prev-icon{filter:invert(1) grayscale(100)}[data-bs-theme=dark] .carousel .carousel-indicators [data-bs-target],[data-bs-theme=dark].carousel .carousel-indicators [data-bs-target]{background-color:#000}[data-bs-theme=dark] .carousel .carousel-caption,[data-bs-theme=dark].carousel .carousel-caption{color:#000}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color:var(--bs-body-color);--bs-offcanvas-bg:var(--bs-body-bg);--bs-offcanvas-border-width:var(--bs-border-width);--bs-offcanvas-border-color:var(--bs-border-color-translucent);--bs-offcanvas-box-shadow:var(--bs-box-shadow-sm);--bs-offcanvas-transition:transform 0.3s ease-in-out;--bs-offcanvas-title-line-height:1.5}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin:calc(-.5 * var(--bs-offcanvas-padding-y)) calc(-.5 * var(--bs-offcanvas-padding-x)) calc(-.5 * var(--bs-offcanvas-padding-y)) auto}.offcanvas-title{margin-bottom:0;line-height:var(--bs-offcanvas-title-line-height)}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(var(--bs-primary-rgb),var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(var(--bs-secondary-rgb),var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(var(--bs-success-rgb),var(--bs-bg-opacity,1))!important}.text-bg-info{color:#000!important;background-color:RGBA(var(--bs-info-rgb),var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#000!important;background-color:RGBA(var(--bs-warning-rgb),var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(var(--bs-danger-rgb),var(--bs-bg-opacity,1))!important}.text-bg-light{color:#000!important;background-color:RGBA(var(--bs-light-rgb),var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(var(--bs-dark-rgb),var(--bs-bg-opacity,1))!important}.link-primary{color:RGBA(var(--bs-primary-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-primary-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-primary-rgb),var(--bs-link-underline-opacity,1))!important}.link-primary:focus,.link-primary:hover{color:RGBA(10,88,202,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(10,88,202,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(10,88,202,var(--bs-link-underline-opacity,1))!important}.link-secondary{color:RGBA(var(--bs-secondary-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-secondary-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-secondary-rgb),var(--bs-link-underline-opacity,1))!important}.link-secondary:focus,.link-secondary:hover{color:RGBA(86,94,100,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(86,94,100,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(86,94,100,var(--bs-link-underline-opacity,1))!important}.link-success{color:RGBA(var(--bs-success-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-success-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-success-rgb),var(--bs-link-underline-opacity,1))!important}.link-success:focus,.link-success:hover{color:RGBA(20,108,67,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(20,108,67,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(20,108,67,var(--bs-link-underline-opacity,1))!important}.link-info{color:RGBA(var(--bs-info-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-info-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-info-rgb),var(--bs-link-underline-opacity,1))!important}.link-info:focus,.link-info:hover{color:RGBA(61,213,243,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(61,213,243,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(61,213,243,var(--bs-link-underline-opacity,1))!important}.link-warning{color:RGBA(var(--bs-warning-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-warning-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-warning-rgb),var(--bs-link-underline-opacity,1))!important}.link-warning:focus,.link-warning:hover{color:RGBA(255,205,57,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(255,205,57,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(255,205,57,var(--bs-link-underline-opacity,1))!important}.link-danger{color:RGBA(var(--bs-danger-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-danger-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-danger-rgb),var(--bs-link-underline-opacity,1))!important}.link-danger:focus,.link-danger:hover{color:RGBA(176,42,55,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(176,42,55,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(176,42,55,var(--bs-link-underline-opacity,1))!important}.link-light{color:RGBA(var(--bs-light-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-light-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-light-rgb),var(--bs-link-underline-opacity,1))!important}.link-light:focus,.link-light:hover{color:RGBA(249,250,251,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(249,250,251,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(249,250,251,var(--bs-link-underline-opacity,1))!important}.link-dark{color:RGBA(var(--bs-dark-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-dark-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-dark-rgb),var(--bs-link-underline-opacity,1))!important}.link-dark:focus,.link-dark:hover{color:RGBA(26,30,33,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(26,30,33,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(26,30,33,var(--bs-link-underline-opacity,1))!important}.link-body-emphasis{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-body-emphasis:focus,.link-body-emphasis:hover{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,.75))!important;-webkit-text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,0.75))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,0.75))!important}.focus-ring:focus{outline:0;box-shadow:var(--bs-focus-ring-x,0) var(--bs-focus-ring-y,0) var(--bs-focus-ring-blur,0) var(--bs-focus-ring-width) var(--bs-focus-ring-color)}.icon-link{display:inline-flex;gap:.375rem;align-items:center;-webkit-text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,0.5));text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,0.5));text-underline-offset:0.25em;-webkit-backface-visibility:hidden;backface-visibility:hidden}.icon-link>.bi{flex-shrink:0;width:1em;height:1em;fill:currentcolor;transition:.2s ease-in-out transform}@media (prefers-reduced-motion:reduce){.icon-link>.bi{transition:none}}.icon-link-hover:focus-visible>.bi,.icon-link-hover:hover>.bi{transform:var(--bs-icon-link-transform,translate3d(.25em,0,0))}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.visually-hidden-focusable:not(:focus):not(:focus-within):not(caption),.visually-hidden:not(caption){position:absolute!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:var(--bs-border-width);min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.object-fit-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-none{-o-object-fit:none!important;object-fit:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.overflow-x-auto{overflow-x:auto!important}.overflow-x-hidden{overflow-x:hidden!important}.overflow-x-visible{overflow-x:visible!important}.overflow-x-scroll{overflow-x:scroll!important}.overflow-y-auto{overflow-y:auto!important}.overflow-y-hidden{overflow-y:hidden!important}.overflow-y-visible{overflow-y:visible!important}.overflow-y-scroll{overflow-y:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-inline-grid{display:inline-grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:var(--bs-box-shadow)!important}.shadow-sm{box-shadow:var(--bs-box-shadow-sm)!important}.shadow-lg{box-shadow:var(--bs-box-shadow-lg)!important}.shadow-none{box-shadow:none!important}.focus-ring-primary{--bs-focus-ring-color:rgba(var(--bs-primary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-secondary{--bs-focus-ring-color:rgba(var(--bs-secondary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-success{--bs-focus-ring-color:rgba(var(--bs-success-rgb), var(--bs-focus-ring-opacity))}.focus-ring-info{--bs-focus-ring-color:rgba(var(--bs-info-rgb), var(--bs-focus-ring-opacity))}.focus-ring-warning{--bs-focus-ring-color:rgba(var(--bs-warning-rgb), var(--bs-focus-ring-opacity))}.focus-ring-danger{--bs-focus-ring-color:rgba(var(--bs-danger-rgb), var(--bs-focus-ring-opacity))}.focus-ring-light{--bs-focus-ring-color:rgba(var(--bs-light-rgb), var(--bs-focus-ring-opacity))}.focus-ring-dark{--bs-focus-ring-color:rgba(var(--bs-dark-rgb), var(--bs-focus-ring-opacity))}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-black{--bs-border-opacity:1;border-color:rgba(var(--bs-black-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-primary-subtle{border-color:var(--bs-primary-border-subtle)!important}.border-secondary-subtle{border-color:var(--bs-secondary-border-subtle)!important}.border-success-subtle{border-color:var(--bs-success-border-subtle)!important}.border-info-subtle{border-color:var(--bs-info-border-subtle)!important}.border-warning-subtle{border-color:var(--bs-warning-border-subtle)!important}.border-danger-subtle{border-color:var(--bs-danger-border-subtle)!important}.border-light-subtle{border-color:var(--bs-light-border-subtle)!important}.border-dark-subtle{border-color:var(--bs-dark-border-subtle)!important}.border-1{border-width:1px!important}.border-2{border-width:2px!important}.border-3{border-width:3px!important}.border-4{border-width:4px!important}.border-5{border-width:5px!important}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.row-gap-0{row-gap:0!important}.row-gap-1{row-gap:.25rem!important}.row-gap-2{row-gap:.5rem!important}.row-gap-3{row-gap:1rem!important}.row-gap-4{row-gap:1.5rem!important}.row-gap-5{row-gap:3rem!important}.column-gap-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-lighter{font-weight:lighter!important}.fw-light{font-weight:300!important}.fw-normal{font-weight:400!important}.fw-medium{font-weight:500!important}.fw-semibold{font-weight:600!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-body-secondary{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-body-tertiary{--bs-text-opacity:1;color:var(--bs-tertiary-color)!important}.text-body-emphasis{--bs-text-opacity:1;color:var(--bs-emphasis-color)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.text-primary-emphasis{color:var(--bs-primary-text-emphasis)!important}.text-secondary-emphasis{color:var(--bs-secondary-text-emphasis)!important}.text-success-emphasis{color:var(--bs-success-text-emphasis)!important}.text-info-emphasis{color:var(--bs-info-text-emphasis)!important}.text-warning-emphasis{color:var(--bs-warning-text-emphasis)!important}.text-danger-emphasis{color:var(--bs-danger-text-emphasis)!important}.text-light-emphasis{color:var(--bs-light-text-emphasis)!important}.text-dark-emphasis{color:var(--bs-dark-text-emphasis)!important}.link-opacity-10{--bs-link-opacity:0.1}.link-opacity-10-hover:hover{--bs-link-opacity:0.1}.link-opacity-25{--bs-link-opacity:0.25}.link-opacity-25-hover:hover{--bs-link-opacity:0.25}.link-opacity-50{--bs-link-opacity:0.5}.link-opacity-50-hover:hover{--bs-link-opacity:0.5}.link-opacity-75{--bs-link-opacity:0.75}.link-opacity-75-hover:hover{--bs-link-opacity:0.75}.link-opacity-100{--bs-link-opacity:1}.link-opacity-100-hover:hover{--bs-link-opacity:1}.link-offset-1{text-underline-offset:0.125em!important}.link-offset-1-hover:hover{text-underline-offset:0.125em!important}.link-offset-2{text-underline-offset:0.25em!important}.link-offset-2-hover:hover{text-underline-offset:0.25em!important}.link-offset-3{text-underline-offset:0.375em!important}.link-offset-3-hover:hover{text-underline-offset:0.375em!important}.link-underline-primary{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-primary-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-primary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-secondary{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-secondary-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-secondary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-success{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-success-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-success-rgb),var(--bs-link-underline-opacity))!important}.link-underline-info{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-info-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-info-rgb),var(--bs-link-underline-opacity))!important}.link-underline-warning{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-warning-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-warning-rgb),var(--bs-link-underline-opacity))!important}.link-underline-danger{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-danger-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-danger-rgb),var(--bs-link-underline-opacity))!important}.link-underline-light{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-light-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-light-rgb),var(--bs-link-underline-opacity))!important}.link-underline-dark{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-dark-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-dark-rgb),var(--bs-link-underline-opacity))!important}.link-underline{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-underline-opacity-0{--bs-link-underline-opacity:0}.link-underline-opacity-0-hover:hover{--bs-link-underline-opacity:0}.link-underline-opacity-10{--bs-link-underline-opacity:0.1}.link-underline-opacity-10-hover:hover{--bs-link-underline-opacity:0.1}.link-underline-opacity-25{--bs-link-underline-opacity:0.25}.link-underline-opacity-25-hover:hover{--bs-link-underline-opacity:0.25}.link-underline-opacity-50{--bs-link-underline-opacity:0.5}.link-underline-opacity-50-hover:hover{--bs-link-underline-opacity:0.5}.link-underline-opacity-75{--bs-link-underline-opacity:0.75}.link-underline-opacity-75-hover:hover{--bs-link-underline-opacity:0.75}.link-underline-opacity-100{--bs-link-underline-opacity:1}.link-underline-opacity-100-hover:hover{--bs-link-underline-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-body-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-bg-rgb),var(--bs-bg-opacity))!important}.bg-body-tertiary{--bs-bg-opacity:1;background-color:rgba(var(--bs-tertiary-bg-rgb),var(--bs-bg-opacity))!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-primary-subtle{background-color:var(--bs-primary-bg-subtle)!important}.bg-secondary-subtle{background-color:var(--bs-secondary-bg-subtle)!important}.bg-success-subtle{background-color:var(--bs-success-bg-subtle)!important}.bg-info-subtle{background-color:var(--bs-info-bg-subtle)!important}.bg-warning-subtle{background-color:var(--bs-warning-bg-subtle)!important}.bg-danger-subtle{background-color:var(--bs-danger-bg-subtle)!important}.bg-light-subtle{background-color:var(--bs-light-bg-subtle)!important}.bg-dark-subtle{background-color:var(--bs-dark-bg-subtle)!important}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-xxl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-0{border-top-left-radius:0!important;border-top-right-radius:0!important}.rounded-top-1{border-top-left-radius:var(--bs-border-radius-sm)!important;border-top-right-radius:var(--bs-border-radius-sm)!important}.rounded-top-2{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-3{border-top-left-radius:var(--bs-border-radius-lg)!important;border-top-right-radius:var(--bs-border-radius-lg)!important}.rounded-top-4{border-top-left-radius:var(--bs-border-radius-xl)!important;border-top-right-radius:var(--bs-border-radius-xl)!important}.rounded-top-5{border-top-left-radius:var(--bs-border-radius-xxl)!important;border-top-right-radius:var(--bs-border-radius-xxl)!important}.rounded-top-circle{border-top-left-radius:50%!important;border-top-right-radius:50%!important}.rounded-top-pill{border-top-left-radius:var(--bs-border-radius-pill)!important;border-top-right-radius:var(--bs-border-radius-pill)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-0{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.rounded-end-1{border-top-right-radius:var(--bs-border-radius-sm)!important;border-bottom-right-radius:var(--bs-border-radius-sm)!important}.rounded-end-2{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-3{border-top-right-radius:var(--bs-border-radius-lg)!important;border-bottom-right-radius:var(--bs-border-radius-lg)!important}.rounded-end-4{border-top-right-radius:var(--bs-border-radius-xl)!important;border-bottom-right-radius:var(--bs-border-radius-xl)!important}.rounded-end-5{border-top-right-radius:var(--bs-border-radius-xxl)!important;border-bottom-right-radius:var(--bs-border-radius-xxl)!important}.rounded-end-circle{border-top-right-radius:50%!important;border-bottom-right-radius:50%!important}.rounded-end-pill{border-top-right-radius:var(--bs-border-radius-pill)!important;border-bottom-right-radius:var(--bs-border-radius-pill)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-0{border-bottom-right-radius:0!important;border-bottom-left-radius:0!important}.rounded-bottom-1{border-bottom-right-radius:var(--bs-border-radius-sm)!important;border-bottom-left-radius:var(--bs-border-radius-sm)!important}.rounded-bottom-2{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-3{border-bottom-right-radius:var(--bs-border-radius-lg)!important;border-bottom-left-radius:var(--bs-border-radius-lg)!important}.rounded-bottom-4{border-bottom-right-radius:var(--bs-border-radius-xl)!important;border-bottom-left-radius:var(--bs-border-radius-xl)!important}.rounded-bottom-5{border-bottom-right-radius:var(--bs-border-radius-xxl)!important;border-bottom-left-radius:var(--bs-border-radius-xxl)!important}.rounded-bottom-circle{border-bottom-right-radius:50%!important;border-bottom-left-radius:50%!important}.rounded-bottom-pill{border-bottom-right-radius:var(--bs-border-radius-pill)!important;border-bottom-left-radius:var(--bs-border-radius-pill)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-0{border-bottom-left-radius:0!important;border-top-left-radius:0!important}.rounded-start-1{border-bottom-left-radius:var(--bs-border-radius-sm)!important;border-top-left-radius:var(--bs-border-radius-sm)!important}.rounded-start-2{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-3{border-bottom-left-radius:var(--bs-border-radius-lg)!important;border-top-left-radius:var(--bs-border-radius-lg)!important}.rounded-start-4{border-bottom-left-radius:var(--bs-border-radius-xl)!important;border-top-left-radius:var(--bs-border-radius-xl)!important}.rounded-start-5{border-bottom-left-radius:var(--bs-border-radius-xxl)!important;border-top-left-radius:var(--bs-border-radius-xxl)!important}.rounded-start-circle{border-bottom-left-radius:50%!important;border-top-left-radius:50%!important}.rounded-start-pill{border-bottom-left-radius:var(--bs-border-radius-pill)!important;border-top-left-radius:var(--bs-border-radius-pill)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}.z-n1{z-index:-1!important}.z-0{z-index:0!important}.z-1{z-index:1!important}.z-2{z-index:2!important}.z-3{z-index:3!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.object-fit-sm-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-sm-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-sm-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-sm-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-sm-none{-o-object-fit:none!important;object-fit:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-inline-grid{display:inline-grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.row-gap-sm-0{row-gap:0!important}.row-gap-sm-1{row-gap:.25rem!important}.row-gap-sm-2{row-gap:.5rem!important}.row-gap-sm-3{row-gap:1rem!important}.row-gap-sm-4{row-gap:1.5rem!important}.row-gap-sm-5{row-gap:3rem!important}.column-gap-sm-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-sm-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-sm-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-sm-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-sm-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-sm-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.object-fit-md-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-md-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-md-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-md-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-md-none{-o-object-fit:none!important;object-fit:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-inline-grid{display:inline-grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.row-gap-md-0{row-gap:0!important}.row-gap-md-1{row-gap:.25rem!important}.row-gap-md-2{row-gap:.5rem!important}.row-gap-md-3{row-gap:1rem!important}.row-gap-md-4{row-gap:1.5rem!important}.row-gap-md-5{row-gap:3rem!important}.column-gap-md-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-md-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-md-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-md-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-md-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-md-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.object-fit-lg-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-lg-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-lg-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-lg-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-lg-none{-o-object-fit:none!important;object-fit:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-inline-grid{display:inline-grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.row-gap-lg-0{row-gap:0!important}.row-gap-lg-1{row-gap:.25rem!important}.row-gap-lg-2{row-gap:.5rem!important}.row-gap-lg-3{row-gap:1rem!important}.row-gap-lg-4{row-gap:1.5rem!important}.row-gap-lg-5{row-gap:3rem!important}.column-gap-lg-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-lg-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-lg-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-lg-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-lg-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-lg-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.object-fit-xl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xl-none{-o-object-fit:none!important;object-fit:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-inline-grid{display:inline-grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.row-gap-xl-0{row-gap:0!important}.row-gap-xl-1{row-gap:.25rem!important}.row-gap-xl-2{row-gap:.5rem!important}.row-gap-xl-3{row-gap:1rem!important}.row-gap-xl-4{row-gap:1.5rem!important}.row-gap-xl-5{row-gap:3rem!important}.column-gap-xl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.object-fit-xxl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xxl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xxl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xxl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xxl-none{-o-object-fit:none!important;object-fit:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-inline-grid{display:inline-grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.row-gap-xxl-0{row-gap:0!important}.row-gap-xxl-1{row-gap:.25rem!important}.row-gap-xxl-2{row-gap:.5rem!important}.row-gap-xxl-3{row-gap:1rem!important}.row-gap-xxl-4{row-gap:1.5rem!important}.row-gap-xxl-5{row-gap:3rem!important}.column-gap-xxl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xxl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xxl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xxl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xxl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xxl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-inline-grid{display:inline-grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ From 18b29163fa4014f532fb8cb8a48c19aad6e93ea0 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Mon, 6 Oct 2025 15:32:13 +0700 Subject: [PATCH 28/36] chore: add index.php --- index.php | 364 +++++++++++++++++++++++++++--------------------------- 1 file changed, 182 insertions(+), 182 deletions(-) diff --git a/index.php b/index.php index 8db5725..a348040 100644 --- a/index.php +++ b/index.php @@ -1,182 +1,182 @@ - - -
    -
    -
    - - KeymanWeb.com - - - - -
    -
    -
    Keyboard Selection menu
    -
    -

    Open Search to get your keyboard

    -
    - - -
    -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - - -
    -
    - -
    - -
    -
    - -
    -
    -

    No example is available for this keyboard.

    -
    -
    -
    -
    - -
    - - - - - - + + +
    +
    +
    + + KeymanWeb.com + + + + +
    +
    +
    Keyboard Selection menu
    +
    +

    Open Search to get your keyboard

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

    No example is available for this keyboard.

    +
    +
    +
    +
    + +
    + + + + + + From 4f3170919bc673752a8366992f25f204a69c10eb Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Mon, 6 Oct 2025 15:33:14 +0700 Subject: [PATCH 29/36] chore: add head.php --- inc/head.php | 466 +++++++++++++++++++++++++-------------------------- 1 file changed, 233 insertions(+), 233 deletions(-) diff --git a/inc/head.php b/inc/head.php index 266769f..1229730 100644 --- a/inc/head.php +++ b/inc/head.php @@ -1,233 +1,233 @@ - get_major_version($kmw_builds['alpha']), - 'beta' => get_major_version($kmw_builds['beta']), - 'stable' => get_major_version($kmw_builds['stable']), - ); - $hasBeta = version_compare($kmw_builds['stable'], $kmw_builds['beta']) < 0; - - if(isset($_REQUEST['version']) && preg_match('/^(\d+)\.(\d+)\.(\d+)$/', $_REQUEST['version'])) { - $kmwbuild = $_REQUEST['version']; - - $version = get_major_version($kmwbuild); - - // ignore tier as passed in, compare to the major version of each tier - if($version == $kmw_builds_major_versions['alpha']) $tier = 'alpha'; - else if($version == $kmw_builds_major_versions['stable']) $tier = 'stable'; - else if($version == $kmw_builds_major_versions['beta']) $tier = 'beta'; - else $tier = 'stable'; - } else { - // Used to enable the release-tier selection code below. - // For general usage, we recommend `get_keymanweb_version($tier)` instead. - if(isset($_REQUEST['tier']) && in_array($_REQUEST['tier'], $kmw_tiers, TRUE)) { - $tier = $_REQUEST['tier']; - } else { - // Selects the 'stable' version unless we're in a beta cycle. - // - // Note: if API calls fail to retrieve proper version data, - // the return will be 0 due to equal fallback versions. - // Net result: selection of the 'stable' tier. - $tier = $hasBeta ? 'beta' :'stable'; - } - - $kmwbuild = $kmw_builds[$tier]; - $version = get_major_version($kmwbuild); - } - - $VersionWithTag = $kmwbuild . ($tier == 'stable' ? '' : "-$tier"); -?> - - - - - - - - - - - -KeymanWeb.com <?php if($tier != 'stable') echo "($tier)"; ?> - - - - -" /> -" /> - - - - - - - - - - - - - - - - - - - - - - - - + get_major_version($kmw_builds['alpha']), + 'beta' => get_major_version($kmw_builds['beta']), + 'stable' => get_major_version($kmw_builds['stable']), + ); + $hasBeta = version_compare($kmw_builds['stable'], $kmw_builds['beta']) < 0; + + if(isset($_REQUEST['version']) && preg_match('/^(\d+)\.(\d+)\.(\d+)$/', $_REQUEST['version'])) { + $kmwbuild = $_REQUEST['version']; + + $version = get_major_version($kmwbuild); + + // ignore tier as passed in, compare to the major version of each tier + if($version == $kmw_builds_major_versions['alpha']) $tier = 'alpha'; + else if($version == $kmw_builds_major_versions['stable']) $tier = 'stable'; + else if($version == $kmw_builds_major_versions['beta']) $tier = 'beta'; + else $tier = 'stable'; + } else { + // Used to enable the release-tier selection code below. + // For general usage, we recommend `get_keymanweb_version($tier)` instead. + if(isset($_REQUEST['tier']) && in_array($_REQUEST['tier'], $kmw_tiers, TRUE)) { + $tier = $_REQUEST['tier']; + } else { + // Selects the 'stable' version unless we're in a beta cycle. + // + // Note: if API calls fail to retrieve proper version data, + // the return will be 0 due to equal fallback versions. + // Net result: selection of the 'stable' tier. + $tier = $hasBeta ? 'beta' :'stable'; + } + + $kmwbuild = $kmw_builds[$tier]; + $version = get_major_version($kmwbuild); + } + + $VersionWithTag = $kmwbuild . ($tier == 'stable' ? '' : "-$tier"); +?> + + + + + + + + + + + +KeymanWeb.com <?php if($tier != 'stable') echo "($tier)"; ?> + + + + +" /> +" /> + + + + + + + + + + + + + + + + + + + + + + + + From fddc10aa6e92d7875c3a92bf3f637d7b509be39e Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Mon, 6 Oct 2025 15:36:36 +0700 Subject: [PATCH 30/36] chore: add styles files --- cdn/dev/css/kmw-desktop.css | 434 ++++----- cdn/dev/css/kmw-header.css | 1732 +++++++++++++++++------------------ cdn/dev/css/kmw-mobile.css | 332 +++---- cdn/dev/css/kmw-tablet.css | 1100 +++++++++++----------- 4 files changed, 1799 insertions(+), 1799 deletions(-) diff --git a/cdn/dev/css/kmw-desktop.css b/cdn/dev/css/kmw-desktop.css index 518796e..f139398 100644 --- a/cdn/dev/css/kmw-desktop.css +++ b/cdn/dev/css/kmw-desktop.css @@ -1,217 +1,217 @@ -/* Desktop browser CSS rules */ - -/* -====================== -==Universal Elements== -====================== -*/ - - #kmw_controls{ - border-top-left-radius: 8px; - border-top-right-radius: 8px; - -moz-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); - } - - #kmw_btn_osk{ - border-top-right-radius: 10px; - } - - #kmw_controls_start{ - border-top-left-radius: 10px; - } - -textarea { - height:260px; - width:554px; - float:left; - margin: 0px 10px 10px; - color:black; - font-size:16px; - font-family:SindhiWeb,Verdana,GeezWeb,LaoWeb,TibetanWeb,MyanmarWeb,SinhalaWeb,TamilWeb,KhmerWeb,LatinWeb,OriyaWeb,EgyptianWeb !important; - } - -form { - padding-right:10px; - float:left; - } -#messageContainer { - float:left; - width:80%; -} -/* -====================== -==Keyboard Examples== -====================== -*/ - -#example,#help { - margin: 5px 0px; - text-align: center; -} - -#example { - visibility: hidden; - width: 100%; - min-height: 10px; - max-height: 45px; - display: flex; - justify-content: center; - align-items: center; - padding-top: 5px; -} - -#example a { - padding-left: 10px; -} - -.highlightKeys kbd { - border: solid 1px #808080; - border-radius: 4px; - background: #cccccf; - color: black; - font-family: Verdana; - font-weight: normal; - min-width: 16px; - display: inline-block; - box-shadow: 2px 2px 1px rgba(128, 128, 128, 0.3); - margin-right: 4px; -} - -.highlightKeys kbd.space { - min-width: 64px; -} - -/* -====================== -==Keyboard Styling== -====================== -*/ -.desktop, .kmw-osk-frame { - display: block !important; - position: static !important; - width: 100% !important; - height: 100% !important; - max-width: 100% !important; - max-height: 100% !important; - border-radius: 0; -} - -.kmw-help-osk-frame { - height: 100% !important; - scroll-behavior: smooth !important; - scrollbar-width: thin; - overflow-x: hidden !important; - overflow-y: scroll !important; - text-align: center !important; -} - -.kmw-osk-static { - height: fit-content !important; - text-align: center !important; - border: solid 1px var(--keyman-blue) !important; -} - -.kmw-osk-static table { - display: flex !important; - flex-direction: row !important; - align-items: center !important; - justify-content: center !important; - width: 100% !important; -} - -#kmw-osk-help-page > table > tbody > tr > td > .row { - --bs-gutter-x: 0 !important; -} - -.kmw-title-bar { - background-color: #2EADD3 !important; - border-radius: 0 !important; - height: fit-content !important; -} - -#keyboard_europeanlatin_help p, .kmw-osk-static p { - display: flex !important; - justify-content: end !important; - position: relative !important; - right: 0 !important; - top: 0 !important; -} - -.kmw-key-square { - z-index: 0 !important; -} - -.kmw-spacebar-caption { - color: gray !important; -} - -.desktop .kmw-osk-frame, .desktop .kmw-osk-inner-frame, .desktop .kmw-key-layer-group { - background-color: #95C6D6 !important; -} - -.desktop .kmw-key-default { - background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #EEEFF0), color-stop(100%, #D3D3D9)); - background-image: -moz-linear-gradient(#EEEFF0,#D3D3D9); - background-color: #E0E0E4; -} - -.desktop .kmw-key-touched { - background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #B5B5B5), color-stop(100%, #93969B)); - background-image: -moz-linear-gradient(#B5B5B5, #93969B) !important; - background-color: #B5B5B5; - } - -.desktop .kmw-key-shift{ - background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #DBDBDB), color-stop(100%, #C0C0C4)); - background-image: -moz-linear-gradient(#DBDBDB, #C0C0C4) !important; - background-color: #DBDBDB; -} - - .desktop .kmw-key-shift-on { - background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #B5B5B5), color-stop(100%, #93969B)); - background-image: -moz-linear-gradient(#B5B5B5, #93969B) !important; - background-color: #93969B; - } - - .desktop .kmw-key-shift .kmw-key-text, .desktop .kmw-key-shift-on .kmw-key-text { color: gray; font-size: 0.9em !important; text-shadow: 0 1px 1px #fff;} - .desktop .kmw-key-shift .kmw-key-text, .desktop .kmw-key-shift-on .kmw-key-text { top: 10%; } - .desktop .kmw-key-label { top: 5%; } - .desktop .kmw-key-label { left: 10%; } - .desktop .kmw-key-default .kmw-key-text { top: 25%; } - .desktop .kmw-footer, .desktop .kmw-title-bar { background-color: #2EADD3 !important; display: none;} - .desktop .kmw-title-bar div{min-height: 100%;} - .desktop .kmw-footer-caption a { color: white !important; } - .kmw-osk-frame, .kmw-osk-inner-frame { border-color: #2EADD3 !important; } - .kmw-key-shift, .kmw-key-shift-on { border-width: 2px !important; } - .kmw-key-shift, .kmw-key-shift-on { border-radius: 6px !important; } - .kmw-key-shift, .kmw-key-shift-on { border-color: #95C6D6 !important; } - .kmw-key-default { border-width: 2px !important; } - .kmw-key-default { border-radius: 6px !important; } - .kmw-key-default { border-color: #95C6D6 !important; } - .kmw-key-label { color: #2EADD3 !important; } - .kmw-key-label { top: 10% !important; } - .kmw-key-label { left: 15% !important; } - .kmw-key-default { - color: #313149; - } - -#keymandesktop p { - font-size: 11pt; - font-weight: bold; - text-align: center; -} - -@media all and (min-width: 1320px) { - ins.adsbygoogle { - display: inline-block !important; - height: 600px; - position: absolute; - right: 16px; - top: 120px; - width: 160px; - } -} - -.desktop .kmw-keyboard-dari_clra .kmw-key-default .kmw-key-text { - top: -33%; -} +/* Desktop browser CSS rules */ + +/* +====================== +==Universal Elements== +====================== +*/ + + #kmw_controls{ + border-top-left-radius: 8px; + border-top-right-radius: 8px; + -moz-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); + } + + #kmw_btn_osk{ + border-top-right-radius: 10px; + } + + #kmw_controls_start{ + border-top-left-radius: 10px; + } + +textarea { + height:260px; + width:554px; + float:left; + margin: 0px 10px 10px; + color:black; + font-size:16px; + font-family:SindhiWeb,Verdana,GeezWeb,LaoWeb,TibetanWeb,MyanmarWeb,SinhalaWeb,TamilWeb,KhmerWeb,LatinWeb,OriyaWeb,EgyptianWeb !important; + } + +form { + padding-right:10px; + float:left; + } +#messageContainer { + float:left; + width:80%; +} +/* +====================== +==Keyboard Examples== +====================== +*/ + +#example,#help { + margin: 5px 0px; + text-align: center; +} + +#example { + visibility: hidden; + width: 100%; + min-height: 10px; + max-height: 45px; + display: flex; + justify-content: center; + align-items: center; + padding-top: 5px; +} + +#example a { + padding-left: 10px; +} + +.highlightKeys kbd { + border: solid 1px #808080; + border-radius: 4px; + background: #cccccf; + color: black; + font-family: Verdana; + font-weight: normal; + min-width: 16px; + display: inline-block; + box-shadow: 2px 2px 1px rgba(128, 128, 128, 0.3); + margin-right: 4px; +} + +.highlightKeys kbd.space { + min-width: 64px; +} + +/* +====================== +==Keyboard Styling== +====================== +*/ +.desktop, .kmw-osk-frame { + display: block !important; + position: static !important; + width: 100% !important; + height: 100% !important; + max-width: 100% !important; + max-height: 100% !important; + border-radius: 0; +} + +.kmw-help-osk-frame { + height: 100% !important; + scroll-behavior: smooth !important; + scrollbar-width: thin; + overflow-x: hidden !important; + overflow-y: scroll !important; + text-align: center !important; +} + +.kmw-osk-static { + height: fit-content !important; + text-align: center !important; + border: solid 1px var(--keyman-blue) !important; +} + +.kmw-osk-static table { + display: flex !important; + flex-direction: row !important; + align-items: center !important; + justify-content: center !important; + width: 100% !important; +} + +#kmw-osk-help-page > table > tbody > tr > td > .row { + --bs-gutter-x: 0 !important; +} + +.kmw-title-bar { + background-color: #2EADD3 !important; + border-radius: 0 !important; + height: fit-content !important; +} + +#keyboard_europeanlatin_help p, .kmw-osk-static p { + display: flex !important; + justify-content: end !important; + position: relative !important; + right: 0 !important; + top: 0 !important; +} + +.kmw-key-square { + z-index: 0 !important; +} + +.kmw-spacebar-caption { + color: gray !important; +} + +.desktop .kmw-osk-frame, .desktop .kmw-osk-inner-frame, .desktop .kmw-key-layer-group { + background-color: #95C6D6 !important; +} + +.desktop .kmw-key-default { + background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #EEEFF0), color-stop(100%, #D3D3D9)); + background-image: -moz-linear-gradient(#EEEFF0,#D3D3D9); + background-color: #E0E0E4; +} + +.desktop .kmw-key-touched { + background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #B5B5B5), color-stop(100%, #93969B)); + background-image: -moz-linear-gradient(#B5B5B5, #93969B) !important; + background-color: #B5B5B5; + } + +.desktop .kmw-key-shift{ + background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #DBDBDB), color-stop(100%, #C0C0C4)); + background-image: -moz-linear-gradient(#DBDBDB, #C0C0C4) !important; + background-color: #DBDBDB; +} + + .desktop .kmw-key-shift-on { + background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #B5B5B5), color-stop(100%, #93969B)); + background-image: -moz-linear-gradient(#B5B5B5, #93969B) !important; + background-color: #93969B; + } + + .desktop .kmw-key-shift .kmw-key-text, .desktop .kmw-key-shift-on .kmw-key-text { color: gray; font-size: 0.9em !important; text-shadow: 0 1px 1px #fff;} + .desktop .kmw-key-shift .kmw-key-text, .desktop .kmw-key-shift-on .kmw-key-text { top: 10%; } + .desktop .kmw-key-label { top: 5%; } + .desktop .kmw-key-label { left: 10%; } + .desktop .kmw-key-default .kmw-key-text { top: 25%; } + .desktop .kmw-footer, .desktop .kmw-title-bar { background-color: #2EADD3 !important; display: none;} + .desktop .kmw-title-bar div{min-height: 100%;} + .desktop .kmw-footer-caption a { color: white !important; } + .kmw-osk-frame, .kmw-osk-inner-frame { border-color: #2EADD3 !important; } + .kmw-key-shift, .kmw-key-shift-on { border-width: 2px !important; } + .kmw-key-shift, .kmw-key-shift-on { border-radius: 6px !important; } + .kmw-key-shift, .kmw-key-shift-on { border-color: #95C6D6 !important; } + .kmw-key-default { border-width: 2px !important; } + .kmw-key-default { border-radius: 6px !important; } + .kmw-key-default { border-color: #95C6D6 !important; } + .kmw-key-label { color: #2EADD3 !important; } + .kmw-key-label { top: 10% !important; } + .kmw-key-label { left: 15% !important; } + .kmw-key-default { + color: #313149; + } + +#keymandesktop p { + font-size: 11pt; + font-weight: bold; + text-align: center; +} + +@media all and (min-width: 1320px) { + ins.adsbygoogle { + display: inline-block !important; + height: 600px; + position: absolute; + right: 16px; + top: 120px; + width: 160px; + } +} + +.desktop .kmw-keyboard-dari_clra .kmw-key-default .kmw-key-text { + top: -33%; +} diff --git a/cdn/dev/css/kmw-header.css b/cdn/dev/css/kmw-header.css index 09bbb23..da9c3f9 100644 --- a/cdn/dev/css/kmw-header.css +++ b/cdn/dev/css/kmw-header.css @@ -1,867 +1,867 @@ -:root { - --box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; - --keyman-orange: #FC7200; - --keyman-red: #B92034; - --keyman-blue: #2EADD3; -} - -* { - letter-spacing: .05rem; - font-weight: 400; -} - -hr { - margin: 0; -} - -header > div > img { - width: 100%; - display: block; - height: 5px; -} - -#searchDropdownMenu { - padding: 10px; - margin: 0; -} - -.main-header { - display: grid; - grid-template-columns: 1fr 1fr; - height: 75px; - padding: 0 10px; - box-shadow: var(--box-shadow); -} - -/* Left side of Header: - Search - Keyboard dropdown -*/ - -.left-header { - display: flex; - align-items: center; -} - -.left-header img { - margin-right: 10px; -} - -/* -Language Search box -*/ -#searchBar { - position: relative; - width: 550px; - margin-right: 10px; -} - -#searchIcons { - position: absolute; - right: 5px; - top: 12px; - border-left: 1px solid gray; - background-color: white; -} - -#searchIcons > * { - margin-right: 10px; - padding-left: 15px; - opacity: 50%; -} - -#searchIcons > *:hover { - padding-left: 15px; - opacity: 100%; -} - -#magnifyingGlassIcon { - display: inline; -} - -#clearSearchIcon { - display: none; -} - -#searchBar #searchInput { - height: 50px; - width: 100%; - text-indent: 10px; - border-radius: 15px; - text-align: left; - font-family: inherit !important; - box-shadow: none; -} - -#searchInput:hover, #searchInput:focus { - border: 1px solid var(--keyman-orange); -} - -#searchDropdownMenu { - width: 100%; - max-height: 600px; - overflow: auto; - scrollbar-width: thin; -} - -#searchDropdownMenu hr { - margin: 15px 0; -} - -/* Enable keyboard Animation */ -.kb-icon-plus-animate { - animation: plustoTickToMinus 2s forwards; -} - -@keyframes plustoTickToMinus { - 0% { - content: "+"; - transform: scale(1); - } - 30% { - color: lime; - content: "โœ“"; - transform: scale(1.5); - } - 60% { - color: lime; - content: "โœ“"; - transform: scale(1.3); - } - 100% { - content: "-"; - transform: scale(1); - } -} - -/* Instruction on dropdown */ -.instruction-title, .keyboard-title { - width: 100%; -} - -.instruction-title p, .keyboard-title { - font-weight: 500; - font-size: 16px; - text-align: center; -} - -/* Map and Most download */ -.left-header .dropdown-menu .top-row #worldMap { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - margin: 10px 10px !important; -} - -#worldMap span { - opacity: 50%; -} - -#worldMap span:hover { - opacity: 100%; - cursor: pointer; -} - -#KeymanWebControl #kmw_controls -{ - display: flex !important; - flex-direction: row; - justify-content: space-evenly; - border-radius: 20px; - box-shadow: var(--box-shadow); - height: 35px; - padding: 5px; -} - -#KeymanWebControl .kmw_button, -#keymanWebControl .kmw_button_disabled, -#KeymanWebControl .kmw_button_selected -{ - width: fit-content !important; - background: none !important; - height: 0 !important; -} - -#KeymanWebControl #kmw_controls_start, -#KeymanWebControl #kmw_btn_osk, -.kmw_bar, #kmw_controls_end { - display: none; -} - -#KeymanWebControl .kmw_language { - padding: 3px; -} - -#kmw_control_keyboards { - width: fit-content; -} - -#kmw_selector_regions { - height: 100%; - overflow: hidden; - position: relative; -} - -.kmw_selector_region { - overflow-y: scroll; - overflow-x: hidden; - scrollbar-width: thin; - height: 600px; -} - -/* Search Dropdown cards */ -#languageSearchList > * { - margin-bottom: 5px; -} - -#languageSearchList > div:hover { - border: 1px solid var(--keyman-orange); - margin: 3px; -} - -.card-wrap { - box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;; - padding: 10px; - border-radius: 10px; - letter-spacing: .05rem; - overflow: hidden; - margin-bottom: 5px; -} - -.card-wrap.disabled { - opacity: 0.5; - pointer-events: none; - position: relative; -} - -.card-wrap.disabled .kb-icon-plus { - pointer-events: auto; - opacity: 1; - position: absolute; - right: 15px; - z-index: 1; -} - -.kb-icon-plus { - transition: 0.5s ease; -} - -.kb-icon-plus.animate { - color: green; -} - -.keyboard-id { - font-size: 12px; - margin-bottom: 10px; - color: #006622; -} - -.card-wrap h6 { - opacity: 75%; - font-size: 12px; - margin: 0 0 0.35rem; -} - -.keyboard-description { - color: gray; -} - -.keyboard-specs { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; -} - -.keyboard-specs .platform { - display: flex; - flex-direction: row; -} - -.keyboard-specs .platform span, -.keyboard-content .keyboard-platforms .platform span { - font-size: 0px; - width: 15px; - height: 20px; - margin: 0; -} - -.card-wrap .monthly-download { - opacity: 75%; -} - -.card-header { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - margin-bottom: 8px; -} - -.card-header h4 { - color: #0000EE; - font-weight: 400; - font-size: large; - margin: 0; -} - -.card-header h4 span { - color: black; -} - -.card-header p { - margin: 0; - position: relative; - float: right; - font-weight: 200; - font-size: medium; - color: var(--keyman-red); -} - -/* Pagination */ -#searchDropdownMenu .bottom-row-search { - background-color: white; - align-items: center; - justify-content: center; - width: fit-content; - border-radius: 10px; - width: 100%; - bottom: 0; - text-align: center; - box-shadow: rgba(9, 30, 66, 0.25) 0px 1px 1px, rgba(9, 30, 66, 0.13) 0px 0px 1px 1px; -} - -.bottom-row-search > * { - margin: 10px; - cursor: pointer; -} - -/* Selected Keyboard Menu */ -#keyboardSelectionButton { - z-index: 3; -} - -.scroll-wrapper-keyboard-tab { - width: 350px; - height: 35px; - position: relative; -} - -#keyboardSelection { - display: flex; - flex-direction: column; - text-align: center; - width: 0; - height: 100%; - background-color: white; - color: black; - box-shadow: var(--box-shadow); - overflow-y: scroll; - scrollbar-width: none; - transition: all 1s ease-in-out; - margin-left: -10px; - border-radius: 10px; - z-index: 0; - white-space: nowrap; - text-indent: 15px; -} - -#keyboardSelection.open { - position: relative; - width: 400px; - height: fit-content; - padding: 0 0 10px; - z-index: 2; -} - -#keyboardSelection p { - margin: 0; - height: 25px; - width: 100%; -} - -.kb-item-header, .kb-item-footer { - display: flex; - align-items: center; - justify-content: center; - height: 30px; - font-weight: 500; - margin: 5px 0; -} - -.kb-item-header { - border-bottom: 1px solid gray; -} - -.kb-item-footer { - border-top: 1px solid gray; - cursor: pointer; -} - -.kb-item { - width: 100%; - max-height: fit-content; - height: 38px; - display: flex; - flex-direction: row; - justify-content: space-between; - padding: 5px; -} - -.kb-item:hover { - cursor: pointer; - background-color: var(--keyman-orange); - color: white; -} - -.kb-item span { - width: 50%; - text-wrap: wrap; - align-self: center; -} - -.keyboard-configs { - width: 50%; - height: fit-content; - display: grid; - grid-template-columns: repeat(4, 1fr); - list-style-type: none; - padding: 2px 0 0; -} - -::-webkit-scrollbar:horizontal { - height: 5px; -} - -::-webkit-scrollbar-thumb:horizontal { - background: #2c7be5; - border-radius: 6px; -} - -::-webkit-scrollbar-track:horizontal { - background: #f1f1f1; -} - -.btn-keyman-orange { - background-color: var(--keyman-orange) !important; - color: white !important; -} - -.keyboard-details { - position: absolute; - width: 400px; - height: fit-content; - background-color: white; - color: black; - box-shadow: var(--box-shadow); - border-radius: 20px; - padding: 10px; - z-index: 2; -} - -.keyboard-content-wrapper { - margin-top: 10px; -} - -.keyboard-content { - width: max-content; - list-style-type: none; - padding: 0; - text-align: left; - display: flex; - flex-direction: column; -} - -.keyboard-content > * { - margin: 5px 0px; -} - -.keyboard-content .keyboard-platforms .platform { - display: flex; - flex-direction: row; -} - -.keyboard-content li .row .col:nth-child(2), -.keyboard-content li .row .col:nth-child(2) * { - text-align: center; - white-space: normal; - word-break: break-word; - width: 200px; - overflow: hidden; -} - -.keyboard-content li .row .col:nth-child(1) { - width: 200px; -} - -#removeLanguage { - cursor: pointer; -} - -.platform span { - background-repeat: no-repeat; - padding-left: 24px; - background-size: 18px; - display: block; - margin: 4px 0; -} - -.platform span:hover, .keyboard-configs li:hover{ - cursor: help; -} - -.platform .platform-windows { - background-image: url('/cdn/dev/img/platforms/icon-windows.png'); -} - -.platform .platform-macos { - background-image: url('/cdn/dev/img/platforms/icon-macos.png'); -} - -.platform .platform-linux { - background-image: url('/cdn/dev/img/platforms/icon-linux.png'); -} - -.platform .platform-android { - background-image: url('/cdn/dev/img/platforms/icon-android.png'); -} - -.platform .platform-ios { - background-image: url('/cdn/dev/img/platforms/icon-ios.png'); -} - -.platform .platform-desktopweb { - background-image: url('/cdn/dev/img/platforms/icon-desktopWeb.png'); -} - -.platform .platform-mobileweb { - background-image: url('/cdn/dev/img/platforms/icon-mobileWeb.png'); -} - -/* Limits of Keyboard Selection */ -.warning-container { - position: fixed; - height: 100vh; - width: 100%; - z-index: 1000; - top: 0; - left: 0; - display: flex; - justify-content: center; - align-items: center; -} - -.warning-content { - width: 500px; - display: flex; - flex-direction: column; - align-items: center; - background-color: white; - color: black; - text-align: center; - padding: 30px 30px 70px; - border-radius: 20px; - box-shadow: var(--box-shadow); -} - -.warning-cancel-btn { - width: 30px; - font-size: 20px; - opacity: 50%; - align-self: flex-end; - background-color: transparent; - border: none; - margin-bottom: 10px; -} - -.warning-keyman-image { - width: 82px; - margin-bottom: 15px; -} - -.warning-text { - margin-bottom: 40px; - font-size: 18px; -} - -.warning-accept-btn { - background-color: var(--keyman-orange); - border: none; - border-radius: 5px; - width: 200px; - padding: 14px; - color: white; - box-shadow: var(--box-shadow); -} - -/* Middle of the header */ -.middle-header { - display: flex; - justify-content: center; - align-items: center; -} - -.middle-header i, .right-header i { - font-size: 24px; - opacity: 50%; -} - -.middle-header i:hover { - opacity: 100%; - cursor: pointer; - color: var(--keyman-red); -} - -/* Right side of the header: - Tools - Hamburger menu -*/ - -.right-header { - display: grid; - grid-template-columns: 80% 20%; - width: 100%; - justify-items: right; - align-items: center; - margin-right: 0; -} - -.right-header i:hover { - opacity: 100%; - cursor: pointer; - color: var(--keyman-blue); -} - -/* Font size slider + Hide/show keyboard */ -.tool-container { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; -} - -.tool-container > * { - margin: 10px; -} - -.font-size-container { - display: flex; - flex-direction: row; - align-items: center; -} - -.font-size-slider { - display: flex; - flex-direction: column; - justify-content: end; - align-items: center; - height: 60px; -} - -#fontSizeRange[type=range] { - -webkit-appearance: none; - margin: 10px 0; - width: 100%; -} - - -.font-large { - font-size: 20px; -} - -input[type="range"] { - width: 100px; - background-color: transparent; -} - -input[type="range"]::-webkit-slider-runnable-track { - height: 3px; - background: rgb(107, 107, 107); - border-radius: 10px; -} - -input[type="range"]::-webkit-slider-thumb { - border-radius: 50%; - height: 20px; - width: 20px; - position: relative; - bottom: 6px; - background-size: 50%; - box-shadow: 0px 3px 5px 0px rgba(0, 0, 0, 0.4); - cursor: grab; -} - -#fontSizeRange[type=range]::-webkit-slider-runnable-track { - width: 100%; - cursor: pointer; - transform: 0.2s; - box-shadow: var(--box-shadow); - background: gray; - border-radius: 25px; -} - -#fontSizeRange[type=range]::-webkit-slider-thumb { - height: 10px; - width: 20px; - border-radius: 7px; - background: var(--keyman-blue); - cursor: pointer; - -webkit-appearance: none; - box-shadow: 0px 0px 5px rgb(143, 143, 143); - margin-top: 3px; -} - -#burgerMenu ul { - box-shadow: var(--box-shadow); -} - -#burgerMenu ul:hover { - cursor: pointer; -} - -.dropdown-grid-container { - display: grid; - grid-template-columns: 1fr 1fr; - grid-template-rows: 1fr; -} - -.dropdown-item:active { - background-color: transparent !important; -} - -#burgerMenu ul li { - align-items: center; - width: 300px; - border-bottom: 1px solid rgb(196, 196, 196); - margin-top: 10px; -} - -#burgerMenu ul li::after { - background-color: orange; -} - -#burgerMenu ul li p:hover { - opacity: 100%; -} - -#burgerMenu ul li p { - width: 90%; - white-space: normal; - position: relative; - left: 40px; - font-size: 14px; - opacity: 50%; - margin-top: 10px; -} - -#burgerMenu ul li a { - text-decoration: none; - color: black; - font-style: bold; - font-size: 16px; -} - -#burgerMenu ul li i, #burgerMenu ul li img { - margin: 0 10px; - font-size: 16px; - width: 18px; - opacity: 100%; - color: var(--keyman-orange) -} - -#burgerMenu button i:hover { - cursor: pointer; -} - -.kmw-socials, .kmw-version, .sil-logo { - font-size: 14px; -} - -.kmw-socials { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - padding: 10px; -} - -.kmw-socials-icons { - display: grid; - grid-template-columns: 1fr 1fr 1fr; - justify-content: center; - align-items: center; - gap: 10px; -} - -.kmw-socials-icons > a { - text-decoration: none; - color: black; - opacity: 50%; - position: relative; -} - -.kmw-socials-icons > a:hover { - opacity: 100%; -} - -@font-face { - font-family: "social-logos"; - src: url("../../fonts/social-logos.ttf"), - url("social-logos.woff2") format("woff2"), - url("social-logos.woff") format("woff"); - font-weight: normal; - font-style: normal; -} - -[data-icon]:before { - font-family: "social-logos" !important; - content: attr(data-icon); - padding-right: 4px; - font-size: 16px; -} - -.kmw-version { - display: flex; - flex-direction: row; - justify-content: center; -} - -.sil-logo { - display: flex; - flex-direction: column; - align-items: center; -} - -/* Animation */ - -.keyboardTab-animation { - animation: keyboardTab 1s; -} -.keyboardSelection-animation { - animation: keyboardSelection 1s ease-in; -} - -@keyframes keyboardSelection { - 0% { - transform: translateY(-5px); - } - 50% { - transform: translateY(-3px); - } - 75% { - transform: translateY(-1px); - } - 100% { - transform: translateY(0); - } -} - -@keyframes keyboardTab { - from { - opacity: 50%; - } - to { - opacity: 100%; - } +:root { + --box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; + --keyman-orange: #FC7200; + --keyman-red: #B92034; + --keyman-blue: #2EADD3; +} + +* { + letter-spacing: .05rem; + font-weight: 400; +} + +hr { + margin: 0; +} + +header > div > img { + width: 100%; + display: block; + height: 5px; +} + +#searchDropdownMenu { + padding: 10px; + margin: 0; +} + +.main-header { + display: grid; + grid-template-columns: 1fr 1fr; + height: 75px; + padding: 0 10px; + box-shadow: var(--box-shadow); +} + +/* Left side of Header: + Search + Keyboard dropdown +*/ + +.left-header { + display: flex; + align-items: center; +} + +.left-header img { + margin-right: 10px; +} + +/* +Language Search box +*/ +#searchBar { + position: relative; + width: 550px; + margin-right: 10px; +} + +#searchIcons { + position: absolute; + right: 5px; + top: 12px; + border-left: 1px solid gray; + background-color: white; +} + +#searchIcons > * { + margin-right: 10px; + padding-left: 15px; + opacity: 50%; +} + +#searchIcons > *:hover { + padding-left: 15px; + opacity: 100%; +} + +#magnifyingGlassIcon { + display: inline; +} + +#clearSearchIcon { + display: none; +} + +#searchBar #searchInput { + height: 50px; + width: 100%; + text-indent: 10px; + border-radius: 15px; + text-align: left; + font-family: inherit !important; + box-shadow: none; +} + +#searchInput:hover, #searchInput:focus { + border: 1px solid var(--keyman-orange); +} + +#searchDropdownMenu { + width: 100%; + max-height: 600px; + overflow: auto; + scrollbar-width: thin; +} + +#searchDropdownMenu hr { + margin: 15px 0; +} + +/* Enable keyboard Animation */ +.kb-icon-plus-animate { + animation: plustoTickToMinus 2s forwards; +} + +@keyframes plustoTickToMinus { + 0% { + content: "+"; + transform: scale(1); + } + 30% { + color: lime; + content: "โœ“"; + transform: scale(1.5); + } + 60% { + color: lime; + content: "โœ“"; + transform: scale(1.3); + } + 100% { + content: "-"; + transform: scale(1); + } +} + +/* Instruction on dropdown */ +.instruction-title, .keyboard-title { + width: 100%; +} + +.instruction-title p, .keyboard-title { + font-weight: 500; + font-size: 16px; + text-align: center; +} + +/* Map and Most download */ +.left-header .dropdown-menu .top-row #worldMap { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + margin: 10px 10px !important; +} + +#worldMap span { + opacity: 50%; +} + +#worldMap span:hover { + opacity: 100%; + cursor: pointer; +} + +#KeymanWebControl #kmw_controls +{ + display: flex !important; + flex-direction: row; + justify-content: space-evenly; + border-radius: 20px; + box-shadow: var(--box-shadow); + height: 35px; + padding: 5px; +} + +#KeymanWebControl .kmw_button, +#keymanWebControl .kmw_button_disabled, +#KeymanWebControl .kmw_button_selected +{ + width: fit-content !important; + background: none !important; + height: 0 !important; +} + +#KeymanWebControl #kmw_controls_start, +#KeymanWebControl #kmw_btn_osk, +.kmw_bar, #kmw_controls_end { + display: none; +} + +#KeymanWebControl .kmw_language { + padding: 3px; +} + +#kmw_control_keyboards { + width: fit-content; +} + +#kmw_selector_regions { + height: 100%; + overflow: hidden; + position: relative; +} + +.kmw_selector_region { + overflow-y: scroll; + overflow-x: hidden; + scrollbar-width: thin; + height: 600px; +} + +/* Search Dropdown cards */ +#languageSearchList > * { + margin-bottom: 5px; +} + +#languageSearchList > div:hover { + border: 1px solid var(--keyman-orange); + margin: 3px; +} + +.card-wrap { + box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;; + padding: 10px; + border-radius: 10px; + letter-spacing: .05rem; + overflow: hidden; + margin-bottom: 5px; +} + +.card-wrap.disabled { + opacity: 0.5; + pointer-events: none; + position: relative; +} + +.card-wrap.disabled .kb-icon-plus { + pointer-events: auto; + opacity: 1; + position: absolute; + right: 15px; + z-index: 1; +} + +.kb-icon-plus { + transition: 0.5s ease; +} + +.kb-icon-plus.animate { + color: green; +} + +.keyboard-id { + font-size: 12px; + margin-bottom: 10px; + color: #006622; +} + +.card-wrap h6 { + opacity: 75%; + font-size: 12px; + margin: 0 0 0.35rem; +} + +.keyboard-description { + color: gray; +} + +.keyboard-specs { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; +} + +.keyboard-specs .platform { + display: flex; + flex-direction: row; +} + +.keyboard-specs .platform span, +.keyboard-content .keyboard-platforms .platform span { + font-size: 0px; + width: 15px; + height: 20px; + margin: 0; +} + +.card-wrap .monthly-download { + opacity: 75%; +} + +.card-header { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + margin-bottom: 8px; +} + +.card-header h4 { + color: #0000EE; + font-weight: 400; + font-size: large; + margin: 0; +} + +.card-header h4 span { + color: black; +} + +.card-header p { + margin: 0; + position: relative; + float: right; + font-weight: 200; + font-size: medium; + color: var(--keyman-red); +} + +/* Pagination */ +#searchDropdownMenu .bottom-row-search { + background-color: white; + align-items: center; + justify-content: center; + width: fit-content; + border-radius: 10px; + width: 100%; + bottom: 0; + text-align: center; + box-shadow: rgba(9, 30, 66, 0.25) 0px 1px 1px, rgba(9, 30, 66, 0.13) 0px 0px 1px 1px; +} + +.bottom-row-search > * { + margin: 10px; + cursor: pointer; +} + +/* Selected Keyboard Menu */ +#keyboardSelectionButton { + z-index: 3; +} + +.scroll-wrapper-keyboard-tab { + width: 350px; + height: 35px; + position: relative; +} + +#keyboardSelection { + display: flex; + flex-direction: column; + text-align: center; + width: 0; + height: 100%; + background-color: white; + color: black; + box-shadow: var(--box-shadow); + overflow-y: scroll; + scrollbar-width: none; + transition: all 1s ease-in-out; + margin-left: -10px; + border-radius: 10px; + z-index: 0; + white-space: nowrap; + text-indent: 15px; +} + +#keyboardSelection.open { + position: relative; + width: 400px; + height: fit-content; + padding: 0 0 10px; + z-index: 2; +} + +#keyboardSelection p { + margin: 0; + height: 25px; + width: 100%; +} + +.kb-item-header, .kb-item-footer { + display: flex; + align-items: center; + justify-content: center; + height: 30px; + font-weight: 500; + margin: 5px 0; +} + +.kb-item-header { + border-bottom: 1px solid gray; +} + +.kb-item-footer { + border-top: 1px solid gray; + cursor: pointer; +} + +.kb-item { + width: 100%; + max-height: fit-content; + height: 38px; + display: flex; + flex-direction: row; + justify-content: space-between; + padding: 5px; +} + +.kb-item:hover { + cursor: pointer; + background-color: var(--keyman-orange); + color: white; +} + +.kb-item span { + width: 50%; + text-wrap: wrap; + align-self: center; +} + +.keyboard-configs { + width: 50%; + height: fit-content; + display: grid; + grid-template-columns: repeat(4, 1fr); + list-style-type: none; + padding: 2px 0 0; +} + +::-webkit-scrollbar:horizontal { + height: 5px; +} + +::-webkit-scrollbar-thumb:horizontal { + background: #2c7be5; + border-radius: 6px; +} + +::-webkit-scrollbar-track:horizontal { + background: #f1f1f1; +} + +.btn-keyman-orange { + background-color: var(--keyman-orange) !important; + color: white !important; +} + +.keyboard-details { + position: absolute; + width: 400px; + height: fit-content; + background-color: white; + color: black; + box-shadow: var(--box-shadow); + border-radius: 20px; + padding: 10px; + z-index: 2; +} + +.keyboard-content-wrapper { + margin-top: 10px; +} + +.keyboard-content { + width: max-content; + list-style-type: none; + padding: 0; + text-align: left; + display: flex; + flex-direction: column; +} + +.keyboard-content > * { + margin: 5px 0px; +} + +.keyboard-content .keyboard-platforms .platform { + display: flex; + flex-direction: row; +} + +.keyboard-content li .row .col:nth-child(2), +.keyboard-content li .row .col:nth-child(2) * { + text-align: center; + white-space: normal; + word-break: break-word; + width: 200px; + overflow: hidden; +} + +.keyboard-content li .row .col:nth-child(1) { + width: 200px; +} + +#removeLanguage { + cursor: pointer; +} + +.platform span { + background-repeat: no-repeat; + padding-left: 24px; + background-size: 18px; + display: block; + margin: 4px 0; +} + +.platform span:hover, .keyboard-configs li:hover{ + cursor: help; +} + +.platform .platform-windows { + background-image: url('/cdn/dev/img/platforms/icon-windows.png'); +} + +.platform .platform-macos { + background-image: url('/cdn/dev/img/platforms/icon-macos.png'); +} + +.platform .platform-linux { + background-image: url('/cdn/dev/img/platforms/icon-linux.png'); +} + +.platform .platform-android { + background-image: url('/cdn/dev/img/platforms/icon-android.png'); +} + +.platform .platform-ios { + background-image: url('/cdn/dev/img/platforms/icon-ios.png'); +} + +.platform .platform-desktopweb { + background-image: url('/cdn/dev/img/platforms/icon-desktopWeb.png'); +} + +.platform .platform-mobileweb { + background-image: url('/cdn/dev/img/platforms/icon-mobileWeb.png'); +} + +/* Limits of Keyboard Selection */ +.warning-container { + position: fixed; + height: 100vh; + width: 100%; + z-index: 1000; + top: 0; + left: 0; + display: flex; + justify-content: center; + align-items: center; +} + +.warning-content { + width: 500px; + display: flex; + flex-direction: column; + align-items: center; + background-color: white; + color: black; + text-align: center; + padding: 30px 30px 70px; + border-radius: 20px; + box-shadow: var(--box-shadow); +} + +.warning-cancel-btn { + width: 30px; + font-size: 20px; + opacity: 50%; + align-self: flex-end; + background-color: transparent; + border: none; + margin-bottom: 10px; +} + +.warning-keyman-image { + width: 82px; + margin-bottom: 15px; +} + +.warning-text { + margin-bottom: 40px; + font-size: 18px; +} + +.warning-accept-btn { + background-color: var(--keyman-orange); + border: none; + border-radius: 5px; + width: 200px; + padding: 14px; + color: white; + box-shadow: var(--box-shadow); +} + +/* Middle of the header */ +.middle-header { + display: flex; + justify-content: center; + align-items: center; +} + +.middle-header i, .right-header i { + font-size: 24px; + opacity: 50%; +} + +.middle-header i:hover { + opacity: 100%; + cursor: pointer; + color: var(--keyman-red); +} + +/* Right side of the header: + Tools + Hamburger menu +*/ + +.right-header { + display: grid; + grid-template-columns: 80% 20%; + width: 100%; + justify-items: right; + align-items: center; + margin-right: 0; +} + +.right-header i:hover { + opacity: 100%; + cursor: pointer; + color: var(--keyman-blue); +} + +/* Font size slider + Hide/show keyboard */ +.tool-container { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; +} + +.tool-container > * { + margin: 10px; +} + +.font-size-container { + display: flex; + flex-direction: row; + align-items: center; +} + +.font-size-slider { + display: flex; + flex-direction: column; + justify-content: end; + align-items: center; + height: 60px; +} + +#fontSizeRange[type=range] { + -webkit-appearance: none; + margin: 10px 0; + width: 100%; +} + + +.font-large { + font-size: 20px; +} + +input[type="range"] { + width: 100px; + background-color: transparent; +} + +input[type="range"]::-webkit-slider-runnable-track { + height: 3px; + background: rgb(107, 107, 107); + border-radius: 10px; +} + +input[type="range"]::-webkit-slider-thumb { + border-radius: 50%; + height: 20px; + width: 20px; + position: relative; + bottom: 6px; + background-size: 50%; + box-shadow: 0px 3px 5px 0px rgba(0, 0, 0, 0.4); + cursor: grab; +} + +#fontSizeRange[type=range]::-webkit-slider-runnable-track { + width: 100%; + cursor: pointer; + transform: 0.2s; + box-shadow: var(--box-shadow); + background: gray; + border-radius: 25px; +} + +#fontSizeRange[type=range]::-webkit-slider-thumb { + height: 10px; + width: 20px; + border-radius: 7px; + background: var(--keyman-blue); + cursor: pointer; + -webkit-appearance: none; + box-shadow: 0px 0px 5px rgb(143, 143, 143); + margin-top: 3px; +} + +#burgerMenu ul { + box-shadow: var(--box-shadow); +} + +#burgerMenu ul:hover { + cursor: pointer; +} + +.dropdown-grid-container { + display: grid; + grid-template-columns: 1fr 1fr; + grid-template-rows: 1fr; +} + +.dropdown-item:active { + background-color: transparent !important; +} + +#burgerMenu ul li { + align-items: center; + width: 300px; + border-bottom: 1px solid rgb(196, 196, 196); + margin-top: 10px; +} + +#burgerMenu ul li::after { + background-color: orange; +} + +#burgerMenu ul li p:hover { + opacity: 100%; +} + +#burgerMenu ul li p { + width: 90%; + white-space: normal; + position: relative; + left: 40px; + font-size: 14px; + opacity: 50%; + margin-top: 10px; +} + +#burgerMenu ul li a { + text-decoration: none; + color: black; + font-style: bold; + font-size: 16px; +} + +#burgerMenu ul li i, #burgerMenu ul li img { + margin: 0 10px; + font-size: 16px; + width: 18px; + opacity: 100%; + color: var(--keyman-orange) +} + +#burgerMenu button i:hover { + cursor: pointer; +} + +.kmw-socials, .kmw-version, .sil-logo { + font-size: 14px; +} + +.kmw-socials { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 10px; +} + +.kmw-socials-icons { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + justify-content: center; + align-items: center; + gap: 10px; +} + +.kmw-socials-icons > a { + text-decoration: none; + color: black; + opacity: 50%; + position: relative; +} + +.kmw-socials-icons > a:hover { + opacity: 100%; +} + +@font-face { + font-family: "social-logos"; + src: url("../../fonts/social-logos.ttf"), + url("social-logos.woff2") format("woff2"), + url("social-logos.woff") format("woff"); + font-weight: normal; + font-style: normal; +} + +[data-icon]:before { + font-family: "social-logos" !important; + content: attr(data-icon); + padding-right: 4px; + font-size: 16px; +} + +.kmw-version { + display: flex; + flex-direction: row; + justify-content: center; +} + +.sil-logo { + display: flex; + flex-direction: column; + align-items: center; +} + +/* Animation */ + +.keyboardTab-animation { + animation: keyboardTab 1s; +} +.keyboardSelection-animation { + animation: keyboardSelection 1s ease-in; +} + +@keyframes keyboardSelection { + 0% { + transform: translateY(-5px); + } + 50% { + transform: translateY(-3px); + } + 75% { + transform: translateY(-1px); + } + 100% { + transform: translateY(0); + } +} + +@keyframes keyboardTab { + from { + opacity: 50%; + } + to { + opacity: 100%; + } } \ No newline at end of file diff --git a/cdn/dev/css/kmw-mobile.css b/cdn/dev/css/kmw-mobile.css index 6c72d31..8d8eb6d 100644 --- a/cdn/dev/css/kmw-mobile.css +++ b/cdn/dev/css/kmw-mobile.css @@ -1,166 +1,166 @@ -/* KMW LIVE CSS for iPhone and other mobiles */ - -/* -====================== -==Universal Elements== -====================== -*/ - -:root { - --mobile-font-size: 12px; - --mobile-search-max-width: 250px; - --mobile-search-min-width: 50px; -} - -html { - overflow-y: scroll; - overflow-x: hidden; -} - -body { - width:100%;height:100%; - font-family: Verdana, Arial, Helvetica, sans-serif; - color:#2D2C2C; - background-color: #eeeeee; - margin:0px; - } - -a { - text-decoration:none; - color: #AD4A28; - } - -a:hover { - text-decoration:underline; - } - -h3 { - font-size:18px; - } - -p { - font-size:13px; - line-height:1.5em; - } - -/* -==================== -==Content Elements== -==================== -*/ - -/* KMW Main App */ -#app { - width: 100%; - margin: 0px; -} - -#KeymanWebControl { - display: none; -} - -#exampleBox, #example { - display: none; -} - -.main-header { - width: 100%; - grid-template-columns: 2fr 1fr; -} - -.left-header { - width: 70vw; -} - -.left-header img { - display: none; -} - -.right-header { - grid-template-columns: 50% 50%; -} - -.right-header { - width: 30vw; -} - -/* -Language Search box -*/ - -#searchBar { - width: 50%; -} - -#searchInput:focus, #searchDropdownMenu, #keyboardSelection:active { - width: var(--mobile-search-max-width) !important; -} - -#textArea { - height: 45vh !important; -} - -.mobile-font-size-container { - display: flex; - flex-direction: row; - position: absolute; - right: 50px; - top: 80px; - width: 150px; - background: white; - border: 1px solid black; - padding: 10px; - border-radius: 10px; -} - -/* Additional rules for portrait orientation */ -@media only screen and (orientation: portrait) { - - #message { - height: 170px; - } - - #messageContainer { - float: left; - width: 80%; - height: 40%; - } -} - -/* Additional rules for landscape orientation */ -@media only screen and (orientation: landscape) { - - #messageContainer { - float: left; - width: 85%; - height: 50%; - } - #message { - height: 50%; - } - #buttons { - margin: 4px 15px 4px 0; - } - #font { - display: none; - } -} - -/* -====================== -==Keyboard Styling== -====================== -*/ - -#kmw-language-menu p { - color: #000 !important; -} - -#kmw-language-menu .selected { - background-color: gray !important; -} - -.phone .kmw-keyboard-dari_clra .kmw-key-default .kmw-key-text { - top: -33%; - font-size: 0.8em !important; -} +/* KMW LIVE CSS for iPhone and other mobiles */ + +/* +====================== +==Universal Elements== +====================== +*/ + +:root { + --mobile-font-size: 12px; + --mobile-search-max-width: 250px; + --mobile-search-min-width: 50px; +} + +html { + overflow-y: scroll; + overflow-x: hidden; +} + +body { + width:100%;height:100%; + font-family: Verdana, Arial, Helvetica, sans-serif; + color:#2D2C2C; + background-color: #eeeeee; + margin:0px; + } + +a { + text-decoration:none; + color: #AD4A28; + } + +a:hover { + text-decoration:underline; + } + +h3 { + font-size:18px; + } + +p { + font-size:13px; + line-height:1.5em; + } + +/* +==================== +==Content Elements== +==================== +*/ + +/* KMW Main App */ +#app { + width: 100%; + margin: 0px; + } + +#KeymanWebControl { + display: none; + } + +#exampleBox, #example { + display: none; +} + +.main-header { + width: 100%; + grid-template-columns: 2fr 1fr; +} + +.left-header { + width: 70vw; + } + +.left-header img { + display: none; +} + +.right-header { + grid-template-columns: 50% 50%; +} + +.right-header { + width: 30vw; +} + +/* +Language Search box +*/ + +#searchBar { + width: 50%; +} + +#searchInput:focus, #searchDropdownMenu, #keyboardSelection:active { + width: var(--mobile-search-max-width) !important; +} + +#textArea { + height: 45vh !important; +} + +.mobile-font-size-container { + display: flex; + flex-direction: row; + position: absolute; + right: 50px; + top: 80px; + width: 150px; + background: white; + border: 1px solid black; + padding: 10px; + border-radius: 10px; +} + + /* Additional rules for portrait orientation */ +@media only screen and (orientation: portrait) { + + #message { + height: 170px; + } + + #messageContainer { + float: left; + width: 80%; + height: 40%; + } +} + + /* Additional rules for landscape orientation */ +@media only screen and (orientation: landscape) { + + #messageContainer { + float: left; + width: 85%; + height: 50%; + } + #message { + height: 50%; + } + #buttons { + margin: 4px 15px 4px 0; + } + #font { + display: none; + } +} + +/* +====================== +==Keyboard Styling== +====================== +*/ + +#kmw-language-menu p { + color: #000 !important; +} + +#kmw-language-menu .selected { + background-color: gray !important; +} + +.phone .kmw-keyboard-dari_clra .kmw-key-default .kmw-key-text { + top: -33%; + font-size: 0.8em !important; +} diff --git a/cdn/dev/css/kmw-tablet.css b/cdn/dev/css/kmw-tablet.css index 4b1c4da..bd11ca5 100644 --- a/cdn/dev/css/kmw-tablet.css +++ b/cdn/dev/css/kmw-tablet.css @@ -1,550 +1,550 @@ -/* KMW LIVE CSS for iPad and other tablet devices */ - -/* -====================== -==Universal Elements== -====================== -*/ - -html { - overflow-y: scroll; - overflow-x: hidden; -} - -body { - width:100%; - font-family: Verdana, Arial, Helvetica, sans-serif; - color:#2D2C2C; - background-color: #eeeeee; - margin:0px; - } -section { - background-color: darkred; -} - -a { - text-decoration:none; - color: #AD4A28; - } - -a:hover { - text-decoration:underline; - } - -h3 { - font-size:18px; - } - -p { - font-size:13px; - line-height:1.5em; - } - -header, footer { - width:100%; - margin:0px auto; - /*clear: both;*/ - } - -hr { - display: none; - } - -.box { - -webkit-border-radius: 8px;-moz-border-radius: 8px; border-radius: 8px; - -moz-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); - } - -/* -=================== -==Header Elements== -=================== -*/ -header { - margin-top:0px; - } - -#headerLeft img { - display: block; /* default (inline) display inserts an unwanted bottom border */ - margin-top:0px; - height:60px; - /*-webkit-border-radius: 0px 0px 8px 8px; -moz-border-radius: 0px 0px 8px 8px; border-radius: 0px 0px 8px 8px;*/ - } - -header > div > img { - display: block; - width: 100%; - height: 8px; -} - - -/* Expanding the search box */ -/* @media screen and (940px <= width <= 1045px) { - .main-header { - grid-template-columns: 2fr 1fr 1fr; - } -} */ - -.main-header { - width: 100%; - grid-template-columns: 3fr 1fr; -} - -.left-header { - width: 70vw; -} - -.right-header { - width: 300px; -} - -/* -==================== -==Content Elements== -==================== -*/ -#content { - width: 100%; /* specific for tablet and mobile */ - margin: 0px auto; - background-color: #eeeeee; - /*min-height:375px;*/ - } - - -/* KMW Main App */ -#app { - /*float:left;*/ - /*height:330px;*/ - width:100%; /*710px; */ - margin: 0px;/*30px 15px 15px;*/ - } - -#KeymanWebControl { - display: none; - } - -#exampleBox, #example { - display: none; - } - -#messageContainer { - width: 80%; - float:left; - } - -#message { - height:195px; - width: 100%;/*554px;*/ - float:left; - margin: 10px; - color:black; - font-size:17px; - font-family:SindhiWeb,Verdana,GeezWeb,LaoWeb,TibetanWeb,MyanmarWeb,SinhalaWeb,TamilWeb,KhmerWeb,LatinWeb,OriyaWeb,EgyptianWeb !important; - } - -/* KMW App Buttons */ - -#buttons { - float: right; - width:15%; - margin: 0px 20px; - margin-top: -6px; - } - -#buttons div { - width:140px; - -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; - background: #fff; - border: 1px solid #888888; - margin: 0px 10px; - padding: 3px; - padding-top: 9px; - height: 41px; - line-height: 36px; - background-repeat: no-repeat; - background-position: center left; - } - -#buttons div:disabled { - cursor: default !important; - color: gray !important; - border-color: gray !important; - } - -#buttons p{ - margin-left: 41px; -} - -#search.links, #search{ - background-image:url('../img/btn_google_small.png'); - -} - -#search.linksOff{ - background-image:url('../img/btn_google_small_white.png'); -} - -#copy.links, #copy{ - background-image:url('../img/btn_copy_small.png'); - -} - -#copy.linksOff{ - background-image:url('../img/btn_copy_small_white.png'); -} - -#buttons div * { - display:inline; - } - -div.links { - cursor:pointer; - } - -div.linksOff { - cursor:default !important; - border: 1px solid #cccccc !important; - } - -div.linksOff * { - color: gray; - -webkit-user-select:none; - } - -/* Aside Elements */ - -aside { - display:none; - } - -#font-size{ - display: none; -} - -/* - -#font, -=================== -==Footer Elements== -=================== -*/ -.footer, footer { - display: none; - background-color: #6A2915; - height:50px; - left:0px; - bottom:0px; - position: fixed; - /* -webkit-border-radius: 8px 8px 0px 0px; -moz-border-radius: 8px 8px 0px 0px; border-radius: 8px 8px 0px 0px; */ - } - -nav ul { - list-style: none outside none; - width:90%; - margin:0px auto; - padding:15px 0px; - } - -nav li { - display:inline; - padding:20px 39px; - } - -nav a { - color:#eee; - font-family:Tahoma; - font-weight:bold; - font-size:10.7px; - } - -.messageBox { - box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -o-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -moz-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -khtml-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - background: #c4c4c4; - position: fixed; - left: 50%; - top: 20%; - z-index: 999 !important; - margin-left: -250px; - margin-top: -100px; - width: 500px; - height: 200px; -} - -.messageBox div { - width: 464px; - height: 134px; - left: 10px; - top: 10px; - padding: 8px; - font-size: 13px; - position: absolute; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 3px; - background: white; -} - -.messageBox button { - width:83px; - position: absolute; - right: 10px; - bottom: 4px; - background: #414141; - border-top: 1px solid #383838; - border-right: 1px solid #1F1F1F; - border-bottom: 1px solid #151515; - border-left: 1px solid #1F1F1F; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -o-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - color: white; - font: bold 12px Helvetica, Verdana, Arial, sans-serif; - text-shadow: 0px -1px 1px #1E2D4D; - text-align:center; - margin: 0 auto 6px; - padding: 3px; - } - -.messageBox button:disabled { - cursor: default !important; - color: gray !important; - -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -o-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; -} - -.messageBox button:hover { - -webkit-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -moz-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -ms-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -o-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - cursor: pointer; -} - -.messageBox button:active { - -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - -o-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; -} - -.progressBox { - box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -o-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -moz-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -khtml-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - background: #c4c4c4; - position: fixed; - left: 50%; - top: 20%; - z-index: 999; - margin-left: -200px; - margin-top: -54px; - width: 400px; - height: 54px; -} - -.progressBox div { - width: 364px; - height: 18px; - left: 10px; - top: 10px; - padding: 8px; - background: url('../img/wait.gif') no-repeat 354px 8px white; - font-size: 13px; - position: absolute; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 3px; -} - -/* Elements modified for tablet */ -#headerBackground { - width: 100%; - background-color:white; -} - -#headerLeft { - float: left; - margin-left: 28px; -} - -#headerRight { - text-align: right; - height: 40px; - float: right; - padding-bottom: 33px; - padding-right: 10px; -} - -#headerRight-beta { - display: block; - font-weight: bold; - color: red; - font-size: 16pt; - padding: 16px 12px 0; -} - -#headerRight-link { - padding: 0 12px 0; -} - - -#instructions { - margin:10px; - font:12pt Helvetica,Verdana,Arial,sans-serif; - color: white; -} - -/* Additional rules for portrait orientation */ -@media only screen and (orientation: landscape) { - #buttons{ - padding-top: 11px; - } - #buttons div { - margin: 4px 20px 10px 0px; - padding: 0px; - } - #font span:first-child{ - margin-left: 3px; - } - #font p{ - margin-left: 8px; - position: relative; - top: -5px; - } - #mobile-font{ - display: none; - width: 136px; - border-radius: 4px; - position: absolute; - left: 100%; - top: 136px; - margin-left: -170px; - text-align: center; - font-size: 24pt; - background: #fff; - } - - #mobile-increase{ - height: 40px; - line-height: 40px; - border-bottom: solid 1px #000; - } - - #mobile-decrease{ - height: 40px; - line-height: 40px; - } -} - -/* Additional rules for portrait orientation */ -@media only screen and (orientation: portrait) { - - #app { - width: 97%; - } - - #message { - height: 350px; - } - - #messageContainer { - width: 100%; - } - - #buttons { - clear:both; - width: 90%; - } - - #buttons div { - display: inline-block; - margin: 10px 10px 0; - width: 130px; - height: 40px; - } - - #font{ - position: relative; - top: 4px; - } - - #font span:first-child{ - margin-left: 3px; - } - - #font p{ - margin-left: 8px; - position: relative; - top: -4px; - } - - #mobile-font{ - display: none; - width: 301px; - position: absolute; - left: 50%; - top: 452px; - margin-left: -155px; - text-align: center; - font-size: 24pt; - } - - #mobile-increase{ - float: right; - width: 136px; - height: 53px; - line-height: 53px; - background: #fff; - border: 1px solid #888888; - border-radius: 4px; - } - - #mobile-decrease{ - float: right; - width: 136px; - height: 53px; - line-height: 53px; - background: #fff; - border: 1px solid #888888; - margin-right: 25px; - border-radius: 4px; - } -} - -/* -====================== -==Keyboard Styling== -====================== -*/ - -#kmw-language-menu p { - color: #000 !important; -} - -#kmw-language-menu .selected { - background-color: gray !important; -} - -.tablet .kmw-keyboard-dari_clra .kmw-key-default .kmw-key-text { - top: -33%; -} +/* KMW LIVE CSS for iPad and other tablet devices */ + +/* +====================== +==Universal Elements== +====================== +*/ + +html { + overflow-y: scroll; + overflow-x: hidden; +} + +body { + width:100%; + font-family: Verdana, Arial, Helvetica, sans-serif; + color:#2D2C2C; + background-color: #eeeeee; + margin:0px; + } +section { + background-color: darkred; +} + +a { + text-decoration:none; + color: #AD4A28; + } + +a:hover { + text-decoration:underline; + } + +h3 { + font-size:18px; + } + +p { + font-size:13px; + line-height:1.5em; + } + +header, footer { + width:100%; + margin:0px auto; + /*clear: both;*/ + } + +hr { + display: none; + } + +.box { + -webkit-border-radius: 8px;-moz-border-radius: 8px; border-radius: 8px; + -moz-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); + } + +/* +=================== +==Header Elements== +=================== +*/ +header { + margin-top:0px; + } + +#headerLeft img { + display: block; /* default (inline) display inserts an unwanted bottom border */ + margin-top:0px; + height:60px; + /*-webkit-border-radius: 0px 0px 8px 8px; -moz-border-radius: 0px 0px 8px 8px; border-radius: 0px 0px 8px 8px;*/ + } + +header > div > img { + display: block; + width: 100%; + height: 8px; +} + + +/* Expanding the search box */ +/* @media screen and (940px <= width <= 1045px) { + .main-header { + grid-template-columns: 2fr 1fr 1fr; + } +} */ + +.main-header { + width: 100%; + grid-template-columns: 3fr 1fr; +} + +.left-header { + width: 70vw; +} + +.right-header { + width: 300px; +} + +/* +==================== +==Content Elements== +==================== +*/ +#content { + width: 100%; /* specific for tablet and mobile */ + margin: 0px auto; + background-color: #eeeeee; + /*min-height:375px;*/ + } + + +/* KMW Main App */ +#app { + /*float:left;*/ + /*height:330px;*/ + width:100%; /*710px; */ + margin: 0px;/*30px 15px 15px;*/ + } + +#KeymanWebControl { + display: none; + } + +#exampleBox, #example { + display: none; + } + +#messageContainer { + width: 80%; + float:left; + } + +#message { + height:195px; + width: 100%;/*554px;*/ + float:left; + margin: 10px; + color:black; + font-size:17px; + font-family:SindhiWeb,Verdana,GeezWeb,LaoWeb,TibetanWeb,MyanmarWeb,SinhalaWeb,TamilWeb,KhmerWeb,LatinWeb,OriyaWeb,EgyptianWeb !important; + } + +/* KMW App Buttons */ + +#buttons { + float: right; + width:15%; + margin: 0px 20px; + margin-top: -6px; + } + +#buttons div { + width:140px; + -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; + background: #fff; + border: 1px solid #888888; + margin: 0px 10px; + padding: 3px; + padding-top: 9px; + height: 41px; + line-height: 36px; + background-repeat: no-repeat; + background-position: center left; + } + +#buttons div:disabled { + cursor: default !important; + color: gray !important; + border-color: gray !important; + } + +#buttons p{ + margin-left: 41px; +} + +#search.links, #search{ + background-image:url('../img/btn_google_small.png'); + +} + +#search.linksOff{ + background-image:url('../img/btn_google_small_white.png'); +} + +#copy.links, #copy{ + background-image:url('../img/btn_copy_small.png'); + +} + +#copy.linksOff{ + background-image:url('../img/btn_copy_small_white.png'); +} + +#buttons div * { + display:inline; + } + +div.links { + cursor:pointer; + } + +div.linksOff { + cursor:default !important; + border: 1px solid #cccccc !important; + } + +div.linksOff * { + color: gray; + -webkit-user-select:none; + } + +/* Aside Elements */ + +aside { + display:none; + } + +#font-size{ + display: none; +} + +/* + +#font, +=================== +==Footer Elements== +=================== +*/ +.footer, footer { + display: none; + background-color: #6A2915; + height:50px; + left:0px; + bottom:0px; + position: fixed; + /* -webkit-border-radius: 8px 8px 0px 0px; -moz-border-radius: 8px 8px 0px 0px; border-radius: 8px 8px 0px 0px; */ + } + +nav ul { + list-style: none outside none; + width:90%; + margin:0px auto; + padding:15px 0px; + } + +nav li { + display:inline; + padding:20px 39px; + } + +nav a { + color:#eee; + font-family:Tahoma; + font-weight:bold; + font-size:10.7px; + } + +.messageBox { + box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); + -o-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); + -moz-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); + -khtml-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); + background: #c4c4c4; + position: fixed; + left: 50%; + top: 20%; + z-index: 999 !important; + margin-left: -250px; + margin-top: -100px; + width: 500px; + height: 200px; +} + +.messageBox div { + width: 464px; + height: 134px; + left: 10px; + top: 10px; + padding: 8px; + font-size: 13px; + position: absolute; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -ms-border-radius: 4px; + -o-border-radius: 4px; + border-radius: 3px; + background: white; +} + +.messageBox button { + width:83px; + position: absolute; + right: 10px; + bottom: 4px; + background: #414141; + border-top: 1px solid #383838; + border-right: 1px solid #1F1F1F; + border-bottom: 1px solid #151515; + border-left: 1px solid #1F1F1F; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -ms-border-radius: 4px; + -o-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + -o-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + color: white; + font: bold 12px Helvetica, Verdana, Arial, sans-serif; + text-shadow: 0px -1px 1px #1E2D4D; + text-align:center; + margin: 0 auto 6px; + padding: 3px; + } + +.messageBox button:disabled { + cursor: default !important; + color: gray !important; + -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; + -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; + -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; + -o-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; + box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; +} + +.messageBox button:hover { + -webkit-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + -moz-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + -ms-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + -o-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; + cursor: pointer; +} + +.messageBox button:active { + -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; + -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; + -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; + -o-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; + box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; +} + +.progressBox { + box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); + -o-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); + -moz-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); + -khtml-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); + background: #c4c4c4; + position: fixed; + left: 50%; + top: 20%; + z-index: 999; + margin-left: -200px; + margin-top: -54px; + width: 400px; + height: 54px; +} + +.progressBox div { + width: 364px; + height: 18px; + left: 10px; + top: 10px; + padding: 8px; + background: url('../img/wait.gif') no-repeat 354px 8px white; + font-size: 13px; + position: absolute; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -ms-border-radius: 4px; + -o-border-radius: 4px; + border-radius: 3px; +} + +/* Elements modified for tablet */ +#headerBackground { + width: 100%; + background-color:white; +} + +#headerLeft { + float: left; + margin-left: 28px; +} + +#headerRight { + text-align: right; + height: 40px; + float: right; + padding-bottom: 33px; + padding-right: 10px; +} + +#headerRight-beta { + display: block; + font-weight: bold; + color: red; + font-size: 16pt; + padding: 16px 12px 0; +} + +#headerRight-link { + padding: 0 12px 0; +} + + +#instructions { + margin:10px; + font:12pt Helvetica,Verdana,Arial,sans-serif; + color: white; +} + +/* Additional rules for portrait orientation */ +@media only screen and (orientation: landscape) { + #buttons{ + padding-top: 11px; + } + #buttons div { + margin: 4px 20px 10px 0px; + padding: 0px; + } + #font span:first-child{ + margin-left: 3px; + } + #font p{ + margin-left: 8px; + position: relative; + top: -5px; + } + #mobile-font{ + display: none; + width: 136px; + border-radius: 4px; + position: absolute; + left: 100%; + top: 136px; + margin-left: -170px; + text-align: center; + font-size: 24pt; + background: #fff; + } + + #mobile-increase{ + height: 40px; + line-height: 40px; + border-bottom: solid 1px #000; + } + + #mobile-decrease{ + height: 40px; + line-height: 40px; + } +} + +/* Additional rules for portrait orientation */ +@media only screen and (orientation: portrait) { + + #app { + width: 97%; + } + + #message { + height: 350px; + } + + #messageContainer { + width: 100%; + } + + #buttons { + clear:both; + width: 90%; + } + + #buttons div { + display: inline-block; + margin: 10px 10px 0; + width: 130px; + height: 40px; + } + + #font{ + position: relative; + top: 4px; + } + + #font span:first-child{ + margin-left: 3px; + } + + #font p{ + margin-left: 8px; + position: relative; + top: -4px; + } + + #mobile-font{ + display: none; + width: 301px; + position: absolute; + left: 50%; + top: 452px; + margin-left: -155px; + text-align: center; + font-size: 24pt; + } + + #mobile-increase{ + float: right; + width: 136px; + height: 53px; + line-height: 53px; + background: #fff; + border: 1px solid #888888; + border-radius: 4px; + } + + #mobile-decrease{ + float: right; + width: 136px; + height: 53px; + line-height: 53px; + background: #fff; + border: 1px solid #888888; + margin-right: 25px; + border-radius: 4px; + } +} + +/* +====================== +==Keyboard Styling== +====================== +*/ + +#kmw-language-menu p { + color: #000 !important; +} + +#kmw-language-menu .selected { + background-color: gray !important; +} + +.tablet .kmw-keyboard-dari_clra .kmw-key-default .kmw-key-text { + top: -33%; +} From aec44d28c9f51a9ca5f6b5395f26d8265b7e153a Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Mon, 6 Oct 2025 15:39:26 +0700 Subject: [PATCH 31/36] chore: add js files --- cdn/dev/js/kmwBody.js | 234 ++-- cdn/dev/js/kmwHeader.js | 2710 +++++++++++++++++++-------------------- 2 files changed, 1472 insertions(+), 1472 deletions(-) diff --git a/cdn/dev/js/kmwBody.js b/cdn/dev/js/kmwBody.js index d0f800a..bd9701c 100644 --- a/cdn/dev/js/kmwBody.js +++ b/cdn/dev/js/kmwBody.js @@ -1,118 +1,118 @@ -document.addEventListener('DOMContentLoaded', function() { - // Define the divider, text area and keyboard - const container = document.querySelector('.container-flex') - const divider = document.getElementById('Divider') - - const resizer = divider.querySelector('#resizeGrip') - const prevElementOfResizer = divider.previousElementSibling.querySelector('.text-area') - const nextElementOfResizer = divider.nextElementSibling - - let isResizing = false; - - let startY, startHeightTop, startHeightBottom = 0 - - const mouseDownHandler = (e) => { - e.preventDefault(); - resizer.style.cursor = 'grabbing' - isResizing = true - - startY = e.clientY - startHeightTop = prevElementOfResizer.offsetHeight - startHeightBottom = nextElementOfResizer.offsetHeight - - document.addEventListener('mousemove', mouseMoveHandler) - document.addEventListener('mouseup', mouseUpHandler) - } - - const mouseUpHandler = () => { - resizer.style.removeProperty('cursor') - isResizing = false - document.removeEventListener('mousemove', mouseMoveHandler) - } - - const mouseMoveHandler = function (e) { - if (!isResizing) return; - - let deltaY = e.clientY - startY // Get up or down direction - - let newTopHeight = startHeightTop + deltaY - let newBottomHeight = startHeightBottom - deltaY - - newTopHeight = Math.max(100, Math.min(newTopHeight, window.innerHeight * 0.8)) - newBottomHeight = Math.max(100, Math.min(newBottomHeight, window.innerHeight * 0.7)) - - prevElementOfResizer.style.height = `${newTopHeight}px` - nextElementOfResizer.style.height = `${newBottomHeight}px` - - if (newBottomHeight <= 200) { - fullScreenSize() - } - } - - /* Hide-Show Keyboard */ - const hideKeyboardBtn = document.querySelector('#hideKeyboard') - - let isTextAreaFullHeight = false - const fullHeightTextArea = window.innerHeight * 0.9 - const defaultHeightTextArea = window.innerHeight * 0.3 - - function defaultSize() { - prevElementOfResizer.style.height = `${defaultHeightTextArea}px` - nextElementOfResizer.style.height = `500px` - // nextElementOfResizer.style.width = `900px` - isTextAreaFullHeight = false - } - - function fullScreenSize() { - prevElementOfResizer.style.height = `${fullHeightTextArea}px` - isTextAreaFullHeight = true - } - - hideKeyboardBtn.addEventListener('click', () => { - if (isTextAreaFullHeight) { - defaultSize() - } else { - fullScreenSize() - } - }) - - // Copy tool - const copyBtn = document.querySelector('#copyTool') - const textArea = document.querySelector('#textArea') - copyBtn.addEventListener('click', async function() { - try { - let textToCopy = textArea.value.trim() - - if(!textToCopy) { - copyBtn.classList.replace('fa-copy', 'fa-xmark') - // copyBtn.textContent = ' No characters to copy' - setTimeout(() => { - copyBtn.classList.replace('fa-xmark', 'fa-copy') - copyBtn.textContent = '' - }, 3000) - return; - } - - await navigator.clipboard.writeText(textToCopy) - - copyBtn.classList.replace('fa-copy', 'fa-check'); - - setTimeout(() => { - copyBtn.classList.replace('fa-check', 'fa-copy'); - }, 1000); - - } catch (error) { - console.error('Failed to copy: ', error) - } - }) - - // Font slider - const fontSliderBtn = document.querySelector('#fontSizeRange') - fontSliderBtn.addEventListener('input', function() { - textArea.style.fontSize = `${this.value}px` - }) - - defaultSize() - - resizer.addEventListener('mousedown', mouseDownHandler) +document.addEventListener('DOMContentLoaded', function() { + // Define the divider, text area and keyboard + const container = document.querySelector('.container-flex') + const divider = document.getElementById('Divider') + + const resizer = divider.querySelector('#resizeGrip') + const prevElementOfResizer = divider.previousElementSibling.querySelector('.text-area') + const nextElementOfResizer = divider.nextElementSibling + + let isResizing = false; + + let startY, startHeightTop, startHeightBottom = 0 + + const mouseDownHandler = (e) => { + e.preventDefault(); + resizer.style.cursor = 'grabbing' + isResizing = true + + startY = e.clientY + startHeightTop = prevElementOfResizer.offsetHeight + startHeightBottom = nextElementOfResizer.offsetHeight + + document.addEventListener('mousemove', mouseMoveHandler) + document.addEventListener('mouseup', mouseUpHandler) + } + + const mouseUpHandler = () => { + resizer.style.removeProperty('cursor') + isResizing = false + document.removeEventListener('mousemove', mouseMoveHandler) + } + + const mouseMoveHandler = function (e) { + if (!isResizing) return; + + let deltaY = e.clientY - startY // Get up or down direction + + let newTopHeight = startHeightTop + deltaY + let newBottomHeight = startHeightBottom - deltaY + + newTopHeight = Math.max(100, Math.min(newTopHeight, window.innerHeight * 0.8)) + newBottomHeight = Math.max(100, Math.min(newBottomHeight, window.innerHeight * 0.7)) + + prevElementOfResizer.style.height = `${newTopHeight}px` + nextElementOfResizer.style.height = `${newBottomHeight}px` + + if (newBottomHeight <= 200) { + fullScreenSize() + } + } + + /* Hide-Show Keyboard */ + const hideKeyboardBtn = document.querySelector('#hideKeyboard') + + let isTextAreaFullHeight = false + const fullHeightTextArea = window.innerHeight * 0.9 + const defaultHeightTextArea = window.innerHeight * 0.3 + + function defaultSize() { + prevElementOfResizer.style.height = `${defaultHeightTextArea}px` + nextElementOfResizer.style.height = `500px` + // nextElementOfResizer.style.width = `900px` + isTextAreaFullHeight = false + } + + function fullScreenSize() { + prevElementOfResizer.style.height = `${fullHeightTextArea}px` + isTextAreaFullHeight = true + } + + hideKeyboardBtn.addEventListener('click', () => { + if (isTextAreaFullHeight) { + defaultSize() + } else { + fullScreenSize() + } + }) + + // Copy tool + const copyBtn = document.querySelector('#copyTool') + const textArea = document.querySelector('#textArea') + copyBtn.addEventListener('click', async function() { + try { + let textToCopy = textArea.value.trim() + + if(!textToCopy) { + copyBtn.classList.replace('fa-copy', 'fa-xmark') + // copyBtn.textContent = ' No characters to copy' + setTimeout(() => { + copyBtn.classList.replace('fa-xmark', 'fa-copy') + copyBtn.textContent = '' + }, 3000) + return; + } + + await navigator.clipboard.writeText(textToCopy) + + copyBtn.classList.replace('fa-copy', 'fa-check'); + + setTimeout(() => { + copyBtn.classList.replace('fa-check', 'fa-copy'); + }, 1000); + + } catch (error) { + console.error('Failed to copy: ', error) + } + }) + + // Font slider + const fontSliderBtn = document.querySelector('#fontSizeRange') + fontSliderBtn.addEventListener('input', function() { + textArea.style.fontSize = `${this.value}px` + }) + + defaultSize() + + resizer.addEventListener('mousedown', mouseDownHandler) }) \ No newline at end of file diff --git a/cdn/dev/js/kmwHeader.js b/cdn/dev/js/kmwHeader.js index c9a76d4..f5c7941 100644 --- a/cdn/dev/js/kmwHeader.js +++ b/cdn/dev/js/kmwHeader.js @@ -1,1356 +1,1356 @@ -keyman = getKeymanWeb() - -function getKeymanWeb() { - if(window.tavultesoft) { - return window.tavultesoft.keymanweb; - } - return window.keyman; -} -/* Global Variables */ -let selectedKbList = [] // Main array for the search, kb selection...etc. -let kbSearchData = [] // For History search -let kmwLang = keyman.getActiveLanguage() -let kmwKb = keyman.getActiveKeyboard() - -const clearSearchIcon = document.querySelector('#clearSearchIcon') -const magnifying = document.querySelector('#magnifyingGlassIcon') - -const elements = { - worldMapBtn: document.querySelector('#worldMap'), - kmwControls: document.querySelector('#KeymanWebControl'), - - kbSelection: document.querySelector('#keyboardSelection'), - keyboardSelectionButton: document.querySelector('#keyboardSelectionButton'), - caretRightIcon: keyboardSelectionButton.querySelector('.fa-caret-right'), - - searchBar: document.querySelector('#searchBar'), - searchInput: document.querySelector('#searchInput'), - searchDropdownMenu: document.querySelector('#searchDropdownMenu'), - searchIcons: document.querySelector('#searchIcons'), -} - -const state = { - mapIsOpen: false -} - -/* - ===================================== Default keyboard ========================================= -*/ - -function defaultKeyboard(kbdname = "basic_kbdus", languageCode = "en") { - if(!exists(kbdname, languageCode)) { - if (textArea) textArea.placeholder = 'A Keyboard name isn\'t specified. Select a keyboard and start typing' - return - } - setKeyboardWithDirection(kbdname, languageCode) -} - -/* - ============================= Toggle between World Map and Search ============================== -*/ -elements.worldMapBtn?.addEventListener('click', (e) => { - e.preventDefault() - state.mapIsOpen = true - if (state.mapIsOpen == true) { - openMap() - keyman.addEventListener('keyboardchange', () => { - location.replace(`#${keyman.getActiveLanguage()},${keyman.getActiveKeyboard()}`) - updateExample(keyman.getActiveKeyboard()) - setTimeout(() => { - applyClassToKb(), 0 - }) - }) - } else { - openSearch() - } -}) - -function openSearch() { - state.mapIsOpen = false - hideEls( - elements.kmwControls, - ) - showEls( - elements.searchDropdownMenu, - elements.searchIcons - ) - - if (selectedKbList.length > 0) { - elements.caretRightIcon.textContent = selectedKbList.length - removeClass(elements.caretRightIcon, 'fa-magnifying-glass') - } else { - elements.caretRightIcon.textContent = '' - elements.caretRightIcon.classList.add('fa-caret-right') - } - - elements.searchBar.replaceChildren( - elements.searchInput, - elements.searchIcons, - elements.searchDropdownMenu - ) -} - -function openMap() { - state.mapIsOpen = true - removeClass( - elements.kmwControls, 'hidden', - elements.caretRightIcon, 'fa-caret-right' - ) - hideEls( - elements.searchDropdownMenu - ) - removeTextContent( - elements.caretRightIcon - ) - elements.keyboardSelectionButton.removeAttribute('id', 'keyboardSelectionButton') - elements.keyboardSelectionButton.setAttribute('id', 'returnToSearchButton') - elements.caretRightIcon.classList.add('fa-magnifying-glass') - elements.keyboardSelectionButton.style.backgroundColor = "var(--keyman-orange)" - elements.keyboardSelectionButton.style.border = '0px' - elements.keyboardSelectionButton.classList.add('return-to-search') - elements.kbSelection.style.display = "none" - elements.searchBar.replaceChildren( - elements.kmwControls - ) -} - -function returnToSearch() { - elements.keyboardSelectionButton.removeAttribute('id', 'returnToSearchButton') - elements.keyboardSelectionButton.setAttribute('id', 'keyboardSelectionButton') - - if ((selectedKbList?.length || 0) < 1) { - elements.caretRightIcon.classList.add('fa-caret-right') - removeClass(elements.caretRightIcon, 'fa-magnifying-glass') - elements.caretRightIcon.textContent = '' - } - - elements.keyboardSelectionButton.style.backgroundColor = "" - elements.kbSelection.style.display = "block" - openSearch() -} - -function waitForElement(selector) { - return new Promise((resolve) => { - const interval = setInterval(() => { - const element = document.querySelector(selector) - if (element) { - clearInterval(interval) - resolve(element) - } - }, 100) - }) -} - -waitForElement('#returnToSearchButton').then((element) => { - element.addEventListener('click', (e) => { - e.preventDefault() - returnToSearch() - }) -}) - -waitForElement(".kmw-osk-frame").then((oskDiv) => { - document.querySelector('.keyboard-area').appendChild(oskDiv) -}) - -/* - ==================== Search Interaction =================== -*/ - -/* Search Input */ -const dropdown = new bootstrap.Dropdown(elements.searchInput, { - autoClose: 'outside' -}) - -document.addEventListener('click', (e) => { - if (!elements.searchInput.contains(e.target) && !elements.searchDropdownMenu.contains(e.target)) { - dropdown.hide() - } -}) - -elements.searchInput.addEventListener('click', (e) => { - e.stopPropagation() - // defaultKeyboard() - dropdown.show() -}) - -// Hide Dropdown Search on Mouse leave -elements.searchDropdownMenu.addEventListener('mouseleave', (e) => { - e.preventDefault() - dropdown.hide() -}) - -/* - =========================== Utility functions ============================ -*/ -function hideEls(...elements) { - return elements.every(el => el.classList.add('hidden')) -} - -function showEls(...elements) { - return elements.every(el => el.classList.remove('hidden')) -} - -function removeClass(element, className) { - return element.classList.remove(className) -} - -function removeTextContent(...elements) { - return elements.every(el => el.textContent = '') -} - -/* Elements validation */ -function exists(...elements) { - return elements.every(el => el != null) -} - -document.addEventListener('DOMContentLoaded', () => { - /* UI Behavior of the Selected Keyboard menu */ - if (exists(elements)) { - elements.keyboardSelectionButton.addEventListener('mouseenter', () => { - elements.kbSelection.classList.add('open') - }) - elements.keyboardSelectionButton.addEventListener('click', () => { - elements.kbSelection.classList.remove('open') - }) - elements.kbSelection.addEventListener('mouseleave', () => { - elements.kbSelection.classList.remove('open') - }) - } -}) - -/* - === Keyboard Execution === -*/ -const downloadBtn = document.getElementById('kbDownloadPage') -const textArea = document.getElementById('textArea') -let langExamples = []; - -function selectKb(kbdname, languageCode) { - if(!exists(kbdname, languageCode)) { - if (textArea) textArea.placeholder = 'A Keyboard name isn\'t specified. Select a keyboard and start typing' - return - } - setKeyboardWithDirection(kbdname, languageCode) -} - -function setTextDirection(targetEls, dir) { - const copyBtn = document.querySelector('#copyTool') - - targetEls.dir = dir - if (dir == 'rtl') { - copyBtn.style.right = '0' - copyBtn.style.left = '10px' - } else { - copyBtn.style.right = '' - copyBtn.style.left = '' - } -} - -// Change and type keyboard -async function setKeyboardWithDirection(kbdname, languageCode) { - const kbSpan = document.querySelector('#kbSpan') - const langTag = `#${languageCode}` - let kbTag = '' - - if (kbdname.match(/Keyboard_*/)) { - kbTag = `${kbdname}` - } else { - kbTag = `Keyboard_${kbdname}` - } - - location.replace(`${langTag},${kbTag}`) - await keyman.addKeyboards(kbdname) - const kbd = keyman.getKeyboard(kbdname, languageCode) - await keyman.setActiveKeyboard(kbdname, languageCode) - - // setTimeout(() => { - // applyClassToKb(), 0 - // }) - - if(kbd) { - textArea.placeholder = `The ${kbdname} keyboard is selected. Start typing...` - kbSpan.innerHTML = `${kbdname}` - - setTextDirection(textArea, textArea.dir) - } - updateExample(kbdname) - if(typeof(KeyboardChange_EmbedFonts) != 'undefined') KeyboardChange_EmbedFonts(kbdname) -} - -/* Language Examples AJAX */ -async function updateExample(kbdname) { - const keymanExample = document.getElementById("example") - const exampleBox = document.getElementById("exampleBox") - - if (!keymanExample || !exampleBox) return false; - - if(kbdname == '') - { - keymanExample.textContent = `No example is available due to empty Keyboard name.` - return true; - } - - let activeLanguage = keyman.getActiveLanguage(); - - if(langExamples[activeLanguage + '_' + kbdname]) - { - keymanExample.innerHTML = langExamples[activeLanguage + '_' + kbdname]; - return true; - } - - langExamples[activeLanguage + '_' + kbdname] = 'Loading...'; - keymanExample.innerHTML = 'Loading...'; - - const link = `/prog/languageexample.php?keyboard=${kbdname}&language=${activeLanguage}`; - try { - const response = await fetch(link); - if(response.status == 200) { - const content = await response.text(); - - langExamples[activeLanguage + '_' + kbdname] = keymanExample.innerHTML = content; - } else { - throw new Error(`Unable to retrieve content, status was ${response.status}: ${response.statusText}`); - } - } catch(e) { - langExamples[activeLanguage + '_' + kbdname] = keymanExample.innerHTML = 'Error retrieving example: '+e.message; - throw e; - } -} - -function applyClassToKb() { - - const kbArea = document.querySelector('.keyboard-area') - if (!kbArea) return - - const apply = () => { - const child = kbArea.children - for (const c of child) { - if (!c.classList.contains('kmw-osk-frame')) { - c.classList.add('kmw-osk-frame') - c.classList.add('kmw-help-osk-frame') - } - } - } - - apply() - - // const observer = new MutationObserver(() => { - // for (const m of mutations) { - // if (m.type === 'childlist' && m.addedNodes.length) { - // apply() - // } - // } - // }) - // observer.observe(kbArea, {childList: true}) -} - -/* Search */ -const kbSearchCard = document.getElementById('kbSearchCardUI'); -let debounceTimer - -/* Pagination */ -prevBtn = document.getElementById('prevPage') -nextBtn = document.getElementById('nextPage') -pageInfo = document.getElementById('pageInfo') - -searchResultCount = document.getElementById('resultCount') -paginationCtrl = document.getElementById('paginationControls') - -let currentPage = 1 -let currentQuery = '' -let totalPage -const itemPerPage = 10 - -prevBtn.addEventListener('click', goPrevPage) -nextBtn.addEventListener('click', goNextPage) - -function updatePaginationCtrl() { - pageInfo.textContent = `${currentPage} of ${totalPage}` - nextBtn.disabled = currentPage >= totalPage - prevBtn.disabled = currentPage <= 1 -} - -function goPrevPage() { - if (currentPage > 1) { - currentPage-- - searchKeyboard(currentQuery, currentPage) - } -} - -function goNextPage() { - if (currentPage < totalPage) { - currentPage++ - searchKeyboard(currentQuery, currentPage) - } -} - -/* Click: Open Search and Display search instructions */ -elements.searchInput.addEventListener('click', function(e) { - const query = e.target.value.trim() - - defaultKeyboard() - if (query == "") { - resetSearch() - } else { - searchKeyboard(query) - } -}) - -/* Input: Search and Display keyboards */ -elements.searchInput.addEventListener('input', function(e) { - handleSearch(e.target.value) -}) - -clearSearchIcon.addEventListener('click', () => { - elements.searchInput.value = '' - handleSearch() - elements.searchInput.focus() -}) - -function handleSearch(value = "") { - currentQuery = value.trim() - currentPage = 1 - - updateSearchIcon(value) - - if (!currentQuery) { - resetSearch() - return - } - debounceSearch(currentQuery, currentPage) -} - -function resetSearch() { - paginationCtrl.style.display = 'none' - defaultSearch() -} - -function updateSearchIcon(value) { - const hasValue = value.length > 0 - magnifying.style.display = hasValue ? 'none' : 'inline' - clearSearchIcon.style.display = hasValue ? 'inline' : 'none' -} - -function debounceSearch(query, page) { - clearTimeout(debounceTimer) - if (query.length > 1) { - debounceTimer = setTimeout(() => { - searchKeyboard(query, page) - }, 300) - } -} - -/* == Section == - Search -*/ - -/* Display top downloads with search Instruction */ -async function defaultSearch() { - kbSearchCard.innerHTML = `

    Loading...

    ` - try { - let response = await fetch(`https://api.keyman.com/search/2.0?q=p:popular`) - if (!response.ok) { - throw new Error(`API request failed with status ${response.status}`) - } - - let data = await response.json() - - let mostDownloadkb = data.keyboards - - if (!mostDownloadkb || !Array.isArray(mostDownloadkb)) { - throw new Error(`Invalid API response structure`) - } - displaySearch(mostDownloadkb) - } - catch(error) { - console.error(`Error fetching ${error}`) - kbSearchCard.innerHTML = `
    No keyboards are found.
    ` - paginationCtrl.style.display = 'none' - } -} - -/* Get query and return search */ -async function searchKeyboard(query = null, page) { - kbSearchCard.innerHTML = `
    Searching ${query}...
    ` - kbSearchCard.style.display = 'block' - - let response = await fetch(`https://api.keyman.com/search/2.0?q=${encodeURIComponent(query)}&p=${page}`) - if (!response.ok) { - throw new Error(`API request failed with status ${response.status}`) - } - - searchHistory(query) - let data = await response.json() - // Found with Context: Setup pagination - if (data.context) { - totalPage = data.context.totalPages || 1; - currentPage = data.context.pageNumber || 1; - } else { - totalPage = Math.ceil(data.keyboards.length / itemPerPage); - } - - // Validate data.keyboards - let keyboardData = data.keyboards - if (!keyboardData || !Array.isArray(keyboardData)) { - throw new Error("Invalid API response structure") - } - - // Get total result - let totalFound = data.context.totalRows - - updatePaginationCtrl() - displaySearch(keyboardData, totalFound, query) -} - -/* Display items return from search */ -function displaySearch(data, total = 0, query = '') { - kbSearchCard.innerHTML = ''; - - if (!data || data.length == 0) { - kbSearchCard.innerHTML = 'No keyboards are found.' - paginationCtrl.style.display = 'none' - return - } - - if (total) { - searchResultCount.innerHTML = `${total} results` - searchResultCount.classList.remove('hidden') - } - - // Getting searched Word ready for highlight - const marked = getMarkedContext(query) - - const searchInstruction = document.querySelector('.search-instruction') - const kbHrTitle = document.querySelector('.keyboard-title') - if (!query) { - searchInstruction.classList.remove("hidden") - kbHrTitle.textContent = "Most Downloads" - } else { - searchInstruction.classList.add("hidden") - kbHrTitle.textContent = "" - } - data.forEach(kb => { - const card = searchKbCardUI(kb, marked, selectedKbList, data) - kbSearchCard.appendChild(card) - }) - paginationCtrl.style.display = 'flex'; -} - -// UI Search card -function searchKbCardUI(kb, marked = '', selectedKbList, data) { - const kbFoundInList = selectedKbList.some(selected => selected.id == kb.id) - // Keyboard card container - let cardWrap = document.createElement('div') - cardWrap.classList.add('card-wrap') - cardWrap.setAttribute('id', 'keyboardCardWrap') - - // Keyboard header container - let cardHeader = document.createElement('div') - cardHeader.classList.add('card-header') - - const {matchFound, matchField, matchValue} = highlightSearchContext(kb, marked) - - const kbNameHeading = matchFound ? showMarkedContext(kb, matchField, matchValue) - : (() => { - const heading = document.createElement('h4') - heading.innerHTML = kb.name - return heading - }) - - // Keyboard Plus (+) icon - const kbIconPTag = document.createElement('p') - kbIconPTag.textContent = kbFoundInList ? "-" : "+" - kbIconPTag.style.fontSize = '20px' - kbIconPTag.style.cursor = 'pointer' - kbIconPTag.classList.add('kb-icon-plus') - - checkKbCardUI(kbIconPTag, cardWrap, kb) - // Keyboard ID - const kbIdPTag = document.createElement('p') - kbIdPTag.classList.add('keyboard-id') - kbIdPTag.textContent = kb.id - - // Keyboard Description - const kbDescHeading = truncateDesc(kb, matchField, marked) - - // Keyboard monthly downloads and platform support - const kbSpecs = document.createElement('div') - kbSpecs.classList.add('keyboard-specs') - - const kbDownloadHeading = document.createElement('h6') - kbDownloadHeading.textContent = `${kb.match.downloads} monthly downloads` - kbDownloadHeading.classList.add('monthly-download') - - const kbPlatformSupport = document.createElement('div') - kbPlatformSupport.classList.add('platform') - kbPlatformSupport.innerHTML = platformSupport(kb.platformSupport) - - // Append children - cardHeader.appendChild(kbNameHeading) - cardHeader.appendChild(kbIconPTag) - - kbSpecs.appendChild(kbDownloadHeading) - kbSpecs.appendChild(kbPlatformSupport) - - cardWrap.appendChild(cardHeader) - cardWrap.appendChild(kbIdPTag) - cardWrap.appendChild(kbDescHeading) - cardWrap.appendChild(kbSpecs) - - // Choose keyboard to selection - kbIconPTag.onclick = (e) => { - e.stopPropagation() - addKbToSelectionMenu(kbIconPTag, cardWrap, kb, data) - textArea.focus() - selectKb() - } - // console.log("Recent:", historyKbSelection.getHistory()); - - return cardWrap -} - -// Disable or Enable search card -function checkKbCardUI(kbIconPTag, cardWrap, kb) { - // For checking if the keyboard exists in selected Kbs - let kbFoundInList = selectedKbList.some(selected => selected.id == kb.id) - if (kbFoundInList) { - cardWrap.classList.add('disabled') - } else { - cardWrap.classList.remove('disabled') - } -} - -// Highlight word searched -function getMarkedContext(query) { - let escapedTerm = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') - return new RegExp(escapedTerm, 'i') -} - -// Find a match between Search Context and Language, Keyboard name, Description -function highlightSearchContext(kb, marked) { - let matchFound = false - let matchField = "" - let matchValue = "" - - // Get and find language that matches the search - for (lang in kb.languages) { - let langData = kb.languages[lang] - for (key in langData) { - const value = langData[key] - if (typeof value == "string" && marked.test(value)) { - matchFound = true - matchValue = value.replace(marked, (m) => m ? `${m}` : m) - matchField = "language" - break - } - } - if (matchFound) break - } - - // Find a match for keyboard name if language is not a match - if (!matchFound && marked.test(kb.name)) { - matchFound = true - matchValue = kb.name.replace(marked, '$&') - matchField = "keyboard" - } - - // Find a match for keyboard description if name is not a match - if (!matchFound && marked.test(kb.description)) { - matchFound = true - matchField = "description" - } - - return {matchField, matchValue, matchFound} -} - -// Display Highlighted Search Context -function showMarkedContext(kb, matchField, matchValue) { - const kbNameHeading = document.createElement('h4') - - const kbHelpLink = document.createElement('a') - kbHelpLink.href = `https://help.keyman.com/keyboard/${kb.id}` - kbHelpLink.target = '_blank' - kbHelpLink.rel = 'noopener noreferrer' - - // Display matched language - const langNameSpan = document.createElement('span') - langNameSpan.style.fontSize = "14px" - if (matchField == "language") { - langNameSpan.innerHTML = matchField == "language" ? ` (${matchValue} language)` : "" - } - - // Display matched keyboard - if (matchField == "keyboard") { - kbHelpLink.innerHTML = matchValue - } else { - kbHelpLink.textContent = kb.name - } - kbNameHeading.appendChild(kbHelpLink) - kbNameHeading.appendChild(langNameSpan) - kbNameHeading.addEventListener('click', () => { - const checkedURL = validateURL(`https://help.keyman.com/keyboard/`) - const newURL = checkedURL + kb.id - window.open(newURL, '_blank') - }) - - return kbNameHeading -} - -// Truncated Keyboard Description -function truncateDesc(kb, matchField, marked) { - const kbDescHeading = document.createElement('h6') - kbDescHeading.classList.add("keyboard-description") - const word_limits = 90 - - let temp = document.createElement('div') - temp.innerHTML = kb.description - - let fullDesc = kb.description - let plainText = temp.textContent - let shortText = "" - - let isTruncated = false - - if (plainText.length >= word_limits) { - shortText = plainText.slice(0, word_limits) + "..." - kbDescHeading.innerHTML = shortText - isTruncated = true - } else { - kbDescHeading.innerHTML = fullDesc - isTruncated = false - } - - if (isTruncated) { - const toggleBtn = document.createElement('a') - toggleBtn.href = "#" - toggleBtn.style.marginLeft = "6px" - toggleBtn.textContent = "Show more" - - toggleBtn.addEventListener('click', e => { - e.preventDefault() - const isExpanded = toggleBtn.textContent == "Show more" - kbDescHeading.innerHTML = !isExpanded ? shortText.replace(marked, (m) => m ? `${m}` : m) : fullDesc - if (matchField == 'description') { - kbDescHeading.innerHTML = isExpanded ? fullDesc.replace(marked, '$&') : shortText - } - kbDescHeading.style.color = isExpanded ? 'black' : 'gray' - toggleBtn.textContent = isExpanded ? "Show less" : "Show more" - kbDescHeading.appendChild(toggleBtn) - }) - kbDescHeading.appendChild(toggleBtn) - } - - return kbDescHeading -} - -/* - == End of Search Section == -*/ - -// Platform Support -function platformSupport(data) { - const platformMap = { - android: "Android", - desktopWeb: "Web", - ios: "iPhone and iPad", - linux: "Linux", - macos: "macOS", - mobileWeb: "Mobile web", - windows: "Windows" - } - let platformSpan = Object.entries(data) - .filter(([_, supportLevel]) => supportLevel == 'full') - .map(([platform]) => `${platformMap[platform]}`).join('') - - return platformSpan -} - -/* == Section == - Keyboard Selection Menu -*/ -function addKbToSelectionMenu(kbIconPTag, cardWrap, kb, data) { - const keyboardSelectionButton = document.getElementById('keyboardSelectionButton') - let isSelected = selectedKbList.some(selected => selected.id == kb.id) - addDataKb(data) - // Remove keyboard - if (isSelected) { - removeKbSelected(kb.id) - kbIconPTag.textContent = '+' - generateKbUI(selectedKbList) - checkKbCardUI(kbIconPTag, cardWrap, kb) - - return - } - if(selectedKbList.length < 5) { - addKbToSelection(kb) - generateKbUI(selectedKbList) - kbIconPTag.textContent = 'โœ“' - kbIconPTag.classList.add('kb-icon-plus-animate') - - setTimeout(() => { - kbIconPTag.textContent = '-' - kbIconPTag.classList.remove('kb-icon-plus-animate') - keyboardSelectionButton.classList.remove('btn-secondary') - keyboardSelectionButton.classList.add('btn-keyman-orange') - }, 800) - - checkKbCardUI(kbIconPTag, cardWrap, kb) - return - } - confirmAndAddKb(() => { - addKbToSelection(kb) - generateKbUI(selectedKbList) - - kbIconPTag.textContent = 'โœ“' - kbIconPTag.classList.add('kb-icon-plus-animate') - - setTimeout(() => { - kbIconPTag.textContent = '-' - kbIconPTag.classList.remove('kb-icon-plus-animate') - keyboardSelectionButton.classList.remove('btn-secondary') - keyboardSelectionButton.classList.add('btn-keyman-orange') - }, 800) - checkKbCardUI(kbIconPTag, cardWrap, kb) - }) -} - -// Add keyboard for kb search and selection UI -function addKbToSelection(kb) { - const kbInfo = { - "id": kb.id, - "name": kb.name, - "version": kb.version, - "helpLink": kb.helpLink, - "platformSupport": kb.platformSupport, - "totalDownloads": kb.match.totalDownloads, - "sourcePath": kb.sourcePath, - "supportedLanguage": kb.languages, - "lastUpdated": kb.lastModifiedDate - } - // historyKbSelection.add(kbInfo) - selectedKbList.push(kbInfo) -} - -// UI for keyboard selection menu -function generateKbUI(selectedKbList) { - const keyboardSelection = document.getElementById("keyboardSelection") - keyboardSelection.innerHTML = '' - - if(selectedKbList.length < 1) { - triggerKbCount(selectedKbList) - resetKbSelectionMenu() - return - } - - const kbDivHeader = document.createElement('div') - kbDivHeader.textContent = "Keyboard Selection menu" - kbDivHeader.classList.add('kb-item-header') - - const kbDivFoot = document.createElement('div') - kbDivFoot.textContent = "US Basic Keyboard" - kbDivFoot.classList.add('kb-item-footer') - - keyboardSelection.appendChild(kbDivHeader) - - selectedKbList.forEach(data => { - const kbDiv = document.createElement('div') - kbDiv.classList.add("kb-item") - kbDiv.setAttribute('id', `${data.id}`) - - const kbName = document.createElement('span') - kbName.textContent = data.name - - const kbConfigList = document.createElement('ul') - kbConfigList.classList.add('keyboard-configs') - kbConfigList.innerHTML = ` -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • - ` - - const kbDetails = displayKbDetails(data) - - kbDiv.appendChild(kbName) - kbDiv.appendChild(kbConfigList) - kbDiv.appendChild(kbDetails) - keyboardSelection.appendChild(kbDiv) - keyboardSelection.append(kbDivFoot) - - let kbdName = data.id - let langCode = Object.keys(data.supportedLanguage)[0] || "en" - - selectKb(kbdName, langCode) - kbConfigList.addEventListener('click', (e) => { - const target = e.target - if (target.tagName == 'I' && target.dataset.action) { - const action = target.dataset.action - const id = target.dataset.id - const helpLink = target.dataset.helplink - kbConfigMenu(action, id, helpLink) - } - }) - - kbDiv.addEventListener('click', () => { - kbdName = data.id - langCode = Object.keys(data.supportedLanguage)[0] || "en" - textArea.focus() - selectKb(kbdName, langCode) - }) - - kbDivFoot.onclick = () => { - defaultKeyboard() - } - - const kbHelpLink = document.querySelector('#kbHelpdocLink') - kbHelpLink.addEventListener('click', (e) => { - kbConfigMenu('help', '', data.helpLink) - }) - }) - triggerKbCount(selectedKbList) -} - -// Keyboard count for Keyboard selection menu -function triggerKbCount(selectedKbList) { - const kbSelectedLength = selectedKbList.length - const keyboardSelectionButton = document.querySelector('#keyboardSelectionButton') - const keyboardCount = document.querySelector('#kbCount') - - if (kbSelectedLength >= 1) { - keyboardCount.classList.remove('fa-caret-right') - keyboardCount.textContent = `${kbSelectedLength}` - keyboardSelectionButton.classList.add('btn-keyman-orange') - keyboardSelectionButton.classList.remove('btn-secondary') - } else { - keyboardCount.classList.add('fa-caret-right') - keyboardCount.textContent = '' - keyboardSelectionButton.classList.remove('btn-keyman-orange') - keyboardSelectionButton.classList.add('btn-secondary') - } -} - -// Keyboard count default for Keyboard selection menu -function resetKbSelectionMenu() { - const keyboardSelection = document.querySelector("#keyboardSelection") - - const kbDivHeader = document.createElement('div') - kbDivHeader.textContent = "Keyboard Selection menu" - kbDivHeader.classList.add('kb-item-header') - - const kbItem = document.createElement('div') - kbItem.classList.add('.kb-item') - - const pTag = document.createElement('p') - pTag.textContent = "Open Search to get your keyboard" - - const kbDivFoot = document.createElement('div') - kbDivFoot.textContent = "US Basic Keyboard" - kbDivFoot.classList.add('kb-item-footer') - - kbItem.appendChild(pTag) - - keyboardSelection.appendChild(kbDivHeader) - keyboardSelection.appendChild(kbItem) - keyboardSelection.appendChild(kbDivFoot) -} - -// Compare and remove keyboard -function removeKbSelected(kbId) { - if(kbId) { - selectedKbList = selectedKbList.filter(kb => kb.id !== kbId) - } -} - -// Check 6th keyboard -function confirmAndAddKb(onConfirmAdd) { - if (typeof onConfirmAdd != 'function') { - console.log("Expected the onConfirmAdd a function, instead got: " + typeof onConfirmAdd) - alert("Click on the keyboard again to enable.") - } - - const warningDialogUI = limitKbSelectionUI(() => { - onConfirmAdd() - selectedKbList.shift() - generateKbUI(selectedKbList) - }) - - document.body.appendChild(warningDialogUI) -} - -// UI for Keyboard Selected Limitation -function limitKbSelectionUI(onAccept) { - const dialogDiv = document.createElement('div') - dialogDiv.classList.add('warning-container') - - const dialogContentDiv = document.createElement('div') - dialogContentDiv.classList.add('warning-content') - - const dialogCancel = document.createElement('button') - dialogCancel.classList.add('warning-cancel-btn') - dialogCancel.setAttribute('id', 'cancelWarningBtn') - dialogCancel.textContent = 'โœ–' - dialogCancel.onclick = () => { - dialogDiv.remove() - generateKbUI(selectedKbList) - } - - const dialogImgTag = document.createElement('img') - dialogImgTag.classList.add('warning-keyman-image') - dialogImgTag.src = `/cdn/dev/img/keymanweb-mini-logo-88.png` - dialogImgTag.alt = "Keyman Logo" - - const firstKeyboard = selectedKbList[0].name - - const dialogPTag = document.createElement('p') - dialogPTag.classList.add('warning-text') - dialogPTag.innerHTML = `The keyboards selected exceeds the limitation of 5 keyboards. Click 'Allow' to remove the
    ${firstKeyboard} keyboard.` - - const dialogUlTag = document.createElement('ol') - dialogUlTag.textContent = "Your keyboards selection:" - selectedKbList.forEach((kb, index) => { - const dialogLiTag = document.createElement('li') - if (index == 0) { - const markKeyboard = document.createElement('mark') - markKeyboard.textContent = kb.name - dialogLiTag.appendChild(markKeyboard) - } else { - dialogLiTag.textContent = kb.name - } - dialogUlTag.appendChild(dialogLiTag) - - }) - - const dialogAccept = document.createElement('button') - dialogAccept.classList.add('warning-accept-btn') - dialogAccept.setAttribute('id', 'acceptWarningBtn') - dialogAccept.textContent = "Allow" - dialogAccept.onclick = () => { - dialogDiv.remove() - onAccept() - } - - dialogContentDiv.appendChild(dialogCancel) - dialogContentDiv.appendChild(dialogImgTag) - dialogContentDiv.appendChild(dialogPTag) - dialogContentDiv.appendChild(dialogUlTag) - dialogContentDiv.appendChild(dialogAccept) - - dialogDiv.appendChild(dialogContentDiv) - - return dialogDiv -} - -// Seperate list for History/Remember Search - -/* - ========================== To be continued ========================== -*/ -function addDataKb(data) { - let selectedKbData = [] - // console.log(data) - const kbInfo = { - "platformSupport": data.platformSupport, - // "monthlyDownloads": data.match.downloads, - "sourceFile": data.sourcePath, - } - selectedKbData.push(kbInfo) -} - -// End of History search - -// Keyboard selection menu's tools: help, download, and remove -function kbConfigMenu(action, id, helplink) { - if (action == "help") { - window.open(helplink, '_blank') - } - - if (action == "download") { - const downloadUrl = `https://keyman.com/keyboards/install/${id}` - window.open(downloadUrl, '_blank') - } - - if (action == "remove") { - removeKbSelected(id) - generateKbUI(selectedKbList) - triggerKbCount(selectedKbList) - } - - if (action == "info") { - const kbDetails = document.querySelector(`#keyboard-${id}-details`) - - kbDetails.addEventListener('mouseleave', () => { - kbDetails.classList.add('hidden') - }) - kbDetails.classList.remove('hidden') - } -} - -// Keyboard details for Keyboard selection menu -function displayKbDetails(data) { - const item = selectedKbList.find(kb => kb.id == data.id) - if (!item) return; - - const kbDetails = document.createElement('div') - kbDetails.classList.add('keyboard-details') - kbDetails.setAttribute('id', `keyboard-${data.id}-details`) - kbDetails.classList.add('animate__animated', 'animate__fadeIn') - kbDetails.classList.add('hidden') - - const kbDetailsHead = document.createElement('div') - kbDetailsHead.textContent = 'Keyboard Details' - kbDetailsHead.classList.add('kb-item-header') - - const kbDetailsContent = document.createElement('div') - kbDetailsContent.classList.add('keyboard-content-wrapper') - kbDetailsContent.innerHTML = ` -
      -
    • -
      -
      Name
      -
      ${item.name || "N/A"}
      -
      -
    • -
    • -
      -
      Keyboard ID
      -
      ${item.id || "N/A"}
      -
      -
    • -
    • -
      -
      Version
      -
      ${item.version || "N/A"}
      -
      -
    • -
    • -
      -
      Total downloads
      -
      ${item.totalDownloads || 0}
      -
      -
    • -
    • -
      -
      Source Path
      - -
      -
    • -
    • -
      -
      Supported Platforms
      -
      - ${platformSupport(item.platformSupport) || 'No platforms supported'} -
      -
      -
    • -
    • -
      -
      Last Updated
      -
      ${getOnlyDates(item.lastUpdated) || 0}
      -
      -
    • -
    - ` - kbDetails.appendChild(kbDetailsHead) - kbDetails.appendChild(kbDetailsContent) - - return kbDetails -} - -// Get only the YYYY-mm-dd format -function getOnlyDates(dateData) { - const finalDateData = dateData.match(/^\d{4}-\d{2}-\d{2}/) - return finalDateData -} - -// Validate URLs -function validateURL(string) { - try { - const newUrl = new URL(string) - if (newUrl.protocol === 'https:') { - return newUrl - } else { - return false - } - } catch (error) { - console.error(error) - } -} -/* - == End of Keyboard Selection menu Section == -*/ - -/* - == Store data in localStorage to use for reload == -*/ -let appState = { - fontSize: 16, - writtenText: "", - selectedKbList: [], - enabledKb: null, - keyboardSizes: null, - textAreaSizes: null -} -const keyboardContainer = document.querySelector('.keyboard-container') -const fontSizeRange = document.querySelector('#fontSizeRange') - -function getFontSize(element) { - let theFontSize - theFontSize = parseInt(window.getComputedStyle(element).fontSize) || "16" - - return theFontSize -} - -function getSelectedKb() { - return selectedKbList || [] -} - -function getEnabledKb() { - let hash = location.hash.match(/^#(.+),(Keyboard_.+)$/i)[0] - - let kbValues = hash.replace('#', '') - kbValues = hash.split(',') - - return [hash, kbValues] -} - -function getElementsSize(element) { - const rect = element.getBoundingClientRect() - return { - height: rect.height, - width: rect.width, - positionX: rect.x, - positionY: rect.y - } -} - -function getElementValue(element) { - return element.value -} - -function setFontSize(size) { - textArea.style.fontSize = size + "px" - fontSizeRange.value = size -} - -function setWrittenText(text) { - textArea.value = text -} - -function setElementsSize(element, sizes) { - element.style.height = sizes.height + "px" - element.style.left = sizes.positionX + "px" - element.style.top = sizes.positionY + "px" -} - -function setSelectedKb(savedKbList) { - selectedKbList = savedKbList -} - -function setEnabledKb(kb) { - if (kb) { - selectKb(kb) - } -} - -function buildAppState() { - appState = { - fontSize: getFontSize(textArea), - selectedKbList: getSelectedKb(), - enabledKb: getEnabledKb(), - textAreaSizes: getElementsSize(textArea), - keyboardSizes: getElementsSize(keyboardContainer), - writtenText: getElementValue(textArea) - } - saveSettings("keymanWebState", appState) -} - -function saveSettings(key, state) { - let recentTime = new Date() - const time = 5000 // equals to An hour - let item - - // console.log("recentTime: ", recentTime) - // console.log("recentTime.getTime(): ", recentTime.getTime()) - - if (state) { - item = { - value: state, - expiry: recentTime.getTime() + time - } - } - localStorage.setItem(key, JSON.stringify(item)) -} - -function loadSettings(key) { - const raw = localStorage.getItem(key) - if (raw) { - let appState = JSON.parse(raw) - const newTime = new Date() - - console.log("newTime: ", newTime, "appState.expiry: ", appState.expiry) - console.log(newTime.getTime() > appState.expiry) - if (newTime.getTime() > appState.expiry) { - localStorage.removeItem(key) - alert("Session expired!") - return null - } - - setFontSize(appState.value.fontSize) - setWrittenText(appState.value.writtenText) - setElementsSize(textArea, appState.value.textAreaSizes) - setElementsSize(keyboardContainer, appState.value.keyboardSizes) - setSelectedKb(appState.value.selectedKbList) - setEnabledKb(appState.value.enabledKb[0]) - - generateKbUI(appState.value.selectedKbList) - console.log(appState.value.enabledKb[1][1], appState.value.enabledKb[1][0]) - // selectKb(appState.value.enabledKb[1][1], appState.value.enabledKb[1][0]) - } -} - -window.addEventListener('load', () => { - loadSettings("keymanWebState") -}) - -window.addEventListener('beforeunload', () => { - buildAppState() -}) - -window.addEventListener('storage', (e) => { - if (e.key == "keymanWebState") { - appState = JSON.parse(e.newValue) - buildAppState() - } -}) - -function searchHistory(value) { - if (kbSearchData.length < 0) { - kbSearchData.push(value) - for (i=0; i<=kbSearchData.length; i++) { - if (value != kbSearchData[i] || kbSearchData.length >= 5) { - kbSearchData.shift() - } - } - } - // console.log(kbSearchData) +keyman = getKeymanWeb() + +function getKeymanWeb() { + if(window.tavultesoft) { + return window.tavultesoft.keymanweb; + } + return window.keyman; +} +/* Global Variables */ +let selectedKbList = [] // Main array for the search, kb selection...etc. +let kbSearchData = [] // For History search +let kmwLang = keyman.getActiveLanguage() +let kmwKb = keyman.getActiveKeyboard() + +const clearSearchIcon = document.querySelector('#clearSearchIcon') +const magnifying = document.querySelector('#magnifyingGlassIcon') + +const elements = { + worldMapBtn: document.querySelector('#worldMap'), + kmwControls: document.querySelector('#KeymanWebControl'), + + kbSelection: document.querySelector('#keyboardSelection'), + keyboardSelectionButton: document.querySelector('#keyboardSelectionButton'), + caretRightIcon: keyboardSelectionButton.querySelector('.fa-caret-right'), + + searchBar: document.querySelector('#searchBar'), + searchInput: document.querySelector('#searchInput'), + searchDropdownMenu: document.querySelector('#searchDropdownMenu'), + searchIcons: document.querySelector('#searchIcons'), +} + +const state = { + mapIsOpen: false +} + +/* + ===================================== Default keyboard ========================================= +*/ + +function defaultKeyboard(kbdname = "basic_kbdus", languageCode = "en") { + if(!exists(kbdname, languageCode)) { + if (textArea) textArea.placeholder = 'A Keyboard name isn\'t specified. Select a keyboard and start typing' + return + } + setKeyboardWithDirection(kbdname, languageCode) +} + +/* + ============================= Toggle between World Map and Search ============================== +*/ +elements.worldMapBtn?.addEventListener('click', (e) => { + e.preventDefault() + state.mapIsOpen = true + if (state.mapIsOpen == true) { + openMap() + keyman.addEventListener('keyboardchange', () => { + location.replace(`#${keyman.getActiveLanguage()},${keyman.getActiveKeyboard()}`) + updateExample(keyman.getActiveKeyboard()) + setTimeout(() => { + applyClassToKb(), 0 + }) + }) + } else { + openSearch() + } +}) + +function openSearch() { + state.mapIsOpen = false + hideEls( + elements.kmwControls, + ) + showEls( + elements.searchDropdownMenu, + elements.searchIcons + ) + + if (selectedKbList.length > 0) { + elements.caretRightIcon.textContent = selectedKbList.length + removeClass(elements.caretRightIcon, 'fa-magnifying-glass') + } else { + elements.caretRightIcon.textContent = '' + elements.caretRightIcon.classList.add('fa-caret-right') + } + + elements.searchBar.replaceChildren( + elements.searchInput, + elements.searchIcons, + elements.searchDropdownMenu + ) +} + +function openMap() { + state.mapIsOpen = true + removeClass( + elements.kmwControls, 'hidden', + elements.caretRightIcon, 'fa-caret-right' + ) + hideEls( + elements.searchDropdownMenu + ) + removeTextContent( + elements.caretRightIcon + ) + elements.keyboardSelectionButton.removeAttribute('id', 'keyboardSelectionButton') + elements.keyboardSelectionButton.setAttribute('id', 'returnToSearchButton') + elements.caretRightIcon.classList.add('fa-magnifying-glass') + elements.keyboardSelectionButton.style.backgroundColor = "var(--keyman-orange)" + elements.keyboardSelectionButton.style.border = '0px' + elements.keyboardSelectionButton.classList.add('return-to-search') + elements.kbSelection.style.display = "none" + elements.searchBar.replaceChildren( + elements.kmwControls + ) +} + +function returnToSearch() { + elements.keyboardSelectionButton.removeAttribute('id', 'returnToSearchButton') + elements.keyboardSelectionButton.setAttribute('id', 'keyboardSelectionButton') + + if ((selectedKbList?.length || 0) < 1) { + elements.caretRightIcon.classList.add('fa-caret-right') + removeClass(elements.caretRightIcon, 'fa-magnifying-glass') + elements.caretRightIcon.textContent = '' + } + + elements.keyboardSelectionButton.style.backgroundColor = "" + elements.kbSelection.style.display = "block" + openSearch() +} + +function waitForElement(selector) { + return new Promise((resolve) => { + const interval = setInterval(() => { + const element = document.querySelector(selector) + if (element) { + clearInterval(interval) + resolve(element) + } + }, 100) + }) +} + +waitForElement('#returnToSearchButton').then((element) => { + element.addEventListener('click', (e) => { + e.preventDefault() + returnToSearch() + }) +}) + +waitForElement(".kmw-osk-frame").then((oskDiv) => { + document.querySelector('.keyboard-area').appendChild(oskDiv) +}) + +/* + ==================== Search Interaction =================== +*/ + +/* Search Input */ +const dropdown = new bootstrap.Dropdown(elements.searchInput, { + autoClose: 'outside' +}) + +document.addEventListener('click', (e) => { + if (!elements.searchInput.contains(e.target) && !elements.searchDropdownMenu.contains(e.target)) { + dropdown.hide() + } +}) + +elements.searchInput.addEventListener('click', (e) => { + e.stopPropagation() + // defaultKeyboard() + dropdown.show() +}) + +// Hide Dropdown Search on Mouse leave +elements.searchDropdownMenu.addEventListener('mouseleave', (e) => { + e.preventDefault() + dropdown.hide() +}) + +/* + =========================== Utility functions ============================ +*/ +function hideEls(...elements) { + return elements.every(el => el.classList.add('hidden')) +} + +function showEls(...elements) { + return elements.every(el => el.classList.remove('hidden')) +} + +function removeClass(element, className) { + return element.classList.remove(className) +} + +function removeTextContent(...elements) { + return elements.every(el => el.textContent = '') +} + +/* Elements validation */ +function exists(...elements) { + return elements.every(el => el != null) +} + +document.addEventListener('DOMContentLoaded', () => { + /* UI Behavior of the Selected Keyboard menu */ + if (exists(elements)) { + elements.keyboardSelectionButton.addEventListener('mouseenter', () => { + elements.kbSelection.classList.add('open') + }) + elements.keyboardSelectionButton.addEventListener('click', () => { + elements.kbSelection.classList.remove('open') + }) + elements.kbSelection.addEventListener('mouseleave', () => { + elements.kbSelection.classList.remove('open') + }) + } +}) + +/* + === Keyboard Execution === +*/ +const downloadBtn = document.getElementById('kbDownloadPage') +const textArea = document.getElementById('textArea') +let langExamples = []; + +function selectKb(kbdname, languageCode) { + if(!exists(kbdname, languageCode)) { + if (textArea) textArea.placeholder = 'A Keyboard name isn\'t specified. Select a keyboard and start typing' + return + } + setKeyboardWithDirection(kbdname, languageCode) +} + +function setTextDirection(targetEls, dir) { + const copyBtn = document.querySelector('#copyTool') + + targetEls.dir = dir + if (dir == 'rtl') { + copyBtn.style.right = '0' + copyBtn.style.left = '10px' + } else { + copyBtn.style.right = '' + copyBtn.style.left = '' + } +} + +// Change and type keyboard +async function setKeyboardWithDirection(kbdname, languageCode) { + const kbSpan = document.querySelector('#kbSpan') + const langTag = `#${languageCode}` + let kbTag = '' + + if (kbdname.match(/Keyboard_*/)) { + kbTag = `${kbdname}` + } else { + kbTag = `Keyboard_${kbdname}` + } + + location.replace(`${langTag},${kbTag}`) + await keyman.addKeyboards(kbdname) + const kbd = keyman.getKeyboard(kbdname, languageCode) + await keyman.setActiveKeyboard(kbdname, languageCode) + + // setTimeout(() => { + // applyClassToKb(), 0 + // }) + + if(kbd) { + textArea.placeholder = `The ${kbdname} keyboard is selected. Start typing...` + kbSpan.innerHTML = `${kbdname}` + + setTextDirection(textArea, textArea.dir) + } + updateExample(kbdname) + if(typeof(KeyboardChange_EmbedFonts) != 'undefined') KeyboardChange_EmbedFonts(kbdname) +} + +/* Language Examples AJAX */ +async function updateExample(kbdname) { + const keymanExample = document.getElementById("example") + const exampleBox = document.getElementById("exampleBox") + + if (!keymanExample || !exampleBox) return false; + + if(kbdname == '') + { + keymanExample.textContent = `No example is available due to empty Keyboard name.` + return true; + } + + let activeLanguage = keyman.getActiveLanguage(); + + if(langExamples[activeLanguage + '_' + kbdname]) + { + keymanExample.innerHTML = langExamples[activeLanguage + '_' + kbdname]; + return true; + } + + langExamples[activeLanguage + '_' + kbdname] = 'Loading...'; + keymanExample.innerHTML = 'Loading...'; + + const link = `/prog/languageexample.php?keyboard=${kbdname}&language=${activeLanguage}`; + try { + const response = await fetch(link); + if(response.status == 200) { + const content = await response.text(); + + langExamples[activeLanguage + '_' + kbdname] = keymanExample.innerHTML = content; + } else { + throw new Error(`Unable to retrieve content, status was ${response.status}: ${response.statusText}`); + } + } catch(e) { + langExamples[activeLanguage + '_' + kbdname] = keymanExample.innerHTML = 'Error retrieving example: '+e.message; + throw e; + } +} + +function applyClassToKb() { + + const kbArea = document.querySelector('.keyboard-area') + if (!kbArea) return + + const apply = () => { + const child = kbArea.children + for (const c of child) { + if (!c.classList.contains('kmw-osk-frame')) { + c.classList.add('kmw-osk-frame') + c.classList.add('kmw-help-osk-frame') + } + } + } + + apply() + + // const observer = new MutationObserver(() => { + // for (const m of mutations) { + // if (m.type === 'childlist' && m.addedNodes.length) { + // apply() + // } + // } + // }) + // observer.observe(kbArea, {childList: true}) +} + +/* Search */ +const kbSearchCard = document.getElementById('kbSearchCardUI'); +let debounceTimer + +/* Pagination */ +prevBtn = document.getElementById('prevPage') +nextBtn = document.getElementById('nextPage') +pageInfo = document.getElementById('pageInfo') + +searchResultCount = document.getElementById('resultCount') +paginationCtrl = document.getElementById('paginationControls') + +let currentPage = 1 +let currentQuery = '' +let totalPage +const itemPerPage = 10 + +prevBtn.addEventListener('click', goPrevPage) +nextBtn.addEventListener('click', goNextPage) + +function updatePaginationCtrl() { + pageInfo.textContent = `${currentPage} of ${totalPage}` + nextBtn.disabled = currentPage >= totalPage + prevBtn.disabled = currentPage <= 1 +} + +function goPrevPage() { + if (currentPage > 1) { + currentPage-- + searchKeyboard(currentQuery, currentPage) + } +} + +function goNextPage() { + if (currentPage < totalPage) { + currentPage++ + searchKeyboard(currentQuery, currentPage) + } +} + +/* Click: Open Search and Display search instructions */ +elements.searchInput.addEventListener('click', function(e) { + const query = e.target.value.trim() + + defaultKeyboard() + if (query == "") { + resetSearch() + } else { + searchKeyboard(query) + } +}) + +/* Input: Search and Display keyboards */ +elements.searchInput.addEventListener('input', function(e) { + handleSearch(e.target.value) +}) + +clearSearchIcon.addEventListener('click', () => { + elements.searchInput.value = '' + handleSearch() + elements.searchInput.focus() +}) + +function handleSearch(value = "") { + currentQuery = value.trim() + currentPage = 1 + + updateSearchIcon(value) + + if (!currentQuery) { + resetSearch() + return + } + debounceSearch(currentQuery, currentPage) +} + +function resetSearch() { + paginationCtrl.style.display = 'none' + defaultSearch() +} + +function updateSearchIcon(value) { + const hasValue = value.length > 0 + magnifying.style.display = hasValue ? 'none' : 'inline' + clearSearchIcon.style.display = hasValue ? 'inline' : 'none' +} + +function debounceSearch(query, page) { + clearTimeout(debounceTimer) + if (query.length > 1) { + debounceTimer = setTimeout(() => { + searchKeyboard(query, page) + }, 300) + } +} + +/* == Section == + Search +*/ + +/* Display top downloads with search Instruction */ +async function defaultSearch() { + kbSearchCard.innerHTML = `

    Loading...

    ` + try { + let response = await fetch(`https://api.keyman.com/search/2.0?q=p:popular`) + if (!response.ok) { + throw new Error(`API request failed with status ${response.status}`) + } + + let data = await response.json() + + let mostDownloadkb = data.keyboards + + if (!mostDownloadkb || !Array.isArray(mostDownloadkb)) { + throw new Error(`Invalid API response structure`) + } + displaySearch(mostDownloadkb) + } + catch(error) { + console.error(`Error fetching ${error}`) + kbSearchCard.innerHTML = `
    No keyboards are found.
    ` + paginationCtrl.style.display = 'none' + } +} + +/* Get query and return search */ +async function searchKeyboard(query = null, page) { + kbSearchCard.innerHTML = `
    Searching ${query}...
    ` + kbSearchCard.style.display = 'block' + + let response = await fetch(`https://api.keyman.com/search/2.0?q=${encodeURIComponent(query)}&p=${page}`) + if (!response.ok) { + throw new Error(`API request failed with status ${response.status}`) + } + + searchHistory(query) + let data = await response.json() + // Found with Context: Setup pagination + if (data.context) { + totalPage = data.context.totalPages || 1; + currentPage = data.context.pageNumber || 1; + } else { + totalPage = Math.ceil(data.keyboards.length / itemPerPage); + } + + // Validate data.keyboards + let keyboardData = data.keyboards + if (!keyboardData || !Array.isArray(keyboardData)) { + throw new Error("Invalid API response structure") + } + + // Get total result + let totalFound = data.context.totalRows + + updatePaginationCtrl() + displaySearch(keyboardData, totalFound, query) +} + +/* Display items return from search */ +function displaySearch(data, total = 0, query = '') { + kbSearchCard.innerHTML = ''; + + if (!data || data.length == 0) { + kbSearchCard.innerHTML = 'No keyboards are found.' + paginationCtrl.style.display = 'none' + return + } + + if (total) { + searchResultCount.innerHTML = `${total} results` + searchResultCount.classList.remove('hidden') + } + + // Getting searched Word ready for highlight + const marked = getMarkedContext(query) + + const searchInstruction = document.querySelector('.search-instruction') + const kbHrTitle = document.querySelector('.keyboard-title') + if (!query) { + searchInstruction.classList.remove("hidden") + kbHrTitle.textContent = "Most Downloads" + } else { + searchInstruction.classList.add("hidden") + kbHrTitle.textContent = "" + } + data.forEach(kb => { + const card = searchKbCardUI(kb, marked, selectedKbList, data) + kbSearchCard.appendChild(card) + }) + paginationCtrl.style.display = 'flex'; +} + +// UI Search card +function searchKbCardUI(kb, marked = '', selectedKbList, data) { + const kbFoundInList = selectedKbList.some(selected => selected.id == kb.id) + // Keyboard card container + let cardWrap = document.createElement('div') + cardWrap.classList.add('card-wrap') + cardWrap.setAttribute('id', 'keyboardCardWrap') + + // Keyboard header container + let cardHeader = document.createElement('div') + cardHeader.classList.add('card-header') + + const {matchFound, matchField, matchValue} = highlightSearchContext(kb, marked) + + const kbNameHeading = matchFound ? showMarkedContext(kb, matchField, matchValue) + : (() => { + const heading = document.createElement('h4') + heading.innerHTML = kb.name + return heading + }) + + // Keyboard Plus (+) icon + const kbIconPTag = document.createElement('p') + kbIconPTag.textContent = kbFoundInList ? "-" : "+" + kbIconPTag.style.fontSize = '20px' + kbIconPTag.style.cursor = 'pointer' + kbIconPTag.classList.add('kb-icon-plus') + + checkKbCardUI(kbIconPTag, cardWrap, kb) + // Keyboard ID + const kbIdPTag = document.createElement('p') + kbIdPTag.classList.add('keyboard-id') + kbIdPTag.textContent = kb.id + + // Keyboard Description + const kbDescHeading = truncateDesc(kb, matchField, marked) + + // Keyboard monthly downloads and platform support + const kbSpecs = document.createElement('div') + kbSpecs.classList.add('keyboard-specs') + + const kbDownloadHeading = document.createElement('h6') + kbDownloadHeading.textContent = `${kb.match.downloads} monthly downloads` + kbDownloadHeading.classList.add('monthly-download') + + const kbPlatformSupport = document.createElement('div') + kbPlatformSupport.classList.add('platform') + kbPlatformSupport.innerHTML = platformSupport(kb.platformSupport) + + // Append children + cardHeader.appendChild(kbNameHeading) + cardHeader.appendChild(kbIconPTag) + + kbSpecs.appendChild(kbDownloadHeading) + kbSpecs.appendChild(kbPlatformSupport) + + cardWrap.appendChild(cardHeader) + cardWrap.appendChild(kbIdPTag) + cardWrap.appendChild(kbDescHeading) + cardWrap.appendChild(kbSpecs) + + // Choose keyboard to selection + kbIconPTag.onclick = (e) => { + e.stopPropagation() + addKbToSelectionMenu(kbIconPTag, cardWrap, kb, data) + textArea.focus() + selectKb() + } + // console.log("Recent:", historyKbSelection.getHistory()); + + return cardWrap +} + +// Disable or Enable search card +function checkKbCardUI(kbIconPTag, cardWrap, kb) { + // For checking if the keyboard exists in selected Kbs + let kbFoundInList = selectedKbList.some(selected => selected.id == kb.id) + if (kbFoundInList) { + cardWrap.classList.add('disabled') + } else { + cardWrap.classList.remove('disabled') + } +} + +// Highlight word searched +function getMarkedContext(query) { + let escapedTerm = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + return new RegExp(escapedTerm, 'i') +} + +// Find a match between Search Context and Language, Keyboard name, Description +function highlightSearchContext(kb, marked) { + let matchFound = false + let matchField = "" + let matchValue = "" + + // Get and find language that matches the search + for (lang in kb.languages) { + let langData = kb.languages[lang] + for (key in langData) { + const value = langData[key] + if (typeof value == "string" && marked.test(value)) { + matchFound = true + matchValue = value.replace(marked, (m) => m ? `${m}` : m) + matchField = "language" + break + } + } + if (matchFound) break + } + + // Find a match for keyboard name if language is not a match + if (!matchFound && marked.test(kb.name)) { + matchFound = true + matchValue = kb.name.replace(marked, '$&') + matchField = "keyboard" + } + + // Find a match for keyboard description if name is not a match + if (!matchFound && marked.test(kb.description)) { + matchFound = true + matchField = "description" + } + + return {matchField, matchValue, matchFound} +} + +// Display Highlighted Search Context +function showMarkedContext(kb, matchField, matchValue) { + const kbNameHeading = document.createElement('h4') + + const kbHelpLink = document.createElement('a') + kbHelpLink.href = `https://help.keyman.com/keyboard/${kb.id}` + kbHelpLink.target = '_blank' + kbHelpLink.rel = 'noopener noreferrer' + + // Display matched language + const langNameSpan = document.createElement('span') + langNameSpan.style.fontSize = "14px" + if (matchField == "language") { + langNameSpan.innerHTML = matchField == "language" ? ` (${matchValue} language)` : "" + } + + // Display matched keyboard + if (matchField == "keyboard") { + kbHelpLink.innerHTML = matchValue + } else { + kbHelpLink.textContent = kb.name + } + kbNameHeading.appendChild(kbHelpLink) + kbNameHeading.appendChild(langNameSpan) + kbNameHeading.addEventListener('click', () => { + const checkedURL = validateURL(`https://help.keyman.com/keyboard/`) + const newURL = checkedURL + kb.id + window.open(newURL, '_blank') + }) + + return kbNameHeading +} + +// Truncated Keyboard Description +function truncateDesc(kb, matchField, marked) { + const kbDescHeading = document.createElement('h6') + kbDescHeading.classList.add("keyboard-description") + const word_limits = 90 + + let temp = document.createElement('div') + temp.innerHTML = kb.description + + let fullDesc = kb.description + let plainText = temp.textContent + let shortText = "" + + let isTruncated = false + + if (plainText.length >= word_limits) { + shortText = plainText.slice(0, word_limits) + "..." + kbDescHeading.innerHTML = shortText + isTruncated = true + } else { + kbDescHeading.innerHTML = fullDesc + isTruncated = false + } + + if (isTruncated) { + const toggleBtn = document.createElement('a') + toggleBtn.href = "#" + toggleBtn.style.marginLeft = "6px" + toggleBtn.textContent = "Show more" + + toggleBtn.addEventListener('click', e => { + e.preventDefault() + const isExpanded = toggleBtn.textContent == "Show more" + kbDescHeading.innerHTML = !isExpanded ? shortText.replace(marked, (m) => m ? `${m}` : m) : fullDesc + if (matchField == 'description') { + kbDescHeading.innerHTML = isExpanded ? fullDesc.replace(marked, '$&') : shortText + } + kbDescHeading.style.color = isExpanded ? 'black' : 'gray' + toggleBtn.textContent = isExpanded ? "Show less" : "Show more" + kbDescHeading.appendChild(toggleBtn) + }) + kbDescHeading.appendChild(toggleBtn) + } + + return kbDescHeading +} + +/* + == End of Search Section == +*/ + +// Platform Support +function platformSupport(data) { + const platformMap = { + android: "Android", + desktopWeb: "Web", + ios: "iPhone and iPad", + linux: "Linux", + macos: "macOS", + mobileWeb: "Mobile web", + windows: "Windows" + } + let platformSpan = Object.entries(data) + .filter(([_, supportLevel]) => supportLevel == 'full') + .map(([platform]) => `${platformMap[platform]}`).join('') + + return platformSpan +} + +/* == Section == + Keyboard Selection Menu +*/ +function addKbToSelectionMenu(kbIconPTag, cardWrap, kb, data) { + const keyboardSelectionButton = document.getElementById('keyboardSelectionButton') + let isSelected = selectedKbList.some(selected => selected.id == kb.id) + addDataKb(data) + // Remove keyboard + if (isSelected) { + removeKbSelected(kb.id) + kbIconPTag.textContent = '+' + generateKbUI(selectedKbList) + checkKbCardUI(kbIconPTag, cardWrap, kb) + + return + } + if(selectedKbList.length < 5) { + addKbToSelection(kb) + generateKbUI(selectedKbList) + kbIconPTag.textContent = 'โœ“' + kbIconPTag.classList.add('kb-icon-plus-animate') + + setTimeout(() => { + kbIconPTag.textContent = '-' + kbIconPTag.classList.remove('kb-icon-plus-animate') + keyboardSelectionButton.classList.remove('btn-secondary') + keyboardSelectionButton.classList.add('btn-keyman-orange') + }, 800) + + checkKbCardUI(kbIconPTag, cardWrap, kb) + return + } + confirmAndAddKb(() => { + addKbToSelection(kb) + generateKbUI(selectedKbList) + + kbIconPTag.textContent = 'โœ“' + kbIconPTag.classList.add('kb-icon-plus-animate') + + setTimeout(() => { + kbIconPTag.textContent = '-' + kbIconPTag.classList.remove('kb-icon-plus-animate') + keyboardSelectionButton.classList.remove('btn-secondary') + keyboardSelectionButton.classList.add('btn-keyman-orange') + }, 800) + checkKbCardUI(kbIconPTag, cardWrap, kb) + }) +} + +// Add keyboard for kb search and selection UI +function addKbToSelection(kb) { + const kbInfo = { + "id": kb.id, + "name": kb.name, + "version": kb.version, + "helpLink": kb.helpLink, + "platformSupport": kb.platformSupport, + "totalDownloads": kb.match.totalDownloads, + "sourcePath": kb.sourcePath, + "supportedLanguage": kb.languages, + "lastUpdated": kb.lastModifiedDate + } + // historyKbSelection.add(kbInfo) + selectedKbList.push(kbInfo) +} + +// UI for keyboard selection menu +function generateKbUI(selectedKbList) { + const keyboardSelection = document.getElementById("keyboardSelection") + keyboardSelection.innerHTML = '' + + if(selectedKbList.length < 1) { + triggerKbCount(selectedKbList) + resetKbSelectionMenu() + return + } + + const kbDivHeader = document.createElement('div') + kbDivHeader.textContent = "Keyboard Selection menu" + kbDivHeader.classList.add('kb-item-header') + + const kbDivFoot = document.createElement('div') + kbDivFoot.textContent = "US Basic Keyboard" + kbDivFoot.classList.add('kb-item-footer') + + keyboardSelection.appendChild(kbDivHeader) + + selectedKbList.forEach(data => { + const kbDiv = document.createElement('div') + kbDiv.classList.add("kb-item") + kbDiv.setAttribute('id', `${data.id}`) + + const kbName = document.createElement('span') + kbName.textContent = data.name + + const kbConfigList = document.createElement('ul') + kbConfigList.classList.add('keyboard-configs') + kbConfigList.innerHTML = ` +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • + ` + + const kbDetails = displayKbDetails(data) + + kbDiv.appendChild(kbName) + kbDiv.appendChild(kbConfigList) + kbDiv.appendChild(kbDetails) + keyboardSelection.appendChild(kbDiv) + keyboardSelection.append(kbDivFoot) + + let kbdName = data.id + let langCode = Object.keys(data.supportedLanguage)[0] || "en" + + selectKb(kbdName, langCode) + kbConfigList.addEventListener('click', (e) => { + const target = e.target + if (target.tagName == 'I' && target.dataset.action) { + const action = target.dataset.action + const id = target.dataset.id + const helpLink = target.dataset.helplink + kbConfigMenu(action, id, helpLink) + } + }) + + kbDiv.addEventListener('click', () => { + kbdName = data.id + langCode = Object.keys(data.supportedLanguage)[0] || "en" + textArea.focus() + selectKb(kbdName, langCode) + }) + + kbDivFoot.onclick = () => { + defaultKeyboard() + } + + const kbHelpLink = document.querySelector('#kbHelpdocLink') + kbHelpLink.addEventListener('click', (e) => { + kbConfigMenu('help', '', data.helpLink) + }) + }) + triggerKbCount(selectedKbList) +} + +// Keyboard count for Keyboard selection menu +function triggerKbCount(selectedKbList) { + const kbSelectedLength = selectedKbList.length + const keyboardSelectionButton = document.querySelector('#keyboardSelectionButton') + const keyboardCount = document.querySelector('#kbCount') + + if (kbSelectedLength >= 1) { + keyboardCount.classList.remove('fa-caret-right') + keyboardCount.textContent = `${kbSelectedLength}` + keyboardSelectionButton.classList.add('btn-keyman-orange') + keyboardSelectionButton.classList.remove('btn-secondary') + } else { + keyboardCount.classList.add('fa-caret-right') + keyboardCount.textContent = '' + keyboardSelectionButton.classList.remove('btn-keyman-orange') + keyboardSelectionButton.classList.add('btn-secondary') + } +} + +// Keyboard count default for Keyboard selection menu +function resetKbSelectionMenu() { + const keyboardSelection = document.querySelector("#keyboardSelection") + + const kbDivHeader = document.createElement('div') + kbDivHeader.textContent = "Keyboard Selection menu" + kbDivHeader.classList.add('kb-item-header') + + const kbItem = document.createElement('div') + kbItem.classList.add('.kb-item') + + const pTag = document.createElement('p') + pTag.textContent = "Open Search to get your keyboard" + + const kbDivFoot = document.createElement('div') + kbDivFoot.textContent = "US Basic Keyboard" + kbDivFoot.classList.add('kb-item-footer') + + kbItem.appendChild(pTag) + + keyboardSelection.appendChild(kbDivHeader) + keyboardSelection.appendChild(kbItem) + keyboardSelection.appendChild(kbDivFoot) +} + +// Compare and remove keyboard +function removeKbSelected(kbId) { + if(kbId) { + selectedKbList = selectedKbList.filter(kb => kb.id !== kbId) + } +} + +// Check 6th keyboard +function confirmAndAddKb(onConfirmAdd) { + if (typeof onConfirmAdd != 'function') { + console.log("Expected the onConfirmAdd a function, instead got: " + typeof onConfirmAdd) + alert("Click on the keyboard again to enable.") + } + + const warningDialogUI = limitKbSelectionUI(() => { + onConfirmAdd() + selectedKbList.shift() + generateKbUI(selectedKbList) + }) + + document.body.appendChild(warningDialogUI) +} + +// UI for Keyboard Selected Limitation +function limitKbSelectionUI(onAccept) { + const dialogDiv = document.createElement('div') + dialogDiv.classList.add('warning-container') + + const dialogContentDiv = document.createElement('div') + dialogContentDiv.classList.add('warning-content') + + const dialogCancel = document.createElement('button') + dialogCancel.classList.add('warning-cancel-btn') + dialogCancel.setAttribute('id', 'cancelWarningBtn') + dialogCancel.textContent = 'โœ–' + dialogCancel.onclick = () => { + dialogDiv.remove() + generateKbUI(selectedKbList) + } + + const dialogImgTag = document.createElement('img') + dialogImgTag.classList.add('warning-keyman-image') + dialogImgTag.src = `/cdn/dev/img/keymanweb-mini-logo-88.png` + dialogImgTag.alt = "Keyman Logo" + + const firstKeyboard = selectedKbList[0].name + + const dialogPTag = document.createElement('p') + dialogPTag.classList.add('warning-text') + dialogPTag.innerHTML = `The keyboards selected exceeds the limitation of 5 keyboards. Click 'Allow' to remove the
    ${firstKeyboard} keyboard.` + + const dialogUlTag = document.createElement('ol') + dialogUlTag.textContent = "Your keyboards selection:" + selectedKbList.forEach((kb, index) => { + const dialogLiTag = document.createElement('li') + if (index == 0) { + const markKeyboard = document.createElement('mark') + markKeyboard.textContent = kb.name + dialogLiTag.appendChild(markKeyboard) + } else { + dialogLiTag.textContent = kb.name + } + dialogUlTag.appendChild(dialogLiTag) + + }) + + const dialogAccept = document.createElement('button') + dialogAccept.classList.add('warning-accept-btn') + dialogAccept.setAttribute('id', 'acceptWarningBtn') + dialogAccept.textContent = "Allow" + dialogAccept.onclick = () => { + dialogDiv.remove() + onAccept() + } + + dialogContentDiv.appendChild(dialogCancel) + dialogContentDiv.appendChild(dialogImgTag) + dialogContentDiv.appendChild(dialogPTag) + dialogContentDiv.appendChild(dialogUlTag) + dialogContentDiv.appendChild(dialogAccept) + + dialogDiv.appendChild(dialogContentDiv) + + return dialogDiv +} + +// Seperate list for History/Remember Search + +/* + ========================== To be continued ========================== +*/ +function addDataKb(data) { + let selectedKbData = [] + // console.log(data) + const kbInfo = { + "platformSupport": data.platformSupport, + // "monthlyDownloads": data.match.downloads, + "sourceFile": data.sourcePath, + } + selectedKbData.push(kbInfo) +} + +// End of History search + +// Keyboard selection menu's tools: help, download, and remove +function kbConfigMenu(action, id, helplink) { + if (action == "help") { + window.open(helplink, '_blank') + } + + if (action == "download") { + const downloadUrl = `https://keyman.com/keyboards/install/${id}` + window.open(downloadUrl, '_blank') + } + + if (action == "remove") { + removeKbSelected(id) + generateKbUI(selectedKbList) + triggerKbCount(selectedKbList) + } + + if (action == "info") { + const kbDetails = document.querySelector(`#keyboard-${id}-details`) + + kbDetails.addEventListener('mouseleave', () => { + kbDetails.classList.add('hidden') + }) + kbDetails.classList.remove('hidden') + } +} + +// Keyboard details for Keyboard selection menu +function displayKbDetails(data) { + const item = selectedKbList.find(kb => kb.id == data.id) + if (!item) return; + + const kbDetails = document.createElement('div') + kbDetails.classList.add('keyboard-details') + kbDetails.setAttribute('id', `keyboard-${data.id}-details`) + kbDetails.classList.add('animate__animated', 'animate__fadeIn') + kbDetails.classList.add('hidden') + + const kbDetailsHead = document.createElement('div') + kbDetailsHead.textContent = 'Keyboard Details' + kbDetailsHead.classList.add('kb-item-header') + + const kbDetailsContent = document.createElement('div') + kbDetailsContent.classList.add('keyboard-content-wrapper') + kbDetailsContent.innerHTML = ` +
      +
    • +
      +
      Name
      +
      ${item.name || "N/A"}
      +
      +
    • +
    • +
      +
      Keyboard ID
      +
      ${item.id || "N/A"}
      +
      +
    • +
    • +
      +
      Version
      +
      ${item.version || "N/A"}
      +
      +
    • +
    • +
      +
      Total downloads
      +
      ${item.totalDownloads || 0}
      +
      +
    • +
    • +
      +
      Source Path
      + +
      +
    • +
    • +
      +
      Supported Platforms
      +
      + ${platformSupport(item.platformSupport) || 'No platforms supported'} +
      +
      +
    • +
    • +
      +
      Last Updated
      +
      ${getOnlyDates(item.lastUpdated) || 0}
      +
      +
    • +
    + ` + kbDetails.appendChild(kbDetailsHead) + kbDetails.appendChild(kbDetailsContent) + + return kbDetails +} + +// Get only the YYYY-mm-dd format +function getOnlyDates(dateData) { + const finalDateData = dateData.match(/^\d{4}-\d{2}-\d{2}/) + return finalDateData +} + +// Validate URLs +function validateURL(string) { + try { + const newUrl = new URL(string) + if (newUrl.protocol === 'https:') { + return newUrl + } else { + return false + } + } catch (error) { + console.error(error) + } +} +/* + == End of Keyboard Selection menu Section == +*/ + +/* + == Store data in localStorage to use for reload == +*/ +let appState = { + fontSize: 16, + writtenText: "", + selectedKbList: [], + enabledKb: null, + keyboardSizes: null, + textAreaSizes: null +} +const keyboardContainer = document.querySelector('.keyboard-container') +const fontSizeRange = document.querySelector('#fontSizeRange') + +function getFontSize(element) { + let theFontSize + theFontSize = parseInt(window.getComputedStyle(element).fontSize) || "16" + + return theFontSize +} + +function getSelectedKb() { + return selectedKbList || [] +} + +function getEnabledKb() { + let hash = location.hash.match(/^#(.+),(Keyboard_.+)$/i)[0] + + let kbValues = hash.replace('#', '') + kbValues = hash.split(',') + + return [hash, kbValues] +} + +function getElementsSize(element) { + const rect = element.getBoundingClientRect() + return { + height: rect.height, + width: rect.width, + positionX: rect.x, + positionY: rect.y + } +} + +function getElementValue(element) { + return element.value +} + +function setFontSize(size) { + textArea.style.fontSize = size + "px" + fontSizeRange.value = size +} + +function setWrittenText(text) { + textArea.value = text +} + +function setElementsSize(element, sizes) { + element.style.height = sizes.height + "px" + element.style.left = sizes.positionX + "px" + element.style.top = sizes.positionY + "px" +} + +function setSelectedKb(savedKbList) { + selectedKbList = savedKbList +} + +function setEnabledKb(kb) { + if (kb) { + selectKb(kb) + } +} + +function buildAppState() { + appState = { + fontSize: getFontSize(textArea), + selectedKbList: getSelectedKb(), + enabledKb: getEnabledKb(), + textAreaSizes: getElementsSize(textArea), + keyboardSizes: getElementsSize(keyboardContainer), + writtenText: getElementValue(textArea) + } + saveSettings("keymanWebState", appState) +} + +function saveSettings(key, state) { + let recentTime = new Date() + const time = 5000 // equals to An hour + let item + + // console.log("recentTime: ", recentTime) + // console.log("recentTime.getTime(): ", recentTime.getTime()) + + if (state) { + item = { + value: state, + expiry: recentTime.getTime() + time + } + } + localStorage.setItem(key, JSON.stringify(item)) +} + +function loadSettings(key) { + const raw = localStorage.getItem(key) + if (raw) { + let appState = JSON.parse(raw) + const newTime = new Date() + + console.log("newTime: ", newTime, "appState.expiry: ", appState.expiry) + console.log(newTime.getTime() > appState.expiry) + if (newTime.getTime() > appState.expiry) { + localStorage.removeItem(key) + alert("Session expired!") + return null + } + + setFontSize(appState.value.fontSize) + setWrittenText(appState.value.writtenText) + setElementsSize(textArea, appState.value.textAreaSizes) + setElementsSize(keyboardContainer, appState.value.keyboardSizes) + setSelectedKb(appState.value.selectedKbList) + setEnabledKb(appState.value.enabledKb[0]) + + generateKbUI(appState.value.selectedKbList) + console.log(appState.value.enabledKb[1][1], appState.value.enabledKb[1][0]) + // selectKb(appState.value.enabledKb[1][1], appState.value.enabledKb[1][0]) + } +} + +window.addEventListener('load', () => { + loadSettings("keymanWebState") +}) + +window.addEventListener('beforeunload', () => { + buildAppState() +}) + +window.addEventListener('storage', (e) => { + if (e.key == "keymanWebState") { + appState = JSON.parse(e.newValue) + buildAppState() + } +}) + +function searchHistory(value) { + if (kbSearchData.length < 0) { + kbSearchData.push(value) + for (i=0; i<=kbSearchData.length; i++) { + if (value != kbSearchData[i] || kbSearchData.length >= 5) { + kbSearchData.shift() + } + } + } + // console.log(kbSearchData) } \ No newline at end of file From a13f8e9fe95fe1922abb50c4bf6ab9ff8ed13a56 Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Mon, 6 Oct 2025 15:41:27 +0700 Subject: [PATCH 32/36] feat: remove unused images --- cdn/dev/img/desktop-keyboard.png | Bin 116931 -> 0 bytes cdn/dev/img/headerbar copy.png | Bin 507 -> 0 bytes cdn/dev/img/phone-keyboard.png | Bin 81945 -> 0 bytes 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 cdn/dev/img/desktop-keyboard.png delete mode 100644 cdn/dev/img/headerbar copy.png delete mode 100644 cdn/dev/img/phone-keyboard.png diff --git a/cdn/dev/img/desktop-keyboard.png b/cdn/dev/img/desktop-keyboard.png deleted file mode 100644 index 29706d44a41c1a78740f8a853768d045016b5c3f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 116931 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 C0V>G= From f3224cf5238cb7db964e05b1e7ba3bb0bc6b604a Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Tue, 14 Oct 2025 11:21:16 +0200 Subject: [PATCH 33/36] docs: add Docker instructions to README.md Part of a set of README.md updates for all our major websites. Test-bot: skip --- README.md | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 42105f7..0ba5475 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,106 @@ # keymanweb.com -Home page for online web keyboard with support for over 2000 languages +This is the source for the website https://keymanweb.com/, which hosts the +KeymanWeb online keyboard supporting over 2500 different languages. This site +runs on Apache in a Docker container. + +## Other Keyman websites + +* **[api.keyman.com]** - database backend for Keyman websites +* **[help.keyman.com]** - documentation home for Keyman +* **[keyman.com]** - Keyman home +* **[keymanweb.com]** - KeymanWeb online keyboard +* **[s.keyman.com]** - static Javascript, font, and related resources +* **[website-local-proxy]** - run all Keyman sites on localhost on the same port + +## How to run keymanweb.com locally + +When run locally, this site can be accessed at http://localhost:8057 or +http://web.keyman.com.localhost:8057. Note that the site is internally called +web.keyman.com, but the public site is at keymanweb.com; web.keyman.com +automatically forwards to keymanweb.com. + +**Recommended:** Use [website-local-proxy] to run multiple keyman.com sites +all from the same port (default port 80). + +**Recommended:** Use [shared-sites] to control startup and shutdown of all +keyman.com sites together. + +### Prerequisites + +The host machine needs the following apps installed: +* [Git] +* Bash 5.x (on Windows, you can use Git Bash that comes with [Git]) +* [Docker Desktop] + +
    + Configuration of Docker on Windows + + On Windows machines, you can setup Docker in two different ways, either of + which should work: + * [Enable Hyper-V on Windows 11](https://techcommunity.microsoft.com/t5/educator-developer-blog/step-by-step-enabling-hyper-v-for-use-on-windows-11/ba-p/3745905) + * [WSL2](https://ubuntu.com/tutorials/install-ubuntu-on-wsl2-on-windows-10#1-overview) + +
    + +### Actions + +#### Build the Docker image + +The first time you want to start up the site, or if there have been Docker +configuration changes, you will need to rebuild the Docker images. Start a bash +shell, and from this folder, run: + +```sh +./build.sh build +``` + +#### Start the Docker container + +To start up the website, in bash, run: + +```sh +./build.sh start --debug +``` + +Once the container starts, you can access the web.keyman.com site at +http://localhost:8057 or http://web.keyman.com.localhost:8057. Note that the +site is internally called web.keyman.com, but the public site is at +keymanweb.com; web.keyman.com automatically forwards to keymanweb.com. + +#### Stop the Docker container + +In bash, run: + +```sh +./build.sh stop +``` + +#### Remove the Docker container and image + +In bash, run: + +```sh +./build.sh clean +``` + +#### Running tests + +To check for broken links and .php file conformance, when the site is running, +in bash, run: + +```sh +./build.sh test +``` + +[Git]: https://git-scm.com/downloads +[Docker Desktop]: https://docs.docker.com/get-docker/ +[api.keyman.com]: https://github.com/keymanapp/api.keyman.com +[help.keyman.com]: https://github.com/keymanapp/help.keyman.com +[keyman.com]: https://github.com/keymanapp/keyman.com +[keymanweb.com]: https://github.com/keymanapp/keymanweb.com +[s.keyman.com]: https://github.com/keymanapp/s.keyman.com +[website-local-proxy]: https://github.com/keymanapp/website-local-proxy +[shared-sites]: https://github.com/keymanapp/shared-sites +[enable Hyper-V]: https://techcommunity.microsoft.com/t5/educator-developer-blog/step-by-step-enabling-hyper-v-for-use-on-windows-11/ba-p/3745905 +[enable WSL2]: https://ubuntu.com/tutorials/install-ubuntu-on-wsl2-on-windows-10#1-overview From 8590fc54efc9d6990546850ebdfbafdba1d11e57 Mon Sep 17 00:00:00 2001 From: keyman-server Date: Fri, 17 Oct 2025 03:49:26 +0000 Subject: [PATCH 34/36] chore: update BOOTSTRAP_VERSION to v1.0.7 --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 04c255d..c455dc2 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ ## START STANDARD SITE BUILD SCRIPT INCLUDE readonly THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" readonly BOOTSTRAP="$(dirname "$THIS_SCRIPT")/resources/bootstrap.inc.sh" -readonly BOOTSTRAP_VERSION=v1.0.6 +readonly BOOTSTRAP_VERSION=v1.0.7 [ -f "$BOOTSTRAP" ] && source "$BOOTSTRAP" || source <(curl -H "Cache-Control: no-cache" -fs https://raw.githubusercontent.com/keymanapp/shared-sites/$BOOTSTRAP_VERSION/bootstrap.inc.sh) ## END STANDARD SITE BUILD SCRIPT INCLUDE From 05c8dfd1c8b927d27a193dc69c81ea5271b445eb Mon Sep 17 00:00:00 2001 From: keyman-server Date: Wed, 26 Nov 2025 06:13:49 +0000 Subject: [PATCH 35/36] chore: update BOOTSTRAP_VERSION to v1.08 --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index c455dc2..19ea186 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ ## START STANDARD SITE BUILD SCRIPT INCLUDE readonly THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" readonly BOOTSTRAP="$(dirname "$THIS_SCRIPT")/resources/bootstrap.inc.sh" -readonly BOOTSTRAP_VERSION=v1.0.7 +readonly BOOTSTRAP_VERSION=v1.08 [ -f "$BOOTSTRAP" ] && source "$BOOTSTRAP" || source <(curl -H "Cache-Control: no-cache" -fs https://raw.githubusercontent.com/keymanapp/shared-sites/$BOOTSTRAP_VERSION/bootstrap.inc.sh) ## END STANDARD SITE BUILD SCRIPT INCLUDE From eea9658f06cdfd958b1f9926e76190fd77f32dcb Mon Sep 17 00:00:00 2001 From: Meng-Heng Date: Fri, 9 Jan 2026 16:56:59 +0700 Subject: [PATCH 36/36] feat: divide scripts into operation and feature folders; functions and styles include all of the new kmw design --- cdn/dev/css/footer.css | 0 cdn/dev/css/kmw-body.css | 265 +--- cdn/dev/css/kmw-desktop.css | 157 +- cdn/dev/css/{kmw.css => kmw-global.css} | 44 +- cdn/dev/css/kmw-header.css | 715 +++++---- cdn/dev/css/kmw-interaction.css | 62 + cdn/dev/css/kmw-mobile.css | 260 +++- cdn/dev/css/kmw-screen.css | 71 + cdn/dev/css/kmw-tablet.css | 475 ++---- cdn/dev/js/api.js | 6 + cdn/dev/js/feature/copy.js | 28 + cdn/dev/js/feature/eraser.js | 89 ++ cdn/dev/js/feature/expand-textarea.js | 14 + cdn/dev/js/feature/font-slider.js | 7 + cdn/dev/js/feature/hide-keyboard.js | 14 + cdn/dev/js/feature/kb-selection-menu.js | 366 +++++ cdn/dev/js/feature/pagination.js | 43 + cdn/dev/js/feature/search.js | 180 +++ cdn/dev/js/feature/tool-tray.js | 95 ++ cdn/dev/js/kmwBody.js | 118 -- cdn/dev/js/kmwElements.js | 36 - cdn/dev/js/kmwHeader.js | 1356 ----------------- cdn/dev/js/main.mjs | 133 ++ cdn/dev/js/operation/bundleKbSelectionMenu.js | 18 + cdn/dev/js/operation/confirmKeyboard.js | 19 + cdn/dev/js/operation/handleKeyboardData.js | 17 + cdn/dev/js/operation/keyboard.js | 94 ++ cdn/dev/js/operation/keyboardDetails.js | 31 + cdn/dev/js/operation/paginationLogic.js | 17 + cdn/dev/js/operation/platformSupport.js | 17 + cdn/dev/js/operation/rememberState.js | 36 + cdn/dev/js/operation/resizeKeyboard.js | 61 + cdn/dev/js/operation/resizeTextArea.js | 20 + cdn/dev/js/operation/searchAPI.js | 11 + cdn/dev/js/operation/searchCardContent.js | 136 ++ cdn/dev/js/operation/searchLogic.js | 87 ++ cdn/dev/js/operation/selectedKb.js | 26 + cdn/dev/js/operation/toggleInstruction.js | 27 + cdn/dev/js/operation/validURL.js | 13 + cdn/dev/js/operation/waitForElement.js | 12 + cdn/dev/js/state/appState.js | 65 + cdn/dev/js/state/elementSize.js | 12 + cdn/dev/js/state/elementValue.js | 7 + cdn/dev/js/state/enableKb.js | 29 + cdn/dev/js/state/fontState.js | 10 + cdn/dev/js/state/selectedKbList.js | 10 + cdn/dev/js/state/storage.js | 35 + cdn/fonts/social-logos.ttf | Bin 17356 -> 12968 bytes inc/head.php | 57 +- index.php | 190 ++- 50 files changed, 2941 insertions(+), 2650 deletions(-) delete mode 100644 cdn/dev/css/footer.css rename cdn/dev/css/{kmw.css => kmw-global.css} (58%) create mode 100644 cdn/dev/css/kmw-interaction.css create mode 100644 cdn/dev/css/kmw-screen.css create mode 100644 cdn/dev/js/api.js create mode 100644 cdn/dev/js/feature/copy.js create mode 100644 cdn/dev/js/feature/eraser.js create mode 100644 cdn/dev/js/feature/expand-textarea.js create mode 100644 cdn/dev/js/feature/font-slider.js create mode 100644 cdn/dev/js/feature/hide-keyboard.js create mode 100644 cdn/dev/js/feature/kb-selection-menu.js create mode 100644 cdn/dev/js/feature/pagination.js create mode 100644 cdn/dev/js/feature/search.js create mode 100644 cdn/dev/js/feature/tool-tray.js delete mode 100644 cdn/dev/js/kmwBody.js delete mode 100644 cdn/dev/js/kmwElements.js delete mode 100644 cdn/dev/js/kmwHeader.js create mode 100644 cdn/dev/js/main.mjs create mode 100644 cdn/dev/js/operation/bundleKbSelectionMenu.js create mode 100644 cdn/dev/js/operation/confirmKeyboard.js create mode 100644 cdn/dev/js/operation/handleKeyboardData.js create mode 100644 cdn/dev/js/operation/keyboard.js create mode 100644 cdn/dev/js/operation/keyboardDetails.js create mode 100644 cdn/dev/js/operation/paginationLogic.js create mode 100644 cdn/dev/js/operation/platformSupport.js create mode 100644 cdn/dev/js/operation/rememberState.js create mode 100644 cdn/dev/js/operation/resizeKeyboard.js create mode 100644 cdn/dev/js/operation/resizeTextArea.js create mode 100644 cdn/dev/js/operation/searchAPI.js create mode 100644 cdn/dev/js/operation/searchCardContent.js create mode 100644 cdn/dev/js/operation/searchLogic.js create mode 100644 cdn/dev/js/operation/selectedKb.js create mode 100644 cdn/dev/js/operation/toggleInstruction.js create mode 100644 cdn/dev/js/operation/validURL.js create mode 100644 cdn/dev/js/operation/waitForElement.js create mode 100644 cdn/dev/js/state/appState.js create mode 100644 cdn/dev/js/state/elementSize.js create mode 100644 cdn/dev/js/state/elementValue.js create mode 100644 cdn/dev/js/state/enableKb.js create mode 100644 cdn/dev/js/state/fontState.js create mode 100644 cdn/dev/js/state/selectedKbList.js create mode 100644 cdn/dev/js/state/storage.js diff --git a/cdn/dev/css/footer.css b/cdn/dev/css/footer.css deleted file mode 100644 index e69de29..0000000 diff --git a/cdn/dev/css/kmw-body.css b/cdn/dev/css/kmw-body.css index b3652af..d447622 100644 --- a/cdn/dev/css/kmw-body.css +++ b/cdn/dev/css/kmw-body.css @@ -1,84 +1,65 @@ -* { - box-sizing: border-box; -} +/* + Name: KeymanWeb's Body Styles + Copyright: Copyright (C) 2025 SIL Global + Create Date: 5 November 2024 -:root { - --textarea-box: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgb(209, 213, 219) 0px 0px 0px 1px inset -} + Modified Date: + Authors: Meng-Heng -body { - overflow: hidden; -} + History: + Description: All of the styles for KMW's Body +*/ +/* +========= +==Icons== +========= +*/ +.fa-grip-lines:hover { + cursor: grab; +} +/* +================ +==Section Tag== +================ +*/ .container-flex { display: flex; flex-direction: column; align-items: center; width: 100%; } - -.hidden { - display: none !important; -} - -a { - margin: 0 !important; - padding: 0 !important; - text-decoration: none !important; -} - -/* Icons */ -i:hover { - transition: all 0.3s ease; -} - -.fa-grip-lines:hover { - cursor: grab; -} - -/* End of Icons */ - -/* Section Tag */ - -/* - Text area +/* +============== +==Text area== +============== */ .textarea-container { display: flex; flex-direction: column; justify-content: center; align-items: center; - width: 100%; + width: var(--textarea-width); + height: var(--textarea-height); } .text-area { padding: 10px; resize: none; width: 100%; + height: 100% !important; box-shadow: var(--textarea-box); font-size: 16px; border: none; padding: 10px; + line-height: 1.6em; + font-family:SindhiWeb,Verdana,GeezWeb,LaoWeb,TibetanWeb,MyanmarWeb,SinhalaWeb,TamilWeb,KhmerWeb,LatinWeb,OriyaWeb,EgyptianWeb !important; } - -.text-area::highlight { - border: red; -} - -#copyTool { - color: var(--keyman-blue); - position: absolute; - right: 10px; - top: 97px; - opacity: 50%; -} - -#copyTool:hover { - cursor: pointer; - opacity: 100%; -} - -/* Divider */ +/* +============ +==Divider== +============ +*/ .divider-container i { opacity: 50%; } @@ -87,23 +68,25 @@ i:hover { color: var(--keyman-blue); opacity: 100%; } - -/* Items at the middle of the divider */ +/* +===================================== +==Items in the middle of the divider== +===================================== +*/ .middle-divider { grid-area: middle; - justify-self: center; - height: fit-content; + text-align: center; + width: 100%; + height: 100%; z-index: 1; } - -.font-size-mobile { - display: none; -} - -/* Keyboard */ +/* +============= +==Keyboard== +============= +*/ .keyboard-container { - width: 900px; - height: 500px; + width: 70vw; display: flex; flex-direction: column; align-items: center; @@ -113,26 +96,36 @@ i:hover { .keyboard-area { user-select: none; flex: 1; - width: 100%; - height: 50vh; - border: 1px solid var(--keyman-blue); -} - + width: 70vw; + height: 100%; + border: var(--keyman-blue) 1px solid !important; +} + +.phone.kmw-osk-frame, .tablet.kmw-osk-frame { + display: block !important; + position: relative !important; + height: 100% !important; + width: 100% !important; + max-width: 100vw !important; + max-height: 50vh !important; + z-index: 0 !important; +} +/* +============= +==Examples== +============= +*/ .example-box { background-color: var(--keyman-blue); color: white; - width: 100%; + width: 70vw; text-align: center; padding: 5px; border-bottom: 1px solid rgb(159, 159, 159); } -.desktop-keyboard { - width: 100%; -} - -.phone-keyboard { - display: none; +#exampleBox { + visibility: visible !important; } .example-box p { @@ -143,118 +136,4 @@ i:hover { visibility: visible !important; } -#exampleBox { - visibility: visible !important; -} - /* End of Section Tag */ - -/* ================================ - Computer and Laptop screen sizes -================================ */ -@media screen and (min-width: 940px) { - .item, .section-items { - margin: 5px - } - - /* Divider */ - .divider-container { - user-select: none; - display: grid; - grid-template-columns: repeat(5, 20%); - grid-template-rows: 100%; - align-items: center; - grid-template-areas: ". left middle right ."; - width: 100%; - height: 15px; - } -} - -/* ================================ - Most Tablet to Phone sizes -================================ */ - -@media screen and (max-width: 940px) { - /* Divider */ - .divider-container { - user-select: none; - display: grid; - grid-template-columns: 1fr 1fr 1fr; - grid-template-rows: 100%; - align-items: center; - grid-template-areas: - "left middle right" - ; - width: 100%; - padding: 10px; - border-radius: 5px; - box-shadow: var(--box-shadow); - } - - /* Keyboard */ - .keyboard-container { - width: 100%; - height: 100%; - } - - .desktop-keyboard { - display: none; - } - - .phone-keyboard { - width: 100%; - display: block; - } - - .keyboard-download-box { - display: none; - } - - .spacing-purpose { - display: none; - } -} - -/* ================================ - Smallest Phone sizes -================================ */ -@media screen and (width < 565px) { - .font-size-desktop { - display: none; - } - - .font-size-mobile { - display: flex; - flex-direction: row; - align-items: center; - border-radius: 24px; - opacity: 50%; - } - - .font-size-mobile button { - border: 0; - background-color: #fff; - border-style: none; - } - - .font-size-mobile > *{ - margin: 0 5px; - } -} - -@media screen and (max-width: 400px) { - .example-box p { - font-size: 10px; - } -} - -/* Animation */ - -.textarea-animation { - animation: highlight 3s; -} - -@keyframes highlight { - from {box-shadow:#2EADD3 0px 0px 0px 3px;} - to {box-shadow: var(--textarea-box);} -} \ No newline at end of file diff --git a/cdn/dev/css/kmw-desktop.css b/cdn/dev/css/kmw-desktop.css index f139398..0cb3f68 100644 --- a/cdn/dev/css/kmw-desktop.css +++ b/cdn/dev/css/kmw-desktop.css @@ -6,75 +6,102 @@ ====================== */ - #kmw_controls{ - border-top-left-radius: 8px; - border-top-right-radius: 8px; - -moz-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); - } - - #kmw_btn_osk{ - border-top-right-radius: 10px; - } - - #kmw_controls_start{ - border-top-left-radius: 10px; - } - -textarea { - height:260px; - width:554px; - float:left; - margin: 0px 10px 10px; - color:black; - font-size:16px; - font-family:SindhiWeb,Verdana,GeezWeb,LaoWeb,TibetanWeb,MyanmarWeb,SinhalaWeb,TamilWeb,KhmerWeb,LatinWeb,OriyaWeb,EgyptianWeb !important; - } +#kmw_controls{ + border-top-left-radius: 8px; + border-top-right-radius: 8px; + -moz-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); +} + +#kmw_btn_osk{ + border-top-right-radius: 10px; +} + +#kmw_controls_start{ + border-top-left-radius: 10px; +} + +/* +====================== +==Mobile Tool Box== +====================== +*/ +.tool-menu { + display: none; +} form { padding-right:10px; float:left; - } -#messageContainer { - float:left; - width:80%; } + /* -====================== -==Keyboard Examples== -====================== +================== +==Mobile Divider== +================== */ +.left-divider { + display: none; +} -#example,#help { - margin: 5px 0px; - text-align: center; +.right-divider { + display: none; +} + +/* +================== +==Tool Container== +================== +*/ +.tool-container{ + background-color: var(--bs-body-bg); + border-radius: 15px; + border: var(--bs-border-width) solid var(--bs-border-color); + width: 400px; + height: 50px; + padding: 10px; +} + +.small-icon-tools, .large-icon-tools { + height: 40px; + padding: 0 10px; +} + +.large-icon-tools { + width: 50%; } -#example { - visibility: hidden; - width: 100%; - min-height: 10px; - max-height: 45px; +.small-icon-tools { display: flex; + flex-direction: row; justify-content: center; align-items: center; - padding-top: 5px; + width: 50%; + height: 40px; + border-left: 0.5px solid gray; } -#example a { - padding-left: 10px; +.small-icon-tools > * { + width: max-content; + height: max-content; + padding: 10px; + margin: 0 5px; } - +/* +====================== +==Keyboard Examples== +====================== +*/ .highlightKeys kbd { - border: solid 1px #808080; - border-radius: 4px; - background: #cccccf; - color: black; - font-family: Verdana; - font-weight: normal; - min-width: 16px; - display: inline-block; - box-shadow: 2px 2px 1px rgba(128, 128, 128, 0.3); - margin-right: 4px; + border: solid 1px #808080; + border-radius: 4px; + background: #cccccf; + color: black; + font-family: Verdana; + font-weight: normal; + min-width: 16px; + display: inline-block; + box-shadow: 2px 2px 1px rgba(128, 128, 128, 0.3); + margin-right: 4px; } .highlightKeys kbd.space { @@ -86,18 +113,19 @@ form { ==Keyboard Styling== ====================== */ -.desktop, .kmw-osk-frame { +.kmw-osk-frame { display: block !important; position: static !important; width: 100% !important; height: 100% !important; max-width: 100% !important; max-height: 100% !important; + font-size: 21px !important; border-radius: 0; } .kmw-help-osk-frame { - height: 100% !important; + height: 40vh !important; scroll-behavior: smooth !important; scrollbar-width: thin; overflow-x: hidden !important; @@ -108,7 +136,7 @@ form { .kmw-osk-static { height: fit-content !important; text-align: center !important; - border: solid 1px var(--keyman-blue) !important; + border: none !important; } .kmw-osk-static table { @@ -119,6 +147,14 @@ form { width: 100% !important; } +.kmw-osk-inner-frame { + font-size: 21px !important; + width: 100% !important; + height: 100% !important; + max-width: 100% !important; + max-height: 100% !important; +} + #kmw-osk-help-page > table > tbody > tr > td > .row { --bs-gutter-x: 0 !important; } @@ -201,17 +237,6 @@ form { text-align: center; } -@media all and (min-width: 1320px) { - ins.adsbygoogle { - display: inline-block !important; - height: 600px; - position: absolute; - right: 16px; - top: 120px; - width: 160px; - } -} - .desktop .kmw-keyboard-dari_clra .kmw-key-default .kmw-key-text { top: -33%; } diff --git a/cdn/dev/css/kmw.css b/cdn/dev/css/kmw-global.css similarity index 58% rename from cdn/dev/css/kmw.css rename to cdn/dev/css/kmw-global.css index 02c9c07..50c9ca1 100644 --- a/cdn/dev/css/kmw.css +++ b/cdn/dev/css/kmw-global.css @@ -1,8 +1,33 @@ /* ============= -==Reset CSS== +==Reset & Global CSS== ============= */ +:root { + --textarea-box: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgb(209, 213, 219) 0px 0px 0px 1px inset; + --textarea-width: 100vw; + --textarea-height: calc(100vh - 55vh); + --divider-height: 5vh; + --keyboard-height: calc(97vh - (var(--textarea-height) + var(--divider-height))); + --box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; + --keyman-orange: #FC7200; + --keyman-red: #B92034; + --keyman-blue: #2EADD3; + --tablet--kb-bg-color: #666; + --mobile-font-size: 12px; + --mobile-search-max-width: 100%; +} + +* { + box-sizing: border-box; + letter-spacing: .05rem; + font-weight: 400; +} + +body { + overflow: hidden; +} + html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, @@ -24,11 +49,12 @@ time, mark, audio, video { } a { - margin:0; - padding:0; + margin:0 !important; + padding:0 !important; vertical-align:baseline; background:transparent; - } + text-decoration: none !important; +} article,aside,details,figcaption,figure, section,header,footer,hgroup,menu,nav { @@ -65,6 +91,7 @@ hr { border:0; border-top:1px solid #cccccc; padding:0; + margin: 0; } button, input, select { @@ -76,3 +103,12 @@ button, input, select { ins.adsbygoogle { display: none !important; } + +.hidden { + display: none !important; +} + +/* Icons */ +i:hover { + transition: all 0.3s ease; +} diff --git a/cdn/dev/css/kmw-header.css b/cdn/dev/css/kmw-header.css index da9c3f9..8dbd919 100644 --- a/cdn/dev/css/kmw-header.css +++ b/cdn/dev/css/kmw-header.css @@ -1,18 +1,15 @@ -:root { - --box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; - --keyman-orange: #FC7200; - --keyman-red: #B92034; - --keyman-blue: #2EADD3; -} +/* + Name: KeymanWeb's Header Styles + Copyright: Copyright (C) 2025 SIL Global + Documentation: + Description: All of the styles for KMW's Header + Create Date: 5 November 2024 -* { - letter-spacing: .05rem; - font-weight: 400; -} + Modified Date: + Authors: Meng-Heng -hr { - margin: 0; -} + History: +*/ header > div > img { width: 100%; @@ -20,11 +17,6 @@ header > div > img { height: 5px; } -#searchDropdownMenu { - padding: 10px; - margin: 0; -} - .main-header { display: grid; grid-template-columns: 1fr 1fr; @@ -32,23 +24,31 @@ header > div > img { padding: 0 10px; box-shadow: var(--box-shadow); } - -/* Left side of Header: - Search - Keyboard dropdown +/* +============================================================= +==Left side of Header: Search Box, Keyboard Selection Menu== +============================================================= */ +#searchDropdownMenu { + padding: 10px; + margin: 0; +} + .left-header { display: flex; align-items: center; + width: 70vw; } .left-header img { margin-right: 10px; } -/* -Language Search box +/* +============== +==Search Box== +============== */ #searchBar { position: relative; @@ -56,6 +56,20 @@ Language Search box margin-right: 10px; } +#searchBar #searchInput { + height: 50px; + width: 100%; + text-indent: 10px; + border-radius: 15px; + text-align: left; + font-family: inherit !important; + box-shadow: none; +} + +#searchInput:hover, #searchInput:focus { + border: 1px solid var(--keyman-orange); +} + #searchIcons { position: absolute; right: 5px; @@ -83,20 +97,6 @@ Language Search box display: none; } -#searchBar #searchInput { - height: 50px; - width: 100%; - text-indent: 10px; - border-radius: 15px; - text-align: left; - font-family: inherit !important; - box-shadow: none; -} - -#searchInput:hover, #searchInput:focus { - border: 1px solid var(--keyman-orange); -} - #searchDropdownMenu { width: 100%; max-height: 600px; @@ -107,132 +107,103 @@ Language Search box #searchDropdownMenu hr { margin: 15px 0; } +/* +============================ +==Instruction on dropdown== +============================ +*/ +.instruction-title { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; +} -/* Enable keyboard Animation */ -.kb-icon-plus-animate { - animation: plustoTickToMinus 2s forwards; -} - -@keyframes plustoTickToMinus { - 0% { - content: "+"; - transform: scale(1); - } - 30% { - color: lime; - content: "โœ“"; - transform: scale(1.5); - } - 60% { - color: lime; - content: "โœ“"; - transform: scale(1.3); - } - 100% { - content: "-"; - transform: scale(1); - } -} - -/* Instruction on dropdown */ .instruction-title, .keyboard-title { width: 100%; } .instruction-title p, .keyboard-title { font-weight: 500; - font-size: 16px; + font-size: 18px; text-align: center; } -/* Map and Most download */ -.left-header .dropdown-menu .top-row #worldMap { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - margin: 10px 10px !important; -} - -#worldMap span { - opacity: 50%; -} - -#worldMap span:hover { - opacity: 100%; - cursor: pointer; -} - -#KeymanWebControl #kmw_controls -{ - display: flex !important; - flex-direction: row; - justify-content: space-evenly; +#closeInstruction { + position: absolute; + right: 20px; + top: 10px; + border: 1px solid black; border-radius: 20px; - box-shadow: var(--box-shadow); - height: 35px; - padding: 5px; + text-align: center; + width: 30px; + cursor: pointer; } -#KeymanWebControl .kmw_button, -#keymanWebControl .kmw_button_disabled, -#KeymanWebControl .kmw_button_selected -{ - width: fit-content !important; - background: none !important; - height: 0 !important; +/* +================ +==Search cards== +================ +*/ +.card-wrap { + box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;; + padding: 10px; + border-radius: 10px; + letter-spacing: .05rem; + overflow: hidden; + margin-bottom: 5px; } -#KeymanWebControl #kmw_controls_start, -#KeymanWebControl #kmw_btn_osk, -.kmw_bar, #kmw_controls_end { - display: none; +.card-wrap.disabled { + opacity: 0.5; + pointer-events: none; + position: relative; } - -#KeymanWebControl .kmw_language { - padding: 3px; +.card-wrap .monthly-download { + opacity: 75%; } -#kmw_control_keyboards { - width: fit-content; +.card-header { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + margin-bottom: 8px; } -#kmw_selector_regions { - height: 100%; - overflow: hidden; - position: relative; +.card-header > * { + margin-right: 0 10px 0 0; } -.kmw_selector_region { - overflow-y: scroll; - overflow-x: hidden; - scrollbar-width: thin; - height: 600px; +.card-header .card-header-title { + display: flex; + flex-direction: row; + justify-content: left; + align-items: center; } -/* Search Dropdown cards */ -#languageSearchList > * { - margin-bottom: 5px; +.card-header h4 { + color: var(--keyman-orange); + font-weight: 400; + font-size: large; + margin: 0 5px; } -#languageSearchList > div:hover { - border: 1px solid var(--keyman-orange); - margin: 3px; +.card-header h4 span { + color: black; } -.card-wrap { - box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;; - padding: 10px; - border-radius: 10px; - letter-spacing: .05rem; - overflow: hidden; - margin-bottom: 5px; +.card-header p { + position: relative; + float: right; + font-weight: 200; + font-size: medium; + margin: 0; } -.card-wrap.disabled { - opacity: 0.5; - pointer-events: none; - position: relative; +.card-header p, .card-header .help-icon-span { + color: var(--keyman-red); + cursor: pointer; } .card-wrap.disabled .kb-icon-plus { @@ -286,40 +257,11 @@ Language Search box height: 20px; margin: 0; } - -.card-wrap .monthly-download { - opacity: 75%; -} - -.card-header { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - margin-bottom: 8px; -} - -.card-header h4 { - color: #0000EE; - font-weight: 400; - font-size: large; - margin: 0; -} - -.card-header h4 span { - color: black; -} - -.card-header p { - margin: 0; - position: relative; - float: right; - font-weight: 200; - font-size: medium; - color: var(--keyman-red); -} - -/* Pagination */ +/* +============== +==Pagination== +============== +*/ #searchDropdownMenu .bottom-row-search { background-color: white; align-items: center; @@ -337,12 +279,19 @@ Language Search box cursor: pointer; } -/* Selected Keyboard Menu */ +#paginationControls { + display: none; +} +/* +=========================== +==Selected Keyboard Menu== +=========================== +*/ #keyboardSelectionButton { z-index: 3; } -.scroll-wrapper-keyboard-tab { +.keyboard-selection-menu { width: 350px; height: 35px; position: relative; @@ -359,7 +308,6 @@ Language Search box box-shadow: var(--box-shadow); overflow-y: scroll; scrollbar-width: none; - transition: all 1s ease-in-out; margin-left: -10px; border-radius: 10px; z-index: 0; @@ -381,6 +329,14 @@ Language Search box width: 100%; } +.kb-selection.open { + display: block; +} + +.kb-selection { + display: none; +} + .kb-item-header, .kb-item-footer { display: flex; align-items: center; @@ -399,35 +355,67 @@ Language Search box cursor: pointer; } -.kb-item { - width: 100%; - max-height: fit-content; - height: 38px; +.kb-item-keyboard { display: flex; flex-direction: row; justify-content: space-between; + align-items: center; + width: 100%; + height: fit-content; padding: 5px; + opacity: 50%; } -.kb-item:hover { +.kb-item-keyboard:hover { cursor: pointer; - background-color: var(--keyman-orange); - color: white; + color: black; + padding: 5px; + opacity: 100%; } -.kb-item span { +.kb-item-keyboard span { width: 50%; - text-wrap: wrap; - align-self: center; + height: 30px; + text-align: center; + overflow-x: scroll; + scrollbar-width: thin; + margin: 5px; +} + +.kb-item-keyboard span:hover { + text-decoration: underline; } .keyboard-configs { - width: 50%; height: fit-content; display: grid; grid-template-columns: repeat(4, 1fr); + border-left: 1px solid black; + align-self: center; + justify-content: center; list-style-type: none; - padding: 2px 0 0; + padding-left: 15px; + margin: 5px; +} + +.keyboard-configs > li { + opacity: 50%; + margin-right: 5px; +} + +.keyboard-configs > li:hover { + opacity: 100%; + cursor: pointer !important; + font-size: 20px; +} + +.keyboard-configs li > i { + display: flex; + flex-direction: row; + align-items: center; + width: 35px; + height: 35px; + margin-right: 3px; } ::-webkit-scrollbar:horizontal { @@ -449,15 +437,16 @@ Language Search box } .keyboard-details { - position: absolute; + position: fixed; width: 400px; - height: fit-content; + height: max-content; background-color: white; color: black; box-shadow: var(--box-shadow); border-radius: 20px; padding: 10px; z-index: 2; + top: 100px; } .keyboard-content-wrapper { @@ -538,102 +527,11 @@ Language Search box .platform .platform-mobileweb { background-image: url('/cdn/dev/img/platforms/icon-mobileWeb.png'); } - -/* Limits of Keyboard Selection */ -.warning-container { - position: fixed; - height: 100vh; - width: 100%; - z-index: 1000; - top: 0; - left: 0; - display: flex; - justify-content: center; - align-items: center; -} - -.warning-content { - width: 500px; - display: flex; - flex-direction: column; - align-items: center; - background-color: white; - color: black; - text-align: center; - padding: 30px 30px 70px; - border-radius: 20px; - box-shadow: var(--box-shadow); -} - -.warning-cancel-btn { - width: 30px; - font-size: 20px; - opacity: 50%; - align-self: flex-end; - background-color: transparent; - border: none; - margin-bottom: 10px; -} - -.warning-keyman-image { - width: 82px; - margin-bottom: 15px; -} - -.warning-text { - margin-bottom: 40px; - font-size: 18px; -} - -.warning-accept-btn { - background-color: var(--keyman-orange); - border: none; - border-radius: 5px; - width: 200px; - padding: 14px; - color: white; - box-shadow: var(--box-shadow); -} - -/* Middle of the header */ -.middle-header { - display: flex; - justify-content: center; - align-items: center; -} - -.middle-header i, .right-header i { - font-size: 24px; - opacity: 50%; -} - -.middle-header i:hover { - opacity: 100%; - cursor: pointer; - color: var(--keyman-red); -} - -/* Right side of the header: - Tools - Hamburger menu +/* +========================================= +==Font size slider + Hide/show keyboard== +========================================= */ - -.right-header { - display: grid; - grid-template-columns: 80% 20%; - width: 100%; - justify-items: right; - align-items: center; - margin-right: 0; -} - -.right-header i:hover { - opacity: 100%; - cursor: pointer; - color: var(--keyman-blue); -} - -/* Font size slider + Hide/show keyboard */ .tool-container { display: flex; flex-direction: row; @@ -641,14 +539,12 @@ Language Search box align-items: center; } -.tool-container > * { - margin: 10px; -} - .font-size-container { display: flex; flex-direction: row; align-items: center; + padding: 5px 5px; + height: fit-content; } .font-size-slider { @@ -665,7 +561,6 @@ Language Search box width: 100%; } - .font-large { font-size: 20px; } @@ -712,41 +607,71 @@ input[type="range"]::-webkit-slider-thumb { margin-top: 3px; } -#burgerMenu ul { - box-shadow: var(--box-shadow); +/* +=================================================================================== +==Right side of Header: Font Resizer, Hide keyboard + Hamburger menu== +=================================================================================== +*/ +.right-header { + display: grid; + grid-template-columns: 80% 20%; + width: 100%; + justify-items: right; + align-items: center; + margin-right: 0; } -#burgerMenu ul:hover { +.right-header i { + font-size: 24px; + opacity: 50%; +} + +.right-header i:hover { + opacity: 100%; cursor: pointer; + color: var(--keyman-blue); } -.dropdown-grid-container { - display: grid; - grid-template-columns: 1fr 1fr; - grid-template-rows: 1fr; +.burger-menu-top-section > div { + display: flex; + flex-direction: row; + justify-content: space-around; + align-items: center; + border-bottom: 0.5px solid gray; + padding: 15px; } -.dropdown-item:active { - background-color: transparent !important; +.burger-menu-top-section .instruction-status .title p { + font-size: 16px; + margin: 0; +} + +#burgerMenu #burgerDropDownMenu { + box-shadow: var(--box-shadow); +} + +#burgerMenu #burgerDropDownMenu:hover { + cursor: pointer; } -#burgerMenu ul li { +#burgerMenu #burgerDropDownMenu .burger-menu-middle-section ul li { align-items: center; width: 300px; border-bottom: 1px solid rgb(196, 196, 196); margin-top: 10px; + margin-left: 10px; } -#burgerMenu ul li::after { +#burgerMenu #burgerDropDownMenu .burger-menu-middle-section ul li::after { background-color: orange; } -#burgerMenu ul li p:hover { +#burgerMenu #burgerDropDownMenu .burger-menu-middle-section ul li p:hover { opacity: 100%; } -#burgerMenu ul li p { - width: 90%; +#burgerMenu #burgerDropDownMenu .burger-menu-middle-section ul li p { + width: 80%; white-space: normal; position: relative; left: 40px; @@ -755,14 +680,14 @@ input[type="range"]::-webkit-slider-thumb { margin-top: 10px; } -#burgerMenu ul li a { +#burgerMenu #burgerDropDownMenu .burger-menu-middle-section ul li a { text-decoration: none; color: black; font-style: bold; font-size: 16px; } -#burgerMenu ul li i, #burgerMenu ul li img { +#burgerMenu #burgerDropDownMenu .burger-menu-middle-section ul li i, #burgerMenu #burgerDropDownMenu .burger-menu-middle-section ul li img { margin: 0 10px; font-size: 16px; width: 18px; @@ -774,6 +699,18 @@ input[type="range"]::-webkit-slider-thumb { cursor: pointer; } +.burger-menu-external-links { + display: grid; + grid-template-columns: 1fr 1fr; + grid-template-rows: 1fr; + padding: 0; + list-style-type: none; +} + +.external-links-item:active { + background-color: transparent !important; +} + .kmw-socials, .kmw-version, .sil-logo { font-size: 14px; } @@ -783,7 +720,15 @@ input[type="range"]::-webkit-slider-thumb { flex-direction: column; justify-content: center; align-items: center; - padding: 10px; + padding-bottom: 15px; + line-height: 30em; + margin-bottom: 10px; + border-bottom: 0.5px solid gray; +} + +.kmw-socials h5 { + line-height: 1.5em; + font-size: 25px; } .kmw-socials-icons { @@ -792,12 +737,19 @@ input[type="range"]::-webkit-slider-thumb { justify-content: center; align-items: center; gap: 10px; + margin: 10px; +} + +.kmw-socials-icons > * { + line-height: 1.5em; } .kmw-socials-icons > a { + display: flex; text-decoration: none; color: black; opacity: 50%; + font-size: 16px; position: relative; } @@ -807,9 +759,7 @@ input[type="range"]::-webkit-slider-thumb { @font-face { font-family: "social-logos"; - src: url("../../fonts/social-logos.ttf"), - url("social-logos.woff2") format("woff2"), - url("social-logos.woff") format("woff"); + src: url("../../fonts/social-logos.ttf"); font-weight: normal; font-style: normal; } @@ -831,37 +781,140 @@ input[type="range"]::-webkit-slider-thumb { display: flex; flex-direction: column; align-items: center; + padding: 15px; +} +/* +================================ +==Limits of Keyboard Selection== +================================ +*/ +.warning-container { + background: rgba(0, 0, 0, 0.25); + position: fixed; + height: 100vh; + width: 100%; + z-index: 1000; + top: 0; + left: 0; + display: flex; + justify-content: center; + align-items: center; } -/* Animation */ +.warning-content { + width: 500px; + display: flex; + flex-direction: column; + align-items: center; + background-color: white; + color: black; + text-align: center; + padding: 30px 30px 70px; + border-radius: 20px; + box-shadow: var(--box-shadow); +} -.keyboardTab-animation { - animation: keyboardTab 1s; +.warning-cancel-btn { + width: 30px; + font-size: 20px; + opacity: 50%; + align-self: flex-end; + background-color: transparent; + border: none; + margin-bottom: 10px; } -.keyboardSelection-animation { - animation: keyboardSelection 1s ease-in; + +.warning-keyman-image { + width: 82px; + margin-bottom: 15px; } -@keyframes keyboardSelection { - 0% { - transform: translateY(-5px); - } - 50% { - transform: translateY(-3px); - } - 75% { - transform: translateY(-1px); - } - 100% { - transform: translateY(0); - } +.warning-text { + margin-bottom: 40px; + font-size: 18px; } -@keyframes keyboardTab { - from { - opacity: 50%; - } - to { - opacity: 100%; - } -} \ No newline at end of file +.warning-accept-btn { + background-color: var(--keyman-orange); + border: none; + border-radius: 5px; + width: 200px; + padding: 14px; + color: white; + box-shadow: var(--box-shadow); +} +/* +=============================== +==DELETE: Confirmation Dialog== +=============================== +*/ +.dialog-overlay { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.25); + display: flex; + align-items: center; + justify-content: center; + z-index: 9999; +} + +.dialog-box { + background: #fff; + border-radius: 12px; + padding: 2rem; + width: 90%; + max-width: 400px; + box-shadow: 0 4px 16px rgba(0,0,0,0.1); + text-align: center; +} + +.dialog-icon { + font-size: 2rem; + color: #e74c3c; + margin-bottom: 1rem; +} + +.dialog-title { + font-size: 1.25rem; + font-weight: 600; + margin: 0.5rem 0; +} + +.dialog-message { + font-size: 0.95rem; + color: #555; + margin-bottom: 1.5rem; +} + +.dialog-buttons { + display: flex; + justify-content: space-around; + gap: 1rem; +} + +.btn-cancel, .btn-delete { + flex: 1; + padding: 0.75rem; + border-radius: 8px; + border: none; + cursor: pointer; + font-size: 1rem; +} + +.btn-cancel { + background: #f4f4f4; + color: #333; +} + +.btn-delete { + background: var(--keyman-red); + color: white; +} + +.btn-cancel:hover { + background: #eaeaea; +} + +.btn-delete:hover { + background: #d54335; +} diff --git a/cdn/dev/css/kmw-interaction.css b/cdn/dev/css/kmw-interaction.css new file mode 100644 index 0000000..d50a438 --- /dev/null +++ b/cdn/dev/css/kmw-interaction.css @@ -0,0 +1,62 @@ +/* + Name: KeymanWeb Interaction Styles + Copyright: Copyright (C) 2025 SIL Global + Documentation: + Description: Animation & Styles of every interactable components. + Create Date: 19 Nov 2025 + + Modified Date: + Authors: Meng-Heng + + History: +*/ + +/* Warning before delete */ +.warning-content { + animation: fadeIn 0.2s ease; +} + +.dialog-box { + animation: fadeIn 0.2s ease; +} + +@keyframes fadeIn { + from { opacity: 0; transform: scale(0.9); } + to { opacity: 1; transform: scale(1); } +} + +/* Enable keyboard for Keyboard Selection Animation */ +.kb-icon-plus-animate { + animation: plustoTickToMinus 2s forwards; +} + +@keyframes plustoTickToMinus { + 0% { + content: "+"; + transform: scale(1); + } + 30% { + color: lime; + content: "โœ“"; + transform: scale(1.5); + } + 60% { + color: lime; + content: "โœ“"; + transform: scale(1.3); + } + 100% { + content: "-"; + transform: scale(1); + } +} + +/* Textarea */ +.textarea-animation { + animation: highlight 3s ease; +} + +@keyframes highlight { + from {box-shadow:#2EADD3 0px 0px 0px 3px;} + to {box-shadow: var(--textarea-box);} +} \ No newline at end of file diff --git a/cdn/dev/css/kmw-mobile.css b/cdn/dev/css/kmw-mobile.css index 8d8eb6d..82666a5 100644 --- a/cdn/dev/css/kmw-mobile.css +++ b/cdn/dev/css/kmw-mobile.css @@ -6,29 +6,20 @@ ====================== */ -:root { - --mobile-font-size: 12px; - --mobile-search-max-width: 250px; - --mobile-search-min-width: 50px; -} - -html { - overflow-y: scroll; - overflow-x: hidden; -} - body { - width:100%;height:100%; + width:100%; + height:100%; font-family: Verdana, Arial, Helvetica, sans-serif; color:#2D2C2C; background-color: #eeeeee; margin:0px; - } + overflow: none; +} a { text-decoration:none; color: #AD4A28; - } +} a:hover { text-decoration:underline; @@ -42,62 +33,82 @@ p { font-size:13px; line-height:1.5em; } - /* -==================== -==Content Elements== -==================== +========== +==Header== +========== */ - -/* KMW Main App */ -#app { - width: 100%; - margin: 0px; - } - -#KeymanWebControl { - display: none; - } - -#exampleBox, #example { - display: none; -} - .main-header { width: 100%; grid-template-columns: 2fr 1fr; } -.left-header { - width: 70vw; - } - .left-header img { display: none; } .right-header { grid-template-columns: 50% 50%; + padding: 10px; } -.right-header { - width: 30vw; +.tool-container { + margin: 10px; } +.hamburger-menu-container { + overflow: scroll; + scroll-behavior: smooth; + height: 70vh; +} + +#burgereMenu ul { + width: 80vw; + scroll-behavior: smooth; + flex-direction: column; + height: 60vh; + overflow: hidden; +} + +.burger-menu-external-links{ + display: flex !important; + flex-direction: column !important; +} + +.kmw-socials-icons { + display: flex; + flex-direction: column; +} /* -Language Search box +======================= +==Language Search box== +======================= */ - #searchBar { width: 50%; } -#searchInput:focus, #searchDropdownMenu, #keyboardSelection:active { +#searchInput::placeholder { + opacity: 0; +} + +#searchIcons { + border: 0; + background-color: transparent; + z-index: 0; + user-select: none; +} + +#searchInput:focus, #keyboardSelection:active { width: var(--mobile-search-max-width) !important; } -#textArea { - height: 45vh !important; +#searchDropdownMenu { + width: 95vw !important; +} + +.textarea-container { + height: 100%; } .mobile-font-size-container { @@ -113,39 +124,87 @@ Language Search box border-radius: 10px; } - /* Additional rules for portrait orientation */ -@media only screen and (orientation: portrait) { +.large-icon-tools, .small-icon-tools { + display: none; +} + +#keyboardSelection.open { + width: 70vw !important; +} +/* +==================== +==Content Elements== +==================== +*/ + +/* KMW Main App */ +#app { + width: 100%; + margin: 0px; + } - #message { - height: 170px; - } +#KeymanWebControl { + display: none; + } - #messageContainer { - float: left; - width: 80%; - height: 40%; - } +.kmw-tools { + display: none; } - /* Additional rules for landscape orientation */ -@media only screen and (orientation: landscape) { +/* Divider */ +.divider-container { + cursor: pointer; + display: grid; + grid-template-columns: 1fr 1fr 1fr; + grid-template-rows: 100%; + align-items: center; + grid-template-areas: "left middle right"; + width: 100%; + height: 5vh; + padding: 10px; + border-radius: 5px; + box-shadow: var(--box-shadow); +} + +.left-divider { + display: flex; + flex-direction: row; + justify-content: start; + align-items: center; + height: 100%; +} - #messageContainer { - float: left; - width: 85%; - height: 50%; - } - #message { - height: 50%; - } - #buttons { - margin: 4px 15px 4px 0; - } - #font { - display: none; - } +.left-divider > * { + margin: 0 10px; +} +/* Keyboard */ +#exampleBox { + background-color: gray; + height: 10vh; + width: 100%; +} + +.keyboard-container { + width: 100%; + height: 100% !important; +} + +.desktop-keyboard { + display: none; } +.phone-keyboard { + width: 100%; + display: block; +} + +.keyboard-download-box { + display: none; +} + +.spacing-purpose { + display: none; +} /* ====================== ==Keyboard Styling== @@ -164,3 +223,64 @@ Language Search box top: -33%; font-size: 0.8em !important; } + +.keyboard-area { + border: none; +} + +/* +============ +==Viewport== +============ +*/ +/* Additional rules for portrait orientation */ +@media only screen and (orientation: portrait) { + .keyboard-container > * { + width: 100%; + height: 100%; + } +} + + /* Additional rules for landscape orientation */ +@media only screen and (orientation: landscape) { + body { + overflow: auto; + } + + .main-header { + height: 65px; + } + + .textarea-container { + height: 15vh; + margin-bottom: 10px; + } + + .divider-container { + height: 10vh; + } + + .middle-divider { + align-content: center; + font-size: 20px; + } + + #example { + font-size: 10px; + } + + .phone.android.kmw-osk-frame > * { + height: 100% !important; + } + + .keyboard-container { + width: 100vw; + height: 100% !important; + } + + .keyboard-area { + border: none; + width: 100%; + height: 100%; + } +} diff --git a/cdn/dev/css/kmw-screen.css b/cdn/dev/css/kmw-screen.css new file mode 100644 index 0000000..61ee41d --- /dev/null +++ b/cdn/dev/css/kmw-screen.css @@ -0,0 +1,71 @@ +/* + Name: KeymanWeb Media Screen Styles + Copyright: Copyright (C) 2025 SIL Global + Documentation: + Description: Different media screens to allow components to display uniquely from the index.php. + Create Date: 19 Nov 2025 + + Modified Date: + Authors: Meng-Heng + + History: +*/ +@media only screen and (max-width: 632px) { + /* Smaller Search Box */ + #searchBar #searchInput { + min-width: 50px; + } +} + +@media only screen and (max-width: 456px) { + /* Smaller Keyboard list in Selection Menu */ + .kb-item-keyboard { + min-height: fit-content; + } + + .kb-item-keyboard span { + min-width: 112px; + } + + .kb-item-keyboard { + overflow-x: scroll; + } +} + +@media screen and (width < 565px) { + /* Show Mobile's font resizer */ + .font-size-mobile { + display: flex; + flex-direction: row; + align-items: center; + border-radius: 24px; + opacity: 50%; + } + + .font-size-mobile button { + border: 0; + background-color: #fff; + border-style: none; + } + + .font-size-mobile > *{ + margin: 0 5px; + } +} + +@media screen and (max-width: 400px) { + .example-box p { + font-size: 10px; + } +} + +@media all and (min-width: 1320px) { + ins.adsbygoogle { + display: inline-block !important; + height: 600px; + position: absolute; + right: 16px; + top: 120px; + width: 160px; + } +} diff --git a/cdn/dev/css/kmw-tablet.css b/cdn/dev/css/kmw-tablet.css index bd11ca5..a97b534 100644 --- a/cdn/dev/css/kmw-tablet.css +++ b/cdn/dev/css/kmw-tablet.css @@ -6,30 +6,23 @@ ====================== */ -html { - overflow-y: scroll; - overflow-x: hidden; -} - body { width:100%; + height:100%; font-family: Verdana, Arial, Helvetica, sans-serif; color:#2D2C2C; background-color: #eeeeee; margin:0px; - } -section { - background-color: darkred; } a { text-decoration:none; color: #AD4A28; - } +} a:hover { text-decoration:underline; - } +} h3 { font-size:18px; @@ -46,419 +39,149 @@ header, footer { /*clear: both;*/ } -hr { - display: none; - } - .box { -webkit-border-radius: 8px;-moz-border-radius: 8px; border-radius: 8px; -moz-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.5); } +.container-flex { + display: flex; + flex-direction: column; + height: 100%; +} + /* -=================== -==Header Elements== -=================== +========== +==Header== +========== */ -header { - margin-top:0px; - } - -#headerLeft img { - display: block; /* default (inline) display inserts an unwanted bottom border */ - margin-top:0px; - height:60px; - /*-webkit-border-radius: 0px 0px 8px 8px; -moz-border-radius: 0px 0px 8px 8px; border-radius: 0px 0px 8px 8px;*/ - } - -header > div > img { - display: block; +.main-header { width: 100%; - height: 8px; + grid-template-columns: 3fr 1fr; } - -/* Expanding the search box */ -/* @media screen and (940px <= width <= 1045px) { - .main-header { - grid-template-columns: 2fr 1fr 1fr; - } -} */ - -.main-header { - width: 100%; - grid-template-columns: 3fr 1fr; +.right-header { + grid-template-columns: 70% 30%; } -.left-header { - width: 70vw; +#searchDropdownMenu { + width: 50vw; } -.right-header { - width: 300px; +.burger-menu-external-links { + display: grid; + grid-template-columns: 1fr 1fr; + grid-template-rows: 1fr; + padding: 0; + list-style-type: none; } /* -==================== -==Content Elements== -==================== +================== +==Tool Container== +================== */ -#content { - width: 100%; /* specific for tablet and mobile */ - margin: 0px auto; - background-color: #eeeeee; - /*min-height:375px;*/ - } - - -/* KMW Main App */ -#app { - /*float:left;*/ - /*height:330px;*/ - width:100%; /*710px; */ - margin: 0px;/*30px 15px 15px;*/ - } - -#KeymanWebControl { - display: none; - } - -#exampleBox, #example { - display: none; - } - -#messageContainer { - width: 80%; - float:left; - } - -#message { - height:195px; - width: 100%;/*554px;*/ - float:left; - margin: 10px; - color:black; - font-size:17px; - font-family:SindhiWeb,Verdana,GeezWeb,LaoWeb,TibetanWeb,MyanmarWeb,SinhalaWeb,TamilWeb,KhmerWeb,LatinWeb,OriyaWeb,EgyptianWeb !important; - } - -/* KMW App Buttons */ - -#buttons { - float: right; - width:15%; - margin: 0px 20px; - margin-top: -6px; - } - -#buttons div { - width:140px; - -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; - background: #fff; - border: 1px solid #888888; - margin: 0px 10px; - padding: 3px; - padding-top: 9px; - height: 41px; - line-height: 36px; - background-repeat: no-repeat; - background-position: center left; - } - -#buttons div:disabled { - cursor: default !important; - color: gray !important; - border-color: gray !important; - } - -#buttons p{ - margin-left: 41px; +.tool-menu button { + width: 120px; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + border-radius: 10px; + border: 1px solid gray; + opacity: 50%; + padding: 0 10px; } -#search.links, #search{ - background-image:url('../img/btn_google_small.png'); - +.tool-menu button:hover { + opacity: 100%; } -#search.linksOff{ - background-image:url('../img/btn_google_small_white.png'); +.tool-menu .dropdown-menu { + width: 25vw; + right: 30px; } -#copy.links, #copy{ - background-image:url('../img/btn_copy_small.png'); - +.tool-menu .dropdown-menu > * { + display: flex; + flex-direction: column; + justify-content: center; + width: 100%; + height: 50px; + padding: 10px; } -#copy.linksOff{ - background-image:url('../img/btn_copy_small_white.png'); +.tool-menu .dropdown-menu > div:hover { + color: var(--keyman-blue); + cursor: pointer; } -#buttons div * { - display:inline; - } - -div.links { - cursor:pointer; - } - -div.linksOff { - cursor:default !important; - border: 1px solid #cccccc !important; - } - -div.linksOff * { - color: gray; - -webkit-user-select:none; - } - -/* Aside Elements */ - -aside { - display:none; - } - -#font-size{ - display: none; +#copyTool { + top: 110px; } -/* - -#font, -=================== -==Footer Elements== -=================== -*/ -.footer, footer { - display: none; - background-color: #6A2915; - height:50px; - left:0px; - bottom:0px; - position: fixed; - /* -webkit-border-radius: 8px 8px 0px 0px; -moz-border-radius: 8px 8px 0px 0px; border-radius: 8px 8px 0px 0px; */ - } - -nav ul { - list-style: none outside none; - width:90%; - margin:0px auto; - padding:15px 0px; - } - -nav li { - display:inline; - padding:20px 39px; - } - -nav a { - color:#eee; - font-family:Tahoma; - font-weight:bold; - font-size:10.7px; - } - -.messageBox { - box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -o-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -moz-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -khtml-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - background: #c4c4c4; - position: fixed; - left: 50%; - top: 20%; - z-index: 999 !important; - margin-left: -250px; - margin-top: -100px; - width: 500px; - height: 200px; -} - -.messageBox div { - width: 464px; - height: 134px; - left: 10px; - top: 10px; - padding: 8px; - font-size: 13px; - position: absolute; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 3px; - background: white; +.copy-container span, .eraser-container span, .expand-container span { + display: flex; + flex-direction: row; + justify-content: space-evenly; + align-items: center; } -.messageBox button { - width:83px; - position: absolute; - right: 10px; - bottom: 4px; - background: #414141; - border-top: 1px solid #383838; - border-right: 1px solid #1F1F1F; - border-bottom: 1px solid #151515; - border-left: 1px solid #1F1F1F; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -o-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - color: white; - font: bold 12px Helvetica, Verdana, Arial, sans-serif; - text-shadow: 0px -1px 1px #1E2D4D; - text-align:center; - margin: 0 auto 6px; - padding: 3px; - } - -.messageBox button:disabled { - cursor: default !important; - color: gray !important; - -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - -o-box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; - box-shadow: 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111 !important; +.copy-container span p, .eraser-container span p, .expand-container span p { + margin: 0; } - -.messageBox button:hover { - -webkit-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -moz-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -ms-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - -o-box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - box-shadow: inset 0 0px 20px 1px #878787, 0px 1px 0 #1D1D1D, 0 2px 0px #1F1F1F, 0 2px 4px 1px #111; - cursor: pointer; +/* +========================= +==Section/Body Elements== +========================= +*/ +.example-box { + display: block; + width: 100vw; + height: 7vh; + user-select: none; + align-items: center; + position: sticky; + background-color: var(--tablet--kb-bg-color); } -.messageBox button:active { - -webkit-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - -moz-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - -ms-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - -o-box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; - box-shadow: 0px 1px 0 #1D1D1D, 0 0px 0px #1F1F1F, 0 1px 4px 1px #111; +.left-divider { + display: none; } -.progressBox { - box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -o-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -moz-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - -khtml-box-shadow: 0 0 12px 12px rgba(0, 0, 0, 0.5); - background: #c4c4c4; - position: fixed; - left: 50%; - top: 20%; - z-index: 999; - margin-left: -200px; - margin-top: -54px; - width: 400px; - height: 54px; +.right-divider { + display: none; } -.progressBox div { - width: 364px; - height: 18px; - left: 10px; - top: 10px; - padding: 8px; - background: url('../img/wait.gif') no-repeat 354px 8px white; - font-size: 13px; - position: absolute; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 3px; +.tablet.kmw-osk-frame { + display: block !important; + position: absolute !important; + z-index: 1 !important; + height: 100% !important; + width: 100% !important; } -/* Elements modified for tablet */ -#headerBackground { +/* Keyboard */ +.keyboard-container { + display: flex; width: 100%; - background-color:white; -} - -#headerLeft { - float: left; - margin-left: 28px; -} - -#headerRight { - text-align: right; - height: 40px; - float: right; - padding-bottom: 33px; - padding-right: 10px; -} - -#headerRight-beta { - display: block; - font-weight: bold; - color: red; - font-size: 16pt; - padding: 16px 12px 0; } -#headerRight-link { - padding: 0 12px 0; -} - - -#instructions { - margin:10px; - font:12pt Helvetica,Verdana,Arial,sans-serif; - color: white; +.keyboard-area { + border: none; + width: 100%; + height: 100%; + overflow: hidden !important; + transition: transform 0.2s ease-out !important; + transform: translateY(0) !important; } -/* Additional rules for portrait orientation */ -@media only screen and (orientation: landscape) { - #buttons{ - padding-top: 11px; - } - #buttons div { - margin: 4px 20px 10px 0px; - padding: 0px; - } - #font span:first-child{ - margin-left: 3px; - } - #font p{ - margin-left: 8px; - position: relative; - top: -5px; - } - #mobile-font{ - display: none; - width: 136px; - border-radius: 4px; - position: absolute; - left: 100%; - top: 136px; - margin-left: -170px; - text-align: center; - font-size: 24pt; - background: #fff; - } - - #mobile-increase{ - height: 40px; - line-height: 40px; - border-bottom: solid 1px #000; - } - - #mobile-decrease{ - height: 40px; - line-height: 40px; - } +.keyboard-area.hidden { + transform: translateY(100%) !important; } /* Additional rules for portrait orientation */ @media only screen and (orientation: portrait) { - #app { width: 97%; } @@ -531,6 +254,12 @@ nav a { } } +@media only screen and (orientation: landscape) { + body { + overflow: auto; + } +} + /* ====================== ==Keyboard Styling== diff --git a/cdn/dev/js/api.js b/cdn/dev/js/api.js new file mode 100644 index 0000000..e7b968f --- /dev/null +++ b/cdn/dev/js/api.js @@ -0,0 +1,6 @@ +export function getKeymanWeb() { + if(window.tavultesoft) { + return window.tavultesoft.keymanweb; + } + return window.keyman; +} \ No newline at end of file diff --git a/cdn/dev/js/feature/copy.js b/cdn/dev/js/feature/copy.js new file mode 100644 index 0000000..9e13c71 --- /dev/null +++ b/cdn/dev/js/feature/copy.js @@ -0,0 +1,28 @@ +export function copyTool() { + // Copy tool + const copyDiv = document.querySelector('#copyTool') + const copyBtn = copyDiv.children[0] + copyDiv?.addEventListener('click', async function() { + let textToCopy = textArea.value.trim() + + // Show X icon when there's no text to copy + if(!textToCopy) { + copyBtn.classList.replace('fa-copy', 'fa-xmark') + setTimeout(() => { + copyBtn.classList.replace('fa-xmark', 'fa-copy') + copyBtn.textContent = '' + }, 3000) + return; + } + + await navigator.clipboard.writeText(textToCopy) + + // Once copied, the icon shows a check mark + copyBtn.classList.replace('fa-copy', 'fa-check'); + + // After copied, the icon goes back to its default + setTimeout(() => { + copyBtn.classList.replace('fa-check', 'fa-copy'); + }, 1000); + }) +} \ No newline at end of file diff --git a/cdn/dev/js/feature/eraser.js b/cdn/dev/js/feature/eraser.js new file mode 100644 index 0000000..b4a1c87 --- /dev/null +++ b/cdn/dev/js/feature/eraser.js @@ -0,0 +1,89 @@ +export function eraserTool() { + const eraseDiv = document.querySelector('#eraseTool') + const eraseBtn = eraseDiv.children[0] + + eraseDiv?.addEventListener('click', function() { + let value = textArea.value.trim(); + + // Show X icon when there's no text to erase + if(!value) { + eraseBtn.classList.replace('fa-eraser', 'fa-xmark'); + setTimeout(() => { + eraseBtn.classList.replace('fa-xmark', 'fa-eraser'); + }, 3000); + return; + } else { + confirmAndClearText(() => { + // This function is passed as onConfirmErase + + textArea.value = ''; + // Once erased, the icon shows a check mark + eraseBtn.classList.replace('fa-eraser', 'fa-check'); + // After erased, the icon goes back to its default + setTimeout(() => { + eraseBtn.classList.replace('fa-check', 'fa-eraser'); + }, 1000); + }); + } + }) + + // Check to erase all text + function confirmAndClearText(onConfirmErase) { + if (typeof onConfirmErase !== 'function') { + console.log("Expected onConfirmErase a function, got:", typeof onConfirmErase); + alert("Click on the keyboard again to enable."); + return; + } + + const overlay = eraseTextUI(() => { + onConfirmErase(); + }); + + document.body.appendChild(overlay); + } + + // UI for Keyboard Selected Limitation + function eraseTextUI(onDelete) { + const overlay = document.createElement('div'); + overlay.classList.add('dialog-overlay'); + + // Dialog box + const dialog = document.createElement('div'); + dialog.classList.add('dialog-box'); + + const icon = document.createElement('div'); + icon.classList.add('dialog-icon'); + icon.textContent = "โš ๏ธ" + + const title = document.createElement('h2'); + title.classList.add('dialog-title'); + title.textContent = 'Clear all text?'; + + const message = document.createElement('p'); + message.classList.add('dialog-message'); + message.textContent = 'Are you sure? This action cannot be undone.'; + + const btnContainer = document.createElement('div'); + btnContainer.classList.add('dialog-buttons'); + + const cancelBtn = document.createElement('button'); + cancelBtn.classList.add('btn-cancel'); + cancelBtn.textContent = 'Cancel'; + cancelBtn.onclick = () => overlay.remove(); + + const deleteBtn = document.createElement('button'); + deleteBtn.classList.add('btn-delete'); + deleteBtn.textContent = 'Erase'; + deleteBtn.onclick = () => { + deleteBtn.disabled = true + overlay.remove(); + onDelete?.(); + }; + + btnContainer.append(cancelBtn, deleteBtn); + dialog.append(icon, title, message, btnContainer); + overlay.append(dialog); + + return overlay; + } +} \ No newline at end of file diff --git a/cdn/dev/js/feature/expand-textarea.js b/cdn/dev/js/feature/expand-textarea.js new file mode 100644 index 0000000..59a9106 --- /dev/null +++ b/cdn/dev/js/feature/expand-textarea.js @@ -0,0 +1,14 @@ +import { textAreaState } from "../state/appState.js" +import { defaultSize, fullScreenSize } from "../operation/resizeTextArea.js" + +// Identical to hide-keyboard.js but this is for Tablet & Mobile screen size +export function expandTool() { + const expandTool = document.querySelector('#expandTool') + expandTool?.addEventListener('click', () => { + if (textAreaState.isTextAreaFullHeight) { + defaultSize() + } else { + fullScreenSize() + } + }) +} \ No newline at end of file diff --git a/cdn/dev/js/feature/font-slider.js b/cdn/dev/js/feature/font-slider.js new file mode 100644 index 0000000..8f1fbf8 --- /dev/null +++ b/cdn/dev/js/feature/font-slider.js @@ -0,0 +1,7 @@ +export function fontSliderTool() { + const textArea = document.querySelector('#textArea') + const fontSliderBtn = document.querySelector('#fontSizeRange') + fontSliderBtn.addEventListener('input', function() { + textArea.style.fontSize = `${this.value}px` + }) +} \ No newline at end of file diff --git a/cdn/dev/js/feature/hide-keyboard.js b/cdn/dev/js/feature/hide-keyboard.js new file mode 100644 index 0000000..475d047 --- /dev/null +++ b/cdn/dev/js/feature/hide-keyboard.js @@ -0,0 +1,14 @@ +import { textAreaState } from "../state/appState.js" +import { defaultSize, fullScreenSize } from "../operation/resizeTextArea.js" + +// Identical to hide-keyboard.js but this is for Desktop screen size +export function hideKeyboard() { + const hideKeyboardBtn = document.querySelector('#hideKeyboard') + hideKeyboardBtn?.addEventListener('click', () => { + if (textAreaState.isTextAreaFullHeight) { + defaultSize() + } else { + fullScreenSize() + } + }) +} \ No newline at end of file diff --git a/cdn/dev/js/feature/kb-selection-menu.js b/cdn/dev/js/feature/kb-selection-menu.js new file mode 100644 index 0000000..bfaec5d --- /dev/null +++ b/cdn/dev/js/feature/kb-selection-menu.js @@ -0,0 +1,366 @@ +import { selectedKbList } from "../state/appState.js" +import { platformSupport } from "../operation/platformSupport.js" +import { setKeyboard } from "../operation/handleKeyboardData.js" +import { removeKbSelected, setKbHelpDocHamburger } from "../operation/selectedKb.js" +import { checkKbCardUI } from "./search.js" +import { setKeyboardToType } from "../operation/keyboard.js" +import { confirmAndAddKb } from "../operation/confirmKeyboard.js" +import { bundleKbDataforSelectionMenu } from "../operation/bundleKbSelectionMenu.js" +import { kbConfigMenu } from "../operation/keyboardDetails.js" + +export function addKbToSelectionMenu(kbIconPTag, element, kb, data) { + const keyboardSelectionButton = document.getElementById('keyboardSelectionButton') + + let isSelected = selectedKbList.some(selected => selected.id == kb.id) // Check which keyboard is already in the keyboard selection menu + + // Remove keyboard + if (isSelected) { + removeKbSelected(kb.id) + kbIconPTag.textContent = '+' + generateKbUI(selectedKbList) // Generate Keyboard selection menu UI + checkKbCardUI(kbIconPTag, element, kb) // Disable or Enable Keyboard Search card UI + + return + } + + if(selectedKbList.length < 5) { // if keyboard selection menu has less than 5 keyboards + bundleKbDataforSelectionMenu(kb) // continue to add it to the menu + generateKbUI(selectedKbList) + kbIconPTag.textContent = 'โœ“' + kbIconPTag.classList.add('kb-icon-plus-animate') + + setTimeout(() => { + kbIconPTag.textContent = '-' + kbIconPTag.classList.remove('kb-icon-plus-animate') + keyboardSelectionButton.classList.remove('btn-secondary') + keyboardSelectionButton.classList.add('btn-keyman-orange') + }, 800) + + checkKbCardUI(kbIconPTag, element, kb) + return + } + // if the keyboards in the selection menu are over 5, there's a confirmation needed before adding the keyboard + confirmAndAddKb(() => { + bundleKbDataforSelectionMenu(kb) + generateKbUI(selectedKbList) + + kbIconPTag.textContent = 'โœ“' + kbIconPTag.classList.add('kb-icon-plus-animate') + + setTimeout(() => { + kbIconPTag.textContent = '-' + kbIconPTag.classList.remove('kb-icon-plus-animate') + keyboardSelectionButton.classList.remove('btn-secondary') + keyboardSelectionButton.classList.add('btn-keyman-orange') + }, 800) + checkKbCardUI(kbIconPTag, element, kb) + setKeyboardToType() + textArea.focus() + }) +} + +// UI for keyboard selection menu +export function generateKbUI(selectedKbList) { + const textArea = document.querySelector('#textArea') + const keyboardSelection = document.getElementById("keyboardSelection") + keyboardSelection.innerHTML = '' + + // Check if keyboard selection menu has less than 1 keyboard + if(selectedKbList.length < 1) { + triggerKbCount(selectedKbList) + resetKbSelectionMenu() + return + } + + const kbDivHeader = document.createElement('div') + kbDivHeader.textContent = "Keyboard Selection menu" + kbDivHeader.classList.add('kb-item-header') + + const kbDivFoot = document.createElement('div') + kbDivFoot.textContent = "US Basic Keyboard" + kbDivFoot.classList.add('kb-item-footer') + + keyboardSelection.appendChild(kbDivHeader) + + selectedKbList.forEach(data => { + const kbDiv = document.createElement('div') + kbDiv.classList.add("kb-item-keyboard") + kbDiv.setAttribute('id', `${data.id}`) + + const kbName = document.createElement('span') + kbName.textContent = data.name + + const kbConfigList = document.createElement('ul') + kbConfigList.classList.add('keyboard-configs') + kbConfigList.innerHTML = ` +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • + ` + + const kbDetails = displayKbDetails(data) + + kbDiv.appendChild(kbName) + kbDiv.appendChild(kbConfigList) + kbDiv.appendChild(kbDetails) + keyboardSelection.appendChild(kbDiv) + keyboardSelection.append(kbDivFoot) + + let kbdId = data.id + let langCode = Object.keys(data.supportedLanguage)[0] || "en" + let kbdName = data.name + + highlightKbSelected(kbdId) + + setKeyboard(kbdId, langCode, kbdName) // Set the data to display the keyboard + // Each tools on each of the keyboard in the selection menu + kbConfigList.addEventListener('click', (e) => { + const target = e.target + if (target.tagName == 'I' && target.dataset.action) { + const action = target.dataset.action + const id = target.dataset.id + const helpLink = target.dataset.helplink + kbConfigMenu(action, id, helpLink) + } + }) + + // Click on the keyboard will enable the keyboard for typing + kbName.addEventListener('click', () => { + kbdId = data.id + langCode = Object.keys(data.supportedLanguage)[0] || "en" + setKeyboard(kbdId, langCode, kbdName) + setKeyboardToType() + setKbHelpDocHamburger(kbdId, kbdName) + highlightKbSelected(kbdId) + keyboardSelection.classList.remove('open') + textArea.focus() + }) + + // Default English keyboard + kbDivFoot.onclick = () => { + setKeyboard('basic_kbdus', 'en', 'US Basic') + setKeyboardToType() + } + }) + triggerKbCount(selectedKbList) +} + +// Keyboard count for Keyboard selection menu +export function triggerKbCount(selectedKbList) { + const kbSelectedLength = selectedKbList.length + const keyboardSelectionButton = document.querySelector('#keyboardSelectionButton') + const keyboardCount = document.querySelector('#kbCount') + + if (kbSelectedLength >= 1) { + keyboardCount.classList.remove('fa-caret-right') + keyboardCount.textContent = `${kbSelectedLength}` // Show the number of keyboard in the menu + keyboardSelectionButton.classList.add('btn-keyman-orange') + keyboardSelectionButton.classList.remove('btn-secondary') + } else { + keyboardCount.classList.add('fa-caret-right') + keyboardCount.textContent = '' + keyboardSelectionButton.classList.remove('btn-keyman-orange') + keyboardSelectionButton.classList.add('btn-secondary') + } +} + +// Set the keyboard selection menu to its default UI +function resetKbSelectionMenu() { + const keyboardSelection = document.querySelector("#keyboardSelection") + + const kbDivHeader = document.createElement('div') + kbDivHeader.textContent = "Keyboard Selection menu" + kbDivHeader.classList.add('kb-item-header') + + const kbItem = document.createElement('div') + kbItem.classList.add('.kb-item-keyboard') + + const pTag = document.createElement('p') + pTag.textContent = "Open Search to get your keyboard" + + const kbDivFoot = document.createElement('div') + kbDivFoot.textContent = "US Basic Keyboard" + kbDivFoot.classList.add('kb-item-footer') + + kbItem.appendChild(pTag) + + keyboardSelection.appendChild(kbDivHeader) + keyboardSelection.appendChild(kbItem) + keyboardSelection.appendChild(kbDivFoot) +} + +// UI for Keyboard Selected Limitation +export function limitKbSelectionUI(onAccept) { + const dialogDiv = document.createElement('div') + dialogDiv.classList.add('warning-container') + + const dialogContentDiv = document.createElement('div') + dialogContentDiv.classList.add('warning-content') + + const dialogCancel = document.createElement('button') + dialogCancel.classList.add('warning-cancel-btn') + dialogCancel.setAttribute('id', 'cancelWarningBtn') + dialogCancel.textContent = 'โœ–' + dialogCancel.onclick = () => { + dialogDiv.remove() + generateKbUI(selectedKbList) + } + + const dialogImgTag = document.createElement('img') + dialogImgTag.classList.add('warning-keyman-image') + dialogImgTag.src = `/cdn/dev/img/keymanweb-mini-logo-88.png` + dialogImgTag.alt = "Keyman Logo" + + const firstKeyboard = selectedKbList[0].name + + const dialogPTag = document.createElement('p') + dialogPTag.classList.add('warning-text') + dialogPTag.innerHTML = `The keyboards selected exceeds the limitation of 5 keyboards. Click 'Allow' to remove the
    ${firstKeyboard} keyboard.` + + const dialogUlTag = document.createElement('ol') + dialogUlTag.textContent = "Your keyboards selection:" + selectedKbList.forEach((kb, index) => { + const dialogLiTag = document.createElement('li') + if (index == 0) { + const markKeyboard = document.createElement('mark') + markKeyboard.textContent = kb.name + dialogLiTag.appendChild(markKeyboard) + } else { + dialogLiTag.textContent = kb.name + } + dialogUlTag.appendChild(dialogLiTag) + + }) + + const dialogAccept = document.createElement('button') + dialogAccept.classList.add('warning-accept-btn') + dialogAccept.setAttribute('id', 'acceptWarningBtn') + dialogAccept.textContent = "Allow" + dialogAccept.onclick = () => { + dialogDiv.remove() + onAccept() + } + + dialogContentDiv.appendChild(dialogCancel) + dialogContentDiv.appendChild(dialogImgTag) + dialogContentDiv.appendChild(dialogPTag) + dialogContentDiv.appendChild(dialogUlTag) + dialogContentDiv.appendChild(dialogAccept) + + dialogDiv.appendChild(dialogContentDiv) + + return dialogDiv +} + +// Keyboard details for Keyboard selection menu +function displayKbDetails(data) { + const item = selectedKbList.find(kb => kb.id == data.id) + if (!item) return; + + const kbDetails = document.createElement('div') + kbDetails.classList.add('keyboard-details') + kbDetails.setAttribute('id', `keyboard-${data.id}-details`) + kbDetails.classList.add('hidden') + + const kbDetailsHead = document.createElement('div') + kbDetailsHead.textContent = 'Keyboard Details' + kbDetailsHead.classList.add('kb-item-header') + + const kbDetailsContent = document.createElement('div') + kbDetailsContent.classList.add('keyboard-content-wrapper') + kbDetailsContent.innerHTML = ` +
      +
    • +
      +
      Name
      +
      ${item.name || "N/A"}
      +
      +
    • +
    • +
      +
      Keyboard ID
      +
      ${item.id || "N/A"}
      +
      +
    • +
    • +
      +
      Version
      +
      ${item.version || "N/A"}
      +
      +
    • +
    • +
      +
      Total downloads
      +
      ${item.totalDownloads || 0}
      +
      +
    • +
    • +
      +
      Source Path
      + +
      +
    • +
    • +
      +
      Supported Platforms
      +
      + ${platformSupport(item.platformSupport) || 'No platforms supported'} +
      +
      +
    • +
    • +
      +
      Last Updated
      +
      ${getOnlyDates(item.lastUpdated) || 0}
      +
      +
    • +
    + ` + kbDetails.appendChild(kbDetailsHead) + kbDetails.appendChild(kbDetailsContent) + + return kbDetails +} + +// Get only the YYYY-mm-dd format +function getOnlyDates(dateData) { + const finalDateData = dateData.match(/^\d{4}-\d{2}-\d{2}/) + return finalDateData +} + +// Highlight an enabled keyboard in the Keyboard Selection Menu +export function highlightKbSelected(id) { + document.querySelectorAll('.kb-item-keyboard').forEach(el => { + el.style.backgroundColor = '' + el.style.color = '' + el.style.opacity = '' + }) + + const kbSelectedItem = document.getElementById(id) + if (kbSelectedItem) { + kbSelectedItem.style.backgroundColor = 'var(--keyman-orange)' + kbSelectedItem.style.color = 'white' + kbSelectedItem.style.opacity = '100%' + } +} \ No newline at end of file diff --git a/cdn/dev/js/feature/pagination.js b/cdn/dev/js/feature/pagination.js new file mode 100644 index 0000000..457cbee --- /dev/null +++ b/cdn/dev/js/feature/pagination.js @@ -0,0 +1,43 @@ +// UI for Pagination +import { getKeyboardList } from "../operation/searchAPI.js" +import { searchState } from "../state/appState.js" +import { searchKeyboard } from "../operation/searchLogic.js" + +/* Pagination */ +const prevBtn = document.getElementById('prevPage') +const nextBtn = document.getElementById('nextPage') +const pageInfo = document.getElementById('pageInfo') + +export function updatePaginationCtrl() { + pageInfo.textContent = `${searchState.currentPage} of ${searchState.totalPage}` // Number of Total page + nextBtn.disabled = searchState.currentPage >= searchState.totalPage // Check to disable next page + prevBtn.disabled = searchState.currentPage <= 1 // Check to disable previous page +} + +export function goPrevPage() { + if (searchState.currentPage > 1) { + searchState.currentPage-- + searchKeyboard(searchState.searchQuery, searchState.currentPage) + } +} + +export function goNextPage() { + if (searchState.currentPage < searchState.totalPage) { + searchState.currentPage++ + searchKeyboard(searchState.searchQuery, searchState.currentPage) + } +} + +// Load keyboard search info (pages) +export async function loadPageInfo(defaultQuery = "p:popular") { + const data = await getKeyboardList(defaultQuery) // depending on the query + + if (data?.context) { + searchState.totalPage = data.context.totalPages || 1; + searchState.currentPage = data.context.pageNumber || 1; + } else { + searchState.totalPage = Math.ceil(data.keyboards.length / searchState.itemPerPage); + } + + updatePaginationCtrl() +} diff --git a/cdn/dev/js/feature/search.js b/cdn/dev/js/feature/search.js new file mode 100644 index 0000000..a64fe77 --- /dev/null +++ b/cdn/dev/js/feature/search.js @@ -0,0 +1,180 @@ +// UI for Search +import { searchState, selectedKbList } from "../state/appState.js"; +import { highlightSearchContext, truncateDesc, getMarkedContext, showMarkedContext } from "../operation/searchCardContent.js"; +import { addKbToSelectionMenu } from "./kb-selection-menu.js"; +import { platformSupport } from "../operation/platformSupport.js"; +import { validateURL } from "../operation/validURL.js"; +import { setKeyboardToType } from "../operation/keyboard.js"; +import { setKbHelpDocHamburger } from "../operation/selectedKb.js"; +import { loadPageInfo } from "./pagination.js"; + +/* Search */ +const kbSearchCard = document.getElementById('kbSearchCardUI') +const searchResultCount = document.getElementById('resultCount') +const paginationCtrl = document.getElementById('paginationControls') +const magnifying = document.querySelector('#magnifyingGlassIcon') + +export function updateSearchIcon(value) { + // Base on the value given, it will display one of the icon below + magnifying.style.display = value ? 'none' : 'inline' + clearSearchIcon.style.display = value ? 'inline' : 'none' +} + +/* Display items return from search */ +export function displaySearch(keyboards, total = 0, query = '') { + const searchInstruction = document.querySelector('.search-instruction') + const kbHrTitle = document.querySelector('.keyboard-title') + + kbSearchCard.innerHTML = ''; + + // Validate the keyboards data + if (!keyboards || keyboards.length == 0) { + kbSearchCard.innerHTML = `Well, no keyboards found for ${query}.` + searchInstruction.classList.add("hidden") + kbHrTitle.textContent = "Results" + paginationCtrl.style.display = 'none' + return + } + + if (total) { + searchResultCount.innerHTML = `${total} results` + searchResultCount.classList.remove('hidden') + } + + // Getting searched Word ready for highlight + const marked = getMarkedContext(query) + + if (!query) { + // Most Download UI + searchInstruction.classList.remove("hidden") + kbHrTitle.textContent = "Most Downloads" + paginationCtrl.style.display = 'none' + } else if (total < 2) { + // Total results < 2 UI + searchInstruction.classList.add("hidden") + kbHrTitle.textContent = "Results" + paginationCtrl.style.display = 'none' + } else { + // Result of search query + searchInstruction.classList.add("hidden") + kbHrTitle.textContent = "Results" + paginationCtrl.style.display = 'flex' + } + + // UI for each keyboards + keyboards.forEach(kb => { + const card = searchKbCardUI(kb, marked, selectedKbList, keyboards) + kbSearchCard.appendChild(card) + }) +} + +// Search card UI +function searchKbCardUI(kb, marked = '', selectedKbList, data) { + const searchInput = document.querySelector('#searchInput') + const searchDropdown = new bootstrap.Dropdown(searchInput) + const textArea = document.querySelector('#textArea') + + const kbFoundInList = selectedKbList.some(selected => selected.id == kb.id) // find a match between the keyboard from selection menu & search + // Keyboard card container + let cardWrap = document.createElement('div') + cardWrap.classList.add('card-wrap') + cardWrap.setAttribute('id', 'keyboardCardWrap') + + // Keyboard header container + let cardHeader = document.createElement('div') + cardHeader.classList.add('card-header') + + const {matchFound, matchField, matchValue} = highlightSearchContext(kb, marked) // Highlight search query + + const kbNameHeading = matchFound ? showMarkedContext(kb, matchField, matchValue) // Highlight search query UI + : (() => { + const heading = document.createElement('h4') + heading.innerHTML = kb.name + return heading + })() + + // Keyboard Plus (+) icon + const kbIconPTag = document.createElement('p') + kbIconPTag.textContent = kbFoundInList ? "-" : "+" + kbIconPTag.style.fontSize = '20px' + kbIconPTag.style.cursor = 'pointer' + kbIconPTag.classList.add('kb-icon-plus') + + // Keyboard Help (?) icon + const kbHelpIconSpan = document.createElement('span') + kbHelpIconSpan.classList.add('help-icon-span') + const kbHelpIcon = document.createElement('i') + kbHelpIcon.classList.add('fa-solid', 'fa-question') + kbHelpIconSpan.appendChild(kbHelpIcon) + + const kbHeaderTitle = document.createElement('div') + kbHeaderTitle.classList.add('card-header-title') + + // Must check if the keyboard is in the selection menu + checkKbCardUI(kbIconPTag, cardHeader, kb) + + // Keyboard ID + const kbIdPTag = document.createElement('p') + kbIdPTag.classList.add('keyboard-id') + kbIdPTag.textContent = kb.id + + // Keyboard Description + const kbDescHeading = truncateDesc(kb, matchField, marked) + + // Keyboard monthly downloads and platform support + const kbSpecs = document.createElement('div') + kbSpecs.classList.add('keyboard-specs') + + const kbDownloadHeading = document.createElement('h6') + kbDownloadHeading.textContent = `${kb.match.downloads} monthly downloads` + kbDownloadHeading.classList.add('monthly-download') + + const kbPlatformSupport = document.createElement('div') + kbPlatformSupport.classList.add('platform') + kbPlatformSupport.innerHTML = platformSupport(kb.platformSupport) // Get icons for platform + + // Append children + kbHeaderTitle.appendChild(kbIconPTag) + kbHeaderTitle.appendChild(kbNameHeading) + cardHeader.appendChild(kbHeaderTitle) + cardHeader.appendChild(kbHelpIconSpan) + + kbSpecs.appendChild(kbDownloadHeading) + kbSpecs.appendChild(kbPlatformSupport) + + cardWrap.appendChild(cardHeader) + cardWrap.appendChild(kbIdPTag) + cardWrap.appendChild(kbDescHeading) + cardWrap.appendChild(kbSpecs) + + // Click on a keyboard name to enable the keyboard & add it into selection menu + kbHeaderTitle.onclick = (e) => { + e.stopPropagation() + addKbToSelectionMenu(kbIconPTag, cardHeader, kb, data) + setKeyboardToType() + setKbHelpDocHamburger(kb.id, kb.name) + searchDropdown.hide() + textArea.focus() + } + + // Click on the help icon on the search card to get to the keyboard help documentation + kbHelpIcon.addEventListener('click', () => { + const checkedURL = validateURL(`https://help.keyman.com/keyboard/`) + const newURL = checkedURL + kb.id + window.open(newURL, '_blank') + }) + + return cardWrap +} + +// Disable or Enable UI with opacity +export function checkKbCardUI(kbIconPTag, element, kb) { + // For checking if the keyboard exists in to respond to UI + let kbFoundInList = selectedKbList.some(selected => selected.id == kb.id) + + if (kbFoundInList) { + element.style.opacity = '50%' + } else { + element.style.opacity = '100%' + } +} \ No newline at end of file diff --git a/cdn/dev/js/feature/tool-tray.js b/cdn/dev/js/feature/tool-tray.js new file mode 100644 index 0000000..c908153 --- /dev/null +++ b/cdn/dev/js/feature/tool-tray.js @@ -0,0 +1,95 @@ +const tabletToolElements = ` + + ` + +const desktopToolElements = ` +
    +
    + A + + A +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    + ` + +const phoneToolElements = `
    + + + + + + +
    +
    + +
    +
    +
    + A + + A +
    +
    ` + +const phoneExpandElement = ` + + ` + +const calcScreenSize = Math.min(screen.width, screen.height) + +const toolContainer = document.querySelector('.tool-container') +const divider = document.querySelector('.divider-container') +const resizeGrip = document.querySelector('#resizeGrip') + +export function renderToolsTray() { + if (calcScreenSize < 900 && calcScreenSize >= 720) { // Tablet + toolContainer.innerHTML = tabletToolElements + divider.style.display = 'none' + } else if (calcScreenSize < 720) { // Phone + divider.innerHTML = phoneToolElements + toolContainer.innerHTML = phoneExpandElement + resizeGrip.style.display = 'none' + } else { // Desktop + toolContainer.innerHTML = desktopToolElements + } +} diff --git a/cdn/dev/js/kmwBody.js b/cdn/dev/js/kmwBody.js deleted file mode 100644 index bd9701c..0000000 --- a/cdn/dev/js/kmwBody.js +++ /dev/null @@ -1,118 +0,0 @@ -document.addEventListener('DOMContentLoaded', function() { - // Define the divider, text area and keyboard - const container = document.querySelector('.container-flex') - const divider = document.getElementById('Divider') - - const resizer = divider.querySelector('#resizeGrip') - const prevElementOfResizer = divider.previousElementSibling.querySelector('.text-area') - const nextElementOfResizer = divider.nextElementSibling - - let isResizing = false; - - let startY, startHeightTop, startHeightBottom = 0 - - const mouseDownHandler = (e) => { - e.preventDefault(); - resizer.style.cursor = 'grabbing' - isResizing = true - - startY = e.clientY - startHeightTop = prevElementOfResizer.offsetHeight - startHeightBottom = nextElementOfResizer.offsetHeight - - document.addEventListener('mousemove', mouseMoveHandler) - document.addEventListener('mouseup', mouseUpHandler) - } - - const mouseUpHandler = () => { - resizer.style.removeProperty('cursor') - isResizing = false - document.removeEventListener('mousemove', mouseMoveHandler) - } - - const mouseMoveHandler = function (e) { - if (!isResizing) return; - - let deltaY = e.clientY - startY // Get up or down direction - - let newTopHeight = startHeightTop + deltaY - let newBottomHeight = startHeightBottom - deltaY - - newTopHeight = Math.max(100, Math.min(newTopHeight, window.innerHeight * 0.8)) - newBottomHeight = Math.max(100, Math.min(newBottomHeight, window.innerHeight * 0.7)) - - prevElementOfResizer.style.height = `${newTopHeight}px` - nextElementOfResizer.style.height = `${newBottomHeight}px` - - if (newBottomHeight <= 200) { - fullScreenSize() - } - } - - /* Hide-Show Keyboard */ - const hideKeyboardBtn = document.querySelector('#hideKeyboard') - - let isTextAreaFullHeight = false - const fullHeightTextArea = window.innerHeight * 0.9 - const defaultHeightTextArea = window.innerHeight * 0.3 - - function defaultSize() { - prevElementOfResizer.style.height = `${defaultHeightTextArea}px` - nextElementOfResizer.style.height = `500px` - // nextElementOfResizer.style.width = `900px` - isTextAreaFullHeight = false - } - - function fullScreenSize() { - prevElementOfResizer.style.height = `${fullHeightTextArea}px` - isTextAreaFullHeight = true - } - - hideKeyboardBtn.addEventListener('click', () => { - if (isTextAreaFullHeight) { - defaultSize() - } else { - fullScreenSize() - } - }) - - // Copy tool - const copyBtn = document.querySelector('#copyTool') - const textArea = document.querySelector('#textArea') - copyBtn.addEventListener('click', async function() { - try { - let textToCopy = textArea.value.trim() - - if(!textToCopy) { - copyBtn.classList.replace('fa-copy', 'fa-xmark') - // copyBtn.textContent = ' No characters to copy' - setTimeout(() => { - copyBtn.classList.replace('fa-xmark', 'fa-copy') - copyBtn.textContent = '' - }, 3000) - return; - } - - await navigator.clipboard.writeText(textToCopy) - - copyBtn.classList.replace('fa-copy', 'fa-check'); - - setTimeout(() => { - copyBtn.classList.replace('fa-check', 'fa-copy'); - }, 1000); - - } catch (error) { - console.error('Failed to copy: ', error) - } - }) - - // Font slider - const fontSliderBtn = document.querySelector('#fontSizeRange') - fontSliderBtn.addEventListener('input', function() { - textArea.style.fontSize = `${this.value}px` - }) - - defaultSize() - - resizer.addEventListener('mousedown', mouseDownHandler) -}) \ No newline at end of file diff --git a/cdn/dev/js/kmwElements.js b/cdn/dev/js/kmwElements.js deleted file mode 100644 index 849f8ae..0000000 --- a/cdn/dev/js/kmwElements.js +++ /dev/null @@ -1,36 +0,0 @@ -const calcScreenSize = Math.min(screen.width, screen.height) > 720 ? 'tablet' : 'mobile' - -const searchBox = document.getElementById('searchInput') -const fontSizeContainer = document.getElementsByClassName('font-size-container') -const kbSelectionBtn = document.getElementById('keyboardSelectionButton') -const searchIcon = document.getElementById('searchIcons') - -const fontSizeElements = ` -
    - A - - A -
    ` - -if (calcScreenSize == 'tablet') { - -} - -if (calcScreenSize == 'mobile') { - const firstChild = fontSizeContainer[0].children[0] - const secondChild = fontSizeContainer[0].children[1] - firstChild.remove() - secondChild.remove() - - searchBox.addEventListener('click', () => { - kbSelectionBtn.style.display = 'none' - searchIcon.style.left = '200px' - }) -} - -const fontSizeChild = fontSizeContainer[0].children[0] -fontSizeChild.addEventListener('click', () => { - fontSizeChild.innerHTML = fontSizeElements -}) - - diff --git a/cdn/dev/js/kmwHeader.js b/cdn/dev/js/kmwHeader.js deleted file mode 100644 index f5c7941..0000000 --- a/cdn/dev/js/kmwHeader.js +++ /dev/null @@ -1,1356 +0,0 @@ -keyman = getKeymanWeb() - -function getKeymanWeb() { - if(window.tavultesoft) { - return window.tavultesoft.keymanweb; - } - return window.keyman; -} -/* Global Variables */ -let selectedKbList = [] // Main array for the search, kb selection...etc. -let kbSearchData = [] // For History search -let kmwLang = keyman.getActiveLanguage() -let kmwKb = keyman.getActiveKeyboard() - -const clearSearchIcon = document.querySelector('#clearSearchIcon') -const magnifying = document.querySelector('#magnifyingGlassIcon') - -const elements = { - worldMapBtn: document.querySelector('#worldMap'), - kmwControls: document.querySelector('#KeymanWebControl'), - - kbSelection: document.querySelector('#keyboardSelection'), - keyboardSelectionButton: document.querySelector('#keyboardSelectionButton'), - caretRightIcon: keyboardSelectionButton.querySelector('.fa-caret-right'), - - searchBar: document.querySelector('#searchBar'), - searchInput: document.querySelector('#searchInput'), - searchDropdownMenu: document.querySelector('#searchDropdownMenu'), - searchIcons: document.querySelector('#searchIcons'), -} - -const state = { - mapIsOpen: false -} - -/* - ===================================== Default keyboard ========================================= -*/ - -function defaultKeyboard(kbdname = "basic_kbdus", languageCode = "en") { - if(!exists(kbdname, languageCode)) { - if (textArea) textArea.placeholder = 'A Keyboard name isn\'t specified. Select a keyboard and start typing' - return - } - setKeyboardWithDirection(kbdname, languageCode) -} - -/* - ============================= Toggle between World Map and Search ============================== -*/ -elements.worldMapBtn?.addEventListener('click', (e) => { - e.preventDefault() - state.mapIsOpen = true - if (state.mapIsOpen == true) { - openMap() - keyman.addEventListener('keyboardchange', () => { - location.replace(`#${keyman.getActiveLanguage()},${keyman.getActiveKeyboard()}`) - updateExample(keyman.getActiveKeyboard()) - setTimeout(() => { - applyClassToKb(), 0 - }) - }) - } else { - openSearch() - } -}) - -function openSearch() { - state.mapIsOpen = false - hideEls( - elements.kmwControls, - ) - showEls( - elements.searchDropdownMenu, - elements.searchIcons - ) - - if (selectedKbList.length > 0) { - elements.caretRightIcon.textContent = selectedKbList.length - removeClass(elements.caretRightIcon, 'fa-magnifying-glass') - } else { - elements.caretRightIcon.textContent = '' - elements.caretRightIcon.classList.add('fa-caret-right') - } - - elements.searchBar.replaceChildren( - elements.searchInput, - elements.searchIcons, - elements.searchDropdownMenu - ) -} - -function openMap() { - state.mapIsOpen = true - removeClass( - elements.kmwControls, 'hidden', - elements.caretRightIcon, 'fa-caret-right' - ) - hideEls( - elements.searchDropdownMenu - ) - removeTextContent( - elements.caretRightIcon - ) - elements.keyboardSelectionButton.removeAttribute('id', 'keyboardSelectionButton') - elements.keyboardSelectionButton.setAttribute('id', 'returnToSearchButton') - elements.caretRightIcon.classList.add('fa-magnifying-glass') - elements.keyboardSelectionButton.style.backgroundColor = "var(--keyman-orange)" - elements.keyboardSelectionButton.style.border = '0px' - elements.keyboardSelectionButton.classList.add('return-to-search') - elements.kbSelection.style.display = "none" - elements.searchBar.replaceChildren( - elements.kmwControls - ) -} - -function returnToSearch() { - elements.keyboardSelectionButton.removeAttribute('id', 'returnToSearchButton') - elements.keyboardSelectionButton.setAttribute('id', 'keyboardSelectionButton') - - if ((selectedKbList?.length || 0) < 1) { - elements.caretRightIcon.classList.add('fa-caret-right') - removeClass(elements.caretRightIcon, 'fa-magnifying-glass') - elements.caretRightIcon.textContent = '' - } - - elements.keyboardSelectionButton.style.backgroundColor = "" - elements.kbSelection.style.display = "block" - openSearch() -} - -function waitForElement(selector) { - return new Promise((resolve) => { - const interval = setInterval(() => { - const element = document.querySelector(selector) - if (element) { - clearInterval(interval) - resolve(element) - } - }, 100) - }) -} - -waitForElement('#returnToSearchButton').then((element) => { - element.addEventListener('click', (e) => { - e.preventDefault() - returnToSearch() - }) -}) - -waitForElement(".kmw-osk-frame").then((oskDiv) => { - document.querySelector('.keyboard-area').appendChild(oskDiv) -}) - -/* - ==================== Search Interaction =================== -*/ - -/* Search Input */ -const dropdown = new bootstrap.Dropdown(elements.searchInput, { - autoClose: 'outside' -}) - -document.addEventListener('click', (e) => { - if (!elements.searchInput.contains(e.target) && !elements.searchDropdownMenu.contains(e.target)) { - dropdown.hide() - } -}) - -elements.searchInput.addEventListener('click', (e) => { - e.stopPropagation() - // defaultKeyboard() - dropdown.show() -}) - -// Hide Dropdown Search on Mouse leave -elements.searchDropdownMenu.addEventListener('mouseleave', (e) => { - e.preventDefault() - dropdown.hide() -}) - -/* - =========================== Utility functions ============================ -*/ -function hideEls(...elements) { - return elements.every(el => el.classList.add('hidden')) -} - -function showEls(...elements) { - return elements.every(el => el.classList.remove('hidden')) -} - -function removeClass(element, className) { - return element.classList.remove(className) -} - -function removeTextContent(...elements) { - return elements.every(el => el.textContent = '') -} - -/* Elements validation */ -function exists(...elements) { - return elements.every(el => el != null) -} - -document.addEventListener('DOMContentLoaded', () => { - /* UI Behavior of the Selected Keyboard menu */ - if (exists(elements)) { - elements.keyboardSelectionButton.addEventListener('mouseenter', () => { - elements.kbSelection.classList.add('open') - }) - elements.keyboardSelectionButton.addEventListener('click', () => { - elements.kbSelection.classList.remove('open') - }) - elements.kbSelection.addEventListener('mouseleave', () => { - elements.kbSelection.classList.remove('open') - }) - } -}) - -/* - === Keyboard Execution === -*/ -const downloadBtn = document.getElementById('kbDownloadPage') -const textArea = document.getElementById('textArea') -let langExamples = []; - -function selectKb(kbdname, languageCode) { - if(!exists(kbdname, languageCode)) { - if (textArea) textArea.placeholder = 'A Keyboard name isn\'t specified. Select a keyboard and start typing' - return - } - setKeyboardWithDirection(kbdname, languageCode) -} - -function setTextDirection(targetEls, dir) { - const copyBtn = document.querySelector('#copyTool') - - targetEls.dir = dir - if (dir == 'rtl') { - copyBtn.style.right = '0' - copyBtn.style.left = '10px' - } else { - copyBtn.style.right = '' - copyBtn.style.left = '' - } -} - -// Change and type keyboard -async function setKeyboardWithDirection(kbdname, languageCode) { - const kbSpan = document.querySelector('#kbSpan') - const langTag = `#${languageCode}` - let kbTag = '' - - if (kbdname.match(/Keyboard_*/)) { - kbTag = `${kbdname}` - } else { - kbTag = `Keyboard_${kbdname}` - } - - location.replace(`${langTag},${kbTag}`) - await keyman.addKeyboards(kbdname) - const kbd = keyman.getKeyboard(kbdname, languageCode) - await keyman.setActiveKeyboard(kbdname, languageCode) - - // setTimeout(() => { - // applyClassToKb(), 0 - // }) - - if(kbd) { - textArea.placeholder = `The ${kbdname} keyboard is selected. Start typing...` - kbSpan.innerHTML = `${kbdname}` - - setTextDirection(textArea, textArea.dir) - } - updateExample(kbdname) - if(typeof(KeyboardChange_EmbedFonts) != 'undefined') KeyboardChange_EmbedFonts(kbdname) -} - -/* Language Examples AJAX */ -async function updateExample(kbdname) { - const keymanExample = document.getElementById("example") - const exampleBox = document.getElementById("exampleBox") - - if (!keymanExample || !exampleBox) return false; - - if(kbdname == '') - { - keymanExample.textContent = `No example is available due to empty Keyboard name.` - return true; - } - - let activeLanguage = keyman.getActiveLanguage(); - - if(langExamples[activeLanguage + '_' + kbdname]) - { - keymanExample.innerHTML = langExamples[activeLanguage + '_' + kbdname]; - return true; - } - - langExamples[activeLanguage + '_' + kbdname] = 'Loading...'; - keymanExample.innerHTML = 'Loading...'; - - const link = `/prog/languageexample.php?keyboard=${kbdname}&language=${activeLanguage}`; - try { - const response = await fetch(link); - if(response.status == 200) { - const content = await response.text(); - - langExamples[activeLanguage + '_' + kbdname] = keymanExample.innerHTML = content; - } else { - throw new Error(`Unable to retrieve content, status was ${response.status}: ${response.statusText}`); - } - } catch(e) { - langExamples[activeLanguage + '_' + kbdname] = keymanExample.innerHTML = 'Error retrieving example: '+e.message; - throw e; - } -} - -function applyClassToKb() { - - const kbArea = document.querySelector('.keyboard-area') - if (!kbArea) return - - const apply = () => { - const child = kbArea.children - for (const c of child) { - if (!c.classList.contains('kmw-osk-frame')) { - c.classList.add('kmw-osk-frame') - c.classList.add('kmw-help-osk-frame') - } - } - } - - apply() - - // const observer = new MutationObserver(() => { - // for (const m of mutations) { - // if (m.type === 'childlist' && m.addedNodes.length) { - // apply() - // } - // } - // }) - // observer.observe(kbArea, {childList: true}) -} - -/* Search */ -const kbSearchCard = document.getElementById('kbSearchCardUI'); -let debounceTimer - -/* Pagination */ -prevBtn = document.getElementById('prevPage') -nextBtn = document.getElementById('nextPage') -pageInfo = document.getElementById('pageInfo') - -searchResultCount = document.getElementById('resultCount') -paginationCtrl = document.getElementById('paginationControls') - -let currentPage = 1 -let currentQuery = '' -let totalPage -const itemPerPage = 10 - -prevBtn.addEventListener('click', goPrevPage) -nextBtn.addEventListener('click', goNextPage) - -function updatePaginationCtrl() { - pageInfo.textContent = `${currentPage} of ${totalPage}` - nextBtn.disabled = currentPage >= totalPage - prevBtn.disabled = currentPage <= 1 -} - -function goPrevPage() { - if (currentPage > 1) { - currentPage-- - searchKeyboard(currentQuery, currentPage) - } -} - -function goNextPage() { - if (currentPage < totalPage) { - currentPage++ - searchKeyboard(currentQuery, currentPage) - } -} - -/* Click: Open Search and Display search instructions */ -elements.searchInput.addEventListener('click', function(e) { - const query = e.target.value.trim() - - defaultKeyboard() - if (query == "") { - resetSearch() - } else { - searchKeyboard(query) - } -}) - -/* Input: Search and Display keyboards */ -elements.searchInput.addEventListener('input', function(e) { - handleSearch(e.target.value) -}) - -clearSearchIcon.addEventListener('click', () => { - elements.searchInput.value = '' - handleSearch() - elements.searchInput.focus() -}) - -function handleSearch(value = "") { - currentQuery = value.trim() - currentPage = 1 - - updateSearchIcon(value) - - if (!currentQuery) { - resetSearch() - return - } - debounceSearch(currentQuery, currentPage) -} - -function resetSearch() { - paginationCtrl.style.display = 'none' - defaultSearch() -} - -function updateSearchIcon(value) { - const hasValue = value.length > 0 - magnifying.style.display = hasValue ? 'none' : 'inline' - clearSearchIcon.style.display = hasValue ? 'inline' : 'none' -} - -function debounceSearch(query, page) { - clearTimeout(debounceTimer) - if (query.length > 1) { - debounceTimer = setTimeout(() => { - searchKeyboard(query, page) - }, 300) - } -} - -/* == Section == - Search -*/ - -/* Display top downloads with search Instruction */ -async function defaultSearch() { - kbSearchCard.innerHTML = `

    Loading...

    ` - try { - let response = await fetch(`https://api.keyman.com/search/2.0?q=p:popular`) - if (!response.ok) { - throw new Error(`API request failed with status ${response.status}`) - } - - let data = await response.json() - - let mostDownloadkb = data.keyboards - - if (!mostDownloadkb || !Array.isArray(mostDownloadkb)) { - throw new Error(`Invalid API response structure`) - } - displaySearch(mostDownloadkb) - } - catch(error) { - console.error(`Error fetching ${error}`) - kbSearchCard.innerHTML = `
    No keyboards are found.
    ` - paginationCtrl.style.display = 'none' - } -} - -/* Get query and return search */ -async function searchKeyboard(query = null, page) { - kbSearchCard.innerHTML = `
    Searching ${query}...
    ` - kbSearchCard.style.display = 'block' - - let response = await fetch(`https://api.keyman.com/search/2.0?q=${encodeURIComponent(query)}&p=${page}`) - if (!response.ok) { - throw new Error(`API request failed with status ${response.status}`) - } - - searchHistory(query) - let data = await response.json() - // Found with Context: Setup pagination - if (data.context) { - totalPage = data.context.totalPages || 1; - currentPage = data.context.pageNumber || 1; - } else { - totalPage = Math.ceil(data.keyboards.length / itemPerPage); - } - - // Validate data.keyboards - let keyboardData = data.keyboards - if (!keyboardData || !Array.isArray(keyboardData)) { - throw new Error("Invalid API response structure") - } - - // Get total result - let totalFound = data.context.totalRows - - updatePaginationCtrl() - displaySearch(keyboardData, totalFound, query) -} - -/* Display items return from search */ -function displaySearch(data, total = 0, query = '') { - kbSearchCard.innerHTML = ''; - - if (!data || data.length == 0) { - kbSearchCard.innerHTML = 'No keyboards are found.' - paginationCtrl.style.display = 'none' - return - } - - if (total) { - searchResultCount.innerHTML = `${total} results` - searchResultCount.classList.remove('hidden') - } - - // Getting searched Word ready for highlight - const marked = getMarkedContext(query) - - const searchInstruction = document.querySelector('.search-instruction') - const kbHrTitle = document.querySelector('.keyboard-title') - if (!query) { - searchInstruction.classList.remove("hidden") - kbHrTitle.textContent = "Most Downloads" - } else { - searchInstruction.classList.add("hidden") - kbHrTitle.textContent = "" - } - data.forEach(kb => { - const card = searchKbCardUI(kb, marked, selectedKbList, data) - kbSearchCard.appendChild(card) - }) - paginationCtrl.style.display = 'flex'; -} - -// UI Search card -function searchKbCardUI(kb, marked = '', selectedKbList, data) { - const kbFoundInList = selectedKbList.some(selected => selected.id == kb.id) - // Keyboard card container - let cardWrap = document.createElement('div') - cardWrap.classList.add('card-wrap') - cardWrap.setAttribute('id', 'keyboardCardWrap') - - // Keyboard header container - let cardHeader = document.createElement('div') - cardHeader.classList.add('card-header') - - const {matchFound, matchField, matchValue} = highlightSearchContext(kb, marked) - - const kbNameHeading = matchFound ? showMarkedContext(kb, matchField, matchValue) - : (() => { - const heading = document.createElement('h4') - heading.innerHTML = kb.name - return heading - }) - - // Keyboard Plus (+) icon - const kbIconPTag = document.createElement('p') - kbIconPTag.textContent = kbFoundInList ? "-" : "+" - kbIconPTag.style.fontSize = '20px' - kbIconPTag.style.cursor = 'pointer' - kbIconPTag.classList.add('kb-icon-plus') - - checkKbCardUI(kbIconPTag, cardWrap, kb) - // Keyboard ID - const kbIdPTag = document.createElement('p') - kbIdPTag.classList.add('keyboard-id') - kbIdPTag.textContent = kb.id - - // Keyboard Description - const kbDescHeading = truncateDesc(kb, matchField, marked) - - // Keyboard monthly downloads and platform support - const kbSpecs = document.createElement('div') - kbSpecs.classList.add('keyboard-specs') - - const kbDownloadHeading = document.createElement('h6') - kbDownloadHeading.textContent = `${kb.match.downloads} monthly downloads` - kbDownloadHeading.classList.add('monthly-download') - - const kbPlatformSupport = document.createElement('div') - kbPlatformSupport.classList.add('platform') - kbPlatformSupport.innerHTML = platformSupport(kb.platformSupport) - - // Append children - cardHeader.appendChild(kbNameHeading) - cardHeader.appendChild(kbIconPTag) - - kbSpecs.appendChild(kbDownloadHeading) - kbSpecs.appendChild(kbPlatformSupport) - - cardWrap.appendChild(cardHeader) - cardWrap.appendChild(kbIdPTag) - cardWrap.appendChild(kbDescHeading) - cardWrap.appendChild(kbSpecs) - - // Choose keyboard to selection - kbIconPTag.onclick = (e) => { - e.stopPropagation() - addKbToSelectionMenu(kbIconPTag, cardWrap, kb, data) - textArea.focus() - selectKb() - } - // console.log("Recent:", historyKbSelection.getHistory()); - - return cardWrap -} - -// Disable or Enable search card -function checkKbCardUI(kbIconPTag, cardWrap, kb) { - // For checking if the keyboard exists in selected Kbs - let kbFoundInList = selectedKbList.some(selected => selected.id == kb.id) - if (kbFoundInList) { - cardWrap.classList.add('disabled') - } else { - cardWrap.classList.remove('disabled') - } -} - -// Highlight word searched -function getMarkedContext(query) { - let escapedTerm = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') - return new RegExp(escapedTerm, 'i') -} - -// Find a match between Search Context and Language, Keyboard name, Description -function highlightSearchContext(kb, marked) { - let matchFound = false - let matchField = "" - let matchValue = "" - - // Get and find language that matches the search - for (lang in kb.languages) { - let langData = kb.languages[lang] - for (key in langData) { - const value = langData[key] - if (typeof value == "string" && marked.test(value)) { - matchFound = true - matchValue = value.replace(marked, (m) => m ? `${m}` : m) - matchField = "language" - break - } - } - if (matchFound) break - } - - // Find a match for keyboard name if language is not a match - if (!matchFound && marked.test(kb.name)) { - matchFound = true - matchValue = kb.name.replace(marked, '$&') - matchField = "keyboard" - } - - // Find a match for keyboard description if name is not a match - if (!matchFound && marked.test(kb.description)) { - matchFound = true - matchField = "description" - } - - return {matchField, matchValue, matchFound} -} - -// Display Highlighted Search Context -function showMarkedContext(kb, matchField, matchValue) { - const kbNameHeading = document.createElement('h4') - - const kbHelpLink = document.createElement('a') - kbHelpLink.href = `https://help.keyman.com/keyboard/${kb.id}` - kbHelpLink.target = '_blank' - kbHelpLink.rel = 'noopener noreferrer' - - // Display matched language - const langNameSpan = document.createElement('span') - langNameSpan.style.fontSize = "14px" - if (matchField == "language") { - langNameSpan.innerHTML = matchField == "language" ? ` (${matchValue} language)` : "" - } - - // Display matched keyboard - if (matchField == "keyboard") { - kbHelpLink.innerHTML = matchValue - } else { - kbHelpLink.textContent = kb.name - } - kbNameHeading.appendChild(kbHelpLink) - kbNameHeading.appendChild(langNameSpan) - kbNameHeading.addEventListener('click', () => { - const checkedURL = validateURL(`https://help.keyman.com/keyboard/`) - const newURL = checkedURL + kb.id - window.open(newURL, '_blank') - }) - - return kbNameHeading -} - -// Truncated Keyboard Description -function truncateDesc(kb, matchField, marked) { - const kbDescHeading = document.createElement('h6') - kbDescHeading.classList.add("keyboard-description") - const word_limits = 90 - - let temp = document.createElement('div') - temp.innerHTML = kb.description - - let fullDesc = kb.description - let plainText = temp.textContent - let shortText = "" - - let isTruncated = false - - if (plainText.length >= word_limits) { - shortText = plainText.slice(0, word_limits) + "..." - kbDescHeading.innerHTML = shortText - isTruncated = true - } else { - kbDescHeading.innerHTML = fullDesc - isTruncated = false - } - - if (isTruncated) { - const toggleBtn = document.createElement('a') - toggleBtn.href = "#" - toggleBtn.style.marginLeft = "6px" - toggleBtn.textContent = "Show more" - - toggleBtn.addEventListener('click', e => { - e.preventDefault() - const isExpanded = toggleBtn.textContent == "Show more" - kbDescHeading.innerHTML = !isExpanded ? shortText.replace(marked, (m) => m ? `${m}` : m) : fullDesc - if (matchField == 'description') { - kbDescHeading.innerHTML = isExpanded ? fullDesc.replace(marked, '$&') : shortText - } - kbDescHeading.style.color = isExpanded ? 'black' : 'gray' - toggleBtn.textContent = isExpanded ? "Show less" : "Show more" - kbDescHeading.appendChild(toggleBtn) - }) - kbDescHeading.appendChild(toggleBtn) - } - - return kbDescHeading -} - -/* - == End of Search Section == -*/ - -// Platform Support -function platformSupport(data) { - const platformMap = { - android: "Android", - desktopWeb: "Web", - ios: "iPhone and iPad", - linux: "Linux", - macos: "macOS", - mobileWeb: "Mobile web", - windows: "Windows" - } - let platformSpan = Object.entries(data) - .filter(([_, supportLevel]) => supportLevel == 'full') - .map(([platform]) => `${platformMap[platform]}`).join('') - - return platformSpan -} - -/* == Section == - Keyboard Selection Menu -*/ -function addKbToSelectionMenu(kbIconPTag, cardWrap, kb, data) { - const keyboardSelectionButton = document.getElementById('keyboardSelectionButton') - let isSelected = selectedKbList.some(selected => selected.id == kb.id) - addDataKb(data) - // Remove keyboard - if (isSelected) { - removeKbSelected(kb.id) - kbIconPTag.textContent = '+' - generateKbUI(selectedKbList) - checkKbCardUI(kbIconPTag, cardWrap, kb) - - return - } - if(selectedKbList.length < 5) { - addKbToSelection(kb) - generateKbUI(selectedKbList) - kbIconPTag.textContent = 'โœ“' - kbIconPTag.classList.add('kb-icon-plus-animate') - - setTimeout(() => { - kbIconPTag.textContent = '-' - kbIconPTag.classList.remove('kb-icon-plus-animate') - keyboardSelectionButton.classList.remove('btn-secondary') - keyboardSelectionButton.classList.add('btn-keyman-orange') - }, 800) - - checkKbCardUI(kbIconPTag, cardWrap, kb) - return - } - confirmAndAddKb(() => { - addKbToSelection(kb) - generateKbUI(selectedKbList) - - kbIconPTag.textContent = 'โœ“' - kbIconPTag.classList.add('kb-icon-plus-animate') - - setTimeout(() => { - kbIconPTag.textContent = '-' - kbIconPTag.classList.remove('kb-icon-plus-animate') - keyboardSelectionButton.classList.remove('btn-secondary') - keyboardSelectionButton.classList.add('btn-keyman-orange') - }, 800) - checkKbCardUI(kbIconPTag, cardWrap, kb) - }) -} - -// Add keyboard for kb search and selection UI -function addKbToSelection(kb) { - const kbInfo = { - "id": kb.id, - "name": kb.name, - "version": kb.version, - "helpLink": kb.helpLink, - "platformSupport": kb.platformSupport, - "totalDownloads": kb.match.totalDownloads, - "sourcePath": kb.sourcePath, - "supportedLanguage": kb.languages, - "lastUpdated": kb.lastModifiedDate - } - // historyKbSelection.add(kbInfo) - selectedKbList.push(kbInfo) -} - -// UI for keyboard selection menu -function generateKbUI(selectedKbList) { - const keyboardSelection = document.getElementById("keyboardSelection") - keyboardSelection.innerHTML = '' - - if(selectedKbList.length < 1) { - triggerKbCount(selectedKbList) - resetKbSelectionMenu() - return - } - - const kbDivHeader = document.createElement('div') - kbDivHeader.textContent = "Keyboard Selection menu" - kbDivHeader.classList.add('kb-item-header') - - const kbDivFoot = document.createElement('div') - kbDivFoot.textContent = "US Basic Keyboard" - kbDivFoot.classList.add('kb-item-footer') - - keyboardSelection.appendChild(kbDivHeader) - - selectedKbList.forEach(data => { - const kbDiv = document.createElement('div') - kbDiv.classList.add("kb-item") - kbDiv.setAttribute('id', `${data.id}`) - - const kbName = document.createElement('span') - kbName.textContent = data.name - - const kbConfigList = document.createElement('ul') - kbConfigList.classList.add('keyboard-configs') - kbConfigList.innerHTML = ` -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • - ` - - const kbDetails = displayKbDetails(data) - - kbDiv.appendChild(kbName) - kbDiv.appendChild(kbConfigList) - kbDiv.appendChild(kbDetails) - keyboardSelection.appendChild(kbDiv) - keyboardSelection.append(kbDivFoot) - - let kbdName = data.id - let langCode = Object.keys(data.supportedLanguage)[0] || "en" - - selectKb(kbdName, langCode) - kbConfigList.addEventListener('click', (e) => { - const target = e.target - if (target.tagName == 'I' && target.dataset.action) { - const action = target.dataset.action - const id = target.dataset.id - const helpLink = target.dataset.helplink - kbConfigMenu(action, id, helpLink) - } - }) - - kbDiv.addEventListener('click', () => { - kbdName = data.id - langCode = Object.keys(data.supportedLanguage)[0] || "en" - textArea.focus() - selectKb(kbdName, langCode) - }) - - kbDivFoot.onclick = () => { - defaultKeyboard() - } - - const kbHelpLink = document.querySelector('#kbHelpdocLink') - kbHelpLink.addEventListener('click', (e) => { - kbConfigMenu('help', '', data.helpLink) - }) - }) - triggerKbCount(selectedKbList) -} - -// Keyboard count for Keyboard selection menu -function triggerKbCount(selectedKbList) { - const kbSelectedLength = selectedKbList.length - const keyboardSelectionButton = document.querySelector('#keyboardSelectionButton') - const keyboardCount = document.querySelector('#kbCount') - - if (kbSelectedLength >= 1) { - keyboardCount.classList.remove('fa-caret-right') - keyboardCount.textContent = `${kbSelectedLength}` - keyboardSelectionButton.classList.add('btn-keyman-orange') - keyboardSelectionButton.classList.remove('btn-secondary') - } else { - keyboardCount.classList.add('fa-caret-right') - keyboardCount.textContent = '' - keyboardSelectionButton.classList.remove('btn-keyman-orange') - keyboardSelectionButton.classList.add('btn-secondary') - } -} - -// Keyboard count default for Keyboard selection menu -function resetKbSelectionMenu() { - const keyboardSelection = document.querySelector("#keyboardSelection") - - const kbDivHeader = document.createElement('div') - kbDivHeader.textContent = "Keyboard Selection menu" - kbDivHeader.classList.add('kb-item-header') - - const kbItem = document.createElement('div') - kbItem.classList.add('.kb-item') - - const pTag = document.createElement('p') - pTag.textContent = "Open Search to get your keyboard" - - const kbDivFoot = document.createElement('div') - kbDivFoot.textContent = "US Basic Keyboard" - kbDivFoot.classList.add('kb-item-footer') - - kbItem.appendChild(pTag) - - keyboardSelection.appendChild(kbDivHeader) - keyboardSelection.appendChild(kbItem) - keyboardSelection.appendChild(kbDivFoot) -} - -// Compare and remove keyboard -function removeKbSelected(kbId) { - if(kbId) { - selectedKbList = selectedKbList.filter(kb => kb.id !== kbId) - } -} - -// Check 6th keyboard -function confirmAndAddKb(onConfirmAdd) { - if (typeof onConfirmAdd != 'function') { - console.log("Expected the onConfirmAdd a function, instead got: " + typeof onConfirmAdd) - alert("Click on the keyboard again to enable.") - } - - const warningDialogUI = limitKbSelectionUI(() => { - onConfirmAdd() - selectedKbList.shift() - generateKbUI(selectedKbList) - }) - - document.body.appendChild(warningDialogUI) -} - -// UI for Keyboard Selected Limitation -function limitKbSelectionUI(onAccept) { - const dialogDiv = document.createElement('div') - dialogDiv.classList.add('warning-container') - - const dialogContentDiv = document.createElement('div') - dialogContentDiv.classList.add('warning-content') - - const dialogCancel = document.createElement('button') - dialogCancel.classList.add('warning-cancel-btn') - dialogCancel.setAttribute('id', 'cancelWarningBtn') - dialogCancel.textContent = 'โœ–' - dialogCancel.onclick = () => { - dialogDiv.remove() - generateKbUI(selectedKbList) - } - - const dialogImgTag = document.createElement('img') - dialogImgTag.classList.add('warning-keyman-image') - dialogImgTag.src = `/cdn/dev/img/keymanweb-mini-logo-88.png` - dialogImgTag.alt = "Keyman Logo" - - const firstKeyboard = selectedKbList[0].name - - const dialogPTag = document.createElement('p') - dialogPTag.classList.add('warning-text') - dialogPTag.innerHTML = `The keyboards selected exceeds the limitation of 5 keyboards. Click 'Allow' to remove the
    ${firstKeyboard} keyboard.` - - const dialogUlTag = document.createElement('ol') - dialogUlTag.textContent = "Your keyboards selection:" - selectedKbList.forEach((kb, index) => { - const dialogLiTag = document.createElement('li') - if (index == 0) { - const markKeyboard = document.createElement('mark') - markKeyboard.textContent = kb.name - dialogLiTag.appendChild(markKeyboard) - } else { - dialogLiTag.textContent = kb.name - } - dialogUlTag.appendChild(dialogLiTag) - - }) - - const dialogAccept = document.createElement('button') - dialogAccept.classList.add('warning-accept-btn') - dialogAccept.setAttribute('id', 'acceptWarningBtn') - dialogAccept.textContent = "Allow" - dialogAccept.onclick = () => { - dialogDiv.remove() - onAccept() - } - - dialogContentDiv.appendChild(dialogCancel) - dialogContentDiv.appendChild(dialogImgTag) - dialogContentDiv.appendChild(dialogPTag) - dialogContentDiv.appendChild(dialogUlTag) - dialogContentDiv.appendChild(dialogAccept) - - dialogDiv.appendChild(dialogContentDiv) - - return dialogDiv -} - -// Seperate list for History/Remember Search - -/* - ========================== To be continued ========================== -*/ -function addDataKb(data) { - let selectedKbData = [] - // console.log(data) - const kbInfo = { - "platformSupport": data.platformSupport, - // "monthlyDownloads": data.match.downloads, - "sourceFile": data.sourcePath, - } - selectedKbData.push(kbInfo) -} - -// End of History search - -// Keyboard selection menu's tools: help, download, and remove -function kbConfigMenu(action, id, helplink) { - if (action == "help") { - window.open(helplink, '_blank') - } - - if (action == "download") { - const downloadUrl = `https://keyman.com/keyboards/install/${id}` - window.open(downloadUrl, '_blank') - } - - if (action == "remove") { - removeKbSelected(id) - generateKbUI(selectedKbList) - triggerKbCount(selectedKbList) - } - - if (action == "info") { - const kbDetails = document.querySelector(`#keyboard-${id}-details`) - - kbDetails.addEventListener('mouseleave', () => { - kbDetails.classList.add('hidden') - }) - kbDetails.classList.remove('hidden') - } -} - -// Keyboard details for Keyboard selection menu -function displayKbDetails(data) { - const item = selectedKbList.find(kb => kb.id == data.id) - if (!item) return; - - const kbDetails = document.createElement('div') - kbDetails.classList.add('keyboard-details') - kbDetails.setAttribute('id', `keyboard-${data.id}-details`) - kbDetails.classList.add('animate__animated', 'animate__fadeIn') - kbDetails.classList.add('hidden') - - const kbDetailsHead = document.createElement('div') - kbDetailsHead.textContent = 'Keyboard Details' - kbDetailsHead.classList.add('kb-item-header') - - const kbDetailsContent = document.createElement('div') - kbDetailsContent.classList.add('keyboard-content-wrapper') - kbDetailsContent.innerHTML = ` -
      -
    • -
      -
      Name
      -
      ${item.name || "N/A"}
      -
      -
    • -
    • -
      -
      Keyboard ID
      -
      ${item.id || "N/A"}
      -
      -
    • -
    • -
      -
      Version
      -
      ${item.version || "N/A"}
      -
      -
    • -
    • -
      -
      Total downloads
      -
      ${item.totalDownloads || 0}
      -
      -
    • -
    • -
      -
      Source Path
      - -
      -
    • -
    • -
      -
      Supported Platforms
      -
      - ${platformSupport(item.platformSupport) || 'No platforms supported'} -
      -
      -
    • -
    • -
      -
      Last Updated
      -
      ${getOnlyDates(item.lastUpdated) || 0}
      -
      -
    • -
    - ` - kbDetails.appendChild(kbDetailsHead) - kbDetails.appendChild(kbDetailsContent) - - return kbDetails -} - -// Get only the YYYY-mm-dd format -function getOnlyDates(dateData) { - const finalDateData = dateData.match(/^\d{4}-\d{2}-\d{2}/) - return finalDateData -} - -// Validate URLs -function validateURL(string) { - try { - const newUrl = new URL(string) - if (newUrl.protocol === 'https:') { - return newUrl - } else { - return false - } - } catch (error) { - console.error(error) - } -} -/* - == End of Keyboard Selection menu Section == -*/ - -/* - == Store data in localStorage to use for reload == -*/ -let appState = { - fontSize: 16, - writtenText: "", - selectedKbList: [], - enabledKb: null, - keyboardSizes: null, - textAreaSizes: null -} -const keyboardContainer = document.querySelector('.keyboard-container') -const fontSizeRange = document.querySelector('#fontSizeRange') - -function getFontSize(element) { - let theFontSize - theFontSize = parseInt(window.getComputedStyle(element).fontSize) || "16" - - return theFontSize -} - -function getSelectedKb() { - return selectedKbList || [] -} - -function getEnabledKb() { - let hash = location.hash.match(/^#(.+),(Keyboard_.+)$/i)[0] - - let kbValues = hash.replace('#', '') - kbValues = hash.split(',') - - return [hash, kbValues] -} - -function getElementsSize(element) { - const rect = element.getBoundingClientRect() - return { - height: rect.height, - width: rect.width, - positionX: rect.x, - positionY: rect.y - } -} - -function getElementValue(element) { - return element.value -} - -function setFontSize(size) { - textArea.style.fontSize = size + "px" - fontSizeRange.value = size -} - -function setWrittenText(text) { - textArea.value = text -} - -function setElementsSize(element, sizes) { - element.style.height = sizes.height + "px" - element.style.left = sizes.positionX + "px" - element.style.top = sizes.positionY + "px" -} - -function setSelectedKb(savedKbList) { - selectedKbList = savedKbList -} - -function setEnabledKb(kb) { - if (kb) { - selectKb(kb) - } -} - -function buildAppState() { - appState = { - fontSize: getFontSize(textArea), - selectedKbList: getSelectedKb(), - enabledKb: getEnabledKb(), - textAreaSizes: getElementsSize(textArea), - keyboardSizes: getElementsSize(keyboardContainer), - writtenText: getElementValue(textArea) - } - saveSettings("keymanWebState", appState) -} - -function saveSettings(key, state) { - let recentTime = new Date() - const time = 5000 // equals to An hour - let item - - // console.log("recentTime: ", recentTime) - // console.log("recentTime.getTime(): ", recentTime.getTime()) - - if (state) { - item = { - value: state, - expiry: recentTime.getTime() + time - } - } - localStorage.setItem(key, JSON.stringify(item)) -} - -function loadSettings(key) { - const raw = localStorage.getItem(key) - if (raw) { - let appState = JSON.parse(raw) - const newTime = new Date() - - console.log("newTime: ", newTime, "appState.expiry: ", appState.expiry) - console.log(newTime.getTime() > appState.expiry) - if (newTime.getTime() > appState.expiry) { - localStorage.removeItem(key) - alert("Session expired!") - return null - } - - setFontSize(appState.value.fontSize) - setWrittenText(appState.value.writtenText) - setElementsSize(textArea, appState.value.textAreaSizes) - setElementsSize(keyboardContainer, appState.value.keyboardSizes) - setSelectedKb(appState.value.selectedKbList) - setEnabledKb(appState.value.enabledKb[0]) - - generateKbUI(appState.value.selectedKbList) - console.log(appState.value.enabledKb[1][1], appState.value.enabledKb[1][0]) - // selectKb(appState.value.enabledKb[1][1], appState.value.enabledKb[1][0]) - } -} - -window.addEventListener('load', () => { - loadSettings("keymanWebState") -}) - -window.addEventListener('beforeunload', () => { - buildAppState() -}) - -window.addEventListener('storage', (e) => { - if (e.key == "keymanWebState") { - appState = JSON.parse(e.newValue) - buildAppState() - } -}) - -function searchHistory(value) { - if (kbSearchData.length < 0) { - kbSearchData.push(value) - for (i=0; i<=kbSearchData.length; i++) { - if (value != kbSearchData[i] || kbSearchData.length >= 5) { - kbSearchData.shift() - } - } - } - // console.log(kbSearchData) -} \ No newline at end of file diff --git a/cdn/dev/js/main.mjs b/cdn/dev/js/main.mjs new file mode 100644 index 0000000..05e60af --- /dev/null +++ b/cdn/dev/js/main.mjs @@ -0,0 +1,133 @@ +// Tool imports +import { eraserTool } from "./feature/eraser.js" +import { copyTool } from "./feature/copy.js" +import { fontSliderTool } from "./feature/font-slider.js" +import { expandTool } from "./feature/expand-textarea.js" +import { hideKeyboard } from "./feature/hide-keyboard.js" +import { mouseDownGrabber } from "./operation/resizeKeyboard.js" +import { renderToolsTray } from "./feature/tool-tray.js" + +// Pagination-related imports +import { searchState } from "./state/appState.js" +import { goPrevPage, goNextPage, updatePaginationCtrl } from "./feature/pagination.js" +import { getKeyboard, setKeyboard } from "./operation/handleKeyboardData.js" +import { handleSearch, defaultSearch } from "./operation/searchLogic.js" + +// Keyboard imports +import { defaultSize } from "./operation/resizeTextArea.js" +import { setKeyboardToType } from "./operation/keyboard.js" + +import { waitForElement } from "./operation/waitForElement.js" +waitForElement(".kmw-osk-frame").then((oskDiv) => { + document.querySelector('.keyboard-area').appendChild(oskDiv) +}) + +// Local Storage +import { buildAppState, loadSettings } from "./operation/rememberState.js" +import { setEnabledKb } from "./state/enableKb.js" + +// Search Components +const clearSearchIcon = document.querySelector('#clearSearchIcon') + +// Pagination Components +const prevBtn = document.getElementById('prevPage') +const nextBtn = document.getElementById('nextPage') + +// Keyboard Selection Menu Components +const keyboardSelectionButton = document.querySelector('#keyboardSelectionButton') +const kbSelection = document.querySelector('#keyboardSelection') + +// Search Components +const searchInput = document.querySelector('#searchInput') +const searchDropdownMenu = document.querySelector('#searchDropdownMenu') +const searchDropdown = new bootstrap.Dropdown(searchInput) + +document.addEventListener('DOMContentLoaded', () => { + // Tool Tray for Mobile, Tablet, and Desktop layouts + renderToolsTray() + // Eraser + eraserTool(document.querySelector("#eraseTool")) + // Copy + copyTool(document.querySelector("#copyTool")) + // Font slider + fontSliderTool(document.querySelector("#fontSizeRange")) + // Expand text area (Tablet and Mobile) + expandTool(document?.querySelector("#expandTool")) + // Expand text area (Desktop) + hideKeyboard(document.querySelector('#hideKeyboard')) + + // Pagination + prevBtn.addEventListener('click', goPrevPage) + nextBtn.addEventListener('click', goNextPage) + + // Resizer (between textarea and keyboard) + const resizeGrip = document.querySelector('#resizeGrip') + resizeGrip.addEventListener('mousedown', mouseDownGrabber) + + // Mouse events on Keyboard Selection menu + keyboardSelectionButton.addEventListener('click', () => { + kbSelection.classList.toggle('open') + }) + kbSelection.addEventListener('mouseleave', () => { + kbSelection.classList.remove('open') + }) + + // Set keyboard & examples to load + setKeyboardToType() + + /* Search Interaction */ + // Close search dropdown when clicking outside the dropdown menu + document.addEventListener('click', (e) => { + if (!searchInput.contains(e.target) && !searchDropdownMenu.contains(e.target)) { + searchDropdown.hide() + } + }) + + // Click on search + searchInput.addEventListener('click', function(e) { + e.stopPropagation() + searchDropdown.show() + searchInput.placeholder = 'Search for a keyboard...' + setKeyboard('basic_kbdus', 'en', 'US Basic') // Ensure that this keyboard is always selected + setKeyboardToType() // Set keyboard & examples to load + handleSearch(e.target.value) // Get Search Query + }) + + // Input: Search and Display keyboards + searchInput.addEventListener('input', function(e) { + e.preventDefault() + setKeyboard('basic_kbdus', 'en', 'US Basic') + setKeyboardToType() // Ensure that no keyboard switching mid selecting a keyboard + const query = e.target.value + searchState.searchQuery = query // update query + searchState.currentPage = 1 + handleSearch(query) // Get Search Query + }) + + // Click on clear if there's input + clearSearchIcon.addEventListener('click', (e) => { + let query = e.target.value + handleSearch(query) + searchInput.value = '' + searchInput.focus() + }) + + // Default text area and keyboard size + defaultSize() + + window.addEventListener('load', () => { + const state = loadSettings() + if(state?.enabledKb) { + setEnabledKb(state.enabledKb) + } + }) + + window.addEventListener('beforeunload', buildAppState) + + window.addEventListener('storage', (e) => { + if (e.key == "keymanWebState") { + loadSettings() + } + }) + +}) diff --git a/cdn/dev/js/operation/bundleKbSelectionMenu.js b/cdn/dev/js/operation/bundleKbSelectionMenu.js new file mode 100644 index 0000000..9150ecb --- /dev/null +++ b/cdn/dev/js/operation/bundleKbSelectionMenu.js @@ -0,0 +1,18 @@ +import { selectedKbList } from "../state/appState.js" + +// Add keyboard for kb search and selection UI +export function bundleKbDataforSelectionMenu(kb) { + const kbInfo = { + "id": kb.id, + "name": kb.name, + "version": kb.version, + "helpLink": kb.helpLink, + "platformSupport": kb.platformSupport, + "totalDownloads": kb.match.totalDownloads, + "sourcePath": kb.sourcePath, + "supportedLanguage": kb.languages, + "lastUpdated": kb.lastModifiedDate + } + + selectedKbList.push(kbInfo) +} \ No newline at end of file diff --git a/cdn/dev/js/operation/confirmKeyboard.js b/cdn/dev/js/operation/confirmKeyboard.js new file mode 100644 index 0000000..da8b097 --- /dev/null +++ b/cdn/dev/js/operation/confirmKeyboard.js @@ -0,0 +1,19 @@ +import { selectedKbList } from "../state/appState.js" +import { generateKbUI, limitKbSelectionUI } from "../feature/kb-selection-menu.js" + +// Check 6th keyboard +export function confirmAndAddKb(onConfirmAdd) { + if (typeof onConfirmAdd != 'function') { + console.log("Expected the onConfirmAdd a function, instead got: " + typeof onConfirmAdd) + alert("Click on the keyboard again to enable.") + } + + // Confirm a 6th keyboard then generate keyboard selection menu + const warningDialogUI = limitKbSelectionUI(() => { + onConfirmAdd() + selectedKbList.shift() + generateKbUI(selectedKbList) + }) + + document.body.appendChild(warningDialogUI) +} \ No newline at end of file diff --git a/cdn/dev/js/operation/handleKeyboardData.js b/cdn/dev/js/operation/handleKeyboardData.js new file mode 100644 index 0000000..7dc868d --- /dev/null +++ b/cdn/dev/js/operation/handleKeyboardData.js @@ -0,0 +1,17 @@ +import { kbData } from "../state/appState.js" + +// Set Keyboard Data from AppState +export function setKeyboard(id, lang, name) { + kbData.kbdId = id + kbData.langCode = lang + kbData.kbdName = name +} + +// Fetch Keyboard Data from AppState +export function getKeyboard() { + return { + kbdId: kbData.kbdId, + langCode: kbData.langCode, + kbdName: kbData.kbdName + } +} diff --git a/cdn/dev/js/operation/keyboard.js b/cdn/dev/js/operation/keyboard.js new file mode 100644 index 0000000..d9b7b19 --- /dev/null +++ b/cdn/dev/js/operation/keyboard.js @@ -0,0 +1,94 @@ +/* + === Keyboard Execution === +*/ +import { getKeyboard, setKeyboard } from "./handleKeyboardData.js"; +import { highlightKbSelected } from "../feature/kb-selection-menu.js"; + +const textArea = document.getElementById('textArea') +const keymanExample = document.getElementById("example") +const exampleBox = document.getElementById("exampleBox") +let langExamples = []; + +// Change and type keyboard +export async function setKeyboardToType() { + if (!textArea) return + + const { kbdId, langCode, kbdName } = getKeyboard() // Get the keyboard data + + const langTag = `#${langCode}` + const kbTag = kbdId.startsWith("Keyboard_") ? kbdId : `Keyboard_${kbdId}` + + if(kbdName) { + textArea.placeholder = `The ${kbdName} keyboard is selected. Start typing...` + searchInput.placeholder = "Selected: " + kbdName + " keyboard" + } + + location.replace(`${langTag},${kbTag}`) + + await keyman.addKeyboards(kbdId) + await keyman.setActiveKeyboard(kbdId, langCode) + // const kbd = keyman.getKeyboard(kbdId, langCode) + + setTimeout(() => { + applyClassToKb(), 0 + }) + + // Update Example of enable the keyboard + updateExample(kbdId) + highlightKbSelected(kbdId) + if(typeof(KeyboardChange_EmbedFonts) != 'undefined') KeyboardChange_EmbedFonts(kbdId) +} + +// Language Examples +async function updateExample(kbdId) { + if (!keymanExample || !exampleBox) return false; + + if(kbdId == '') + { + keymanExample.textContent = `No example is available due to empty Keyboard name.` + return true; + } + + let activeLanguage = keyman.getActiveLanguage(); + + if(langExamples[activeLanguage + '_' + kbdId]) + { + keymanExample.innerHTML = langExamples[activeLanguage + '_' + kbdId]; + return true; + } + + langExamples[activeLanguage + '_' + kbdId] = 'Loading...'; + keymanExample.innerHTML = 'Loading...'; + + const link = `/prog/languageexample.php?keyboard=${kbdId}&language=${activeLanguage}`; + try { + const response = await fetch(link); + if(response.status == 200) { + const content = await response.text(); + + langExamples[activeLanguage + '_' + kbdId] = keymanExample.innerHTML = content; + } else { + throw new Error(`Unable to retrieve content, status was ${response.status}: ${response.statusText}`); + } + } catch(e) { + langExamples[activeLanguage + '_' + kbdId] = keymanExample.innerHTML = 'Error retrieving example: '+e.message; + throw e; + } +} + +// Apply classes to instructional keyboards +function applyClassToKb() { + const kbArea = document.querySelector('.keyboard-area') + if (!kbArea) return + + const apply = () => { + const child = kbArea.children + for (const c of child) { + if (!c.classList.contains('kmw-osk-frame')) { + c.classList.add('kmw-osk-frame') + c.classList.add('kmw-help-osk-frame') + } + } + } + apply() +} diff --git a/cdn/dev/js/operation/keyboardDetails.js b/cdn/dev/js/operation/keyboardDetails.js new file mode 100644 index 0000000..2eaf012 --- /dev/null +++ b/cdn/dev/js/operation/keyboardDetails.js @@ -0,0 +1,31 @@ +import { removeKbSelected } from "./selectedKb.js" +import { generateKbUI, triggerKbCount } from "../feature/kb-selection-menu.js" +import { selectedKbList } from "../state/appState.js" + +// Keyboard selection menu's tools: info, help, download, and remove +export function kbConfigMenu(action, id, helplink) { + if (action == "help") { + window.open(helplink, '_blank') + } + + if (action == "download") { + const downloadUrl = `https://keyman.com/keyboards/install/${id}` + window.open(downloadUrl, '_blank') + } + + if (action == "remove") { + removeKbSelected(id) + generateKbUI(selectedKbList) + triggerKbCount(selectedKbList) + searchDropdown.hide() + } + + if (action == "info") { + const kbDetails = document.querySelector(`#keyboard-${id}-details`) + + kbDetails.addEventListener('mouseleave', () => { + kbDetails.classList.add('hidden') + }) + kbDetails.classList.remove('hidden') + } +} \ No newline at end of file diff --git a/cdn/dev/js/operation/paginationLogic.js b/cdn/dev/js/operation/paginationLogic.js new file mode 100644 index 0000000..f460dc4 --- /dev/null +++ b/cdn/dev/js/operation/paginationLogic.js @@ -0,0 +1,17 @@ +import { searchState } from "../state/appState.js" + +// Pagination Previous Page +export function goPrevPage() { + if (searchState.currentPage > 1) { + searchState.currentPage-- + searchKeyboard(searchState.currentQuery, searchState.currentPage) + } +} + +// Pagination Next Page +export function goNextPage() { + if (searchState.currentPage < searchState.totalPage) { + searchState.currentPage++ + searchKeyboard(searchState.currentQuery, searchState.currentPage) + } +} diff --git a/cdn/dev/js/operation/platformSupport.js b/cdn/dev/js/operation/platformSupport.js new file mode 100644 index 0000000..a25f775 --- /dev/null +++ b/cdn/dev/js/operation/platformSupport.js @@ -0,0 +1,17 @@ +// Platform Supports (Icons, OS names) +export function platformSupport(data) { + const platformMap = { + android: "Android", + desktopWeb: "Web", + ios: "iPhone and iPad", + linux: "Linux", + macos: "macOS", + mobileWeb: "Mobile web", + windows: "Windows" + } + let platformSpan = Object.entries(data) + .filter(([_, supportLevel]) => supportLevel == 'full') + .map(([platform]) => `${platformMap[platform]}`).join('') + + return platformSpan +} \ No newline at end of file diff --git a/cdn/dev/js/operation/rememberState.js b/cdn/dev/js/operation/rememberState.js new file mode 100644 index 0000000..6367364 --- /dev/null +++ b/cdn/dev/js/operation/rememberState.js @@ -0,0 +1,36 @@ +import { storage } from "../state/storage.js" +import { getFontSize, setFontSize } from "../state/fontState.js" +import { getElementValue, setElementValue } from "../state/elementValue.js" +import { getElementsSize, setElementsSize } from "../state/elementSize.js" +import { getEnabledKb, setEnabledKb } from "../state/enableKb.js" +import { getSelectedKb, setSelectedKb } from "../state/selectedKbList.js" +import { generateKbUI } from "../feature/kb-selection-menu.js" + +const textAreaContainer = document.querySelector('.textarea-container') +const textArea = document.querySelector('#textArea') + +const STORAGE_KEY = "keymanWebStorage" +const EXP = 60 * 60 * 1000 // 1 hour + +export function buildAppState() { + const state = { + fontSize: getFontSize(textArea), + selectedKbList: getSelectedKb(), + enabledKb: getEnabledKb(), + textAreaSizes: getElementsSize(textAreaContainer), + writtenText: getElementValue(textArea), + } + storage.set(STORAGE_KEY, state, EXP) +} + +export function loadSettings() { + const state = storage.get(STORAGE_KEY) + + if(!state) return + setElementsSize(textAreaContainer, state.textAreaSizes) + setSelectedKb(state.selectedKbList) + generateKbUI(state.selectedKbList) + setEnabledKb(state.enabledKb) + setElementValue(textArea, state.writtenText) + setFontSize(textArea, state.fontSize) +} diff --git a/cdn/dev/js/operation/resizeKeyboard.js b/cdn/dev/js/operation/resizeKeyboard.js new file mode 100644 index 0000000..526d501 --- /dev/null +++ b/cdn/dev/js/operation/resizeKeyboard.js @@ -0,0 +1,61 @@ +import { keyboardResizing } from "../state/appState.js"; +import { fullScreenSize } from "./resizeTextArea.js"; + +const divider = document.getElementById('Divider') + +const resizer = divider.querySelector('#resizeGrip') +const prevElementOfResizer = divider.previousElementSibling +const nextElementOfResizer = divider.nextElementSibling + +// Resizer Activate +export function mouseDownGrabber(e) { + e.preventDefault(); + resizer.style.cursor = 'grabbing' + keyboardResizing.isResizing = true + + keyboardResizing.startY = e.clientY + keyboardResizing.startHeightTop = prevElementOfResizer.offsetHeight + keyboardResizing.startHeightBottom = nextElementOfResizer.offsetHeight + + document.addEventListener('mousemove', mouseMoveGrabber) + document.addEventListener('mouseup', mouseUpGrabber) +} + +// Resizer Deactivate +export function mouseUpGrabber() { + resizer.style.removeProperty('cursor') + keyboardResizing.isResizing = false + document.removeEventListener('mousemove', mouseMoveGrabber) +} + +// Resizer In-process +export function mouseMoveGrabber(e) { + if (!keyboardResizing.isResizing) return; + + let deltaY = e.clientY - keyboardResizing.startY // Get up or down direction + + let newTextareaHeight = keyboardResizing.startHeightTop + deltaY + let newKeyboardHeight = keyboardResizing.startHeightBottom - deltaY + + newTextareaHeight = Math.max(100, Math.min(newTextareaHeight, window.innerHeight * 0.8)) + newKeyboardHeight = Math.max(100, Math.min(newKeyboardHeight, window.innerHeight * 0.5)) + + applyTextareaHeight(newTextareaHeight) + + if (newTextareaHeight > 700) { + fullScreenSize() + } else { + nextElementOfResizer.style.display = 'flex' + } +} + +// Apply heights for two elements +export function applyHeights(taHeight, kbHeight) { + prevElementOfResizer.style.height = `${taHeight}px` + // nextElementOfResizer.style.height = `${kbHeight}px` +} + +// Apply heights +export function applyTextareaHeight(taHeight) { + prevElementOfResizer.style.height = `${taHeight}px` +} diff --git a/cdn/dev/js/operation/resizeTextArea.js b/cdn/dev/js/operation/resizeTextArea.js new file mode 100644 index 0000000..0c8fb0b --- /dev/null +++ b/cdn/dev/js/operation/resizeTextArea.js @@ -0,0 +1,20 @@ +import { textAreaState } from "../state/appState.js" + +const divider = document.querySelector('.divider-container') +const prevElementOfResizer = divider.previousElementSibling +const nextElementOfResizer = divider.nextElementSibling + +// Set default height for Textarea and Keyboard +export function defaultSize() { + prevElementOfResizer.style.height = `${textAreaState.defaultHeightTextArea}vh` + nextElementOfResizer.style.height = `${textAreaState.defaultHeightKb}vh` + textAreaState.isTextAreaFullHeight = false + nextElementOfResizer.style.display = 'flex' +} + +// Set full height (Fullscreen) for Textarea +export function fullScreenSize() { + prevElementOfResizer.style.height = `${textAreaState.fullHeightTextArea}vh` + textAreaState.isTextAreaFullHeight = true + nextElementOfResizer.style.display = 'none' +} diff --git a/cdn/dev/js/operation/searchAPI.js b/cdn/dev/js/operation/searchAPI.js new file mode 100644 index 0000000..919f704 --- /dev/null +++ b/cdn/dev/js/operation/searchAPI.js @@ -0,0 +1,11 @@ +// Calling search API with a custom parameter/query + +const api = 'https://api.keyman.com/search/2.0' + +export async function getKeyboardList(customQuery = "p:popular") { + let response = await fetch(`${api}?q=${customQuery}`) + if (!response.ok) { + throw new Error(`API request failed with status ${response.status}`) + } + return response.json() +} diff --git a/cdn/dev/js/operation/searchCardContent.js b/cdn/dev/js/operation/searchCardContent.js new file mode 100644 index 0000000..4b9a1fe --- /dev/null +++ b/cdn/dev/js/operation/searchCardContent.js @@ -0,0 +1,136 @@ +// Logic of search query highlights + +// Highlight word searched +export function getMarkedContext(query) { + let escapedTerm = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // Mark the query + return new RegExp(escapedTerm, 'i') +} + +// Find a match between Search Context and Language, Keyboard name, Description +export function highlightSearchContext(kb, marked) { + let matchFound = false + let matchField = "" + let matchValue = "" + + // Get and find language that matches the search + for (let lang in kb.languages) { + let langData = kb.languages[lang] + for (let key in langData) { + const value = langData[key] + if (typeof value == "string" && marked.test(value)) { + matchFound = true + matchValue = value.replace(marked, (m) => m ? `${m}` : m) + matchField = "language" + break + } + } + if (matchFound) break + } + + // Find a match for keyboard name if language is not a match + if (!matchFound && marked.test(kb.name)) { + matchFound = true + matchValue = kb.name.replace(marked, '$&') + matchField = "keyboard" + } + + // Find a match for keyboard description if name is not a match + if (!matchFound && marked.test(kb.description)) { + matchFound = true + matchField = "description" + } + + return {matchField, matchValue, matchFound} +} + +// Display Highlighted Search Context +export function showMarkedContext(kb, matchField, matchValue) { + const kbNameHeading = document.createElement('h4') + + // Display matched language + const langNameSpan = document.createElement('span') + langNameSpan.style.fontSize = "14px" + if (matchField == "language") { + langNameSpan.innerHTML = matchField == "language" ? ` (${matchValue} language)` : "" + } + + // Display matched keyboard + if (matchField == "keyboard") { + kbNameHeading.innerHTML = matchValue + } else { + kbNameHeading.textContent = kb.name + } + kbNameHeading.appendChild(langNameSpan) + + return kbNameHeading +} + +// Truncated Keyboard Description +export function truncateDesc(kb, matchField, marked) { + const kbDescHeading = document.createElement('h6') + kbDescHeading.classList.add("keyboard-description") + const wordLimits = 90 + + let temp = document.createElement('div') + temp.innerHTML = kb.description + + let fullDesc = kb.description + let plainText = temp.textContent + let shortText = "" + + let isTruncated = false + + let firstPara = firstParagraph(fullDesc) + + if (plainText.length >= wordLimits) { + shortText = plainText.slice(0, wordLimits) + "..." + kbDescHeading.innerHTML = shortText + isTruncated = true + } else { + kbDescHeading.innerHTML = firstPara + isTruncated = false + } + + // Toggle show more & show less + if (isTruncated) { + const toggleBtn = document.createElement('a') + toggleBtn.href = "#" + toggleBtn.style.marginLeft = "6px" + toggleBtn.textContent = "Show more" + + toggleBtn.addEventListener('click', e => { + e.preventDefault() + const isExpanded = toggleBtn.textContent == "Show more" + kbDescHeading.innerHTML = !isExpanded ? shortText.replace(marked, (m) => m ? `${m}` : m) : firstPara + if (matchField == 'description') { + kbDescHeading.innerHTML = isExpanded ? firstPara.replace(marked, '$&') : shortText + } + kbDescHeading.style.color = isExpanded ? 'black' : 'gray' + toggleBtn.textContent = isExpanded ? "Show less" : "Show more" + kbDescHeading.appendChild(toggleBtn) + }) + kbDescHeading.appendChild(toggleBtn) + } + + return kbDescHeading +} + +// Show first Paragraph for Keyboard Description (Copied from keyman.com) +function firstParagraph(text) { + // Yes, this is HTML parsing by regexp, but we will survive the apocalypse! + const firstPara = /^(((?:.|[\r\n])+?)(<\/p>|
    ))/m.exec(text); + if(!firstPara) { + // No paragraph markers (e.g. legacy .keyboard_info files); it is a plain + // text description, so we stop at first newline marker + const firstPlainTextPara = /^(.+?)(\r|\n|$)/.exec(text); + const html = $('

    ').text(firstPlainTextPara ? firstPlainTextPara[1] : text)[0].outerHTML; + return html; + } + if(firstPara[3] == '
    ') { + // We stop at first
    , so will miss the end of paragraph, so close the + // tag ourselves + return firstPara[2] + '

    '; + } + // Return the whole paragraph + return firstPara[1]; +} \ No newline at end of file diff --git a/cdn/dev/js/operation/searchLogic.js b/cdn/dev/js/operation/searchLogic.js new file mode 100644 index 0000000..6cff5cd --- /dev/null +++ b/cdn/dev/js/operation/searchLogic.js @@ -0,0 +1,87 @@ +// Logic for Search +import { searchState } from "../state/appState.js"; +import { getKeyboardList } from "./searchAPI.js"; +import { updatePaginationCtrl } from "../feature/pagination.js"; +import { updateSearchIcon } from "../feature/search.js" +import { displaySearch } from "../feature/search.js"; +import { loadPageInfo } from "../feature/pagination.js"; + +export async function handleSearch(value) { + let query = value + setQuery(query) + updateSearchIcon(query) + + // Check the query's character number + if (!searchState.searchQuery || searchState.searchQuery.length < 2) { + await defaultSearch() + return + } + + loadPageInfo(searchState.searchQuery) + + await searchKeyboard(searchState.searchQuery, searchState.currentPage) +} + +// Contain a value for searching +export function setQuery(value = '') { + searchState.searchQuery = value + searchState.currentPage = 1 +} + +// Run the search with queries and current page +export async function runSearch() { + const currentQuery = searchState.searchQuery + const currentPage = searchState.currentPage + + const data = await getKeyboardList(`${encodeURIComponent(currentQuery)}&p=${currentPage}`) + + if (data.context) { + searchState.totalPage = data.context.totalPages || 1; + searchState.currentPage = data.context.pageNumber || 1; + } else { + searchState.totalPage = Math.ceil(data.keyboards.length / searchState.itemPerPage); + } + + return data +} + +/* Search */ +const kbSearchCard = document.getElementById('kbSearchCardUI') +/* Display top downloads with search Instruction */ +export async function defaultSearch() { + kbSearchCard.innerHTML = `Please wait. It's Loading...` // Loading UI + + let data = await getKeyboardList('p:popular') // Show top 10 most downloaded keyboards + + if(searchState.searchQuery) return + + let mostDownloadkb = data.keyboards + + // Check data + if (!mostDownloadkb || !Array.isArray(mostDownloadkb)) { + throw new Error(`Invalid API response structure`) + } + + displaySearch(mostDownloadkb) // Keyboard search UI +} + +/* Get query and return search */ +export async function searchKeyboard(query = null, page) { + kbSearchCard.innerHTML = `
    Searching ${query}...
    ` // Loading UI + kbSearchCard.style.display = 'block' + + let data = await getKeyboardList(`${encodeURIComponent(query)}&p=${page}`) + + // Validate data.keyboards + if (!data.keyboards || !Array.isArray(data.keyboards)) { + throw new Error("Invalid API response structure") + } + + if (data.context) { + searchState.currentPage = data.context.pageNumber + searchState.totalPage = data.context.totalPages + } + + displaySearch(data.keyboards, data.context.totalRows, query) + updatePaginationCtrl() +} diff --git a/cdn/dev/js/operation/selectedKb.js b/cdn/dev/js/operation/selectedKb.js new file mode 100644 index 0000000..6e84de2 --- /dev/null +++ b/cdn/dev/js/operation/selectedKb.js @@ -0,0 +1,26 @@ +import { selectedKbList } from "../state/appState.js" +import { validateURL } from "./validURL.js" + +// Compare and remove keyboard +export function removeKbSelected(kbId) { + if(!kbId) return + let filtered = selectedKbList.filter(kb => kb.id !== kbId) + + // Reset and re-enter the Keyboard selection menu + selectedKbList.length = 0 + selectedKbList.push(...filtered) +} + +// Set the right keyboard help link according to the selected keyboard in the hamburger menu +export function setKbHelpDocHamburger(kbdId, kbdName) { + const kbHelpDocLink = document.querySelector('#kbHelpdocLink') + const kbHelpDocSpan = document.querySelector('#kbHelpDocSpan') + + kbHelpDocSpan.innerHTML = `${kbdName}` + const id = kbdId.split("Keyboard_") + kbHelpDocLink.addEventListener('click', () => { + const checkedURL = validateURL(`https://help.keyman.com/keyboard/`) + const newURL = checkedURL + id + kbHelpDocLink.href = newURL + }) +} \ No newline at end of file diff --git a/cdn/dev/js/operation/toggleInstruction.js b/cdn/dev/js/operation/toggleInstruction.js new file mode 100644 index 0000000..cbadcfa --- /dev/null +++ b/cdn/dev/js/operation/toggleInstruction.js @@ -0,0 +1,27 @@ +$(document).ready(function() { + let searchInstructionIsON = true + $('#toggleSearchInstructionBtn').addClass('btn-primary').text('Visible') + function updateInstructionUI(state) { + searchInstructionIsON = state + + if (searchInstructionIsON) { + $('.search-instruction, #hrForKeyboard').fadeIn('200') + $('#toggleSearchInstructionBtn').removeClass('btn-secondary').addClass('btn-primary').text('Visible') + $('#searchInput').click() + $('#searchDropdownMenu').show() + } else { + $('.search-instruction, #hrForKeyboard').fadeOut('200') + $('#toggleSearchInstructionBtn').removeClass('btn-primary').addClass('btn-secondary').text('Hidden') + $('#searchDropdownMenu').show() + $('#searchInput').click() + } + } + + $('#closeInstruction').click( () => { + if (searchInstructionIsON) updateInstructionUI(false) + }) + + $('#toggleSearchInstructionBtn').on('click', () => { + updateInstructionUI(!searchInstructionIsON) + }) +}) \ No newline at end of file diff --git a/cdn/dev/js/operation/validURL.js b/cdn/dev/js/operation/validURL.js new file mode 100644 index 0000000..e33ed14 --- /dev/null +++ b/cdn/dev/js/operation/validURL.js @@ -0,0 +1,13 @@ +// Ensure a valid URL +export function validateURL(string) { + try { + const newUrl = new URL(string) + if (newUrl.protocol === 'https:') { + return newUrl + } else { + return false + } + } catch (error) { + console.error(error) + } +} \ No newline at end of file diff --git a/cdn/dev/js/operation/waitForElement.js b/cdn/dev/js/operation/waitForElement.js new file mode 100644 index 0000000..45b5db8 --- /dev/null +++ b/cdn/dev/js/operation/waitForElement.js @@ -0,0 +1,12 @@ +// Wait for a later-loaded element +export function waitForElement(selector) { + return new Promise((resolve) => { + const interval = setInterval(() => { + const element = document.querySelector(selector) + if (element) { + clearInterval(interval) + resolve(element) + } + }, 100) + }) +} \ No newline at end of file diff --git a/cdn/dev/js/state/appState.js b/cdn/dev/js/state/appState.js new file mode 100644 index 0000000..c6804aa --- /dev/null +++ b/cdn/dev/js/state/appState.js @@ -0,0 +1,65 @@ +/* Text area values + - To resize +*/ +export const textAreaState = { + isTextAreaFullHeight: false, + fullHeightTextArea: 95, + defaultHeightTextArea: 35, + defaultHeightKb: 47 +} + +/* + Keyboard values + - To resize + - To change height +*/ +export const keyboardResizing = { + isResizing: false, + startY: 0, + startHeightTop: 0, + startHeightBottom: 0 +} + +/* + Selected Keyboard Data + - To Enable keyboard for typing + - Change the language example + - Update the UI after the keyboard is generated +*/ +export const kbData = { + kbdId: "basic_kbdus", + langCode: "en", + kbdName: "US Basic" +} + +/* + Main array for Keyboards Selection Menu: + - The interaction between search, kb selection menu...etc + - The enabling of a keyboard for typing + - Data = [ + "id": kb.id, + "name": kb.name, + "version": kb.version, + "helpLink": kb.helpLink, + "platformSupport": kb.platformSupport, + "totalDownloads": kb.match.totalDownloads, + "sourcePath": kb.sourcePath, + "supportedLanguage": kb.languages, + "lastUpdated": kb.lastModifiedDate + ] +*/ +export const selectedKbList = [] + +/* Pagination + - Current Page + - Total Page + - Search Queries + - Timer to pause searching/loading API +*/ +export const searchState = { + currentPage: 1, + totalPage: 1, + itemPerPage: 10, + searchQuery: "", + debounceTimer: null +} \ No newline at end of file diff --git a/cdn/dev/js/state/elementSize.js b/cdn/dev/js/state/elementSize.js new file mode 100644 index 0000000..83ea44a --- /dev/null +++ b/cdn/dev/js/state/elementSize.js @@ -0,0 +1,12 @@ +export function getElementsSize(element) { + const rect = element.getBoundingClientRect() + return { + height: rect.height, + positionX: rect.x, + positionY: rect.y + } +} + +export function setElementsSize(element, sizes) { + element.style.height = sizes.height + "px" +} \ No newline at end of file diff --git a/cdn/dev/js/state/elementValue.js b/cdn/dev/js/state/elementValue.js new file mode 100644 index 0000000..62dbbc5 --- /dev/null +++ b/cdn/dev/js/state/elementValue.js @@ -0,0 +1,7 @@ +export function getElementValue(element) { + return element.value +} + +export function setElementValue(element, value) { + element.value = value +} \ No newline at end of file diff --git a/cdn/dev/js/state/enableKb.js b/cdn/dev/js/state/enableKb.js new file mode 100644 index 0000000..aeb271e --- /dev/null +++ b/cdn/dev/js/state/enableKb.js @@ -0,0 +1,29 @@ +import { setKeyboard } from "../operation/handleKeyboardData.js"; +import { setKeyboardToType } from "../operation/keyboard.js"; +import { selectedKbList } from "./appState.js"; + +export function getEnabledKb() { + let match = location.hash.match(/^#(.+),(Keyboard_.+)$/i) + if(!match) return null; + + const [, langCode, rawKbFromHash] = match + + let kbdId = rawKbFromHash.replace('Keyboard_', '') + + let kbdName = selectedKbList.find(kb => kb.id == kbdId).name + + return { + langCode, + kbdId, + kbdName + } +} + +export function setEnabledKb(enabledKb) { + if(!enabledKb) return + + const {kbdId, langCode, kbdName} = enabledKb + + setKeyboard(kbdId, langCode, kbdName) + setKeyboardToType() +} \ No newline at end of file diff --git a/cdn/dev/js/state/fontState.js b/cdn/dev/js/state/fontState.js new file mode 100644 index 0000000..5a05673 --- /dev/null +++ b/cdn/dev/js/state/fontState.js @@ -0,0 +1,10 @@ +export function getFontSize(element) { + let fontSize = parseInt(window.getComputedStyle(element).fontSize) || "16" + return fontSize +} + +export function setFontSize(element, value) { + const fontSizeRange = document.querySelector('#fontSizeRange') + element.style.fontSize = value + 'px' + fontSizeRange.value = value +} \ No newline at end of file diff --git a/cdn/dev/js/state/selectedKbList.js b/cdn/dev/js/state/selectedKbList.js new file mode 100644 index 0000000..52c8200 --- /dev/null +++ b/cdn/dev/js/state/selectedKbList.js @@ -0,0 +1,10 @@ +import { selectedKbList } from "./appState.js" + +export function setSelectedKb(kbList) { + selectedKbList.length = 0 + selectedKbList.push(...kbList) +} + +export function getSelectedKb() { + return selectedKbList +} \ No newline at end of file diff --git a/cdn/dev/js/state/storage.js b/cdn/dev/js/state/storage.js new file mode 100644 index 0000000..b6d21de --- /dev/null +++ b/cdn/dev/js/state/storage.js @@ -0,0 +1,35 @@ +const STORAGE_KEY = "keymanWebStorage" + +export const storage = { + set(key, value, time = null) { + const item = { + value, + expiry: time ? Date.now() + time : null + }; + window.localStorage.setItem(key, JSON.stringify(item)) + }, + + get(key) { + const raw = window.localStorage.getItem(key) + + if (!raw) return null; + + try { + const item = JSON.parse(raw) + + if (item.expiry && Date.now() > item.expiry) { + window.localStorage.removeItem(key) + return null + } + + return item.value + } + catch { + return null + } + }, + + remove(key) { + window.localStorage.removeItem(key) + } +} \ No newline at end of file diff --git a/cdn/fonts/social-logos.ttf b/cdn/fonts/social-logos.ttf index e8013681b9896473dbe12c201a9bd124222a9426..0ea4af42f26950ded69fcc3621084e43666fddf0 100644 GIT binary patch literal 12968 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 C15{@K literal 17356 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 diff --git a/inc/head.php b/inc/head.php index 1229730..edcf3c3 100644 --- a/inc/head.php +++ b/inc/head.php @@ -60,8 +60,11 @@ +" /> " /> " /> +" /> +" /> @@ -155,31 +158,42 @@ function loadKeyboardFromHash() { - + + diff --git a/index.php b/index.php index a348040..7a02ef5 100644 --- a/index.php +++ b/index.php @@ -16,21 +16,18 @@ × - -
    -
    -
    Keyboard Selection menu
    -
    +
    +
    +
    + Keyboard Selection menu +
    +

    Open Search to get your keyboard

    - +
    @@ -70,85 +71,112 @@
    -
    - A - - A -
    -
    - -
    + +
    +
    + A + + A +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    - + headerBar
    @@ -156,7 +184,6 @@
    -
    @@ -175,8 +202,7 @@
    - - - - +