Version Description
- 2019-10-31
- Bugfix: Admin detected as an agent - doesn't show offline messages form
- Bugfix: Remove picture from chat box doesn't work properly
- Bugfix: Edge JS compatibility issue in dashboard has been fixed
- Bugfix: The page will no longer refresh upon ending a chat with an agent.
- New feature: Agent online/offline switch in Wordpress admin bar
- New feature: Adjustable chatbox height 30% - 80% of page size
- Improvement: Cleaned up async_storage functions
- Improvement: Better alignment for chat popup with no picture
- Improvement: Reworked agent online/offline functions
- Improvement: Default business hours are now 9:00 - 18:00 instead of 00:00 - 00:00
- Improvement: The 'Use Logged In User Details' feature has been moved to the 'Chat Box' settings page
Download this release
Release Info
Developer | WP-LiveChat |
Plugin | WP Live Chat Support |
Version | 8.1.3 |
Comparing to | |
See all releases |
Code changes from version 8.1.2 to 8.1.3
- ajax/agent.php +1 -1
- changelog.txt +13 -0
- config.php +1 -1
- css/bootstrap.css.map +1 -0
- css/switchery.min.css +1 -1
- css/themes/classic.css +0 -2
- css/themes/modern.css +3 -9
- functions.php +553 -665
- includes/dashboard_page.php +1 -1
- includes/settings_page.php +50 -43
- includes/wplc_custom_fields.php +36 -44
- includes/wplc_departments.php +29 -30
- includes/wplc_transfer_chats.php +597 -599
- js/media.js +7 -8
- js/wplc_agent_node.js +1 -4
- js/wplc_choose.js +123 -68
- js/wplc_gutenberg.js +1 -1
- js/wplc_ma_transient.js +1 -0
- js/wplc_server.js +0 -46
- js/wplc_u_admin_events.js +1 -1
- js/wplc_u_pro.js +1 -1
- modules/api/agent/wplc-api-functions.php +865 -834
- modules/api/agent/wplc-api.php +2 -2
- modules/gdpr.php +0 -41
- modules/node_server.php +616 -771
- modules/webhooks_manager.php +325 -324
- readme.txt +18 -4
- wp-live-chat-support.php +203 -230
ajax/agent.php
CHANGED
@@ -14,7 +14,7 @@
|
|
14 |
|
15 |
function wplc_init_agent_ajax_callback() {
|
16 |
|
17 |
-
if(
|
18 |
$array['error'] = 1;
|
19 |
echo json_encode($array);
|
20 |
die();
|
14 |
|
15 |
function wplc_init_agent_ajax_callback() {
|
16 |
|
17 |
+
if (!wplc_user_is_agent()) {
|
18 |
$array['error'] = 1;
|
19 |
echo json_encode($array);
|
20 |
die();
|
changelog.txt
CHANGED
@@ -1,3 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
= 8.1.2 - 2019-10-24
|
2 |
* New feature: improved auto pop-up feature, now 3 options to choose from
|
3 |
* New feature: Pop-up only when agents are online
|
1 |
+
= 8.1.3 - 2019-10-31
|
2 |
+
* Bugfix: Admin detected as an agent - doesn't show offline messages form
|
3 |
+
* Bugfix: Remove picture from chat box doesn't work properly
|
4 |
+
* Bugfix: Edge JS compatibility issue in dashboard has been fixed
|
5 |
+
* Bugfix: The page will no longer refresh upon ending a chat with an agent.
|
6 |
+
* New feature: Agent online/offline switch in Wordpress admin bar
|
7 |
+
* New feature: Adjustable chatbox height 30% - 80% of page size
|
8 |
+
* Improvement: Cleaned up async_storage functions
|
9 |
+
* Improvement: Better alignment for chat popup with no picture
|
10 |
+
* Improvement: Reworked agent online/offline functions
|
11 |
+
* Improvement: Default business hours are now 9:00 - 18:00 instead of 00:00 - 00:00
|
12 |
+
* Improvement: The 'Use Logged In User Details' feature has been moved to the 'Chat Box' settings page.
|
13 |
+
|
14 |
= 8.1.2 - 2019-10-24
|
15 |
* New feature: improved auto pop-up feature, now 3 options to choose from
|
16 |
* New feature: Pop-up only when agents are online
|
config.php
CHANGED
@@ -7,7 +7,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
7 |
exit;
|
8 |
}
|
9 |
|
10 |
-
define('WPLC_PLUGIN_VERSION', "8.1.
|
11 |
define('WPLC_PLUGIN_DIR', dirname(__FILE__));
|
12 |
define('WPLC_PLUGIN_URL', plugins_url( '/', __FILE__ ) );
|
13 |
define('WPLC_PLUGIN', plugin_basename( __FILE__ ) );
|
7 |
exit;
|
8 |
}
|
9 |
|
10 |
+
define('WPLC_PLUGIN_VERSION', "8.1.3");
|
11 |
define('WPLC_PLUGIN_DIR', dirname(__FILE__));
|
12 |
define('WPLC_PLUGIN_URL', plugins_url( '/', __FILE__ ) );
|
13 |
define('WPLC_PLUGIN', plugin_basename( __FILE__ ) );
|
css/bootstrap.css.map
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
{"version":3,"sources":["../../scss/bootstrap.scss","bootstrap.css","../../scss/_root.scss","../../scss/_reboot.scss","../../scss/_variables.scss","../../scss/vendor/_rfs.scss","../../scss/mixins/_hover.scss","../../scss/_type.scss","../../scss/mixins/_lists.scss","../../scss/_images.scss","../../scss/mixins/_image.scss","../../scss/mixins/_border-radius.scss","../../scss/_code.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_breakpoints.scss","../../scss/mixins/_grid-framework.scss","../../scss/_tables.scss","../../scss/mixins/_table-row.scss","../../scss/_functions.scss","../../scss/_forms.scss","../../scss/mixins/_transition.scss","../../scss/mixins/_forms.scss","../../scss/mixins/_gradients.scss","../../scss/_buttons.scss","../../scss/mixins/_buttons.scss","../../scss/_transitions.scss","../../scss/_dropdown.scss","../../scss/mixins/_caret.scss","../../scss/mixins/_nav-divider.scss","../../scss/_button-group.scss","../../scss/_input-group.scss","../../scss/_custom-forms.scss","../../scss/_nav.scss","../../scss/_navbar.scss","../../scss/_card.scss","../../scss/_breadcrumb.scss","../../scss/_pagination.scss","../../scss/mixins/_pagination.scss","../../scss/_badge.scss","../../scss/mixins/_badge.scss","../../scss/_jumbotron.scss","../../scss/_alert.scss","../../scss/mixins/_alert.scss","../../scss/_progress.scss","../../scss/_media.scss","../../scss/_list-group.scss","../../scss/mixins/_list-group.scss","../../scss/_close.scss","../../scss/_toasts.scss","../../scss/_modal.scss","../../scss/_tooltip.scss","../../scss/mixins/_reset-text.scss","../../scss/_popover.scss","../../scss/_carousel.scss","../../scss/mixins/_clearfix.scss","../../scss/_spinners.scss","../../scss/utilities/_align.scss","../../scss/mixins/_background-variant.scss","../../scss/utilities/_background.scss","../../scss/utilities/_borders.scss","../../scss/utilities/_display.scss","../../scss/utilities/_embed.scss","../../scss/utilities/_flex.scss","../../scss/utilities/_float.scss","../../scss/utilities/_overflow.scss","../../scss/utilities/_position.scss","../../scss/utilities/_screenreaders.scss","../../scss/mixins/_screen-reader.scss","../../scss/utilities/_shadows.scss","../../scss/utilities/_sizing.scss","../../scss/utilities/_stretched-link.scss","../../scss/utilities/_spacing.scss","../../scss/utilities/_text.scss","../../scss/mixins/_text-truncate.scss","../../scss/mixins/_text-emphasis.scss","../../scss/mixins/_text-hide.scss","../../scss/utilities/_visibility.scss","../../scss/_print.scss"],"names":[],"mappings":"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AF7G1B;;AAEA;EEmHE,wBAAwB;AFjH1B;;AEyHA;EACE,aAAa;EACb,0BAA0B;AFtH5B;;AE6HA;EACE,qBAAqB;AF1HvB;;AE6HA;EACE,kBAAkB;EAClB,eAAe;AF1HjB;;AE6HA;EACE,aAAa;AF1Hf;;AAEA;EE8HE,wBAAwB;AF5H1B;;AM/VA;;EAEE,qBHiSuC;EG/RvC,gBHiS+B;EGhS/B,gBHiS+B;AHgEjC;;AM7VA;EFgHM,iBAtCY;AJuRlB;;AMhWA;EF+GM,eAtCY;AJ2RlB;;AMnWA;EF8GM,kBAtCY;AJ+RlB;;AMtWA;EF6GM,iBAtCY;AJmSlB;;AMzWA;EF4GM,kBAtCY;AJuSlB;;AM5WA;EF2GM,eAtCY;AJ2SlB;;AM9WA;EFyGM,kBAtCY;EEjEhB,gBHmS+B;AH8EjC;;AM7WA;EFmGM,eAtCY;EE3DhB,gBHsR+B;EGrR/B,gBH6Q+B;AHmGjC;;AM9WA;EF8FM,iBAtCY;EEtDhB,gBHkR+B;EGjR/B,gBHwQ+B;AHyGjC;;AM/WA;EFyFM,iBAtCY;EEjDhB,gBH8Q+B;EG7Q/B,gBHmQ+B;AH+GjC;;AMhXA;EFoFM,iBAtCY;EE5ChB,gBH0Q+B;EGzQ/B,gBH8P+B;AHqHjC;;AE1VA;EIhBE,gBH0EW;EGzEX,mBHyEW;EGxEX,SAAS;EACT,wCHzCa;AHuZf;;AMtWA;;EFMI,cAAW;EEHb,gBHsN+B;AHmJjC;;AMtWA;;EAEE,cH8PgC;EG7PhC,yBHsQmC;AHmGrC;;AMjWA;EC/EE,eAAe;EACf,gBAAgB;APoblB;;AMjWA;ECpFE,eAAe;EACf,gBAAgB;APyblB;;AMnWA;EACE,qBAAqB;ANsWvB;;AMvWA;EAII,oBHgP+B;AHuHnC;;AM7VA;EFjCI,cAAW;EEmCb,yBAAyB;ANgW3B;;AM5VA;EACE,mBHiBW;ECFP,kBAtCY;AJuXlB;;AM5VA;EACE,cAAc;EF7CZ,cAAW;EE+Cb,cH1GgB;AHyclB;;AMlWA;EAMI,qBAAqB;ANgWzB;;AQndA;ECIE,eAAe;EAGf,YAAY;ATidd;;AQldA;EACE,gBL++BwC;EK9+BxC,sBLRa;EKSb,yBLNgB;EOLd,sBPqOgC;EM/NlC,eAAe;EAGf,YAA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AAwB,iBADZ;IACY,QADZ;EfitClB;EehtCM;IAAwB,iBADZ;IACY,QADZ;EfotClB;EentCM;IAAwB,iBADZ;IACY,QADZ;EfutClB;EettCM;IAAwB,iBADZ;IACY,QADZ;Ef0tClB;EeztCM;IAAwB,iBADZ;IACY,QADZ;Ef6tClB;Ee5tCM;IAAwB,iBADZ;IACY,QADZ;EfguClB;Ee/tCM;IAAwB,iBADZ;IACY,QADZ;EfmuClB;EeluCM;IAAwB,iBADZ;IACY,QADZ;EfsuClB;EeruCM;IAAwB,iBADZ;IACY,QADZ;EfyuClB;EexuCM;IAAwB,iBADZ;IACY,QADZ;Ef4uClB;Ee3uCM;IAAwB,kBADZ;IACY,SADZ;Ef+uClB;Ee9uCM;IAAwB,kBADZ;IACY,SADZ;EfkvClB;EejvCM;IAAwB,kBADZ;IACY,SADZ;EfqvClB;Ee9uCQ;IFTR,cAA4B;Eb0vC5B;EejvCQ;IFTR,sBAA8C;Eb6vC9C;EepvCQ;IFTR,uBAA8C;EbgwC9C;EevvCQ;IFTR,gBAA8C;EbmwC9C;Ee1vCQ;IFTR,uBAA8C;EbswC9C;Ee7vCQ;IFTR,uBAA8C;EbywC9C;EehwCQ;IFTR,gBAA8C;Eb4wC9C;EenwCQ;IFTR,uBAA8C;Eb+wC9C;EetwCQ;IFTR,uBAA8C;EbkxC9C;EezwCQ;IFTR,gBAA8C;EbqxC9C;Ee5wCQ;IFTR,uBAA8C;EbwxC9C;Ee/wCQ;IFTR,uBAA8C;Eb2xC9C;AACF;;AgBz0CA;EACE,WAAW;EACX,mBb2HW;Ea1HX,cbSgB;AHm0ClB;;AgB/0CA;;EAQI,gBb8UgC;Ea7UhC,mBAAmB;EACnB,6BbJc;AHg1ClB;;AgBt1CA;EAcI,sBAAsB;EACtB,gCbTc;AHq1ClB;;AgB31CA;EAmBI,6Bbbc;AHy1ClB;;AgBn0CA;;EAGI,ebwT+B;AH6gCnC;;AgB5zCA;EACE,yBbnCgB;AHk2ClB;;AgBh0CA;;EAKI,yBbvCc;AHu2ClB;;AgBr0CA;;EAWM,wBAA4C;AhB+zClD;;AgB1zCA;;;;EAKI,SAAS;AhB4zCb;;AgBpzCA;EAEI,qCb1DW;AHg3Cf;;AKr3CE;EW2EI,cbvEY;EawEZ,sCbvES;AHq3Cf;;AiBj4CE;;;EAII,yBC2E4D;AlBwzClE;;AiBv4CE;;;;EAYM,qBCmE0D;AlB+zClE;;AKv4CE;EYiBM,yBAJsC;AjB83C9C;;AiB/3CE;;EASQ,yBARoC;AjBm4C9C;;AiBv5CE;;;EAII,yBC2E4D;AlB80ClE;;AiB75CE;;;;EAYM,qBCmE0D;AlBq1ClE;;AK75CE;EYiBM,yBAJsC;AjBo5C9C;;AiBr5CE;;EASQ,yBARoC;AjBy5C9C;;AiB76CE;;;EAII,yBC2E4D;AlBo2ClE;;AiBn7CE;;;;EAYM,qBCmE0D;AlB22ClE;;AKn7CE;EYiBM,yBAJsC;AjB06C9C;;AiB36CE;;EASQ,yBARoC;AjB+6C9C;;AiBn8CE;;;EAII,yBC2E4D;AlB03ClE;;AiBz8CE;;;;EAYM,qBCmE0D;AlBi4ClE;;AKz8CE;EYiBM,yBAJsC;AjBg8C9C;;AiBj8CE;;EASQ,yBARoC;AjBq8C9C;;AiBz9CE;;;EAII,yBC2E4D;AlBg5ClE;;AiB/9CE;;;;EAYM,qBCmE0D;AlBu5ClE;;AK/9CE;EYiBM,yBAJsC;AjBs9C9C;;AiBv9CE;;EASQ,yBARoC;AjB29C9C;;AiB/+CE;;;EAII,yBC2E4D;AlBs6ClE;;AiBr/CE;;;;EAYM,qBCmE0D;AlB66ClE;;AKr/CE;EYiBM,yBAJsC;AjB4+C9C;;AiB7+CE;;EASQ,yBARoC;AjBi/C9C;;AiBrgDE;;;EAII,yBC2E4D;AlB47ClE;;AiB3gDE;;;;EAYM,qBCmE0D;AlBm8ClE;;AK3gDE;EYiBM,yBAJsC;AjBkgD9C;;AiBngDE;;EASQ,yBARoC;AjBugD9C;;AiB3hDE;;;EAII,yBC2E4D;AlBk9ClE;;AiBjiDE;;;;EAYM,qBCmE0D;AlBy9ClE;;AKjiDE;EYiBM,yBAJsC;AjBwhD9C;;AiBzhDE;;EASQ,yBARoC;AjB6hD9C;;AiBjjDE;;;EAII,sCdQS;AH2iDf;;AKhjDE;EYiBM,sCAJsC;AjBuiD9C;;AiBxiDE;;EASQ,sCARoC;AjB4iD9C;;AgBt9CA;EAGM,Wb3GS;Ea4GT,yBbpGY;EaqGZ,qBb2PqD;AH4tC3D;;AgB59CA;EAWM,cb5GY;Ea6GZ,yBblHY;EamHZ,qBblHY;AHukDlB;;AgBh9CA;EACE,Wb3Ha;Ea4Hb,yBbpHgB;AHukDlB;;AgBr9CA;;;EAOI,qBbuOuD;AH6uC3D;;AgB39CA;EAWI,SAAS;AhBo9Cb;;AgB/9CA;EAgBM,2Cb1IS;AH6lDf;;AKxlDE;EW4IM,WbjJO;EakJP,4CblJO;AHkmDf;;AchiDI;EEiGA;IAEI,cAAc;IACd,WAAW;IACX,gBAAgB;IAChB,iCAAiC;EhBk8CvC;EgBv8CG;IASK,SAAS;EhBi8CjB;AACF;;Ac5iDI;EEiGA;IAEI,cAAc;IACd,WAAW;IACX,gBAAgB;IAChB,iCAAiC;EhB88CvC;EgBn9CG;IASK,SAAS;EhB68CjB;AACF;;AcxjDI;EEiGA;IAEI,cAAc;IACd,WAAW;IACX,gBAAgB;IAChB,iCAAiC;EhB09CvC;EgB/9CG;IASK,SAAS;EhBy9CjB;AACF;;AcpkDI;EEiGA;IAEI,cAAc;IACd,WAAW;IACX,gBAAgB;IAChB,iCAAiC;EhBs+CvC;EgB3+CG;IASK,SAAS;EhBq+CjB;AACF;;AgBp/CA;EAOQ,cAAc;EACd,WAAW;EACX,gBAAgB;EAChB,iCAAiC;AhBi/CzC;;AgB3/CA;EAcU,SAAS;AhBi/CnB;;AmB9pDA;EACE,cAAc;EACd,WAAW;EACX,mChBqe2H;EgBpe3H,yBhBqXkC;EChQ9B,eAtCY;Ee5EhB,gBhB8Q+B;EgB7Q/B,gBhBkR+B;EgBjR/B,chBDgB;EgBEhB,sBhBTa;EgBUb,4BAA4B;EAC5B,yBhBPgB;EONd,sBPqOgC;EiBpO9B,wEjB4e4F;AHksClG;;AoBzqDI;EDLJ;ICMM,gBAAgB;EpB6qDpB;AACF;;AmBprDA;EAsBI,6BAA6B;EAC7B,SAAS;AnBkqDb;;AqBlrDE;EACE,clBAc;EkBCd,sBlBRW;EkBSX,qBlBgdsE;EkB/ctE,UAAU;EAKR,gDlBcW;AHmqDjB;;AmBjsDA;EA+BI,chBxBc;EgB0Bd,UAAU;AnBqqDd;;AmBtsDA;EA+BI,chBxBc;EgB0Bd,UAAU;AnBqqDd;;AmBtsDA;EA+BI,chBxBc;EgB0Bd,UAAU;AnBqqDd;;AmBtsDA;EA+BI,chBxBc;EgB0Bd,UAAU;AnBqqDd;;AmBtsDA;EA+BI,chBxBc;EgB0Bd,UAAU;AnBqqDd;;AmBtsDA;EA2CI,yBhBxCc;EgB0Cd,UAAU;AnB8pDd;;AmB1pDA;EAOI,chBhDc;EgBiDd,sBhBxDW;AH+sDf;;AmBlpDA;;EAEE,cAAc;EACd,WAAW;AnBqpDb;;AmB3oDA;EACE,iCAA+D;EAC/D,oCAAkE;EAClE,gBAAgB;EfZd,kBAAW;Eecb,gBhB0M+B;AHo8CjC;;AmB3oDA;EACE,+BAAkE;EAClE,kCAAqE;EfoCjE,kBAtCY;EeIhB,gBhBuI+B;AHugDjC;;AmB3oDA;EACE,gCAAkE;EAClE,mCAAqE;Ef6BjE,mBAtCY;EeWhB,gBhBiI+B;AH6gDjC;;AmBroDA;EACE,cAAc;EACd,WAAW;EACX,qBhB8QmC;EgB7QnC,wBhB6QmC;EgB5QnC,gBAAgB;EAChB,gBhB6K+B;EgB5K/B,chBpGgB;EgBqGhB,6BAA6B;EAC7B,yBAAyB;EACzB,mBAAmC;AnBwoDrC;;AmBlpDA;EAcI,gBAAgB;EAChB,eAAe;AnBwoDnB;;AmB5nDA;EACE,kChBsWqI;EgBrWrI,uBhB+PiC;EC1Q7B,mBAtCY;EemDhB,gBhByF+B;EOhO7B,qBPuO+B;AHgiDnC;;AmB5nDA;EACE,gChB+VqI;EgB9VrI,oBhB4PgC;EC/Q5B,kBAtCY;Ee2DhB,gBhBgF+B;EO/N7B,qBPsO+B;AHyiDnC;;AmB3nDA;EAGI,YAAY;AnB4nDhB;;AmBxnDA;EACE,YAAY;AnB2nDd;;AmBnnDA;EACE,mBhBoV0C;AHkyC5C;;AmBnnDA;EACE,cAAc;EACd,mBhBqU4C;AHizC9C;;AmB9mDA;EACE,oBAAa;EAAb,aAAa;EACb,mBAAe;EAAf,eAAe;EACf,kBAA0C;EAC1C,iBAAyC;AnBinD3C;;AmBrnDA;;EAQI,kBAA0C;EAC1C,iBAAyC;AnBknD7C;;AmBzmDA;EACE,kBAAkB;EAClB,cAAc;EACd,qBhB0S6C;AHk0C/C;;AmBzmDA;EACE,kBAAkB;EAClB,kBhBsS2C;EgBrS3C,qBhBoS6C;AHw0C/C;;AmB/mDA;EAMI,chBxMc;AHqzDlB;;AmBzmDA;EACE,gBAAgB;AnB4mDlB;;AmBzmDA;EACE,2BAAoB;EAApB,oBAAoB;EACpB,sBAAmB;EAAnB,mBAAmB;EACnB,eAAe;EACf,qBhByR4C;AHm1C9C;;AmBhnDA;EAQI,gBAAgB;EAChB,aAAa;EACb,uBhBoR4C;EgBnR5C,cAAc;AnB4mDlB;;AqBvzDE;EACE,aAAa;EACb,WAAW;EACX,mBlBod0C;EC5a1C,cAAW;EiBtCX,clBSa;AHizDjB;;AqBvzDE;EACE,kBAAkB;EAClB,SAAS;EACT,UAAU;EACV,aAAa;EACb,eAAe;EACf,uBlBsyBqC;EkBryBrC,iBAAiB;EjBmFf,mBAtCY;EiB3Cd,gBlBkP6B;EkBjP7B,WlBxCW;EkByCX,wClBLa;EOtCb,sBPqOgC;AHioDpC;;AqBtzDI;EAEE,qBlBZW;EkBeT,oClBgb2F;EkB/a3F,4PHfmI;EGgBnI,4BAA4B;EAC5B,2DlB+a6F;EkB9a7F,gElB6awF;AHy4ChG;;AqB/zDI;EAaI,qBlBvBS;EkBwBT,gDlBxBS;AH80DjB;;AqBp0DI;;;EAmBI,cAAc;ArBuzDtB;;AqBhzDI;EAGI,oClBwZ2F;EkBvZ3F,kFlByZ6F;AHw5CrG;;AqB3yDI;EAEE,qBlBhDW;EkBmDT,sDlBqe0J;EkBpe1J,6gBAAkJ;ArB2yD1J;;AqBjzDI;EAUI,qBlBxDS;EkByDT,gDlBzDS;AHo2DjB;;AqBtzDI;;;EAgBI,cAAc;ArB4yDtB;;AqBryDI;;;EAII,cAAc;ArBuyDtB;;AqBjyDI;EAGI,clBlFS;AHo3DjB;;AqBryDI;;;EAQI,cAAc;ArBmyDtB;;AqB7xDI;EAGI,clBhGS;AH83DjB;;AqBjyDI;EAMM,qBlBnGO;AHk4DjB;;AqBryDI;;;EAYI,cAAc;ArB+xDtB;;AqB3yDI;EAiBM,qBAAkC;ECnJxC,yBDoJ+C;ArB8xDnD;;AqBhzDI;EAwBM,gDlBrHO;AHi5DjB;;AqBpzDI;EA4BM,qBlBzHO;AHq5DjB;;AqBpxDI;EAGI,qBlBpIS;AHy5DjB;;AqBxxDI;;;EAQI,cAAc;ArBsxDtB;;AqB9xDI;EAaM,qBlB9IO;EkB+IP,gDlB/IO;AHo6DjB;;AqBl7DE;EACE,aAAa;EACb,WAAW;EACX,mBlBod0C;EC5a1C,cAAW;EiBtCX,clBMa;AH+6DjB;;AqBl7DE;EACE,kBAAkB;EAClB,SAAS;EACT,UAAU;EACV,aAAa;EACb,eAAe;EACf,uBlBsyBqC;EkBryBrC,iBAAiB;EjBmFf,mBAtCY;EiB3Cd,gBlBkP6B;EkBjP7B,WlBxCW;EkByCX,wClBRa;EOnCb,sBPqOgC;AH4vDpC;;AqBj7DI;EAEE,qBlBfW;EkBkBT,oClBgb2F;EkB/a3F,sSHfmI;EGgBnI,4BAA4B;EAC5B,2DlB+a6F;EkB9a7F,gElB6awF;AHogDhG;;AqB17DI;EAaI,qBlB1BS;EkB2BT,gDlB3BS;AH48DjB;;AqB/7DI;;;EAmBI,cAAc;ArBk7DtB;;AqB36DI;EAGI,oClBwZ2F;EkBvZ3F,kFlByZ6F;AHmhDrG;;AqBt6DI;EAEE,qBlBnDW;EkBsDT,sDlBqe0J;EkBpe1J,ujBAAkJ;ArBs6D1J;;AqB56DI;EAUI,qBlB3DS;EkB4DT,gDlB5DS;AHk+DjB;;AqBj7DI;;;EAgBI,cAAc;ArBu6DtB;;AqBh6DI;;;EAII,cAAc;ArBk6DtB;;AqB55DI;EAGI,clBrFS;AHk/DjB;;AqBh6DI;;;EAQI,cAAc;ArB85DtB;;AqBx5DI;EAGI,clBnGS;AH4/DjB;;AqB55DI;EAMM,qBlBtGO;AHggEjB;;AqBh6DI;;;EAYI,cAAc;ArB05DtB;;AqBt6DI;EAiBM,qBAAkC;ECnJxC,yBDoJ+C;ArBy5DnD;;AqB36DI;EAwBM,gDlBxHO;AH+gEjB;;AqB/6DI;EA4BM,qBlB5HO;AHmhEjB;;AqB/4DI;EAGI,qBlBvIS;AHuhEjB;;AqBn5DI;;;EAQI,cAAc;ArBi5DtB;;AqBz5DI;EAaM,qBlBjJO;EkBkJP,gDlBlJO;AHkiEjB;;AmBz0DA;EACE,oBAAa;EAAb,aAAa;EACb,uBAAmB;EAAnB,mBAAmB;EACnB,sBAAmB;EAAnB,mBAAmB;AnB40DrB;;AmB/0DA;EASI,WAAW;AnB00Df;;AcxhEI;EKqMJ;IAeM,oBAAa;IAAb,aAAa;IACb,sBAAmB;IAAnB,mBAAmB;IACnB,qBAAuB;IAAvB,uBAAuB;IACvB,gBAAgB;EnBy0DpB;EmB31DF;IAuBM,oBAAa;IAAb,aAAa;IACb,kBAAc;IAAd,cAAc;IACd,uBAAmB;IAAnB,mBAAmB;IACnB,sBAAmB;IAAnB,mBAAmB;IACnB,gBAAgB;EnBu0DpB;EmBl2DF;IAgCM,qBAAqB;IACrB,WAAW;IACX,sBAAsB;EnBq0D1B;EmBv2DF;IAuCM,qBAAqB;EnBm0DzB;EmB12DF;;IA4CM,WAAW;EnBk0Df;EmB92DF;IAkDM,oBAAa;IAAb,aAAa;IACb,sBAAmB;IAAnB,mBAAmB;IACnB,qBAAuB;IAAvB,uBAAuB;IACvB,WAAW;IACX,eAAe;EnB+zDnB;EmBr3DF;IAyDM,kBAAkB;IAClB,oBAAc;IAAd,cAAc;IACd,aAAa;IACb,qBhB2LwC;IgB1LxC,cAAc;EnB+zDlB;EmB53DF;IAiEM,sBAAmB;IAAnB,mBAAmB;IACnB,qBAAuB;IAAvB,uBAAuB;EnB8zD3B;EmBh4DF;IAqEM,gBAAgB;EnB8zDpB;AACF;;AuB/nEA;EACE,qBAAqB;EAErB,gBpBkR+B;EoBjR/B,cpBMgB;EoBLhB,kBAAkB;EAClB,sBAAsB;EACtB,yBAAiB;EAAjB,sBAAiB;EAAjB,qBAAiB;EAAjB,iBAAiB;EACjB,6BAA6B;EAC7B,6BAA2C;ECsF3C,yBrB0RkC;EChQ9B,eAtCY;EoBchB,gBrByL+B;EO3R7B,sBPqOgC;EiBpO9B,qIjBqb6I;AH0tDnJ;;AoB1oEI;EGLJ;IHMM,gBAAgB;EpB8oEpB;AACF;;AK/oEE;EkBQE,cpBJc;EoBKd,qBAAqB;AvB2oEzB;;AuB1pEA;EAoBI,UAAU;EACV,gDpBSa;AHioEjB;;AuB/pEA;EA2BI,apB8Y6B;AH0vDjC;;AuBznEA;;EAEE,oBAAoB;AvB4nEtB;;AuBnnEE;ECrDA,WrBCa;EmBDX,yBnB8Ba;EqB5Bf,qBrB4Be;AHgpEjB;;AKxqEE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxBqrE7H;;AwBzqEE;EAMI,gDAAiF;AxBuqEvF;;AwBlqEE;EAEE,WrBvBW;EqBwBX,yBrBKa;EqBJb,qBrBIa;AHgqEjB;;AwB7pEE;;EAGE,WrBnCW;EqBoCX,yBAtCuK;EA0CvK,qBA1C+M;AxBssEnN;;AwB1pEI;;EAKI,gDAAiF;AxB0pEzF;;AuBrpEE;ECrDA,WrBCa;EmBDX,yBnBOc;EqBLhB,qBrBKgB;AHysElB;;AK1sEE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxButE7H;;AwB3sEE;EAMI,iDAAiF;AxBysEvF;;AwBpsEE;EAEE,WrBvBW;EqBwBX,yBrBlBc;EqBmBd,qBrBnBc;AHytElB;;AwB/rEE;;EAGE,WrBnCW;EqBoCX,yBAtCuK;EA0CvK,qBA1C+M;AxBwuEnN;;AwB5rEI;;EAKI,iDAAiF;AxB4rEzF;;AuBvrEE;ECrDA,WrBCa;EmBDX,yBnBqCa;EqBnCf,qBrBmCe;AH6sEjB;;AK5uEE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxByvE7H;;AwB7uEE;EAMI,+CAAiF;AxB2uEvF;;AwBtuEE;EAEE,WrBvBW;EqBwBX,yBrBYa;EqBXb,qBrBWa;AH6tEjB;;AwBjuEE;;EAGE,WrBnCW;EqBoCX,yBAtCuK;EA0CvK,qBA1C+M;AxB0wEnN;;AwB9tEI;;EAKI,+CAAiF;AxB8tEzF;;AuBztEE;ECrDA,WrBCa;EmBDX,yBnBuCa;EqBrCf,qBrBqCe;AH6uEjB;;AK9wEE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxB2xE7H;;AwB/wEE;EAMI,gDAAiF;AxB6wEvF;;AwBxwEE;EAEE,WrBvBW;EqBwBX,yBrBca;EqBbb,qBrBaa;AH6vEjB;;AwBnwEE;;EAGE,WrBnCW;EqBoCX,yBAtCuK;EA0CvK,qBA1C+M;AxB4yEnN;;AwBhwEI;;EAKI,gDAAiF;AxBgwEzF;;AuB3vEE;ECrDA,crBUgB;EmBVd,yBnBoCa;EqBlCf,qBrBkCe;AHkxEjB;;AKhzEE;EmBAE,crBIc;EmBVd,yBEDoF;EASpF,qBATyH;AxB6zE7H;;AwBjzEE;EAMI,gDAAiF;AxB+yEvF;;AwB1yEE;EAEE,crBdc;EqBed,yBrBWa;EqBVb,qBrBUa;AHkyEjB;;AwBryEE;;EAGE,crB1Bc;EqB2Bd,yBAtCuK;EA0CvK,qBA1C+M;AxB80EnN;;AwBlyEI;;EAKI,gDAAiF;AxBkyEzF;;AuB7xEE;ECrDA,WrBCa;EmBDX,yBnBkCa;EqBhCf,qBrBgCe;AHszEjB;;AKl1EE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxB+1E7H;;AwBn1EE;EAMI,+CAAiF;AxBi1EvF;;AwB50EE;EAEE,WrBvBW;EqBwBX,yBrBSa;EqBRb,qBrBQa;AHs0EjB;;AwBv0EE;;EAGE,WrBnCW;EqBoCX,yBAtCuK;EA0CvK,qBA1C+M;AxBg3EnN;;AwBp0EI;;EAKI,+CAAiF;AxBo0EzF;;AuB/zEE;ECrDA,crBUgB;EmBVd,yBnBEc;EqBAhB,qBrBAgB;AHw3ElB;;AKp3EE;EmBAE,crBIc;EmBVd,yBEDoF;EASpF,qBATyH;AxBi4E7H;;AwBr3EE;EAMI,iDAAiF;AxBm3EvF;;AwB92EE;EAEE,crBdc;EqBed,yBrBvBc;EqBwBd,qBrBxBc;AHw4ElB;;AwBz2EE;;EAGE,crB1Bc;EqB2Bd,yBAtCuK;EA0CvK,qBA1C+M;AxBk5EnN;;AwBt2EI;;EAKI,iDAAiF;AxBs2EzF;;AuBj2EE;ECrDA,WrBCa;EmBDX,yBnBSc;EqBPhB,qBrBOgB;AHm5ElB;;AKt5EE;EmBAE,WrBLW;EmBDX,yBEDoF;EASpF,qBATyH;AxBm6E7H;;AwBv5EE;EAMI,8CAAiF;AxBq5EvF;;AwBh5EE;EAEE,WrBvBW;EqBwBX,yBrBhBc;EqBiBd,qBrBjBc;AHm6ElB;;AwB34EE;;EAGE,WrBnCW;EqBoCX,yBAtCuK;EA0CvK,qBA1C+M;AxBo7EnN;;AwBx4EI;;EAKI,8CAAiF;AxBw4EzF;;AuB73EE;ECJA,crBzBe;EqB0Bf,qBrB1Be;AH+5EjB;;AKv7EE;EmBqDE,WrB1DW;EqB2DX,yBrB9Ba;EqB+Bb,qBrB/Ba;AHq6EjB;;AwBn4EE;EAEE,+CrBpCa;AHy6EjB;;AwBl4EE;EAEE,crBzCa;EqB0Cb,6BAA6B;AxBo4EjC;;AwBj4EE;;EAGE,WrB7EW;EqB8EX,yBrBjDa;EqBkDb,qBrBlDa;AHq7EjB;;AwBj4EI;;EAKI,+CrBzDS;AH07EjB;;AuB75EE;ECJA,crBhDgB;EqBiDhB,qBrBjDgB;AHs9ElB;;AKv9EE;EmBqDE,WrB1DW;EqB2DX,yBrBrDc;EqBsDd,qBrBtDc;AH49ElB;;AwBn6EE;EAEE,iDrB3Dc;AHg+ElB;;AwBl6EE;EAEE,crBhEc;EqBiEd,6BAA6B;AxBo6EjC;;AwBj6EE;;EAGE,WrB7EW;EqB8EX,yBrBxEc;EqByEd,qBrBzEc;AH4+ElB;;AwBj6EI;;EAKI,iDrBhFU;AHi/ElB;;AuB77EE;ECJA,crBlBe;EqBmBf,qBrBnBe;AHw9EjB;;AKv/EE;EmBqDE,WrB1DW;EqB2DX,yBrBvBa;EqBwBb,qBrBxBa;AH89EjB;;AwBn8EE;EAEE,+CrB7Ba;AHk+EjB;;AwBl8EE;EAEE,crBlCa;EqBmCb,6BAA6B;AxBo8EjC;;AwBj8EE;;EAGE,WrB7EW;EqB8EX,yBrB1Ca;EqB2Cb,qBrB3Ca;AH8+EjB;;AwBj8EI;;EAKI,+CrBlDS;AHm/EjB;;AuB79EE;ECJA,crBhBe;EqBiBf,qBrBjBe;AHs/EjB;;AKvhFE;EmBqDE,WrB1DW;EqB2DX,yBrBrBa;EqBsBb,qBrBtBa;AH4/EjB;;AwBn+EE;EAEE,gDrB3Ba;AHggFjB;;AwBl+EE;EAEE,crBhCa;EqBiCb,6BAA6B;AxBo+EjC;;AwBj+EE;;EAGE,WrB7EW;EqB8EX,yBrBxCa;EqByCb,qBrBzCa;AH4gFjB;;AwBj+EI;;EAKI,gDrBhDS;AHihFjB;;AuB7/EE;ECJA,crBnBe;EqBoBf,qBrBpBe;AHyhFjB;;AKvjFE;EmBqDE,crBjDc;EqBkDd,yBrBxBa;EqByBb,qBrBzBa;AH+hFjB;;AwBngFE;EAEE,+CrB9Ba;AHmiFjB;;AwBlgFE;EAEE,crBnCa;EqBoCb,6BAA6B;AxBogFjC;;AwBjgFE;;EAGE,crBpEc;EqBqEd,yBrB3Ca;EqB4Cb,qBrB5Ca;AH+iFjB;;AwBjgFI;;EAKI,+CrBnDS;AHojFjB;;AuB7hFE;ECJA,crBrBe;EqBsBf,qBrBtBe;AH2jFjB;;AKvlFE;EmBqDE,WrB1DW;EqB2DX,yBrB1Ba;EqB2Bb,qBrB3Ba;AHikFjB;;AwBniFE;EAEE,+CrBhCa;AHqkFjB;;AwBliFE;EAEE,crBrCa;EqBsCb,6BAA6B;AxBoiFjC;;AwBjiFE;;EAGE,WrB7EW;EqB8EX,yBrB7Ca;EqB8Cb,qBrB9Ca;AHilFjB;;AwBjiFI;;EAKI,+CrBrDS;AHslFjB;;AuB7jFE;ECJA,crBrDgB;EqBsDhB,qBrBtDgB;AH2nFlB;;AKvnFE;EmBqDE,crBjDc;EqBkDd,yBrB1Dc;EqB2Dd,qBrB3Dc;AHioFlB;;AwBnkFE;EAEE,iDrBhEc;AHqoFlB;;AwBlkFE;EAEE,crBrEc;EqBsEd,6BAA6B;AxBokFjC;;AwBjkFE;;EAGE,crBpEc;EqBqEd,yBrB7Ec;EqB8Ed,qBrB9Ec;AHipFlB;;AwBjkFI;;EAKI,iDrBrFU;AHspFlB;;AuB7lFE;ECJA,crB9CgB;EqB+ChB,qBrB/CgB;AHopFlB;;AKvpFE;EmBqDE,WrB1DW;EqB2DX,yBrBnDc;EqBoDd,qBrBpDc;AH0pFlB;;AwBnmFE;EAEE,8CrBzDc;AH8pFlB;;AwBlmFE;EAEE,crB9Dc;EqB+Dd,6BAA6B;AxBomFjC;;AwBjmFE;;EAGE,WrB7EW;EqB8EX,yBrBtEc;EqBuEd,qBrBvEc;AH0qFlB;;AwBjmFI;;EAKI,8CrB9EU;AH+qFlB;;AuBlnFA;EACE,gBpB8M+B;EoB7M/B,cpB1Ce;EoB2Cf,qBpB6F4C;AHwhF9C;;AKxrFE;EkBsEE,cpB2F8D;EoB1F9D,0BpB2F+C;AH2hFnD;;AuB7nFA;EAYI,0BpBsF+C;EoBrF/C,gBAAgB;AvBqnFpB;;AuBloFA;EAkBI,cpBjFc;EoBkFd,oBAAoB;AvBonFxB;;AuBzmFA;ECLE,oBrBySgC;EC/Q5B,kBAtCY;EoBchB,gBrB6H+B;EO/N7B,qBPsO+B;AH++EnC;;AuB5mFA;ECTE,uBrBoSiC;EC1Q7B,mBAtCY;EoBchB,gBrB8H+B;EOhO7B,qBPuO+B;AHq/EnC;;AuB1mFA;EACE,cAAc;EACd,WAAW;AvB6mFb;;AuB/mFA;EAMI,kBpBuT+B;AHszEnC;;AuBxmFA;;;EAII,WAAW;AvB0mFf;;AyBhvFA;ELMM,gCjBsP2C;AHw/EjD;;AoBzuFI;EKXJ;ILYM,gBAAgB;EpB6uFpB;AACF;;Ay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CT,gBAAgB;A9B0nGpB;;A8B1oGA;;;;;;;;;;;;EAqBM,iB3B4M2B;AHw7FjC;;A8BzpGA;;;EA6BI,UAAU;A9BkoGd;;A8B/pGA;EAkCI,UAAU;A9BioGd;;A8BnqGA;;EpBeI,0BoBwBmD;EpBvBnD,6BoBuBmD;A9BkoGvD;;A8BzqGA;;EpB6BI,yBoBWmD;EpBVnD,4BoBUmD;A9BuoGvD;;A8B/qGA;EA8CI,oBAAa;EAAb,aAAa;EACb,sBAAmB;EAAnB,mBAAmB;A9BqoGvB;;A8BprGA;;EpBeI,0BoBmC6E;EpBlC7E,6BoBkC6E;A9BwoGjF;;A8B1rGA;EpB6BI,yBoBsBsE;EpBrBtE,4BoBqBsE;A9B4oG1E;;A8BjoGA;;EAEE,oBAAa;EAAb,aAAa;A9BooGf;;A8BtoGA;;EAQI,kBAAkB;EAClB,UAAU;A9BmoGd;;A8B5oGA;;EAYM,UAAU;A9BqoGhB;;A8BjpGA;;;;;;;;EAoBI,iB3B+I6B;AHy/FjC;;A8BpoGA;EAAuB,kB3B2IU;AH6/FjC;;A8BvoGA;EAAsB,iB3B0IW;AHigGjC;;A8BnoGA;EACE,oBAAa;EAAb,aAAa;EACb,sBAAmB;EAAnB,mBAAmB;EACnB,yB3BuRkC;E2BtRlC,gBAAgB;E1BsBZ,eAtCY;E0BkBhB,gB3BgL+B;E2B/K/B,gB3BoL+B;E2BnL/B,c3B/FgB;E2BgGhB,kBAAkB;EAClB,mBAAmB;EACnB,yB3BvGgB;E2BwGhB,yB3BtGgB;EONd,sBPqOgC;AH8gGpC;;A8BnpGA;;EAkBI,aAAa;A9BsoGjB;;A8B5nGA;;EAEE,gC3B6WqI;AHkxFvI;;A8B5nGA;;;;;;EAME,oB3BkQgC;EC/Q5B,kBAtCY;E0BqDhB,gB3BsF+B;EO/N7B,qBPsO+B;AHmiGnC;;A8B5nGA;;EAEE,kC3B2VqI;AHoyFvI;;A8B5nGA;;;;;;EAME,uB3B4OiC;EC1Q7B,mBAtCY;E0BsEhB,gB3BsE+B;EOhO7B,qBPuO+B;AHmjGnC;;A8B5nGA;;EAEE,sBAA0E;A9B+nG5E;;A8BpnGA;;;;;;EpB3JI,0BoBiK4B;EpBhK5B,6BoBgK4B;A9BwnGhC;;A8BrnGA;;;;;;EpBtJI,yBoB4J2B;EpB3J3B,4BoB2J2B;A9BynG/B;;A+B/yGA;EACE,kBAAkB;EAClB,cAAc;EACd,kBAA+C;EAC/C,oBAAqE;A/BkzGvE;;A+B/yGA;EACE,2BAAoB;EAApB,oBAAoB;EACpB,kB5Bqf0C;AH6zF5C;;A+B/yGA;EACE,kBAAkB;EAClB,WAAW;EACX,UAAU;A/BkzGZ;;A+BrzGA;EAMI,W5BpBW;E4BqBX,qB5BQa;EmB9Bb,yBnB8Ba;AH4yGjB;;A+B3zGA;EAiBM,gD5BFW;AHgzGjB;;A+B/zGA;EAsBI,qB5BqbsE;AHw3F1E;;A+Bn0GA;EA0BI,W5BxCW;E4ByCX,yB5B8e8E;E4B7e9E,qB5B6e8E;AHg0FlF;;A+Bz0GA;EAkCM,c5B1CY;AHq1GlB;;A+B70GA;EAqCQ,yB5BjDU;AH61GlB;;A+BlyGA;EACE,kBAAkB;EAClB,gBAAgB;EAChB,mBAAmB;A/BqyGrB;;A+BxyGA;EAOI,kBAAkB;EAClB,YAA+E;EAC/E,aAA+D;EAC/D,cAAc;EACd,W5B0bwC;E4BzbxC,Y5BybwC;E4BxbxC,oBAAoB;EACpB,WAAW;EACX,sB5B5EW;E4B6EX,yB5BmJ6B;AHkpGjC;;A+BrzGA;EAsBI,kBAAkB;EAClB,YAA+E;EAC/E,aAA+D;EAC/D,cAAc;EACd,W5B2awC;E4B1axC,Y5B0awC;E4BzaxC,WAAW;EACX,mCAAgE;A/BmyGpE;;A+B1xGA;ErBrGI,sBPqOgC;AH8pGpC;;A+B9xGA;EAOM,6MbrEqI;AlBg2G3I;;A+BlyGA;EAaM,qB5BnFW;EmB9Bb,yBnB8Ba;AH62GjB;;A+BvyGA;EAkBM,0JbhFqI;AlBy2G3I;;A+B3yGA;EAwBM,wC5B9FW;AHq3GjB;;A+B/yGA;EA2BM,wC5BjGW;AHy3GjB;;A+B/wGA;EAGI,kB5B0Z+C;AHs3FnD;;A+BnxGA;EAQM,uJb1GqI;AlBy3G3I;;A+BvxGA;EAcM,wC5BxHW;AHq4GjB;;A+BnwGA;EACE,qBAA2D;A/BswG7D;;A+BvwGA;EAKM,cAAqD;EACrD,c5BkY+E;E4BjY/E,mBAAmB;EAEnB,qB5BgY4E;AHq4FlF;;A+B9wGA;EAaM,wBAA0I;EAC1I,0BAA+G;EAC/G,uB5B2XiI;E4B1XjI,wB5B0XiI;E4BzXjI,yB5B3KY;E4B6KZ,qB5BsX4E;EiBziB5E,iJjB8f+H;EiB9f/H,yIjB8f+H;EiB9f/H,8KjB8f+H;AH07FrI;;AoBn7GI;EW2JJ;IX1JM,gBAAgB;EpBu7GpB;AACF;;A+B9xGA;EA0BM,sB5BzLS;E4B0LT,sCAA4E;EAA5E,8BAA4E;A/BwwGlF;;A+BnyGA;EAiCM,wC5BnKW;AHy6GjB;;A+B1vGA;EACE,qBAAqB;EACrB,WAAW;EACX,mC5BwR2H;E4BvR3H,0C5BwKkC;EChQ9B,eAtCY;E2BiIhB,gB5BiE+B;E4BhE/B,gB5BqE+B;E4BpE/B,c5B9MgB;E4B+MhB,sBAAsB;EACtB,6M5BmWmI;E4BlWnI,sB5BxNa;E4ByNb,yB5BrNgB;EONd,sBPqOgC;E4BPlC,wBAAgB;EAAhB,qBAAgB;EAAhB,gBAAgB;A/B2vGlB;;A+B3wGA;EAmBI,qB5B0PsE;E4BzPtE,UAAU;EAIR,gD5BvMW;AHg8GjB;;A+BjxGA;EAiCM,c5BtOY;E4BuOZ,sB5B9OS;AHk+Gf;;A+BtxGA;EAwCI,YAAY;EACZ,sB5BmIgC;E4BlIhC,sBAAsB;A/BkvG1B;;A+B5xGA;EA8CI,c5BpPc;E4BqPd,yB5BzPc;AH2+GlB;;A+BjyGA;EAoDI,aAAa;A/BivGjB;;A+B7uGA;EACE,kC5BmOqI;E4BlOrI,oB5B2HkC;E4B1HlC,uB5B0HkC;E4BzHlC,oB5B0HiC;EC1Q7B,mBAtCY;AJu6GlB;;A+B7uGA;EACE,gC5B4NqI;E4B3NrI,mB5BwHiC;E4BvHjC,sB5BuHiC;E4BtHjC,kB5BuHgC;EC/Q5B,kBAtCY;AJ+6GlB;;A+BxuGA;EACE,kBAAkB;EAClB,qBAAqB;EACrB,WAAW;EACX,mC5B0M2H;E4BzM3H,gBAAgB;A/B2uGlB;;A+BxuGA;EACE,kBAAkB;EAClB,UAAU;EACV,WAAW;EACX,mC5BkM2H;E4BjM3H,SAAS;EACT,UAAU;A/B2uGZ;;A+BjvGA;EASI,qB5B+KsE;E4B9KtE,gD5B9Qa;AH0/GjB;;A+BtvGA;EAcI,yB5B7Sc;AHyhHlB;;A+B1vGA;EAmBM,iB5BqUQ;AHs6Fd;;A+B9vGA;EAwBI,0BAA0B;A/B0uG9B;;A+BtuGA;EACE,kBAAkB;EAClB,MAAM;EACN,QAAQ;EACR,OAAO;EACP,UAAU;EACV,mC5BoK2H;E4BnK3H,yB5BoDkC;E4BlDlC,gB5BlD+B;E4BmD/B,gB5B9C+B;E4B+C/B,c5BjUgB;E4BkUhB,sB5BzUa;E4B0Ub,yB5BtUgB;EONd,sBPqOgC;AHg1GpC;;A+BtvGA;EAkBI,kBAAkB;EAClB,MAAM;EACN,QAAQ;EACR,SAAS;EACT,UAAU;EACV,cAAc;EACd,6B5B8I+F;E4B7I/F,yB5BkCgC;E4BjChC,gB5B9D6B;E4B+D7B,c5BjVc;E4BkVd,iBAAiB;ET1VjB,yBnBGc;E4ByVd,oBAAoB;ErB7VpB,kCqB8VgF;A/BwuGpF;;A+B9tGA;EACE,WAAW;EACX,2BAA+F;EAC/F,UAAU;EACV,6BAA6B;EAC7B,wBAAgB;EAAhB,qBAAgB;EAAhB,gBAAgB;A/BiuGlB;;A+BtuGA;EAQI,aAAa;A/BkuGjB;;A+B1uGA;EAY8B,gE5BrVb;AHujHjB;;A+B9uGA;EAa8B,gE5BtVb;AH2jHjB;;A+BlvGA;EAc8B,gE5BvVb;AH+jHjB;;A+BtvGA;EAkBI,SAAS;A/BwuGb;;A+B1vGA;EAsBI,W5B8N6C;E4B7N7C,Y5B6N6C;E4B5N7C,oBAAyE;ET/XzE,yBnB8Ba;E4BmWb,S5B6N0C;EO/lB1C,mBPgmB6C;EiB/lB3C,4GjB8f+H;E4BzHjI,wBAAgB;EAAhB,gBAAgB;A/BuuGpB;;AoBvmHI;EWkWJ;IXjWM,gBAAgB;EpB2mHpB;AACF;;A+B3wGA;ETvWI,yBnBmmB2E;AHmhG/E;;A+B/wGA;EAsCI,W5BuMoC;E4BtMpC,c5BuMqC;E4BtMrC,kBAAkB;EAClB,e5BsMuC;E4BrMvC,yB5B7Yc;E4B8Yd,yBAAyB;ErBnZzB,mBPylBoC;AHwiGxC;;A+BzxGA;EAiDI,W5BmM6C;E4BlM7C,Y5BkM6C;EmB3lB7C,yBnB8Ba;E4B6Xb,S5BmM0C;EO/lB1C,mBPgmB6C;EiB/lB3C,4GjB8f+H;E4B/FjI,qBAAgB;EAAhB,gBAAgB;A/B2uGpB;;AoBroHI;EWkWJ;IXjWM,gBAAgB;EpByoHpB;AACF;;A+BzyGA;ETvWI,yBnBmmB2E;AHijG/E;;A+B7yGA;EAgEI,W5B6KoC;E4B5KpC,c5B6KqC;E4B5KrC,kBAAkB;EAClB,e5B4KuC;E4B3KvC,yB5Bvac;E4Bwad,yBAAyB;ErB7azB,mBPylBoC;AHskGxC;;A+BvzGA;EA2EI,W5ByK6C;E4BxK7C,Y5BwK6C;E4BvK7C,aAAa;EACb,oB5BvD+B;E4BwD/B,mB5BxD+B;EmB9X/B,yBnB8Ba;E4B0Zb,S5BsK0C;EO/lB1C,mBPgmB6C;EiB/lB3C,4GjB8f+H;E4BlEjI,gBAAgB;A/B+uGpB;;AoBtqHI;EWkWJ;IXjWM,gBAAgB;EpB0qHpB;AACF;;A+B10GA;ETvWI,yBnBmmB2E;AHklG/E;;A+B90GA;EA6FI,W5BgJoC;E4B/IpC,c5BgJqC;E4B/IrC,kBAAkB;EAClB,e5B+IuC;E4B9IvC,6BAA6B;EAC7B,yBAAyB;EACzB,oBAA4C;A/BqvGhD;;A+Bx1GA;EAwGI,yB5B3cc;EOLd,mBPylBoC;AH4mGxC;;A+B71GA;EA6GI,kBAAkB;EAClB,yB5Bjdc;EOLd,mBPylBoC;AHknGxC;;A+Bn2GA;EAoHM,yB5BrdY;AHwsHlB;;A+Bv2GA;EAwHM,eAAe;A/BmvGrB;;A+B32GA;EA4HM,yB5B7dY;AHgtHlB;;A+B/2GA;EAgIM,eAAe;A/BmvGrB;;A+Bn3GA;EAoIM,yB5BreY;AHwtHlB;;A+B9uGA;;;EXhfM,4GjB8f+H;AHsuGrI;;AoB/tHI;EW2eJ;;;IX1eM,gBAAgB;EpBquHpB;AACF;;AgC7uHA;EACE,oBAAa;EAAb,aAAa;EACb,mBAAe;EAAf,eAAe;EACf,eAAe;EACf,gBAAgB;EAChB,gBAAgB;AhCgvHlB;;AgC7uHA;EACE,cAAc;EACd,oB7BkqBsC;AH8kGxC;;AK/uHE;E2BEE,qBAAqB;AhCivHzB;;AgCtvHA;EAUI,c7BVc;E6BWd,oBAAoB;EACpB,eAAe;AhCgvHnB;;AgCxuHA;EACE,gC7BxBgB;AHmwHlB;;AgC5uHA;EAII,mB7BkM6B;AH0iHjC;;AgChvHA;EAQI,6BAAgD;EtB3BhD,+BP4NgC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9BzMS;AH+lIf;;AiCh7HA;EA+BI,yB9B9MW;E8B+MX,gC9B/MW;AHomIf;;AiCr7HA;EAoCI,wP9B6fsR;AHw5G1R;;AiCz7HA;EAwCI,yB9BvNW;AH4mIf;;AiC77HA;EA0CM,yB9BzNS;AHgnIf;;AKjnIE;E4B6NM,yB9B5NO;AHonIf;;AiCj5HA;EAEI,W9B/OW;AHkoIf;;AKznIE;E4ByOI,W9BlPS;AHsoIf;;AiCz5HA;EAWM,+B9BxPS;AH0oIf;;AKjoIE;E4BkPM,gC9B3PO;AH8oIf;;AiCj6HA;EAkBQ,gC9B/PO;AHkpIf;;AiCr6HA;;;;EA0BM,W9BvQS;AHypIf;;AiC56HA;EA+BI,+B9B5QW;E8B6QX,sC9B7QW;AH8pIf;;AiCj7HA;EAoCI,8P9BkcqR;AH+8GzR;;AiCr7HA;EAwCI,+B9BrRW;AHsqIf;;AiCz7HA;EA0CM,W9BvRS;AH0qIf;;AKjqIE;E4BiRM,W9B1RO;AH8qIf;;AkCjrIA;EACE,kBAAkB;EAClB,oBAAa;EAAb,aAAa;EACb,0BAAsB;EAAtB,sBAAsB;EACtB,YAAY;EACZ,qBAAqB;EACrB,sB/BHa;E+BIb,2BAA2B;EAC3B,sC/BKa;EOZX,sBPqOgC;AHu9HpC;;AkC7rIA;EAYI,eAAe;EACf,cAAc;AlCqrIlB;;AkClsIA;ExBUI,+BP4NgC;EO3NhC,gCP2NgC;AHi+HpC;;AkCvsIA;ExBwBI,mCP8MgC;EO7MhC,kCP6MgC;AHs+HpC;;AkC/qIA;EAGE,kBAAc;EAAd,cAAc;EACd,gB/B+wByC;AHi6G3C;;AkC5qIA;EACE,sB/BywBwC;AHs6G1C;;AkC5qIA;EACE,qBAA+B;EAC/B,gBAAgB;AlC+qIlB;;AkC5qIA;EACE,gBAAgB;AlC+qIlB;;AKttIE;E6B4CE,qBAAqB;AlC8qIzB;;AkChrIA;EAMI,oB/BwvBuC;AHs7G3C;;AkCtqIA;EACE,wB/B+uByC;E+B9uBzC,gBAAgB;EAEhB,qC/BvDa;E+BwDb,6C/BxDa;AHguIf;;AkC7qIA;ExB/DI,0DwBuE8E;AlCyqIlF;;AkCjrIA;EAaM,aAAa;AlCwqInB;;AkCnqIA;EACE,wB/B6tByC;E+B5tBzC,qC/BvEa;E+BwEb,0C/BxEa;AH8uIf;;AkCzqIA;ExBjFI,0DPmzBoF;AH28GxF;;AkC9pIA;EACE,uBAAiC;EACjC,uB/B4sBwC;E+B3sBxC,sBAAgC;EAChC,gBAAgB;AlCiqIlB;;AkC9pIA;EACE,uBAAiC;EACjC,sBAAgC;AlCiqIlC;;AkC7pIA;EACE,kBAAkB;EAClB,MAAM;EACN,QAAQ;EACR,SAAS;EACT,OAAO;EACP,gB/BssByC;AH09G3C;;AkC7pIA;EACE,WAAW;ExBvHT,kCPmzBoF;AHq+GxF;;AkC5pIA;EACE,WAAW;ExBpHT,2CP0yBoF;EOzyBpF,4CPyyBoF;AH2+GxF;;AkC7pIA;EACE,WAAW;ExB3GT,+CP4xBoF;EO3xBpF,8CP2xBoF;AHi/GxF;;AkC3pIA;EACE,oBAAa;EAAb,aAAa;EACb,0BAAsB;EAAtB,sBAAsB;AlC8pIxB;;AkChqIA;EAKI,mB/B6qBsD;AHk/G1D;;ActvII;EoBkFJ;IASI,uBAAmB;IAAnB,mBAAmB;IACnB,mB/BwqBsD;I+BvqBtD,kB/BuqBsD;EHy/GxD;EkC3qIF;IAcM,oBAAa;IAAb,aAAa;IAEb,gBAAY;IAAZ,YAAY;IACZ,0BAAsB;IAAtB,sBAAsB;IACtB,kB/BgqBoD;I+B/pBpD,gBAAgB;IAChB,iB/B8pBoD;EHigHxD;AACF;;AkCtpIA;EACE,oBAAa;EAAb,aAAa;EACb,0BAAsB;EAAtB,sBAAsB;AlCypIxB;;AkC3pIA;EAOI,mB/B6oBsD;AH2gH1D;;Ac/wII;EoBgHJ;IAWI,uBAAmB;IAAnB,mBAAmB;ElCypIrB;EkCpqIF;IAgBM,gBAAY;IAAZ,YAAY;IACZ,gBAAgB;ElCupIpB;EkCxqIF;IAoBQ,cAAc;IACd,cAAc;ElCupIpB;EkC5qIF;IxBvJI,0BwBkLoC;IxBjLpC,6BwBiLoC;ElCqpItC;EkChrIF;;IAgCY,0BAA0B;ElCopIpC;EkCprIF;;IAqCY,6BAA6B;ElCmpIvC;EkCxrIF;IxBzII,yBwBmLmC;IxBlLnC,4BwBkLmC;ElCkpIrC;EkC5rIF;;IA+CY,yBAAyB;ElCipInC;EkChsIF;;IAoDY,4BAA4B;ElCgpItC;AACF;;AkCpoIA;EAEI,sB/BokBsC;AHkkH1C;;AczzII;EoBiLJ;IAMI,uB/BglBiC;I+BhlBjC,oB/BglBiC;I+BhlBjC,e/BglBiC;I+B/kBjC,2B/BglBuC;I+BhlBvC,wB/BglBuC;I+BhlBvC,mB/BglBuC;I+B/kBvC,UAAU;IACV,SAAS;ElCuoIX;EkChpIF;IAYM,qBAAqB;IACrB,WAAW;ElCuoIf;AACF;;AkC9nIA;EAEI,gBAAgB;AlCgoIpB;;AkCloIA;ExB/PI,gBwBqQ4B;AlCgoIhC;;AkCtoIA;EAUQ,gBAAgB;ExBzQpB,gBwB0Q4B;AlCgoIhC;;AkC3oIA;EAgBM,gBAAgB;ExBxPlB,6BwByPiC;ExBxPjC,4BwBwPiC;AlCgoIrC;;AkCjpIA;ExBtPI,yBwB2Q8B;ExB1Q9B,0BwB0Q8B;AlCioIlC;;AkCtpIA;EAyBM,mB/BtD2B;AHurIjC;;AmC95IA;EACE,oBAAa;EAAb,aAAa;EACb,mBAAe;EAAf,eAAe;EACf,qBhC2gCsC;EgC1gCtC,mBhC6gCsC;EgC5gCtC,gBAAgB;EAChB,yBhCGgB;EOJd,sBPqOgC;AH8rIpC;;AmC95IA;EAGI,oBhCkgCqC;AH65GzC;;AmCl6IA;EAMM,qBAAqB;EACrB,qBhC8/BmC;EgC7/BnC,chCLY;EgCMZ,YhCmgCuC;AH65G7C;;AmCz6IA;EAoBI,0BAA0B;AnCy5I9B;;AmC76IA;EAwBI,qBAAqB;AnCy5IzB;;AmCj7IA;EA4BI,chCzBc;AHk7IlB;;AoC/7IA;EACE,oBAAa;EAAb,aAAa;E7BGb,eAAe;EACf,gBAAgB;EGAd,sBPqOgC;AH4tIpC;;AoCh8IA;EACE,kBAAkB;EAClB,cAAc;EACd,uBjCqwBwC;EiCpwBxC,iBjC6N+B;EiC5N/B,iBjCwwBsC;EiCvwBtC,cjCwBe;EiCvBf,sBjCNa;EiCOb,yBjCJgB;AHu8IlB;;AoC38IA;EAWI,UAAU;EACV,cjC2J8D;EiC1J9D,qBAAqB;EACrB,yBjCXc;EiCYd,qBjCXc;AH+8IlB;;AoCn9IA;EAmBI,UAAU;EACV,UjCiwBiC;EiChwBjC,gDjCSa;AH27IjB;;AoCh8IA;EAGM,cAAc;E1BChB,+BPuMgC;EOtMhC,kCPsMgC;AH2vIpC;;AoCt8IA;E1BVI,gCPqNgC;EOpNhC,mCPoNgC;AHgwIpC;;AoC38IA;EAcI,UAAU;EACV,WjCvCW;EiCwCX,yBjCXa;EiCYb,qBjCZa;AH68IjB;;AoCl9IA;EAqBI,cjCvCc;EiCwCd,oBAAoB;EAEpB,YAAY;EACZ,sBjCjDW;EiCkDX,qBjC/Cc;AH++IlB;;AqCt/IE;EACE,uBlC8wBsC;ECnpBpC,kBAtCY;EiCnFd,gBlC8N6B;AH2xIjC;;AqCp/IM;E3BwBF,8BPwM+B;EOvM/B,iCPuM+B;AHyxInC;;AqCp/IM;E3BKF,+BPsN+B;EOrN/B,kCPqN+B;AH8xInC;;AqCtgJE;EACE,uBlC4wBqC;ECjpBnC,mBAtCY;EiCnFd,gBlC+N6B;AH0yIjC;;AqCpgJM;E3BwBF,8BPyM+B;EOxM/B,iCPwM+B;AHwyInC;;AqCpgJM;E3BKF,+BPuN+B;EOtN/B,kCPsN+B;AH6yInC;;AsCphJA;EACE,qBAAqB;EACrB,qBnC24BsC;EC10BpC,cAAW;EkC/Db,gBnCmR+B;EmClR/B,cAAc;EACd,kBAAkB;EAClB,mBAAmB;EACnB,wBAAwB;E5BRtB,sBPqOgC;EiBpO9B,qIjBqb6I;AH2mInJ;;AoB3hJI;EkBNJ;IlBOM,gBAAgB;EpB+hJpB;AACF;;AK5hJE;EiCGI,qBAAqB;AtC6hJ3B;;AsC3iJA;EAoBI,aAAa;AtC2hJjB;;AsCthJA;EACE,kBAAkB;EAClB,SAAS;AtCyhJX;;AsClhJA;EACE,oBnCg3BsC;EmC/2BtC,mBnC+2BsC;EOn5BpC,oBPs5BqC;AHoqHzC;;AsC7gJE;ECjDA,WpCMa;EoCLb,yBpCkCe;AHgiJjB;;AKpjJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvCkkJxC;;AuCrkJU;EAQJ,UAAU;EACV,+CpCuBW;AH0iJjB;;AsC5hJE;ECjDA,WpCMa;EoCLb,yBpCWgB;AHskJlB;;AKnkJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvCilJxC;;AuCplJU;EAQJ,UAAU;EACV,iDpCAY;AHglJlB;;AsC3iJE;ECjDA,WpCMa;EoCLb,yBpCyCe;AHujJjB;;AKllJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvCgmJxC;;AuCnmJU;EAQJ,UAAU;EACV,+CpC8BW;AHikJjB;;AsC1jJE;ECjDA,WpCMa;EoCLb,yBpC2Ce;AHokJjB;;AKjmJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvC+mJxC;;AuClnJU;EAQJ,UAAU;EACV,gDpCgCW;AH8kJjB;;AsCzkJE;ECjDA,cpCegB;EoCdhB,yBpCwCe;AHslJjB;;AKhnJE;EkCVI,cpCUY;EoCTZ,yBAAkC;AvC8nJxC;;AuCjoJU;EAQJ,UAAU;EACV,+CpC6BW;AHgmJjB;;AsCxlJE;ECjDA,WpCMa;EoCLb,yBpCsCe;AHumJjB;;AK/nJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvC6oJxC;;AuChpJU;EAQJ,UAAU;EACV,+CpC2BW;AHinJjB;;AsCvmJE;ECjDA,cpCegB;EoCdhB,yBpCMgB;AHspJlB;;AK9oJE;EkCVI,cpCUY;EoCTZ,yBAAkC;AvC4pJxC;;AuC/pJU;EAQJ,UAAU;EACV,iDpCLY;AHgqJlB;;AsCtnJE;ECjDA,WpCMa;EoCLb,yBpCagB;AH8pJlB;;AK7pJE;EkCVI,WpCCS;EoCAT,yBAAkC;AvC2qJxC;;AuC9qJU;EAQJ,UAAU;EACV,8CpCEY;AHwqJlB;;AwCvrJA;EACE,kBAAoD;EACpD,mBrC0yBsC;EqCxyBtC,yBrCKgB;EOJd,qBPsO+B;AHm9InC;;AcloJI;E0B5DJ;IAQI,kBrCoyBoC;EHu5HtC;AACF;;AwCxrJA;EACE,gBAAgB;EAChB,eAAe;E9BTb,gB8BUsB;AxC2rJ1B;;AyCtsJA;EACE,kBAAkB;EAClB,wBtCm8ByC;EsCl8BzC,mBtCm8BsC;EsCl8BtC,6BAA6C;E/BH3C,sBPqOgC;AHw+IpC;;AyCrsJA;EAEE,cAAc;AzCusJhB;;AyCnsJA;EACE,gBtCwQ+B;AH87IjC;;AyC9rJA;EACE,mBAAsD;AzCisJxD;;AyClsJA;EAKI,kBAAkB;EAClB,MAAM;EACN,QAAQ;EACR,wBtCq6BuC;EsCp6BvC,cAAc;AzCisJlB;;AyCvrJE;EC9CA,cxBmFgE;EI9E9D,yBJ8E8D;EwBjFhE,qBxBiFgE;AlBwpJlE;;A0CvuJE;EACE,yBAAqC;A1C0uJzC;;A0CvuJE;EACE,cAA0B;A1C0uJ9B;;AyCrsJE;EC9CA,cxBmFgE;EI9E9D,yBJ8E8D;EwBjFhE,qBxBiFgE;AlBsqJlE;;A0CrvJE;EACE,yBAAqC;A1CwvJzC;;A0CrvJE;EACE,cAA0B;A1CwvJ9B;;AyCntJE;EC9CA,cxBmFgE;EI9E9D,yBJ8E8D;EwBjFhE,qBxBiFgE;AlBorJlE;;A0CnwJE;EACE,yBAAqC;A1CswJzC;;A0CnwJE;EACE,cAA0B;A1CswJ9B;;AyCjuJE;EC9CA,cxBmFgE;EI9E9D,yBJ8E8D;EwBjFhE,qBxBiFgE;AlBksJlE;;A0CjxJE;EACE,yBAAqC;A1CoxJzC;;A0CjxJE;EACE,cAA0B;A1CoxJ9B;;AyC/uJE;EC9CA,cxBmFgE;EI9E9D,yBJ8E8D;EwBjFhE,qBxBiFgE;AlBgtJlE;;A0C/xJE;EACE,yBAAqC;A1CkyJzC;;A0C/xJE;EACE,cAA0B;A1CkyJ9B;;AyC7vJE;EC9CA,cxBmFgE;EI9E9D,yBJ8E8D;EwBjFhE,qBxBiFgE;AlB8tJlE;;A0C7yJE;EACE,yBAAqC;A1CgzJzC;;A0C7yJE;EACE,cAA0B;A1CgzJ9B;;AyC3wJE;EC9CA,cxBmFgE;EI9E9D,yBJ8E8D;EwBjFhE,qBxBiFgE;AlB4uJlE;;A0C3zJE;EACE,yBAAqC;A1C8zJzC;;A0C3zJE;EACE,cAA0B;A1C8zJ9B;;AyCzxJE;EC9CA,cxBmFgE;EI9E9D,yBJ8E8D;EwBjFhE,qBxBiFgE;AlB0vJlE;;A0Cz0JE;EACE,yBAAqC;A1C40JzC;;A0Cz0JE;EACE,cAA0B;A1C40J9B;;A2Cp1JE;EACE;IAAO,2BAAuC;E3Cw1JhD;E2Cv1JE;IAAK,wBAAwB;E3C01J/B;AACF;;A2C71JE;EACE;IAAO,2BAAuC;E3Cw1JhD;E2Cv1JE;IAAK,wBAAwB;E3C01J/B;AACF;;A2Cv1JA;EACE,oBAAa;EAAb,aAAa;EACb,YxC48BsC;EwC38BtC,gBAAgB;EvCoHZ,kBAtCY;EuC5EhB,yBxCJgB;EOJd,sBPqOgC;AH8nJpC;;A2Ct1JA;EACE,oBAAa;EAAb,aAAa;EACb,0BAAsB;EAAtB,sBAAsB;EACtB,qBAAuB;EAAvB,uBAAuB;EACvB,WxCfa;EwCgBb,kBAAkB;EAClB,mBAAmB;EACnB,yBxCWe;EiB9BX,2BjBw9B4C;AHq5HlD;;AoBx2JI;EuBOJ;IvBNM,gBAAgB;EpB42JpB;AACF;;A2C51JA;ErBcE,qMAA6I;EqBZ7I,0BxCu7BsC;AHw6HxC;;A2C31JE;EACE,0DxCy7BkD;EwCz7BlD,kDxCy7BkD;AHq6HtD;;A2C51JI;EAHF;IAII,uBAAe;IAAf,eAAe;E3Cg2JnB;AACF;;A4Cx4JA;EACE,oBAAa;EAAb,aAAa;EACb,qBAAuB;EAAvB,uBAAuB;A5C24JzB;;A4Cx4JA;EACE,WAAO;EAAP,OAAO;A5C24JT;;A6C74JA;EACE,oBAAa;EAAb,aAAa;EACb,0BAAsB;EAAtB,sBAAsB;EAGtB,eAAe;EACf,gBAAgB;A7C84JlB;;A6Cr4JA;EACE,WAAW;EACX,c1CPgB;E0CQhB,mBAAmB;A7Cw4JrB;;AK94JE;EwCUE,UAAU;EACV,c1Cbc;E0Ccd,qBAAqB;EACrB,yB1CrBc;AH65JlB;;A6Cl5JA;EAcI,c1CjBc;E0CkBd,yB1CzBc;AHi6JlB;;A6C/3JA;EACE,kBAAkB;EAClB,cAAc;EACd,wB1C47ByC;E0C17BzC,mB1CuL+B;E0CrL/B,sB1C3Ca;E0C4Cb,sC1ClCa;AHk6Jf;;A6Cx4JA;EnC7BI,+BP4NgC;EO3NhC,gCP2NgC;AH8sJpC;;A6C74JA;EAeI,gBAAgB;EnC9BhB,mCP8MgC;EO7MhC,kCP6MgC;AHotJpC;;A6Cn5JA;EAqBI,c1CnDc;E0CoDd,oBAAoB;EACpB,sB1C3DW;AH67Jf;;A6Cz5JA;EA4BI,UAAU;EACV,W1CjEW;E0CkEX,yB1CrCa;E0CsCb,qB1CtCa;AHu6JjB;;A6Cp3JI;EACE,uBAAmB;EAAnB,mBAAmB;A7Cu3JzB;;A6Cx3JI;EAII,kB1C4IyB;E0C3IzB,gBAAgB;A7Cw3JxB;;A6C73JI;EnCpDA,+BPuMgC;EOtMhC,kCPsMgC;EO1LhC,0BmCgDwC;A7C03J5C;;A6Cn4JI;EAaM,eAAe;EnC/ErB,gCPqNgC;EOpNhC,mCPoNgC;EO9KhC,4BmC0C0C;A7C23J9C;;Acr6JI;E+B2BA;IACE,uBAAmB;IAAnB,mBAAmB;E7C84JvB;E6C/4JE;IAII,kB1C4IyB;I0C3IzB,gBAAgB;E7C84JtB;E6Cn5JE;InCpDA,+BPuMgC;IOtMhC,kCPsMgC;IO1LhC,0BmCgDwC;E7C+4J1C;E6Cx5JE;IAaM,eAAe;InC/ErB,gCPqNgC;IOpNhC,mCPoNgC;IO9KhC,4BmC0C0C;E7C+4J5C;AACF;;Ac17JI;E+B2BA;IACE,uBAAmB;IAAnB,mBAAmB;E7Cm6JvB;E6Cp6JE;IAII,kB1C4IyB;I0C3IzB,gBAAgB;E7Cm6JtB;E6Cx6JE;InCpDA,+BPuMgC;IOtMhC,kCPsMgC;IO1LhC,0BmCgDwC;E7Co6J1C;E6C76JE;IAaM,eAAe;InC/ErB,gCPqNgC;IOpNhC,mCPoNgC;IO9KhC,4BmC0C0C;E7Co6J5C;AACF;;Ac/8JI;E+B2BA;IACE,uBAAmB;IAAnB,mBAAmB;E7Cw7JvB;E6Cz7JE;IAII,kB1C4IyB;I0C3IzB,gBAAgB;E7Cw7JtB;E6C77JE;InCpDA,+BPuMgC;IOtMhC,kCPsMgC;IO1LhC,0BmCgDwC;E7Cy7J1C;E6Cl8JE;IAaM,eAAe;InC/ErB,gCPqNgC;IOpNhC,mCPoNgC;IO9KhC,4BmC0C0C;E7Cy7J5C;AACF;;Acp+JI;E+B2BA;IACE,uBAAmB;IAAnB,mBAAmB;E7C68JvB;E6C98JE;IAII,kB1C4IyB;I0C3IzB,gBAAgB;E7C68JtB;E6Cl9JE;InCpDA,+BPuMgC;IOtMhC,kCPsMgC;IO1LhC,0BmCgDwC;E7C88J1C;E6Cv9JE;IAaM,eAAe;InC/ErB,gCPqNgC;IOpNhC,mCPoNgC;IO9KhC,4BmC0C0C;E7C88J5C;AACF;;A6Cl8JA;EAEI,eAAe;EACf,cAAc;EnCjHd,gBmCkHwB;A7Co8J5B;;A6Cx8JA;EAOM,mB1C6G2B;AHw1JjC;;A6C58JA;EAaM,aAAa;A7Cm8JnB;;A6Ch9JA;EAmBM,gBAAgB;EAChB,gBAAgB;A7Ci8JtB;;A8CrkKE;EACE,c5BgF8D;E4B/E9D,yB5B+E8D;AlBy/JlE;;AK7jKE;EyCPM,c5B2E0D;E4B1E1D,yBAAyC;A9CwkKjD;;A8C/kKE;EAWM,W3CPO;E2CQP,yB5BqE0D;E4BpE1D,qB5BoE0D;AlBogKlE;;A8CrlKE;EACE,c5BgF8D;E4B/E9D,yB5B+E8D;AlBygKlE;;AK7kKE;EyCPM,c5B2E0D;E4B1E1D,yBAAyC;A9CwlKjD;;A8C/lKE;EAWM,W3CPO;E2CQP,yB5BqE0D;E4BpE1D,qB5BoE0D;AlBohKlE;;A8CrmKE;EACE,c5BgF8D;E4B/E9D,yB5B+E8D;AlByhKlE;;AK7lKE;EyCPM,c5B2E0D;E4B1E1D,yBAAyC;A9CwmKjD;;A8C/mKE;EAWM,W3CPO;E2CQP,yB5BqE0D;E4BpE1D,qB5BoE0D;AlBoiKlE;;A8CrnKE;EACE,c5BgF8D;E4B/E9D,yB5B+E8D;AlByiKlE;;AK7mKE;EyCPM,c5B2E0D;E4B1E1D,yBAAyC;A9CwnKjD;;A8C/nKE;EAWM,W3CPO;E2CQP,yB5BqE0D;E4BpE1D,qB5BoE0D;AlBojKlE;;A8CroKE;EACE,c5BgF8D;E4B/E9D,yB5B+E8D;AlByjKlE;;AK7nKE;EyCPM,c5B2E0D;E4B1E1D,yBAAyC;A9CwoKjD;;A8C/oKE;EAWM,W3CPO;E2CQP,yB5BqE0D;E4BpE1D,qB5BoE0D;AlBokKlE;;A8CrpKE;EACE,c5BgF8D;E4B/E9D,yB5B+E8D;AlBykKlE;;AK7oKE;EyCPM,c5B2E0D;E4B1E1D,yBAAyC;A9CwpKjD;;A8C/pKE;EAWM,W3CPO;E2CQP,yB5BqE0D;E4BpE1D,qB5BoE0D;AlBolKlE;;A8CrqKE;EACE,c5BgF8D;E4B/E9D,yB5B+E8D;AlBylKlE;;AK7pKE;EyCPM,c5B2E0D;E4B1E1D,yBAAyC;A9CwqKjD;;A8C/qKE;EAWM,W3CPO;E2CQP,yB5BqE0D;E4BpE1D,qB5BoE0D;AlBomKlE;;A8CrrKE;EACE,c5BgF8D;E4B/E9D,yB5B+E8D;AlBymKlE;;AK7qKE;EyCPM,c5B2E0D;E4B1E1D,yBAAyC;A9CwrKjD;;A8C/rKE;EAWM,W3CPO;E2CQP,yB5BqE0D;E4BpE1D,qB5BoE0D;AlBonKlE;;A+CxsKA;EACE,YAAY;E3C8HR,iBAtCY;E2CtFhB,gB5CyR+B;E4CxR/B,cAAc;EACd,W5CYa;E4CXb,yB5CCa;E4CAb,WAAW;A/C2sKb;;AKtsKE;E0CDE,W5CMW;E4CLX,qBAAqB;A/C2sKzB;;AKvsKE;E0CCI,YAAY;A/C0sKlB;;A+C/rKA;EACE,UAAU;EACV,6BAA6B;EAC7B,SAAS;EACT,wBAAgB;EAAhB,qBAAgB;EAAhB,gBAAgB;A/CksKlB;;A+C5rKA;EACE,oBAAoB;A/C+rKtB;;AgDtuKA;EACE,gB7C43BuC;E6C33BvC,gBAAgB;E5C6HZ,mBAtCY;E4CpFhB,2C7CEa;E6CDb,4BAA4B;EAC5B,oC7C63BmD;E6C53BnD,gD7CSa;E6CRb,mCAA2B;EAA3B,2BAA2B;EAC3B,UAAU;EtCLR,sBPg4BsC;AH82I1C;;AgDnvKA;EAcI,sB7Cg3BsC;AHy3I1C;;AgDvvKA;EAkBI,UAAU;AhDyuKd;;AgD3vKA;EAsBI,cAAc;EACd,UAAU;AhDyuKd;;AgDhwKA;EA2BI,aAAa;AhDyuKjB;;AgDruKA;EACE,oBAAa;EAAb,aAAa;EACb,sBAAmB;EAAnB,mBAAmB;EACnB,wB7C41BwC;E6C31BxC,c7CtBgB;E6CuBhB,2C7C7Ba;E6C8Bb,4BAA4B;EAC5B,4C7Co2BoD;AHo4ItD;;AgDruKA;EACE,gB7Co1BwC;AHo5I1C;;AiD5wKA;EAEE,gBAAgB;AjD8wKlB;;AiDhxKA;EAKI,kBAAkB;EAClB,gBAAgB;AjD+wKpB;;AiD1wKA;EACE,eAAe;EACf,MAAM;EACN,OAAO;EACP,a9CopBsC;E8CnpBtC,aAAa;EACb,WAAW;EACX,YAAY;EACZ,gBAAgB;EAGhB,UAAU;AjD2wKZ;;AiDpwKA;EACE,kBAAkB;EAClB,WAAW;EACX,c9C63BuC;E8C33BvC,oBAAoB;AjDswKtB;;AiDnwKE;E7BrCI,2CjB27BoD;EiB37BpD,mCjB27BoD;EiB37BpD,oEjB27BoD;E8Cp5BtD,sC9Ck5BmD;E8Cl5BnD,8B9Ck5BmD;AHo3IvD;;AoBxyKI;E6BgCF;I7B/BI,gBAAgB;EpB4yKpB;AACF;;AiD1wKE;EACE,uB9Cg5BoC;E8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hLf;;AkD3+KA;EACE,iBAAgC;AlD8+KlC;;AkD/+KA;EAII,MAAM;AlD++KV;;AkDn/KA;EAOM,SAAS;EACT,6B/CgxBmC;E+C/wBnC,yB/CrDS;AHqiLf;;AkD3+KA;EACE,iB/CywBuC;AHquJzC;;AkD/+KA;EAII,QAAQ;EACR,a/CqwBqC;E+CpwBrC,c/CmwBqC;AH4uJzC;;AkDr/KA;EASM,OAAO;EACP,oC/CgwBmC;E+C/vBnC,uB/CrES;AHqjLf;;AkD39KA;EACE,gB/C+tBuC;E+C9tBvC,uB/CouBuC;E+CnuBvC,W/CvGa;E+CwGb,kBAAkB;EAClB,sB/C/Fa;EOZX,sBPqOgC;AHq2KpC;;AoD/kLA;EACE,kBAAkB;EAClB,MAAM;EACN,OAAO;EACP,ajDsqBsC;EiDrqBtC,cAAc;EACd,gBjD+1BuC;EgDp2BvC,kMhD+QiN;EgD7QjN,kBAAkB;EAClB,gBhDuR+B;EgDtR/B,gBhD2R+B;EgD1R/B,gBAAgB;EAChB,iBAAiB;EACjB,qBAAqB;EACrB,iBAAiB;EACjB,oBAAoB;EACpB,sBAAsB;EACtB,kBAAkB;EAClB,oBAAoB;EACpB,mBAAmB;EACnB,gBAAgB;E/CgHZ,mBAtCY;EgD7EhB,qBAAqB;EACrB,sBjDNa;EiDOb,4BAA4B;EAC5B,oCjDEa;EOZX,qBPsO+B;AHi4KnC;;AoD5mLA;EAoBI,kBAAkB;EAClB,cAAc;EACd,WjD81BoC;EiD71BpC,cjD81BqC;EiD71BrC,gBjDmN+B;AHy4KnC;;AoDpnLA;EA4BM,kBAAkB;EAClB,cAAc;EACd,WAAW;EACX,yBAAyB;EACzB,mBAAmB;ApD4lLzB;;AoDvlLA;EACE,qBjD+0BuC;AH2wJzC;;AoD3lLA;EAII,iCAAwE;ApD2lL5E;;AoD/lLA;EAOM,SAAS;EACT,6BAAgE;EAChE,qCjD00BiE;AHkxJvE;;AoDrmLA;EAaM,WjDqL2B;EiDpL3B,6BAAgE;EAChE,sBjD7CS;AHyoLf;;AoDvlLA;EACE,mBjD2zBuC;AH+xJzC;;AoD3lLA;EAII,+BAAsE;EACtE,ajDuzBqC;EiDtzBrC,YjDqzBoC;EiDpzBpC,gBAA2B;ApD2lL/B;;AoDlmLA;EAUM,OAAO;EACP,oCAA2F;EAC3F,uCjDmzBiE;AHyyJvE;;AoDxmLA;EAgBM,SjD8J2B;EiD7J3B,oCAA2F;EAC3F,wBjDpES;AHgqLf;;AoDvlLA;EACE,kBjDoyBuC;AHszJzC;;AoD3lLA;EAII,8BAAqE;ApD2lLzE;;AoD/lLA;EAOM,MAAM;EACN,oCAA2F;EAC3F,wCjD+xBiE;AH6zJvE;;AoDrmLA;EAaM,QjD0I2B;EiDzI3B,oCAA2F;EAC3F,yBjDxFS;AHorLf;;AoD3mLA;EAqBI,kBAAkB;EAClB,MAAM;EACN,SAAS;EACT,cAAc;EACd,WjD2wBoC;EiD1wBpC,oBAAsC;EACtC,WAAW;EACX,gCjD+vBuD;AH21J3D;;AoDtlLA;EACE,oBjDowBuC;AHq1JzC;;AoD1lLA;EAII,gCAAuE;EACvE,ajDgwBqC;EiD/vBrC,YjD8vBoC;EiD7vBpC,gBAA2B;ApD0lL/B;;AoDjmLA;EAUM,QAAQ;EACR,oCjD0vBmC;EiDzvBnC,sCjD4vBiE;AH+1JvE;;AoDvmLA;EAgBM,UjDuG2B;EiDtG3B,oCjDovBmC;EiDnvBnC,uBjD3HS;AHstLf;;AoDrkLA;EACE,uBjDqtBwC;EiDptBxC,gBAAgB;EhD3BZ,eAtCY;EgDoEhB,yBjD8sByD;EiD7sBzD,gCAAyE;E1ChJvE,0C0CiJyE;E1ChJzE,2C0CgJyE;ApDwkL7E;;AoD/kLA;EAWI,aAAa;ApDwkLjB;;AoDpkLA;EACE,uBjDssBwC;EiDrsBxC,cjDzJgB;AHguLlB;;AqDnuLA;EACE,kBAAkB;ArDsuLpB;;AqDnuLA;EACE,uBAAmB;EAAnB,mBAAmB;ArDsuLrB;;AqDnuLA;EACE,kBAAkB;EAClB,WAAW;EACX,gBAAgB;ArDsuLlB;;AsD7vLE;EACE,cAAc;EACd,WAAW;EACX,WAAW;AtDgwLf;;AqDxuLA;EACE,kBAAkB;EAClB,aAAa;EACb,WAAW;EACX,WAAW;EACX,mBAAmB;EACnB,mCAA2B;EAA3B,2BAA2B;EjC5BvB,8CjB6iCkF;EiB7iClF,sCjB6iCkF;EiB7iClF,0EjB6iCkF;AH2tJxF;;AoBnwLI;EiCiBJ;IjChBM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E,oCAAmC;AzD4/LvC;;AKl/LE;;;EoDLI,oCAAgD;AzD6/LtD;;AyDngME;EACE,oCAAmC;AzDsgMvC;;AK5/LE;;;EoDLI,oCAAgD;AzDugMtD;;AyD7gME;EACE,oCAAmC;AzDghMvC;;AKtgME;;;EoDLI,oCAAgD;AzDihMtD;;AyDvhME;EACE,oCAAmC;AzD0hMvC;;AKhhME;;;EoDLI,oCAAgD;AzD2hMtD;;AyDjiME;EACE,oCAAmC;AzDoiMvC;;AK1hME;;;EoDLI,oCAAgD;AzDqiMtD;;AyD3iME;EACE,oCAAmC;AzD8iMvC;;AKpiME;;;EoDLI,oCAAgD;AzD+iMtD;;AyDrjME;EACE,oCAAmC;AzDwjMvC;;AK9iME;;;EoDLI,oCAAgD;AzDyjMtD;;A0DxjMA;EACE,iCAAmC;A1D2jMrC;;A0DxjMA;EACE,wCAAwC;A1D2jM1C;;A2DtkMA;EAAkB,oCAAoD;A3D0kMtE;;A2DzkMA;EAAkB,wCAAwD;A3D6kM1E;;A2D5kMA;EAAkB,0CAA0D;A3DglM5E;;A2D/kMA;EAAkB,2CAA2D;A3DmlM7E;;A2DllMA;EAAkB,yCAAyD;A3DslM3E;;A2DplMA;EAAmB,oBAAoB;A3DwlMvC;;A2DvlMA;EAAmB,wBAAwB;A3D2lM3C;;A2D1lMA;EAAmB,0BAA0B;A3D8lM7C;;A2D7lMA;EAAmB,2BAA2B;A3DimM9C;;A2DhmMA;EAAmB,yBAAyB;A3DomM5C;;A2DjmME;EACE,gCAA+B;A3DomMnC;;A2DrmME;EACE,gCAA+B;A3DwmMnC;;A2DzmME;EACE,gCAA+B;A3D4mMnC;;A2D7mME;EACE,gCAA+B;A3DgnMnC;;A2DjnME;EACE,gCAA+B;A3DonMnC;;A2DrnME;EACE,gCAA+B;A3DwnMnC;;A2DznME;EACE,gCAA+B;A3D4nMnC;;A2D7nME;EACE,gCAA+B;A3DgoMnC;;A2D5nMA;EACE,6BAA+B;A3D+nMjC;;A2DxnMA;EACE,gCAA2C;A3D2nM7C;;A2DxnMA;EACE,iCAAwC;A3D2nM1C;;A2DxnMA;EACE,0CAAiD;EACjD,2CAAkD;A3D2nMpD;;A2DxnMA;EACE,2CAAkD;EAClD,8CAAqD;A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tOhD;;AuEjuOQ;EAAgC,yBAA4B;AvEquOpE;;AuEpuOQ;;EAEE,6BAAoC;AvEuuO9C;;AuEruOQ;;EAEE,+BAAwC;AvEwuOlD;;AuEtuOQ;;EAEE,gCAA0C;AvEyuOpD;;AuEvuOQ;;EAEE,8BAAsC;AvE0uOhD;;AuEzvOQ;EAAgC,uBAA4B;AvE6vOpE;;AuE5vOQ;;EAEE,2BAAoC;AvE+vO9C;;AuE7vOQ;;EAEE,6BAAwC;AvEgwOlD;;AuE9vOQ;;EAEE,8BAA0C;AvEiwOpD;;AuE/vOQ;;EAEE,4BAAsC;AvEkwOhD;;AuEjxOQ;EAAgC,yBAA4B;AvEqxOpE;;AuEpxOQ;;EAEE,6BAAoC;AvEuxO9C;;AuErxOQ;;EAEE,+BAAwC;AvEwxOlD;;AuEtxOQ;;EAEE,gCAA0C;AvEyxOpD;;AuEvxOQ;;EAEE,8BAAsC;AvE0xOhD;;AuEzyOQ;EAAgC,uBAA4B;AvE6yOpE;;AuE5yOQ;;EAEE,2BAAoC;AvE+yO9C;;AuE7yOQ;;EAEE,6BAAwC;AvEgzOlD;;AuE9yOQ;;EAEE,8BAA0C;AvEizOpD;;AuE/yOQ;;EAEE,4BAAsC;AvEkzOhD;;AuEj0OQ;EAAgC,qBAA4B;AvEq0OpE;;AuEp0OQ;;EAEE,yBAAoC;AvEu0O9C;;AuEr0OQ;;EAEE,2BAAwC;AvEw0OlD;;AuEt0OQ;;EAEE,4BAA0C;AvEy0OpD;;AuEv0OQ;;EAEE,0BAAsC;AvE00OhD;;AuEz1OQ;EAAgC,2BAA4B;AvE61OpE;;AuE51OQ;;EAEE,+BAAoC;AvE+1O9C;;AuE71OQ;;EAEE,iCAAwC;AvEg2OlD;;AuE91OQ;;EAEE,kCAA0C;AvEi2OpD;;AuE/1OQ;;EAEE,gCAAsC;AvEk2OhD;;AuEj3OQ;EAAgC,0BAA4B;AvEq3OpE;;AuEp3OQ;;EAEE,8BAAoC;AvEu3O9C;;AuEr3OQ;;EAEE,gCAAwC;AvEw3OlD;;AuEt3OQ;;EAEE,iCAA0C;AvEy3OpD;;AuEv3OQ;;EAEE,+BAAsC;AvE03OhD;;AuEz4OQ;EAAgC,wBAA4B;AvE64OpE;;AuE54OQ;;EAEE,4BAAoC;AvE+4O9C;;AuE74OQ;;EAEE,8BAAwC;AvEg5OlD;;AuE94OQ;;EAEE,+BAA0C;AvEi5OpD;;AuE/4OQ;;EAEE,6BAAsC;AvEk5OhD;;AuEj6OQ;EAAgC,0BAA4B;AvEq6OpE;;AuEp6OQ;;EAEE,8BAAoC;AvEu6O9C;;AuEr6OQ;;EAEE,gCAAwC;AvEw6OlD;;AuEt6OQ;;EAEE,iCAA0C;AvEy6OpD;;AuEv6OQ;;EAEE,+BAAsC;AvE06OhD;;AuEz7OQ;EAAgC,wBAA4B;AvE67OpE;;AuE57OQ;;EAEE,4BAAoC;AvE+7O9C;;AuE77OQ;;EAEE,8BAAwC;AvEg8OlD;;AuE97OQ;;EAEE,+BAA0C;AvEi8OpD;;AuE/7OQ;;EAEE,6BAAsC;AvEk8OhD;;AuE17OQ;EAAwB,2BAA2B;AvE87O3D;;AuE77OQ;;EAEE,+BAA+B;AvEg8OzC;;AuE97OQ;;EAEE,iCAAiC;AvEi8O3C;;AuE/7OQ;;EAEE,kCAAkC;AvEk8O5C;;AuEh8OQ;;EAEE,gCAAgC;AvEm8O1C;;AuEl9OQ;EAAwB,0BAA2B;AvEs9O3D;;AuEr9OQ;;EAEE,8BAA+B;AvEw9OzC;;AuEt9OQ;;EAEE,gCAAiC;AvEy9O3C;;AuEv9OQ;;EAEE,iCAAkC;AvE09O5C;;AuEx9OQ;;EAEE,+BAAgC;AvE29O1C;;AuE1+OQ;EAAwB,wBAA2B;AvE8+O3D;;AuE7+OQ;;EAEE,4BAA+B;AvEg/OzC;;AuE9+OQ;;EAEE,8BAAiC;AvEi/O3C;;AuE/+OQ;;EAEE,+BAAkC;AvEk/O5C;;AuEh/OQ;;EAEE,6BAAgC;AvEm/O1C;;AuElgPQ;EAAwB,0BAA2B;AvEsgP3D;;AuErgPQ;;EAEE,8BAA+B;AvEwgPzC;;AuEtgPQ;;EAEE,gCAAiC;AvEygP3C;;AuEvgPQ;;EAEE,iCAAkC;AvE0gP5C;;AuExgPQ;;EAEE,+BAAgC;AvE2gP1C;;AuE1hPQ;EAAwB,wBAA2B;AvE8hP3D;;AuE7hPQ;;EAEE,4BAA+B;AvEgiPzC;;AuE9hPQ;;EAEE,8BAAiC;AvEiiP3C;;AuE/hPQ;;EAEE,+BAAkC;AvEkiP5C;;AuEhiPQ;;EAEE,6BAAgC;AvEmiP1C;;AuE7hPI;EAAmB,uBAAuB;AvEiiP9C;;AuEhiPI;;EAEE,2BAA2B;AvEmiPjC;;AuEjiPI;;EAEE,6BAA6B;AvEoiPnC;;AuEliPI;;EAEE,8BAA8B;AvEqiPpC;;AuEniPI;;EAEE,4BAA4B;AvEsiPlC;;Ac/iPI;EyDlDI;IAAgC,oBAA4B;EvEsmPlE;EuErmPM;;IAEE,wBAAoC;EvEumP5C;EuErmPM;;IAEE,0BAAwC;EvEumPhD;EuErmPM;;IAEE,2BAA0C;EvEumPlD;EuErmPM;;IAEE,yBAAsC;EvEumP9C;EuEtnPM;IAAgC,0BAA4B;EvEynPlE;EuExnPM;;IAEE,8BAAoC;EvE0nP5C;EuExnPM;;IAEE,gCAAwC;EvE0nPhD;EuExnPM;;IAEE,iCAA0C;EvE0nPlD;EuExnPM;;IAEE,+BAAsC;EvE0nP9C;EuEzoPM;IAAgC,yBAA4B;EvE4oPlE;EuE3oPM;;IAEE,6BAAoC;EvE6oP5C;EuE3oPM;;IAEE,+BAAwC;EvE6oPhD;EuE3oPM;;IAEE,gCAA0C;EvE6oPlD;EuE3oPM;;IAEE,8BAAsC;EvE6oP9C;EuE5pPM;IAAgC,uBAA4B;EvE+pPlE;EuE9pPM;;IAEE,2BAAoC;EvEgqP5C;EuE9pPM;;IAEE,6BAAwC;EvEgqPhD;EuE9pPM;;IAEE,8BAA0C;EvEgqPlD;EuE9pPM;;IAEE,4BAAsC;EvEgqP9C;EuE/qPM;IAAgC,yBAA4B;EvEkrPlE;EuEjrPM;;IAEE,6BAAoC;EvEmrP5C;EuEjrPM;;IAEE,+BAAwC;EvEmrPhD;EuEjrPM;;IAEE,gCAA0C;EvEmrPlD;EuEjrPM;;IAEE,8BAAsC;EvEmrP9C;EuElsPM;IAAgC,uBAA4B;EvEqsPlE;EuEpsPM;;IAEE,2BAAoC;EvEssP5C;EuEpsPM;;IAEE,6BAAwC;EvEssPhD;EuEpsPM;;IAEE,8BAA0C;EvEssPlD;EuEpsPM;;IAEE,4BAAsC;EvEssP9C;EuErtPM;IAAgC,qBAA4B;EvEwtPlE;EuEvtPM;;IAEE,yBAAoC;EvEytP5C;EuEvtPM;;IAEE,2BAAwC;EvEytPhD;EuEvtPM;;IAEE,4BAA0C;EvEytPlD;EuEvtPM;;IAEE,0BAAsC;EvEytP9C;EuExuPM;IAAgC,2BAA4B;EvE2uPlE;EuE1uPM;;IAEE,+BAAoC;EvE4uP5C;EuE1uPM;;IAEE,iCAAwC;EvE4uPhD;EuE1uPM;;IAEE,kCAA0C;EvE4uPlD;EuE1uPM;;IAEE,gCAAsC;EvE4uP9C;EuE3vPM;IAAgC,0BAA4B;EvE8vPlE;EuE7vPM;;IAEE,8BAAoC;EvE+vP5C;EuE7vPM;;IAEE,gCAAwC;EvE+vPhD;EuE7vPM;;IAEE,iCAA0C;EvE+vPlD;EuE7vPM;;IAEE,+BAAsC;EvE+vP9C;EuE9wPM;IAAgC,wBAA4B;EvEixPlE;EuEhxPM;;IAEE,4BAAoC;EvEkxP5C;EuEhxPM;;IAEE,8BAAwC;EvEkxPhD;EuEhxPM;;IAEE,+BAA0C;EvEkxPlD;EuEhxPM;;IAEE,6BAAsC;EvEkxP9C;EuEjyPM;IAAgC,0BAA4B;EvEoyPlE;EuEnyPM;;IAEE,8BAAoC;EvEqyP5C;EuEnyPM;;IAEE,gCAAwC;EvEqyPhD;EuEnyPM;;IAEE,iCAA0C;EvEqyPlD;EuEnyPM;;IAEE,+BAAsC;EvEqyP9C;EuEpzPM;IAAgC,wBAA4B;EvEuzPlE;EuEtzPM;;IAEE,4BAAoC;EvEwzP5C;EuEtzPM;;IAEE,8BAAwC;EvEwzPhD;EuEtzPM;;IAEE,+BAA0C;EvEwzPlD;EuEtzPM;;IAEE,6BAAsC;EvEwzP9C;EuEhzPM;IAAwB,2BAA2B;EvEmzPzD;EuElzPM;;IAEE,+BAA+B;EvEozPvC;EuElzPM;;IAEE,iCAAiC;EvEozPzC;EuElzPM;;IAEE,kCAAkC;EvEozP1C;EuElzPM;;IAEE,gCAAgC;EvEozPxC;EuEn0PM;IAAwB,0BAA2B;EvEs0PzD;EuEr0PM;;IAEE,8BAA+B;EvEu0PvC;EuEr0PM;;IAEE,gCAAiC;EvEu0PzC;EuEr0PM;;IAEE,iCAAkC;EvEu0P1C;EuEr0PM;;IAEE,+BAAgC;EvEu0PxC;EuEt1PM;IAAwB,wBAA2B;EvEy1PzD;EuEx1PM;;IAEE,4BAA+B;EvE01PvC;EuEx1PM;;IAEE,8BAAiC;EvE01PzC;EuEx1PM;;IAEE,+BAAkC;EvE01P1C;EuEx1PM;;IAEE,6BAAgC;EvE01PxC;EuEz2PM;IAAwB,0BAA2B;EvE42PzD;EuE32PM;;IAEE,8BAA+B;EvE62PvC;EuE32PM;;IAEE,gCAAiC;EvE62PzC;EuE32PM;;IAEE,iCAAkC;EvE62P1C;EuE32PM;;IAEE,+BAAgC;EvE62PxC;EuE53PM;IAAwB,wBAA2B;EvE+3PzD;EuE93PM;;IAEE,4BAA+B;EvEg4PvC;EuE93PM;;IAEE,8BAAiC;EvEg4PzC;EuE93PM;;IAEE,+BAAkC;EvEg4P1C;EuE93PM;;IAEE,6BAAgC;EvEg4PxC;EuE13PE;IAAmB,uBAAuB;EvE63P5C;EuE53PE;;IAEE,2BAA2B;EvE83P/B;EuE53PE;;IAEE,6BAA6B;EvE83PjC;EuE53PE;;IAEE,8BAA8B;EvE83PlC;EuE53PE;;IAEE,4BAA4B;EvE83PhC;AACF;;Acx4PI;EyDlDI;IAAgC,oBAA4B;EvE+7PlE;EuE97PM;;IAEE,wBAAoC;EvEg8P5C;EuE97PM;;IAEE,0BAAwC;EvEg8PhD;EuE97PM;;IAEE,2BAA0C;EvEg8PlD;EuE97PM;;IAEE,yBAAsC;EvEg8P9C;EuE/8PM;IAAgC,0BAA4B;EvEk9PlE;EuEj9PM;;IAEE,8BAAoC;EvEm9P5C;EuEj9PM;;IAEE,gCAAwC;EvEm9PhD;EuEj9PM;;IAEE,iCAA0C;EvEm9PlD;EuEj9PM;;IAEE,+BAAsC;EvEm9P9C;EuEl+PM;IAAgC,yBAA4B;EvEq+PlE;EuEp+PM;;IAEE,6BAAoC;EvEs+P5C;EuEp+PM;;IAEE,+BAAwC;EvEs+PhD;EuEp+PM;;IAEE,gCAA0C;EvEs+PlD;EuEp+PM;;IAEE,8BAAsC;EvEs+P9C;EuEr/PM;IAAgC,uBAA4B;EvEw/PlE;EuEv/PM;;IAEE,2BAAoC;EvEy/P5C;EuEv/PM;;IAEE,6BAAwC;EvEy/PhD;EuEv/PM;;IAEE,8BAA0C;EvEy/PlD;EuEv/PM;;IAEE,4BAAsC;EvEy/P9C;EuExgQM;IAAgC,yBAA4B;EvE2gQlE;EuE1gQM;;IAEE,6BAAoC;EvE4gQ5C;EuE1gQM;;IAEE,+BAAwC;EvE4gQhD;EuE1gQM;;IAEE,gCAA0C;EvE4gQlD;EuE1gQM;;IAEE,8BAAsC;EvE4gQ9C;EuE3hQM;IAAgC,uBAA4B;EvE8hQlE;EuE7hQM;;IAEE,2BAAoC;EvE+hQ5C;EuE7hQM;;IAEE,6BAAwC;EvE+hQhD;EuE7hQM;;IAEE,8BAA0C;EvE+hQlD;EuE7hQM;;IAEE,4BAAsC;EvE+hQ9C;EuE9iQM;IAAgC,qBAA4B;EvEijQlE;EuEhjQM;;IAEE,yBAAoC;EvEkjQ5C;EuEhjQM;;IAEE,2BAAwC;EvEkjQhD;EuEhjQM;;IAEE,4BAA0C;EvEkjQlD;EuEhjQM;;IAEE,0BAAsC;EvEkjQ9C;EuEjkQM;IAAgC,2BAA4B;EvEokQlE;EuEnkQM;;IAEE,+BAAoC;EvEqkQ5C;EuEnkQM;;IAEE,iCAAwC;EvEqkQhD;EuEnkQM;;IAEE,kCAA0C;EvEqkQlD;EuEnkQM;;IAEE,gCAAsC;EvEqkQ9C;EuEplQM;IAAgC,0BAA4B;EvEulQlE;EuEtlQM;;IAEE,8BAAoC;EvEwlQ5C;EuEtlQM;;IAEE,gCAAwC;EvEwlQhD;EuEtlQM;;IAEE,iCAA0C;EvEwlQlD;EuEtlQM;;IAEE,+BAAsC;EvEwlQ9C;EuEvmQM;IAAgC,wBAA4B;EvE0mQlE;EuEzmQM;;IAEE,4BAAoC;EvE2mQ5C;EuEzmQM;;IAEE,8BAAwC;EvE2mQhD;EuEzmQM;;IAEE,+BAA0C;EvE2mQlD;EuEzmQM;;IAEE,6BAAsC;EvE2mQ9C;EuE1nQM;IAAgC,0BAA4B;EvE6nQlE;EuE5nQM;;IAEE,8BAAoC;EvE8nQ5C;EuE5nQM;;IAEE,gCAAwC;EvE8nQhD;EuE5nQM;;IAEE,iCAA0C;EvE8nQlD;EuE5nQM;;IAEE,+BAAsC;EvE8nQ9C;EuE7oQM;IAAgC,wBAA4B;EvEgpQlE;EuE/oQM;;IAEE,4BAAoC;EvEipQ5C;EuE/oQM;;IAEE,8BAAwC;EvEipQhD;EuE/oQM;;IAEE,+BAA0C;EvEipQlD;EuE/oQM;;IAEE,6BAAsC;EvEipQ9C;EuEzoQM;IAAwB,2BAA2B;EvE4oQzD;EuE3oQM;;IAEE,+BAA+B;EvE6oQvC;EuE3oQM;;IAEE,iCAAiC;EvE6oQzC;EuE3oQM;;IAEE,kCAAkC;EvE6oQ1C;EuE3oQM;;IAEE,gCAAgC;EvE6oQxC;EuE5pQM;IAAwB,0BAA2B;EvE+pQzD;EuE9pQM;;IAEE,8BAA+B;EvEgqQvC;EuE9pQM;;IAEE,gCAAiC;EvEgqQzC;EuE9pQM;;IAEE,iCAAkC;EvEgqQ1C;EuE9pQM;;IAEE,+BAAgC;EvEgqQxC;EuE/qQM;IAAwB,wBAA2B;EvEkrQzD;EuEjrQM;;IAEE,4BAA+B;EvEmrQvC;EuEjrQM;;IAEE,8BAAiC;EvEmrQzC;EuEjrQM;;IAEE,+BAAkC;EvEmrQ1C;EuEjrQM;;IAEE,6BAAgC;EvEmrQxC;EuElsQM;IAAwB,0BAA2B;EvEqsQzD;EuEpsQM;;IAEE,8BAA+B;EvEssQvC;EuEpsQM;;IAEE,gCAAiC;EvEssQzC;EuEpsQM;;IAEE,iCAAkC;EvEssQ1C;EuEpsQM;;IAEE,+BAAgC;EvEssQxC;EuErtQM;IAAwB,wBAA2B;EvEwtQzD;EuEvtQM;;IAEE,4BAA+B;EvEytQvC;EuEvtQM;;IAEE,8BAAiC;EvEytQzC;EuEvtQM;;IAEE,+BAAkC;EvEytQ1C;EuEvtQM;;IAEE,6BAAgC;EvEytQxC;EuEntQE;IAAmB,uBAAuB;EvEstQ5C;EuErtQE;;IAEE,2BAA2B;EvEutQ/B;EuErtQE;;IAEE,6BAA6B;EvEutQjC;EuErtQE;;IAEE,8BAA8B;EvEutQlC;EuErtQE;;IAEE,4BAA4B;EvEutQhC;AACF;;AcjuQI;EyDlDI;IAAgC,oBAA4B;EvEwxQlE;EuEvxQM;;IAEE,wBAAoC;EvEyxQ5C;EuEvxQM;;IAEE,0BAAwC;EvEyxQhD;EuEvxQM;;IAEE,2BAA0C;EvEyxQlD;EuEvxQM;;IAEE,yBAAsC;EvEyxQ9C;EuExyQM;IAAgC,0BAA4B;EvE2yQlE;EuE1yQM;;IAEE,8BAAoC;EvE4yQ5C;EuE1yQM;;IAEE,gCAAwC;EvE4yQhD;EuE1yQM;;IAEE,iCAA0C;EvE4yQlD;EuE1yQM;;IAEE,+BAAsC;EvE4yQ9C;EuE3zQM;IAAgC,yBAA4B;EvE8zQlE;EuE7zQM;;IAEE,6BAAoC;EvE+zQ5C;EuE7zQM;;IAEE,+BAAwC;EvE+zQhD;EuE7zQM;;IAEE,gCAA0C;EvE+zQlD;EuE7zQM;;IAEE,8BAAsC;EvE+zQ9C;EuE90QM;IAAgC,uBAA4B;EvEi1QlE;EuEh1QM;;IAEE,2BAAoC;EvEk1Q5C;EuEh1QM;;IAEE,6BAAwC;EvEk1QhD;EuEh1QM;;IAEE,8BAA0C;EvEk1QlD;EuEh1QM;;IAEE,4BAAsC;EvEk1Q9C;EuEj2QM;IAAgC,yBAA4B;EvEo2QlE;EuEn2QM;;IAEE,6BAAoC;EvEq2Q5C;EuEn2QM;;IAEE,+BAAwC;EvEq2QhD;EuEn2QM;;IAEE,gCAA0C;EvEq2QlD;EuEn2QM;;IAEE,8BAAsC;EvEq2Q9C;EuEp3QM;IAAgC,uBAA4B;EvEu3QlE;EuEt3QM;;IAEE,2BAAoC;EvEw3Q5C;EuEt3QM;;IAEE,6BAAwC;EvEw3QhD;EuEt3QM;;IAEE,8BAA0C;EvEw3QlD;EuEt3QM;;IAEE,4BAAsC;EvEw3Q9C;EuEv4QM;IAAgC,qBAA4B;EvE04QlE;EuEz4QM;;IAEE,yBAAoC;EvE24Q5C;EuEz4QM;;IAEE,2BAAwC;EvE24QhD;EuEz4QM;;IAEE,4BAA0C;EvE24QlD;EuEz4QM;;IAEE,0BAAsC;EvE24Q9C;EuE15QM;IAAgC,2BAA4B;EvE65QlE;EuE55QM;;IAEE,+BAAoC;EvE85Q5C;EuE55QM;;IAEE,iCAAwC;EvE85QhD;EuE55QM;;IAEE,kCAA0C;EvE85QlD;EuE55QM;;IAEE,gCAAsC;EvE85Q9C;EuE76QM;IAAgC,0BAA4B;EvEg7QlE;EuE/6QM;;IAEE,8BAAoC;EvEi7Q5C;EuE/6QM;;IAEE,gCAAwC;EvEi7QhD;EuE/6QM;;IAEE,iCAA0C;EvEi7QlD;EuE/6QM;;IAEE,+BAAsC;EvEi7Q9C;EuEh8QM;IAAgC,wBAA4B;EvEm8QlE;EuEl8QM;;IAEE,4BAAoC;EvEo8Q5C;EuEl8QM;;IAEE,8BAAwC;EvEo8QhD;EuEl8QM;;IAEE,+BAA0C;EvEo8QlD;EuEl8QM;;IAEE,6BAAsC;EvEo8Q9C;EuEn9QM;IAAgC,0BAA4B;EvEs9QlE;EuEr9QM;;IAEE,8BAAoC;EvEu9Q5C;EuEr9QM;;IAEE,gCAAwC;EvEu9QhD;EuEr9QM;;IAEE,iCAA0C;EvEu9QlD;EuEr9QM;;IAEE,+BAAsC;EvEu9Q9C;EuEt+QM;IAAgC,wBAA4B;EvEy+QlE;EuEx+QM;;IAEE,4BAAoC;EvE0+Q5C;EuEx+QM;;IAEE,8BAAwC;EvE0+QhD;EuEx+QM;;IAEE,+BAA0C;EvE0+QlD;EuEx+QM;;IAEE,6BAAsC;EvE0+Q9C;EuEl+QM;IAAwB,2BAA2B;EvEq+QzD;EuEp+QM;;IAEE,+BAA+B;EvEs+QvC;EuEp+QM;;IAEE,iCAAiC;EvEs+QzC;EuEp+QM;;IAEE,kCAAkC;EvEs+Q1C;EuEp+QM;;IAEE,gCAAgC;EvEs+QxC;EuEr/QM;IAAwB,0BAA2B;EvEw/QzD;EuEv/QM;;IAEE,8BAA+B;EvEy/QvC;EuEv/QM;;IAEE,gCAAiC;EvEy/QzC;EuEv/QM;;IAEE,iCAAkC;EvEy/Q1C;EuEv/QM;;IAEE,+BAAgC;EvEy/QxC;EuExgRM;IAAwB,wBAA2B;EvE2gRzD;EuE1gRM;;IAEE,4BAA+B;EvE4gRvC;EuE1gRM;;IAEE,8BAAiC;EvE4gRzC;EuE1gRM;;IAEE,+BAAkC;EvE4gR1C;EuE1gRM;;IAEE,6BAAgC;EvE4gRxC;EuE3hRM;IAAwB,0BAA2B;EvE8hRzD;EuE7hRM;;IAEE,8BAA+B;EvE+hRvC;EuE7hRM;;IAEE,gCAAiC;EvE+hRzC;EuE7hRM;;IAEE,iCAAkC;EvE+hR1C;EuE7hRM;;IAEE,+BAAgC;EvE+hRxC;EuE9iRM;IAAwB,wBAA2B;EvEijRzD;EuEhjRM;;IAEE,4BAA+B;EvEkjRvC;EuEhjRM;;IAEE,8BAAiC;EvEkjRzC;EuEhjRM;;IAEE,+BAAkC;EvEkjR1C;EuEhjRM;;IAEE,6BAAgC;EvEkjRxC;EuE5iRE;IAAmB,uBAAuB;EvE+iR5C;EuE9iRE;;IAEE,2BAA2B;EvEgjR/B;EuE9iRE;;IAEE,6BAA6B;EvEgjRjC;EuE9iRE;;IAEE,8BAA8B;EvEgjRlC;EuE9iRE;;IAEE,4BAA4B;EvEgjRhC;AACF;;Ac1jRI;EyDlDI;IAAgC,oBAA4B;EvEinRlE;EuEhnRM;;IAEE,wBAAoC;EvEknR5C;EuEhnRM;;IAEE,0BAAwC;EvEknRhD;EuEhnRM;;IAEE,2BAA0C;EvEknRlD;EuEhnRM;;IAEE,yBAAsC;EvEknR9C;EuEjoRM;IAAgC,0BAA4B;EvEooRlE;EuEnoRM;;IAEE,8BAAoC;EvEqoR5C;EuEnoRM;;IAEE,gCAAwC;EvEqoRhD;EuEnoRM;;IAEE,iCAA0C;EvEqoRlD;EuEnoRM;;IAEE,+BAAsC;EvEqoR9C;EuEppRM;IAAgC,yBAA4B;EvEupRlE;EuEtpRM;;IAEE,6BAAoC;EvEwpR5C;EuEtpRM;;IAEE,+BAAwC;EvEwpRhD;EuEtpRM;;IAEE,gCAA0C;EvEwpRlD;EuEtpRM;;IAEE,8BAAsC;EvEwpR9C;EuEvqRM;IAAgC,uBAA4B;EvE0qRlE;EuEzqRM;;IAEE,2BAAoC;EvE2qR5C;EuEzqRM;;IAEE,6BAAwC;EvE2qRhD;EuEzqRM;;IAEE,8BAA0C;EvE2qRlD;EuEzqRM;;IAEE,4BAAsC;EvE2qR9C;EuE1rRM;IAAgC,yBAA4B;EvE6rRlE;EuE5rRM;;IAEE,6BAAoC;EvE8rR5C;EuE5rRM;;IAEE,+BAAwC;EvE8rRhD;EuE5rRM;;IAEE,gCAA0C;EvE8rRlD;EuE5rRM;;IAEE,8BAAsC;EvE8rR9C;EuE7sRM;IAAgC,uBAA4B;EvEgtRlE;EuE/sRM;;IAEE,2BAAoC;EvEitR5C;EuE/sRM;;IAEE,6BAAwC;EvEitRhD;EuE/sRM;;IAEE,8BAA0C;EvEitRlD;EuE/sRM;;IAEE,4BAAsC;EvEitR9C;EuEhuRM;IAAgC,qBAA4B;EvEmuRlE;EuEluRM;;IAEE,yBAAoC;EvEouR5C;EuEluRM;;IAEE,2BAAwC;EvEouRhD;EuEluRM;;IAEE,4BAA0C;EvEouRlD;EuEluRM;;IAEE,0BAAsC;EvEouR9C;EuEnvRM;IAAgC,2BAA4B;EvEsvRlE;EuErvRM;;IAEE,+BAAoC;EvEuvR5C;EuErvRM;;IAEE,iCAAwC;EvEuvRhD;EuErvRM;;IAEE,kCAA0C;EvEuvRlD;EuErvRM;;IAEE,gCAAsC;EvEuvR9C;EuEtwRM;IAAgC,0BAA4B;EvEywRlE;EuExwRM;;IAEE,8BAAoC;EvE0wR5C;EuExwRM;;IAEE,gCAAwC;EvE0wRhD;EuExwRM;;IAEE,iCAA0C;EvE0wRlD;EuExwRM;;IAEE,+BAAsC;EvE0wR9C;EuEzxRM;IAAgC,wBAA4B;EvE4xRlE;EuE3xRM;;IAEE,4BAAoC;EvE6xR5C;EuE3xRM;;IAEE,8BAAwC;EvE6xRhD;EuE3xRM;;IAEE,+BAA0C;EvE6xRlD;EuE3xRM;;IAEE,6BAAsC;EvE6xR9C;EuE5yRM;IAAgC,0BAA4B;EvE+yRlE;EuE9yRM;;IAEE,8BAAoC;EvEgzR5C;EuE9yRM;;IAEE,gCAAwC;EvEgzRhD;EuE9yRM;;IAEE,iCAA0C;EvEgzRlD;EuE9yRM;;IAEE,+BAAsC;EvEgzR9C;EuE/zRM;IAAgC,wBAA4B;EvEk0RlE;EuEj0RM;;IAEE,4BAAoC;EvEm0R5C;EuEj0RM;;IAEE,8BAAwC;EvEm0RhD;EuEj0RM;;IAEE,+BAA0C;EvEm0RlD;EuEj0RM;;IAEE,6BAAsC;EvEm0R9C;EuE3zRM;IAAwB,2BAA2B;EvE8zRzD;EuE7zRM;;IAEE,+BAA+B;EvE+zRvC;EuE7zRM;;IAEE,iCAAiC;EvE+zRzC;EuE7zRM;;IAEE,kCAAkC;EvE+zR1C;EuE7zRM;;IAEE,gCAAgC;EvE+zRxC;EuE90RM;IAAwB,0BAA2B;EvEi1RzD;EuEh1RM;;IAEE,8BAA+B;EvEk1RvC;EuEh1RM;;IAEE,gCAAiC;EvEk1RzC;EuEh1RM;;IAEE,iCAAkC;EvEk1R1C;EuEh1RM;;IAEE,+BAAgC;EvEk1RxC;EuEj2RM;IAAwB,wBAA2B;EvEo2RzD;EuEn2RM;;IAEE,4BAA+B;EvEq2RvC;EuEn2RM;;IAEE,8BAAiC;EvEq2RzC;EuEn2RM;;IAEE,+BAAkC;EvEq2R1C;EuEn2RM;;IAEE,6BAAgC;EvEq2RxC;EuEp3RM;IAAwB,0BAA2B;EvEu3RzD;EuEt3RM;;IAEE,8BAA+B;EvEw3RvC;EuEt3RM;;IAEE,gCAAiC;EvEw3RzC;EuEt3RM;;IAEE,iCAAkC;EvEw3R1C;EuEt3RM;;IAEE,+BAAgC;EvEw3RxC;EuEv4RM;IAAwB,wBAA2B;EvE04RzD;EuEz4RM;;IAEE,4BAA+B;EvE24RvC;EuEz4RM;;IAEE,8BAAiC;EvE24RzC;EuEz4RM;;IAEE,+BAAkC;EvE24R1C;EuEz4RM;;IAEE,6BAAgC;EvE24RxC;EuEr4RE;IAAmB,uBAAuB;EvEw4R5C;EuEv4RE;;IAEE,2BAA2B;EvEy4R/B;EuEv4RE;;IAEE,6BAA6B;EvEy4RjC;EuEv4RE;;IAEE,8BAA8B;EvEy4RlC;EuEv4RE;;IAEE,4BAA4B;EvEy4RhC;AACF;;AwEz8RA;EAAkB,4GAA8C;AxE68RhE;;AwEz8RA;EAAiB,8BAA8B;AxE68R/C;;AwE58RA;EAAiB,8BAA8B;AxEg9R/C;;AwE/8RA;EAAiB,8BAA8B;AxEm9R/C;;AwEl9RA;ECTE,gBAAgB;EAChB,uBAAuB;EACvB,mBAAmB;AzE+9RrB;;AwEh9RI;EAAwB,2BAA2B;AxEo9RvD;;AwEn9RI;EAAwB,4BAA4B;AxEu9RxD;;AwEt9RI;EAAwB,6BAA6B;AxE09RzD;;Acr7RI;E0DvCA;IAAwB,2BAA2B;ExEi+RrD;EwEh+RE;IAAwB,4BAA4B;ExEm+RtD;EwEl+RE;IAAwB,6BAA6B;ExEq+RvD;AACF;;Acj8RI;E0DvCA;IAAwB,2BAA2B;ExE6+RrD;EwE5+RE;IAAwB,4BAA4B;ExE++RtD;EwE9+RE;IAAwB,6BAA6B;ExEi/RvD;AACF;;Ac78RI;E0DvCA;IAAwB,2BAA2B;ExEy/RrD;EwEx/RE;IAAwB,4BAA4B;ExE2/RtD;EwE1/RE;IAAwB,6BAA6B;ExE6/RvD;AACF;;Acz9RI;E0DvCA;IAAwB,2BAA2B;ExEqgSrD;EwEpgSE;IAAwB,4BAA4B;ExEugStD;EwEtgSE;IAAwB,6BAA6B;ExEygSvD;AACF;;AwEpgSA;EAAmB,oCAAoC;AxEwgSvD;;AwEvgSA;EAAmB,oCAAoC;AxE2gSvD;;AwE1gSA;EAAmB,qCAAqC;AxE8gSxD;;AwE1gSA;EAAuB,2BAA0C;AxE8gSjE;;AwE7gSA;EAAuB,+BAA4C;AxEihSnE;;AwEhhSA;EAAuB,2BAA2C;AxEohSlE;;AwEnhSA;EAAuB,2BAAyC;AxEuhShE;;AwEthSA;EAAuB,8BAA2C;AxE0hSlE;;AwEzhSA;EAAuB,6BAA6B;AxE6hSpD;;AwEzhSA;EAAc,sBAAwB;AxE6hStC;;A0EpkSE;EACE,yBAAwB;A1EukS5B;;AK7jSE;EqELM,yBAA0E;A1EskSlF;;A0E5kSE;EACE,yBAAwB;A1E+kS5B;;AKrkSE;EqELM,yBAA0E;A1E8kSlF;;A0EplSE;EACE,yBAAwB;A1EulS5B;;AK7kSE;EqELM,yBAA0E;A1EslSlF;;A0E5lSE;EACE,yBAAwB;A1E+lS5B;;AKrlSE;EqELM,yBAA0E;A1E8lSlF;;A0EpmSE;EACE,yBAAwB;A1EumS5B;;AK7lSE;EqELM,yBAA0E;A1EsmSlF;;A0E5mSE;EACE,yBAAwB;A1E+mS5B;;AKrmSE;EqELM,yBAA0E;A1E8mSlF;;A0EpnSE;EACE,yBAAwB;A1EunS5B;;AK7mSE;EqELM,yBAA0E;A1EsnSlF;;A0E5nSE;EACE,yBAAwB;A1E+nS5B;;AKrnSE;EqELM,yBAA0E;A1E8nSlF;;AwEvlSA;EAAa,yBAA6B;AxE2lS1C;;AwE1lSA;EAAc,yBAA6B;AxE8lS3C;;AwE5lSA;EAAiB,oCAAkC;AxEgmSnD;;AwE/lSA;EAAiB,0CAAkC;AxEmmSnD;;AwE/lSA;EGvDE,WAAW;EACX,kBAAkB;EAClB,iBAAiB;EACjB,6BAA6B;EAC7B,SAAS;A3E0pSX;;AwEnmSA;EAAwB,gCAAgC;AxEumSxD;;AwErmSA;EACE,iCAAiC;EACjC,oCAAoC;AxEwmStC;;AwEnmSA;EAAc,yBAAyB;AxEumSvC;;A4ExqSA;EACE,8BAA8B;A5E2qShC;;A4ExqSA;EACE,6BAA6B;A5E2qS/B;;A6E3qSE;E3EOF;;;I2EDM,4BAA4B;IAE5B,2BAA2B;E7E2qS/B;E6ExqSE;IAEI,0BAA0B;E7EyqShC;E6EhqSE;IACE,6BAA6B;E7EkqSjC;EEn+RF;I2EhLM,gCAAgC;E7EspSpC;E6EppSE;;IAEE,yB1EzCY;I0E0CZ,wBAAwB;E7EspS5B;E6E9oSE;IACE,2BAA2B;E7EgpS/B;E6E7oSE;;IAEE,wBAAwB;E7E+oS5B;E6E5oSE;;;IAGE,UAAU;IACV,SAAS;E7E8oSb;E6E3oSE;;IAEE,uBAAuB;E7E6oS3B;E6EroSE;IACE,Q1EwgCgC;EH+nQpC;EEnrSF;I2E+CM,2BAA2C;E7EuoS/C;EY9tSA;IiE0FI,2BAA2C;E7EuoS/C;EiCrtSF;I4CmFM,aAAa;E7EqoSjB;EsCpuSF;IuCkGM,sB1EtFS;EH2tSb;EgBxuSF;I6DuGM,oCAAoC;E7EooSxC;E6EroSE;;IAKI,iCAAmC;E7EooSzC;EgBvsSF;;I6D0EQ,oCAAsC;E7EioS5C;EgBtnSF;I6DNM,cAAc;E7E+nSlB;EiBrvSA;;;;I4D4HM,qB1EvHU;EHsvShB;EgBjpSF;I6DuBM,cAAc;IACd,qB1E7HY;EH0vShB;AACF","file":"bootstrap.css","sourcesContent":["/*!\n * Bootstrap v4.3.1 (https://getbootstrap.com/)\n * Copyright 2011-2019 The Bootstrap Authors\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"root\";\n@import \"reboot\";\n@import \"type\";\n@import \"images\";\n@import \"code\";\n@import \"grid\";\n@import \"tables\";\n@import \"forms\";\n@import \"buttons\";\n@import \"transitions\";\n@import \"dropdown\";\n@import \"button-group\";\n@import \"input-group\";\n@import \"custom-forms\";\n@import \"nav\";\n@import \"navbar\";\n@import \"card\";\n@import \"breadcrumb\";\n@import \"pagination\";\n@import \"badge\";\n@import \"jumbotron\";\n@import \"alert\";\n@import \"progress\";\n@import \"media\";\n@import \"list-group\";\n@import \"close\";\n@import \"toasts\";\n@import \"modal\";\n@import \"tooltip\";\n@import \"popover\";\n@import \"carousel\";\n@import \"spinners\";\n@import \"utilities\";\n@import \"print\";\n","/*!\n * Bootstrap v4.3.1 (https://getbootstrap.com/)\n * Copyright 2011-2019 The Bootstrap Authors\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n:root {\n --blue: #007bff;\n --indigo: #6610f2;\n --purple: #6f42c1;\n --pink: #e83e8c;\n --red: #dc3545;\n --orange: #fd7e14;\n --yellow: #ffc107;\n --green: #28a745;\n --teal: #20c997;\n --cyan: #17a2b8;\n --white: #fff;\n --gray: #6c757d;\n --gray-dark: #343a40;\n --primary: #007bff;\n --secondary: #6c757d;\n --success: #28a745;\n --info: #17a2b8;\n --warning: #ffc107;\n --danger: #dc3545;\n --light: #f8f9fa;\n --dark: #343a40;\n --breakpoint-xs: 0;\n --breakpoint-sm: 576px;\n --breakpoint-md: 768px;\n --breakpoint-lg: 992px;\n --breakpoint-xl: 1200px;\n --font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):focus {\n outline: 0;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\nselect {\n word-wrap: normal;\n}\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton:not(:disabled),\n[type=\"button\"]:not(:disabled),\n[type=\"reset\"]:not(:disabled),\n[type=\"submit\"]:not(:disabled) {\n cursor: pointer;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: 0.5rem;\n font-weight: 500;\n line-height: 1.2;\n}\n\nh1, .h1 {\n font-size: 2.5rem;\n}\n\nh2, .h2 {\n font-size: 2rem;\n}\n\nh3, .h3 {\n font-size: 1.75rem;\n}\n\nh4, .h4 {\n font-size: 1.5rem;\n}\n\nh5, .h5 {\n font-size: 1.25rem;\n}\n\nh6, .h6 {\n font-size: 1rem;\n}\n\n.lead {\n font-size: 1.25rem;\n font-weight: 300;\n}\n\n.display-1 {\n font-size: 6rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-2 {\n font-size: 5.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-3 {\n font-size: 4.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\n.display-4 {\n font-size: 3.5rem;\n font-weight: 300;\n line-height: 1.2;\n}\n\nhr {\n margin-top: 1rem;\n margin-bottom: 1rem;\n border: 0;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\nsmall,\n.small {\n font-size: 80%;\n font-weight: 400;\n}\n\nmark,\n.mark {\n padding: 0.2em;\n background-color: #fcf8e3;\n}\n\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline-item {\n display: inline-block;\n}\n\n.list-inline-item:not(:last-child) {\n margin-right: 0.5rem;\n}\n\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n.blockquote {\n margin-bottom: 1rem;\n font-size: 1.25rem;\n}\n\n.blockquote-footer {\n display: block;\n font-size: 80%;\n color: #6c757d;\n}\n\n.blockquote-footer::before {\n content: \"\\2014\\00A0\";\n}\n\n.img-fluid {\n max-width: 100%;\n height: auto;\n}\n\n.img-thumbnail {\n padding: 0.25rem;\n background-color: #fff;\n border: 1px solid #dee2e6;\n border-radius: 0.25rem;\n max-width: 100%;\n height: auto;\n}\n\n.figure {\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: 0.5rem;\n line-height: 1;\n}\n\n.figure-caption {\n font-size: 90%;\n color: #6c757d;\n}\n\ncode {\n font-size: 87.5%;\n color: #e83e8c;\n word-break: break-word;\n}\n\na > code {\n color: inherit;\n}\n\nkbd {\n padding: 0.2rem 0.4rem;\n font-size: 87.5%;\n color: #fff;\n background-color: #212529;\n border-radius: 0.2rem;\n}\n\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n}\n\npre {\n display: block;\n font-size: 87.5%;\n color: #212529;\n}\n\npre code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n}\n\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n\n.container {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container {\n max-width: 540px;\n }\n}\n\n@media (min-width: 768px) {\n .container {\n max-width: 720px;\n }\n}\n\n@media (min-width: 992px) {\n .container {\n max-width: 960px;\n }\n}\n\n@media (min-width: 1200px) {\n .container {\n max-width: 1140px;\n }\n}\n\n.container-fluid {\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n.row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n\n.no-gutters > .col,\n.no-gutters > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n\n.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,\n.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,\n.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,\n.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,\n.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,\n.col-xl-auto {\n position: relative;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n.col {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n}\n\n.col-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n}\n\n.col-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n}\n\n.col-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n}\n\n.col-3 {\n flex: 0 0 25%;\n max-width: 25%;\n}\n\n.col-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n}\n\n.col-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n}\n\n.col-6 {\n flex: 0 0 50%;\n max-width: 50%;\n}\n\n.col-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n}\n\n.col-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n}\n\n.col-9 {\n flex: 0 0 75%;\n max-width: 75%;\n}\n\n.col-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n}\n\n.col-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n}\n\n.col-12 {\n flex: 0 0 100%;\n max-width: 100%;\n}\n\n.order-first {\n order: -1;\n}\n\n.order-last {\n order: 13;\n}\n\n.order-0 {\n order: 0;\n}\n\n.order-1 {\n order: 1;\n}\n\n.order-2 {\n order: 2;\n}\n\n.order-3 {\n order: 3;\n}\n\n.order-4 {\n order: 4;\n}\n\n.order-5 {\n order: 5;\n}\n\n.order-6 {\n order: 6;\n}\n\n.order-7 {\n order: 7;\n}\n\n.order-8 {\n order: 8;\n}\n\n.order-9 {\n order: 9;\n}\n\n.order-10 {\n order: 10;\n}\n\n.order-11 {\n order: 11;\n}\n\n.order-12 {\n order: 12;\n}\n\n.offset-1 {\n margin-left: 8.333333%;\n}\n\n.offset-2 {\n margin-left: 16.666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.333333%;\n}\n\n.offset-5 {\n margin-left: 41.666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.333333%;\n}\n\n.offset-8 {\n margin-left: 66.666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.333333%;\n}\n\n.offset-11 {\n margin-left: 91.666667%;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-sm-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-sm-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-sm-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-sm-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-sm-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-sm-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-sm-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-sm-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-sm-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-sm-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-sm-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-sm-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-sm-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-sm-first {\n order: -1;\n }\n .order-sm-last {\n order: 13;\n }\n .order-sm-0 {\n order: 0;\n }\n .order-sm-1 {\n order: 1;\n }\n .order-sm-2 {\n order: 2;\n }\n .order-sm-3 {\n order: 3;\n }\n .order-sm-4 {\n order: 4;\n }\n .order-sm-5 {\n order: 5;\n }\n .order-sm-6 {\n order: 6;\n }\n .order-sm-7 {\n order: 7;\n }\n .order-sm-8 {\n order: 8;\n }\n .order-sm-9 {\n order: 9;\n }\n .order-sm-10 {\n order: 10;\n }\n .order-sm-11 {\n order: 11;\n }\n .order-sm-12 {\n order: 12;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.333333%;\n }\n .offset-sm-2 {\n margin-left: 16.666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.333333%;\n }\n .offset-sm-5 {\n margin-left: 41.666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.333333%;\n }\n .offset-sm-8 {\n margin-left: 66.666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.333333%;\n }\n .offset-sm-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 768px) {\n .col-md {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-md-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-md-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-md-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-md-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-md-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-md-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-md-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-md-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-md-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-md-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-md-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-md-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-md-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-md-first {\n order: -1;\n }\n .order-md-last {\n order: 13;\n }\n .order-md-0 {\n order: 0;\n }\n .order-md-1 {\n order: 1;\n }\n .order-md-2 {\n order: 2;\n }\n .order-md-3 {\n order: 3;\n }\n .order-md-4 {\n order: 4;\n }\n .order-md-5 {\n order: 5;\n }\n .order-md-6 {\n order: 6;\n }\n .order-md-7 {\n order: 7;\n }\n .order-md-8 {\n order: 8;\n }\n .order-md-9 {\n order: 9;\n }\n .order-md-10 {\n order: 10;\n }\n .order-md-11 {\n order: 11;\n }\n .order-md-12 {\n order: 12;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.333333%;\n }\n .offset-md-2 {\n margin-left: 16.666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.333333%;\n }\n .offset-md-5 {\n margin-left: 41.666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.333333%;\n }\n .offset-md-8 {\n margin-left: 66.666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.333333%;\n }\n .offset-md-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 992px) {\n .col-lg {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-lg-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-lg-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-lg-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-lg-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-lg-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-lg-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-lg-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-lg-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-lg-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-lg-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-lg-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-lg-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-lg-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-lg-first {\n order: -1;\n }\n .order-lg-last {\n order: 13;\n }\n .order-lg-0 {\n order: 0;\n }\n .order-lg-1 {\n order: 1;\n }\n .order-lg-2 {\n order: 2;\n }\n .order-lg-3 {\n order: 3;\n }\n .order-lg-4 {\n order: 4;\n }\n .order-lg-5 {\n order: 5;\n }\n .order-lg-6 {\n order: 6;\n }\n .order-lg-7 {\n order: 7;\n }\n .order-lg-8 {\n order: 8;\n }\n .order-lg-9 {\n order: 9;\n }\n .order-lg-10 {\n order: 10;\n }\n .order-lg-11 {\n order: 11;\n }\n .order-lg-12 {\n order: 12;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.333333%;\n }\n .offset-lg-2 {\n margin-left: 16.666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.333333%;\n }\n .offset-lg-5 {\n margin-left: 41.666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.333333%;\n }\n .offset-lg-8 {\n margin-left: 66.666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.333333%;\n }\n .offset-lg-11 {\n margin-left: 91.666667%;\n }\n}\n\n@media (min-width: 1200px) {\n .col-xl {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col-xl-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%;\n }\n .col-xl-1 {\n flex: 0 0 8.333333%;\n max-width: 8.333333%;\n }\n .col-xl-2 {\n flex: 0 0 16.666667%;\n max-width: 16.666667%;\n }\n .col-xl-3 {\n flex: 0 0 25%;\n max-width: 25%;\n }\n .col-xl-4 {\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n .col-xl-5 {\n flex: 0 0 41.666667%;\n max-width: 41.666667%;\n }\n .col-xl-6 {\n flex: 0 0 50%;\n max-width: 50%;\n }\n .col-xl-7 {\n flex: 0 0 58.333333%;\n max-width: 58.333333%;\n }\n .col-xl-8 {\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n .col-xl-9 {\n flex: 0 0 75%;\n max-width: 75%;\n }\n .col-xl-10 {\n flex: 0 0 83.333333%;\n max-width: 83.333333%;\n }\n .col-xl-11 {\n flex: 0 0 91.666667%;\n max-width: 91.666667%;\n }\n .col-xl-12 {\n flex: 0 0 100%;\n max-width: 100%;\n }\n .order-xl-first {\n order: -1;\n }\n .order-xl-last {\n order: 13;\n }\n .order-xl-0 {\n order: 0;\n }\n .order-xl-1 {\n order: 1;\n }\n .order-xl-2 {\n order: 2;\n }\n .order-xl-3 {\n order: 3;\n }\n .order-xl-4 {\n order: 4;\n }\n .order-xl-5 {\n order: 5;\n }\n .order-xl-6 {\n order: 6;\n }\n .order-xl-7 {\n order: 7;\n }\n .order-xl-8 {\n order: 8;\n }\n .order-xl-9 {\n order: 9;\n }\n .order-xl-10 {\n order: 10;\n }\n .order-xl-11 {\n order: 11;\n }\n .order-xl-12 {\n order: 12;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.333333%;\n }\n .offset-xl-2 {\n margin-left: 16.666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.333333%;\n }\n .offset-xl-5 {\n margin-left: 41.666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.333333%;\n }\n .offset-xl-8 {\n margin-left: 66.666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.333333%;\n }\n .offset-xl-11 {\n margin-left: 91.666667%;\n }\n}\n\n.table {\n width: 100%;\n margin-bottom: 1rem;\n color: #212529;\n}\n\n.table th,\n.table td {\n padding: 0.75rem;\n vertical-align: top;\n border-top: 1px solid #dee2e6;\n}\n\n.table thead th {\n vertical-align: bottom;\n border-bottom: 2px solid #dee2e6;\n}\n\n.table tbody + tbody {\n border-top: 2px solid #dee2e6;\n}\n\n.table-sm th,\n.table-sm td {\n padding: 0.3rem;\n}\n\n.table-bordered {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered th,\n.table-bordered td {\n border: 1px solid #dee2e6;\n}\n\n.table-bordered thead th,\n.table-bordered thead td {\n border-bottom-width: 2px;\n}\n\n.table-borderless th,\n.table-borderless td,\n.table-borderless thead th,\n.table-borderless tbody + tbody {\n border: 0;\n}\n\n.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n.table-hover tbody tr:hover {\n color: #212529;\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-primary,\n.table-primary > th,\n.table-primary > td {\n background-color: #b8daff;\n}\n\n.table-primary th,\n.table-primary td,\n.table-primary thead th,\n.table-primary tbody + tbody {\n border-color: #7abaff;\n}\n\n.table-hover .table-primary:hover {\n background-color: #9fcdff;\n}\n\n.table-hover .table-primary:hover > td,\n.table-hover .table-primary:hover > th {\n background-color: #9fcdff;\n}\n\n.table-secondary,\n.table-secondary > th,\n.table-secondary > td {\n background-color: #d6d8db;\n}\n\n.table-secondary th,\n.table-secondary td,\n.table-secondary thead th,\n.table-secondary tbody + tbody {\n border-color: #b3b7bb;\n}\n\n.table-hover .table-secondary:hover {\n background-color: #c8cbcf;\n}\n\n.table-hover .table-secondary:hover > td,\n.table-hover .table-secondary:hover > th {\n background-color: #c8cbcf;\n}\n\n.table-success,\n.table-success > th,\n.table-success > td {\n background-color: #c3e6cb;\n}\n\n.table-success th,\n.table-success td,\n.table-success thead th,\n.table-success tbody + tbody {\n border-color: #8fd19e;\n}\n\n.table-hover .table-success:hover {\n background-color: #b1dfbb;\n}\n\n.table-hover .table-success:hover > td,\n.table-hover .table-success:hover > th {\n background-color: #b1dfbb;\n}\n\n.table-info,\n.table-info > th,\n.table-info > td {\n background-color: #bee5eb;\n}\n\n.table-info th,\n.table-info td,\n.table-info thead th,\n.table-info tbody + tbody {\n border-color: #86cfda;\n}\n\n.table-hover .table-info:hover {\n background-color: #abdde5;\n}\n\n.table-hover .table-info:hover > td,\n.table-hover .table-info:hover > th {\n background-color: #abdde5;\n}\n\n.table-warning,\n.table-warning > th,\n.table-warning > td {\n background-color: #ffeeba;\n}\n\n.table-warning th,\n.table-warning td,\n.table-warning thead th,\n.table-warning tbody + tbody {\n border-color: #ffdf7e;\n}\n\n.table-hover .table-warning:hover {\n background-color: #ffe8a1;\n}\n\n.table-hover .table-warning:hover > td,\n.table-hover .table-warning:hover > th {\n background-color: #ffe8a1;\n}\n\n.table-danger,\n.table-danger > th,\n.table-danger > td {\n background-color: #f5c6cb;\n}\n\n.table-danger th,\n.table-danger td,\n.table-danger thead th,\n.table-danger tbody + tbody {\n border-color: #ed969e;\n}\n\n.table-hover .table-danger:hover {\n background-color: #f1b0b7;\n}\n\n.table-hover .table-danger:hover > td,\n.table-hover .table-danger:hover > th {\n background-color: #f1b0b7;\n}\n\n.table-light,\n.table-light > th,\n.table-light > td {\n background-color: #fdfdfe;\n}\n\n.table-light th,\n.table-light td,\n.table-light thead th,\n.table-light tbody + tbody {\n border-color: #fbfcfc;\n}\n\n.table-hover .table-light:hover {\n background-color: #ececf6;\n}\n\n.table-hover .table-light:hover > td,\n.table-hover .table-light:hover > th {\n background-color: #ececf6;\n}\n\n.table-dark,\n.table-dark > th,\n.table-dark > td {\n background-color: #c6c8ca;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th,\n.table-dark tbody + tbody {\n border-color: #95999c;\n}\n\n.table-hover .table-dark:hover {\n background-color: #b9bbbe;\n}\n\n.table-hover .table-dark:hover > td,\n.table-hover .table-dark:hover > th {\n background-color: #b9bbbe;\n}\n\n.table-active,\n.table-active > th,\n.table-active > td {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table-hover .table-active:hover > td,\n.table-hover .table-active:hover > th {\n background-color: rgba(0, 0, 0, 0.075);\n}\n\n.table .thead-dark th {\n color: #fff;\n background-color: #343a40;\n border-color: #454d55;\n}\n\n.table .thead-light th {\n color: #495057;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.table-dark {\n color: #fff;\n background-color: #343a40;\n}\n\n.table-dark th,\n.table-dark td,\n.table-dark thead th {\n border-color: #454d55;\n}\n\n.table-dark.table-bordered {\n border: 0;\n}\n\n.table-dark.table-striped tbody tr:nth-of-type(odd) {\n background-color: rgba(255, 255, 255, 0.05);\n}\n\n.table-dark.table-hover tbody tr:hover {\n color: #fff;\n background-color: rgba(255, 255, 255, 0.075);\n}\n\n@media (max-width: 575.98px) {\n .table-responsive-sm {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-sm > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 767.98px) {\n .table-responsive-md {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-md > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 991.98px) {\n .table-responsive-lg {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-lg > .table-bordered {\n border: 0;\n }\n}\n\n@media (max-width: 1199.98px) {\n .table-responsive-xl {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n .table-responsive-xl > .table-bordered {\n border: 0;\n }\n}\n\n.table-responsive {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.table-responsive > .table-bordered {\n border: 0;\n}\n\n.form-control {\n display: block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .form-control {\n transition: none;\n }\n}\n\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n\n.form-control:focus {\n color: #495057;\n background-color: #fff;\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.form-control::placeholder {\n color: #6c757d;\n opacity: 1;\n}\n\n.form-control:disabled, .form-control[readonly] {\n background-color: #e9ecef;\n opacity: 1;\n}\n\nselect.form-control:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n.col-form-label {\n padding-top: calc(0.375rem + 1px);\n padding-bottom: calc(0.375rem + 1px);\n margin-bottom: 0;\n font-size: inherit;\n line-height: 1.5;\n}\n\n.col-form-label-lg {\n padding-top: calc(0.5rem + 1px);\n padding-bottom: calc(0.5rem + 1px);\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.col-form-label-sm {\n padding-top: calc(0.25rem + 1px);\n padding-bottom: calc(0.25rem + 1px);\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n margin-bottom: 0;\n line-height: 1.5;\n color: #212529;\n background-color: transparent;\n border: solid transparent;\n border-width: 1px 0;\n}\n\n.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg {\n padding-right: 0;\n padding-left: 0;\n}\n\n.form-control-sm {\n height: calc(1.5em + 0.5rem + 2px);\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.form-control-lg {\n height: calc(1.5em + 1rem + 2px);\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\nselect.form-control[size], select.form-control[multiple] {\n height: auto;\n}\n\ntextarea.form-control {\n height: auto;\n}\n\n.form-group {\n margin-bottom: 1rem;\n}\n\n.form-text {\n display: block;\n margin-top: 0.25rem;\n}\n\n.form-row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -5px;\n margin-left: -5px;\n}\n\n.form-row > .col,\n.form-row > [class*=\"col-\"] {\n padding-right: 5px;\n padding-left: 5px;\n}\n\n.form-check {\n position: relative;\n display: block;\n padding-left: 1.25rem;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: 0.3rem;\n margin-left: -1.25rem;\n}\n\n.form-check-input:disabled ~ .form-check-label {\n color: #6c757d;\n}\n\n.form-check-label {\n margin-bottom: 0;\n}\n\n.form-check-inline {\n display: inline-flex;\n align-items: center;\n padding-left: 0;\n margin-right: 0.75rem;\n}\n\n.form-check-inline .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: 0.3125rem;\n margin-left: 0;\n}\n\n.valid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #28a745;\n}\n\n.valid-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(40, 167, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid {\n border-color: #28a745;\n padding-right: calc(1.5em + 0.75rem);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.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\");\n background-repeat: no-repeat;\n background-position: center right calc(0.375em + 0.1875rem);\n background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .form-control:valid ~ .valid-feedback,\n.was-validated .form-control:valid ~ .valid-tooltip, .form-control.is-valid ~ .valid-feedback,\n.form-control.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated textarea.form-control:valid, textarea.form-control.is-valid {\n padding-right: calc(1.5em + 0.75rem);\n background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .custom-select:valid, .custom-select.is-valid {\n border-color: #28a745;\n padding-right: calc((1em + 0.75rem) * 3 / 4 + 1.75rem);\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px, url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.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\") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .custom-select:valid:focus, .custom-select.is-valid:focus {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .custom-select:valid ~ .valid-feedback,\n.was-validated .custom-select:valid ~ .valid-tooltip, .custom-select.is-valid ~ .valid-feedback,\n.custom-select.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .form-control-file:valid ~ .valid-feedback,\n.was-validated .form-control-file:valid ~ .valid-tooltip, .form-control-file.is-valid ~ .valid-feedback,\n.form-control-file.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n color: #28a745;\n}\n\n.was-validated .form-check-input:valid ~ .valid-feedback,\n.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback,\n.form-check-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label {\n color: #28a745;\n}\n\n.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-control-input:valid ~ .valid-feedback,\n.was-validated .custom-control-input:valid ~ .valid-tooltip, .custom-control-input.is-valid ~ .valid-feedback,\n.custom-control-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before {\n border-color: #34ce57;\n background-color: #34ce57;\n}\n\n.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.was-validated .custom-control-input:valid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-valid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label {\n border-color: #28a745;\n}\n\n.was-validated .custom-file-input:valid ~ .valid-feedback,\n.was-validated .custom-file-input:valid ~ .valid-tooltip, .custom-file-input.is-valid ~ .valid-feedback,\n.custom-file-input.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label {\n border-color: #28a745;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);\n}\n\n.invalid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 80%;\n color: #dc3545;\n}\n\n.invalid-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: .1rem;\n font-size: 0.875rem;\n line-height: 1.5;\n color: #fff;\n background-color: rgba(220, 53, 69, 0.9);\n border-radius: 0.25rem;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid {\n border-color: #dc3545;\n padding-right: calc(1.5em + 0.75rem);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E\");\n background-repeat: no-repeat;\n background-position: center right calc(0.375em + 0.1875rem);\n background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .form-control:invalid ~ .invalid-feedback,\n.was-validated .form-control:invalid ~ .invalid-tooltip, .form-control.is-invalid ~ .invalid-feedback,\n.form-control.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid {\n padding-right: calc(1.5em + 0.75rem);\n background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .custom-select:invalid, .custom-select.is-invalid {\n border-color: #dc3545;\n padding-right: calc((1em + 0.75rem) * 3 / 4 + 1.75rem);\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px, url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E\") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n\n.was-validated .custom-select:invalid:focus, .custom-select.is-invalid:focus {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .custom-select:invalid ~ .invalid-feedback,\n.was-validated .custom-select:invalid ~ .invalid-tooltip, .custom-select.is-invalid ~ .invalid-feedback,\n.custom-select.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .form-control-file:invalid ~ .invalid-feedback,\n.was-validated .form-control-file:invalid ~ .invalid-tooltip, .form-control-file.is-invalid ~ .invalid-feedback,\n.form-control-file.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n color: #dc3545;\n}\n\n.was-validated .form-check-input:invalid ~ .invalid-feedback,\n.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback,\n.form-check-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label {\n color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-control-input:invalid ~ .invalid-feedback,\n.was-validated .custom-control-input:invalid ~ .invalid-tooltip, .custom-control-input.is-invalid ~ .invalid-feedback,\n.custom-control-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before {\n border-color: #e4606d;\n background-color: #e4606d;\n}\n\n.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .custom-control-input:invalid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-invalid:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label {\n border-color: #dc3545;\n}\n\n.was-validated .custom-file-input:invalid ~ .invalid-feedback,\n.was-validated .custom-file-input:invalid ~ .invalid-tooltip, .custom-file-input.is-invalid ~ .invalid-feedback,\n.custom-file-input.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label {\n border-color: #dc3545;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);\n}\n\n.form-inline {\n display: flex;\n flex-flow: row wrap;\n align-items: center;\n}\n\n.form-inline .form-check {\n width: 100%;\n}\n\n@media (min-width: 576px) {\n .form-inline label {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 0;\n }\n .form-inline .form-group {\n display: flex;\n flex: 0 0 auto;\n flex-flow: row wrap;\n align-items: center;\n margin-bottom: 0;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-plaintext {\n display: inline-block;\n }\n .form-inline .input-group,\n .form-inline .custom-select {\n width: auto;\n }\n .form-inline .form-check {\n display: flex;\n align-items: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-inline .form-check-input {\n position: relative;\n flex-shrink: 0;\n margin-top: 0;\n margin-right: 0.25rem;\n margin-left: 0;\n }\n .form-inline .custom-control {\n align-items: center;\n justify-content: center;\n }\n .form-inline .custom-control-label {\n margin-bottom: 0;\n }\n}\n\n.btn {\n display: inline-block;\n font-weight: 400;\n color: #212529;\n text-align: center;\n vertical-align: middle;\n user-select: none;\n background-color: transparent;\n border: 1px solid transparent;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n line-height: 1.5;\n border-radius: 0.25rem;\n 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;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .btn {\n transition: none;\n }\n}\n\n.btn:hover {\n color: #212529;\n text-decoration: none;\n}\n\n.btn:focus, .btn.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.btn.disabled, .btn:disabled {\n opacity: 0.65;\n}\n\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n.btn-primary {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:hover {\n color: #fff;\n background-color: #0069d9;\n border-color: #0062cc;\n}\n\n.btn-primary:focus, .btn-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-primary.disabled, .btn-primary:disabled {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active,\n.show > .btn-primary.dropdown-toggle {\n color: #fff;\n background-color: #0062cc;\n border-color: #005cbf;\n}\n\n.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5);\n}\n\n.btn-secondary {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:hover {\n color: #fff;\n background-color: #5a6268;\n border-color: #545b62;\n}\n\n.btn-secondary:focus, .btn-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-secondary.disabled, .btn-secondary:disabled {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-secondary.dropdown-toggle {\n color: #fff;\n background-color: #545b62;\n border-color: #4e555b;\n}\n\n.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5);\n}\n\n.btn-success {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:hover {\n color: #fff;\n background-color: #218838;\n border-color: #1e7e34;\n}\n\n.btn-success:focus, .btn-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-success.disabled, .btn-success:disabled {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active,\n.show > .btn-success.dropdown-toggle {\n color: #fff;\n background-color: #1e7e34;\n border-color: #1c7430;\n}\n\n.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5);\n}\n\n.btn-info {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:hover {\n color: #fff;\n background-color: #138496;\n border-color: #117a8b;\n}\n\n.btn-info:focus, .btn-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-info.disabled, .btn-info:disabled {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active,\n.show > .btn-info.dropdown-toggle {\n color: #fff;\n background-color: #117a8b;\n border-color: #10707f;\n}\n\n.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5);\n}\n\n.btn-warning {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:hover {\n color: #212529;\n background-color: #e0a800;\n border-color: #d39e00;\n}\n\n.btn-warning:focus, .btn-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-warning.disabled, .btn-warning:disabled {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active,\n.show > .btn-warning.dropdown-toggle {\n color: #212529;\n background-color: #d39e00;\n border-color: #c69500;\n}\n\n.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5);\n}\n\n.btn-danger {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:hover {\n color: #fff;\n background-color: #c82333;\n border-color: #bd2130;\n}\n\n.btn-danger:focus, .btn-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-danger.disabled, .btn-danger:disabled {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active,\n.show > .btn-danger.dropdown-toggle {\n color: #fff;\n background-color: #bd2130;\n border-color: #b21f2d;\n}\n\n.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5);\n}\n\n.btn-light {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:hover {\n color: #212529;\n background-color: #e2e6ea;\n border-color: #dae0e5;\n}\n\n.btn-light:focus, .btn-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-light.disabled, .btn-light:disabled {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active,\n.show > .btn-light.dropdown-toggle {\n color: #212529;\n background-color: #dae0e5;\n border-color: #d3d9df;\n}\n\n.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5);\n}\n\n.btn-dark {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:hover {\n color: #fff;\n background-color: #23272b;\n border-color: #1d2124;\n}\n\n.btn-dark:focus, .btn-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-dark.disabled, .btn-dark:disabled {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active,\n.show > .btn-dark.dropdown-toggle {\n color: #fff;\n background-color: #1d2124;\n border-color: #171a1d;\n}\n\n.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5);\n}\n\n.btn-outline-primary {\n color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:hover {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:focus, .btn-outline-primary.focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-primary.disabled, .btn-outline-primary:disabled {\n color: #007bff;\n background-color: transparent;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-primary.dropdown-toggle {\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-primary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.btn-outline-secondary {\n color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:hover {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:focus, .btn-outline-secondary.focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-secondary.disabled, .btn-outline-secondary:disabled {\n color: #6c757d;\n background-color: transparent;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active,\n.show > .btn-outline-secondary.dropdown-toggle {\n color: #fff;\n background-color: #6c757d;\n border-color: #6c757d;\n}\n\n.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-secondary.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.btn-outline-success {\n color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:hover {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:focus, .btn-outline-success.focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-success.disabled, .btn-outline-success:disabled {\n color: #28a745;\n background-color: transparent;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active,\n.show > .btn-outline-success.dropdown-toggle {\n color: #fff;\n background-color: #28a745;\n border-color: #28a745;\n}\n\n.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-success.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.btn-outline-info {\n color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:hover {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:focus, .btn-outline-info.focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-info.disabled, .btn-outline-info:disabled {\n color: #17a2b8;\n background-color: transparent;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active,\n.show > .btn-outline-info.dropdown-toggle {\n color: #fff;\n background-color: #17a2b8;\n border-color: #17a2b8;\n}\n\n.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-info.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.btn-outline-warning {\n color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:hover {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:focus, .btn-outline-warning.focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-warning.disabled, .btn-outline-warning:disabled {\n color: #ffc107;\n background-color: transparent;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active,\n.show > .btn-outline-warning.dropdown-toggle {\n color: #212529;\n background-color: #ffc107;\n border-color: #ffc107;\n}\n\n.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-warning.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.btn-outline-danger {\n color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:hover {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:focus, .btn-outline-danger.focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-danger.disabled, .btn-outline-danger:disabled {\n color: #dc3545;\n background-color: transparent;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active,\n.show > .btn-outline-danger.dropdown-toggle {\n color: #fff;\n background-color: #dc3545;\n border-color: #dc3545;\n}\n\n.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-danger.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.btn-outline-light {\n color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:hover {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:focus, .btn-outline-light.focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-light.disabled, .btn-outline-light:disabled {\n color: #f8f9fa;\n background-color: transparent;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active,\n.show > .btn-outline-light.dropdown-toggle {\n color: #212529;\n background-color: #f8f9fa;\n border-color: #f8f9fa;\n}\n\n.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-light.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.btn-outline-dark {\n color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:hover {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:focus, .btn-outline-dark.focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-outline-dark.disabled, .btn-outline-dark:disabled {\n color: #343a40;\n background-color: transparent;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active,\n.show > .btn-outline-dark.dropdown-toggle {\n color: #fff;\n background-color: #343a40;\n border-color: #343a40;\n}\n\n.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus,\n.show > .btn-outline-dark.dropdown-toggle:focus {\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.btn-link {\n font-weight: 400;\n color: #007bff;\n text-decoration: none;\n}\n\n.btn-link:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\n.btn-link:focus, .btn-link.focus {\n text-decoration: underline;\n box-shadow: none;\n}\n\n.btn-link:disabled, .btn-link.disabled {\n color: #6c757d;\n pointer-events: none;\n}\n\n.btn-lg, .btn-group-lg > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.btn-sm, .btn-group-sm > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n.btn-block + .btn-block {\n margin-top: 0.5rem;\n}\n\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n\n.fade {\n transition: opacity 0.15s linear;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fade {\n transition: none;\n }\n}\n\n.fade:not(.show) {\n opacity: 0;\n}\n\n.collapse:not(.show) {\n display: none;\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n transition: height 0.35s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .collapsing {\n transition: none;\n }\n}\n\n.dropup,\n.dropright,\n.dropdown,\n.dropleft {\n position: relative;\n}\n\n.dropdown-toggle {\n white-space: nowrap;\n}\n\n.dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n}\n\n.dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 10rem;\n padding: 0.5rem 0;\n margin: 0.125rem 0 0;\n font-size: 1rem;\n color: #212529;\n text-align: left;\n list-style: none;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 0.25rem;\n}\n\n.dropdown-menu-left {\n right: auto;\n left: 0;\n}\n\n.dropdown-menu-right {\n right: 0;\n left: auto;\n}\n\n@media (min-width: 576px) {\n .dropdown-menu-sm-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-sm-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 768px) {\n .dropdown-menu-md-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-md-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 992px) {\n .dropdown-menu-lg-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-lg-right {\n right: 0;\n left: auto;\n }\n}\n\n@media (min-width: 1200px) {\n .dropdown-menu-xl-left {\n right: auto;\n left: 0;\n }\n .dropdown-menu-xl-right {\n right: 0;\n left: auto;\n }\n}\n\n.dropup .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-top: 0;\n margin-bottom: 0.125rem;\n}\n\n.dropup .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0;\n border-right: 0.3em solid transparent;\n border-bottom: 0.3em solid;\n border-left: 0.3em solid transparent;\n}\n\n.dropup .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-menu {\n top: 0;\n right: auto;\n left: 100%;\n margin-top: 0;\n margin-left: 0.125rem;\n}\n\n.dropright .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0;\n border-bottom: 0.3em solid transparent;\n border-left: 0.3em solid;\n}\n\n.dropright .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropright .dropdown-toggle::after {\n vertical-align: 0;\n}\n\n.dropleft .dropdown-menu {\n top: 0;\n right: 100%;\n left: auto;\n margin-top: 0;\n margin-right: 0.125rem;\n}\n\n.dropleft .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n}\n\n.dropleft .dropdown-toggle::after {\n display: none;\n}\n\n.dropleft .dropdown-toggle::before {\n display: inline-block;\n margin-right: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0.3em solid;\n border-bottom: 0.3em solid transparent;\n}\n\n.dropleft .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle::before {\n vertical-align: 0;\n}\n\n.dropdown-menu[x-placement^=\"top\"], .dropdown-menu[x-placement^=\"right\"], .dropdown-menu[x-placement^=\"bottom\"], .dropdown-menu[x-placement^=\"left\"] {\n right: auto;\n bottom: auto;\n}\n\n.dropdown-divider {\n height: 0;\n margin: 0.5rem 0;\n overflow: hidden;\n border-top: 1px solid #e9ecef;\n}\n\n.dropdown-item {\n display: block;\n width: 100%;\n padding: 0.25rem 1.5rem;\n clear: both;\n font-weight: 400;\n color: #212529;\n text-align: inherit;\n white-space: nowrap;\n background-color: transparent;\n border: 0;\n}\n\n.dropdown-item:hover, .dropdown-item:focus {\n color: #16181b;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.dropdown-item.active, .dropdown-item:active {\n color: #fff;\n text-decoration: none;\n background-color: #007bff;\n}\n\n.dropdown-item.disabled, .dropdown-item:disabled {\n color: #6c757d;\n pointer-events: none;\n background-color: transparent;\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n.dropdown-header {\n display: block;\n padding: 0.5rem 1.5rem;\n margin-bottom: 0;\n font-size: 0.875rem;\n color: #6c757d;\n white-space: nowrap;\n}\n\n.dropdown-item-text {\n display: block;\n padding: 0.25rem 1.5rem;\n color: #212529;\n}\n\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-flex;\n vertical-align: middle;\n}\n\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n flex: 1 1 auto;\n}\n\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover {\n z-index: 1;\n}\n\n.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n z-index: 1;\n}\n\n.btn-toolbar {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-start;\n}\n\n.btn-toolbar .input-group {\n width: auto;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) {\n margin-left: -1px;\n}\n\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.dropdown-toggle-split {\n padding-right: 0.5625rem;\n padding-left: 0.5625rem;\n}\n\n.dropdown-toggle-split::after,\n.dropup .dropdown-toggle-split::after,\n.dropright .dropdown-toggle-split::after {\n margin-left: 0;\n}\n\n.dropleft .dropdown-toggle-split::before {\n margin-right: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n padding-right: 0.375rem;\n padding-left: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n padding-right: 0.75rem;\n padding-left: 0.75rem;\n}\n\n.btn-group-vertical {\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n}\n\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group {\n width: 100%;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) {\n margin-top: -1px;\n}\n\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.btn-group-toggle > .btn,\n.btn-group-toggle > .btn-group > .btn {\n margin-bottom: 0;\n}\n\n.btn-group-toggle > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn input[type=\"checkbox\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"radio\"],\n.btn-group-toggle > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n\n.input-group {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: stretch;\n width: 100%;\n}\n\n.input-group > .form-control,\n.input-group > .form-control-plaintext,\n.input-group > .custom-select,\n.input-group > .custom-file {\n position: relative;\n flex: 1 1 auto;\n width: 1%;\n margin-bottom: 0;\n}\n\n.input-group > .form-control + .form-control,\n.input-group > .form-control + .custom-select,\n.input-group > .form-control + .custom-file,\n.input-group > .form-control-plaintext + .form-control,\n.input-group > .form-control-plaintext + .custom-select,\n.input-group > .form-control-plaintext + .custom-file,\n.input-group > .custom-select + .form-control,\n.input-group > .custom-select + .custom-select,\n.input-group > .custom-select + .custom-file,\n.input-group > .custom-file + .form-control,\n.input-group > .custom-file + .custom-select,\n.input-group > .custom-file + .custom-file {\n margin-left: -1px;\n}\n\n.input-group > .form-control:focus,\n.input-group > .custom-select:focus,\n.input-group > .custom-file .custom-file-input:focus ~ .custom-file-label {\n z-index: 3;\n}\n\n.input-group > .custom-file .custom-file-input:focus {\n z-index: 4;\n}\n\n.input-group > .form-control:not(:last-child),\n.input-group > .custom-select:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .form-control:not(:first-child),\n.input-group > .custom-select:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group > .custom-file {\n display: flex;\n align-items: center;\n}\n\n.input-group > .custom-file:not(:last-child) .custom-file-label,\n.input-group > .custom-file:not(:last-child) .custom-file-label::after {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .custom-file:not(:first-child) .custom-file-label {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.input-group-prepend,\n.input-group-append {\n display: flex;\n}\n\n.input-group-prepend .btn,\n.input-group-append .btn {\n position: relative;\n z-index: 2;\n}\n\n.input-group-prepend .btn:focus,\n.input-group-append .btn:focus {\n z-index: 3;\n}\n\n.input-group-prepend .btn + .btn,\n.input-group-prepend .btn + .input-group-text,\n.input-group-prepend .input-group-text + .input-group-text,\n.input-group-prepend .input-group-text + .btn,\n.input-group-append .btn + .btn,\n.input-group-append .btn + .input-group-text,\n.input-group-append .input-group-text + .input-group-text,\n.input-group-append .input-group-text + .btn {\n margin-left: -1px;\n}\n\n.input-group-prepend {\n margin-right: -1px;\n}\n\n.input-group-append {\n margin-left: -1px;\n}\n\n.input-group-text {\n display: flex;\n align-items: center;\n padding: 0.375rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n text-align: center;\n white-space: nowrap;\n background-color: #e9ecef;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.input-group-text input[type=\"radio\"],\n.input-group-text input[type=\"checkbox\"] {\n margin-top: 0;\n}\n\n.input-group-lg > .form-control:not(textarea),\n.input-group-lg > .custom-select {\n height: calc(1.5em + 1rem + 2px);\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .custom-select,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n line-height: 1.5;\n border-radius: 0.3rem;\n}\n\n.input-group-sm > .form-control:not(textarea),\n.input-group-sm > .custom-select {\n height: calc(1.5em + 0.5rem + 2px);\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .custom-select,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n border-radius: 0.2rem;\n}\n\n.input-group-lg > .custom-select,\n.input-group-sm > .custom-select {\n padding-right: 1.75rem;\n}\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group > .input-group-append:not(:last-child) > .btn,\n.input-group > .input-group-append:not(:last-child) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.custom-control {\n position: relative;\n display: block;\n min-height: 1.5rem;\n padding-left: 1.5rem;\n}\n\n.custom-control-inline {\n display: inline-flex;\n margin-right: 1rem;\n}\n\n.custom-control-input {\n position: absolute;\n z-index: -1;\n opacity: 0;\n}\n\n.custom-control-input:checked ~ .custom-control-label::before {\n color: #fff;\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-control-input:focus ~ .custom-control-label::before {\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-control-input:focus:not(:checked) ~ .custom-control-label::before {\n border-color: #80bdff;\n}\n\n.custom-control-input:not(:disabled):active ~ .custom-control-label::before {\n color: #fff;\n background-color: #b3d7ff;\n border-color: #b3d7ff;\n}\n\n.custom-control-input:disabled ~ .custom-control-label {\n color: #6c757d;\n}\n\n.custom-control-input:disabled ~ .custom-control-label::before {\n background-color: #e9ecef;\n}\n\n.custom-control-label {\n position: relative;\n margin-bottom: 0;\n vertical-align: top;\n}\n\n.custom-control-label::before {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n pointer-events: none;\n content: \"\";\n background-color: #fff;\n border: #adb5bd solid 1px;\n}\n\n.custom-control-label::after {\n position: absolute;\n top: 0.25rem;\n left: -1.5rem;\n display: block;\n width: 1rem;\n height: 1rem;\n content: \"\";\n background: no-repeat 50% / 50% 50%;\n}\n\n.custom-checkbox .custom-control-label::before {\n border-radius: 0.25rem;\n}\n\n.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before {\n border-color: #007bff;\n background-color: #007bff;\n}\n\n.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e\");\n}\n\n.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-radio .custom-control-label::before {\n border-radius: 50%;\n}\n\n.custom-radio .custom-control-input:checked ~ .custom-control-label::after {\n background-image: 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\");\n}\n\n.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-switch {\n padding-left: 2.25rem;\n}\n\n.custom-switch .custom-control-label::before {\n left: -2.25rem;\n width: 1.75rem;\n pointer-events: all;\n border-radius: 0.5rem;\n}\n\n.custom-switch .custom-control-label::after {\n top: calc(0.25rem + 2px);\n left: calc(-2.25rem + 2px);\n width: calc(1rem - 4px);\n height: calc(1rem - 4px);\n background-color: #adb5bd;\n border-radius: 0.5rem;\n transition: transform 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;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-switch .custom-control-label::after {\n transition: none;\n }\n}\n\n.custom-switch .custom-control-input:checked ~ .custom-control-label::after {\n background-color: #fff;\n transform: translateX(0.75rem);\n}\n\n.custom-switch .custom-control-input:disabled:checked ~ .custom-control-label::before {\n background-color: rgba(0, 123, 255, 0.5);\n}\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 1.75rem 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n vertical-align: middle;\n background: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\") no-repeat right 0.75rem center/8px 10px;\n background-color: #fff;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n appearance: none;\n}\n\n.custom-select:focus {\n border-color: #80bdff;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-select:focus::-ms-value {\n color: #495057;\n background-color: #fff;\n}\n\n.custom-select[multiple], .custom-select[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: 0.75rem;\n background-image: none;\n}\n\n.custom-select:disabled {\n color: #6c757d;\n background-color: #e9ecef;\n}\n\n.custom-select::-ms-expand {\n display: none;\n}\n\n.custom-select-sm {\n height: calc(1.5em + 0.5rem + 2px);\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n padding-left: 0.5rem;\n font-size: 0.875rem;\n}\n\n.custom-select-lg {\n height: calc(1.5em + 1rem + 2px);\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n padding-left: 1rem;\n font-size: 1.25rem;\n}\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: calc(1.5em + 0.75rem + 2px);\n margin: 0;\n opacity: 0;\n}\n\n.custom-file-input:focus ~ .custom-file-label {\n border-color: #80bdff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-file-input:disabled ~ .custom-file-label {\n background-color: #e9ecef;\n}\n\n.custom-file-input:lang(en) ~ .custom-file-label::after {\n content: \"Browse\";\n}\n\n.custom-file-input ~ .custom-file-label[data-browse]::after {\n content: attr(data-browse);\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: calc(1.5em + 0.75rem + 2px);\n padding: 0.375rem 0.75rem;\n font-weight: 400;\n line-height: 1.5;\n color: #495057;\n background-color: #fff;\n border: 1px solid #ced4da;\n border-radius: 0.25rem;\n}\n\n.custom-file-label::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: calc(1.5em + 0.75rem);\n padding: 0.375rem 0.75rem;\n line-height: 1.5;\n color: #495057;\n content: \"Browse\";\n background-color: #e9ecef;\n border-left: inherit;\n border-radius: 0 0.25rem 0.25rem 0;\n}\n\n.custom-range {\n width: 100%;\n height: calc(1rem + 0.4rem);\n padding: 0;\n background-color: transparent;\n appearance: none;\n}\n\n.custom-range:focus {\n outline: none;\n}\n\n.custom-range:focus::-webkit-slider-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-moz-range-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range:focus::-ms-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.custom-range::-moz-focus-outer {\n border: 0;\n}\n\n.custom-range::-webkit-slider-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: -0.25rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-webkit-slider-thumb {\n transition: none;\n }\n}\n\n.custom-range::-webkit-slider-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-webkit-slider-runnable-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-moz-range-thumb {\n width: 1rem;\n height: 1rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-moz-range-thumb {\n transition: none;\n }\n}\n\n.custom-range::-moz-range-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-moz-range-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: #dee2e6;\n border-color: transparent;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: 0;\n margin-right: 0.2rem;\n margin-left: 0.2rem;\n background-color: #007bff;\n border: 0;\n border-radius: 1rem;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n appearance: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-range::-ms-thumb {\n transition: none;\n }\n}\n\n.custom-range::-ms-thumb:active {\n background-color: #b3d7ff;\n}\n\n.custom-range::-ms-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: transparent;\n border-color: transparent;\n border-width: 0.5rem;\n}\n\n.custom-range::-ms-fill-lower {\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range::-ms-fill-upper {\n margin-right: 15px;\n background-color: #dee2e6;\n border-radius: 1rem;\n}\n\n.custom-range:disabled::-webkit-slider-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-webkit-slider-runnable-track {\n cursor: default;\n}\n\n.custom-range:disabled::-moz-range-thumb {\n background-color: #adb5bd;\n}\n\n.custom-range:disabled::-moz-range-track {\n cursor: default;\n}\n\n.custom-range:disabled::-ms-thumb {\n background-color: #adb5bd;\n}\n\n.custom-control-label::before,\n.custom-file-label,\n.custom-select {\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .custom-control-label::before,\n .custom-file-label,\n .custom-select {\n transition: none;\n }\n}\n\n.nav {\n display: flex;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: 0.5rem 1rem;\n}\n\n.nav-link:hover, .nav-link:focus {\n text-decoration: none;\n}\n\n.nav-link.disabled {\n color: #6c757d;\n pointer-events: none;\n cursor: default;\n}\n\n.nav-tabs {\n border-bottom: 1px solid #dee2e6;\n}\n\n.nav-tabs .nav-item {\n margin-bottom: -1px;\n}\n\n.nav-tabs .nav-link {\n border: 1px solid transparent;\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n border-color: #e9ecef #e9ecef #dee2e6;\n}\n\n.nav-tabs .nav-link.disabled {\n color: #6c757d;\n background-color: transparent;\n border-color: transparent;\n}\n\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n color: #495057;\n background-color: #fff;\n border-color: #dee2e6 #dee2e6 #fff;\n}\n\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.nav-pills .nav-link {\n border-radius: 0.25rem;\n}\n\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n color: #fff;\n background-color: #007bff;\n}\n\n.nav-fill .nav-item {\n flex: 1 1 auto;\n text-align: center;\n}\n\n.nav-justified .nav-item {\n flex-basis: 0;\n flex-grow: 1;\n text-align: center;\n}\n\n.tab-content > .tab-pane {\n display: none;\n}\n\n.tab-content > .active {\n display: block;\n}\n\n.navbar {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem 1rem;\n}\n\n.navbar > .container,\n.navbar > .container-fluid {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n}\n\n.navbar-brand {\n display: inline-block;\n padding-top: 0.3125rem;\n padding-bottom: 0.3125rem;\n margin-right: 1rem;\n font-size: 1.25rem;\n line-height: inherit;\n white-space: nowrap;\n}\n\n.navbar-brand:hover, .navbar-brand:focus {\n text-decoration: none;\n}\n\n.navbar-nav {\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.navbar-nav .nav-link {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-nav .dropdown-menu {\n position: static;\n float: none;\n}\n\n.navbar-text {\n display: inline-block;\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n\n.navbar-collapse {\n flex-basis: 100%;\n flex-grow: 1;\n align-items: center;\n}\n\n.navbar-toggler {\n padding: 0.25rem 0.75rem;\n font-size: 1.25rem;\n line-height: 1;\n background-color: transparent;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.navbar-toggler:hover, .navbar-toggler:focus {\n text-decoration: none;\n}\n\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: no-repeat center center;\n background-size: 100% 100%;\n}\n\n@media (max-width: 575.98px) {\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 576px) {\n .navbar-expand-sm {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-sm .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-sm .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-sm > .container,\n .navbar-expand-sm > .container-fluid {\n flex-wrap: nowrap;\n }\n .navbar-expand-sm .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-sm .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 767.98px) {\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 768px) {\n .navbar-expand-md {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-md .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-md .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-md > .container,\n .navbar-expand-md > .container-fluid {\n flex-wrap: nowrap;\n }\n .navbar-expand-md .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-md .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 991.98px) {\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 992px) {\n .navbar-expand-lg {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-lg .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-lg .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-lg > .container,\n .navbar-expand-lg > .container-fluid {\n flex-wrap: nowrap;\n }\n .navbar-expand-lg .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-lg .navbar-toggler {\n display: none;\n }\n}\n\n@media (max-width: 1199.98px) {\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n@media (min-width: 1200px) {\n .navbar-expand-xl {\n flex-flow: row nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-xl .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-xl .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n }\n .navbar-expand-xl > .container,\n .navbar-expand-xl > .container-fluid {\n flex-wrap: nowrap;\n }\n .navbar-expand-xl .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-xl .navbar-toggler {\n display: none;\n }\n}\n\n.navbar-expand {\n flex-flow: row nowrap;\n justify-content: flex-start;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n}\n\n.navbar-expand .navbar-nav {\n flex-direction: row;\n}\n\n.navbar-expand .navbar-nav .dropdown-menu {\n position: absolute;\n}\n\n.navbar-expand .navbar-nav .nav-link {\n padding-right: 0.5rem;\n padding-left: 0.5rem;\n}\n\n.navbar-expand > .container,\n.navbar-expand > .container-fluid {\n flex-wrap: nowrap;\n}\n\n.navbar-expand .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n}\n\n.navbar-expand .navbar-toggler {\n display: none;\n}\n\n.navbar-light .navbar-brand {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-nav .nav-link {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus {\n color: rgba(0, 0, 0, 0.7);\n}\n\n.navbar-light .navbar-nav .nav-link.disabled {\n color: rgba(0, 0, 0, 0.3);\n}\n\n.navbar-light .navbar-nav .show > .nav-link,\n.navbar-light .navbar-nav .active > .nav-link,\n.navbar-light .navbar-nav .nav-link.show,\n.navbar-light .navbar-nav .nav-link.active {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-toggler {\n color: rgba(0, 0, 0, 0.5);\n border-color: rgba(0, 0, 0, 0.1);\n}\n\n.navbar-light .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-light .navbar-text {\n color: rgba(0, 0, 0, 0.5);\n}\n\n.navbar-light .navbar-text a {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus {\n color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-dark .navbar-brand {\n color: #fff;\n}\n\n.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus {\n color: #fff;\n}\n\n.navbar-dark .navbar-nav .nav-link {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus {\n color: rgba(255, 255, 255, 0.75);\n}\n\n.navbar-dark .navbar-nav .nav-link.disabled {\n color: rgba(255, 255, 255, 0.25);\n}\n\n.navbar-dark .navbar-nav .show > .nav-link,\n.navbar-dark .navbar-nav .active > .nav-link,\n.navbar-dark .navbar-nav .nav-link.show,\n.navbar-dark .navbar-nav .nav-link.active {\n color: #fff;\n}\n\n.navbar-dark .navbar-toggler {\n color: rgba(255, 255, 255, 0.5);\n border-color: rgba(255, 255, 255, 0.1);\n}\n\n.navbar-dark .navbar-toggler-icon {\n background-image: url(\"data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.navbar-dark .navbar-text {\n color: rgba(255, 255, 255, 0.5);\n}\n\n.navbar-dark .navbar-text a {\n color: #fff;\n}\n\n.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus {\n color: #fff;\n}\n\n.card {\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: border-box;\n border: 1px solid rgba(0, 0, 0, 0.125);\n border-radius: 0.25rem;\n}\n\n.card > hr {\n margin-right: 0;\n margin-left: 0;\n}\n\n.card > .list-group:first-child .list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.card > .list-group:last-child .list-group-item:last-child {\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.card-body {\n flex: 1 1 auto;\n padding: 1.25rem;\n}\n\n.card-title {\n margin-bottom: 0.75rem;\n}\n\n.card-subtitle {\n margin-top: -0.375rem;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link:hover {\n text-decoration: none;\n}\n\n.card-link + .card-link {\n margin-left: 1.25rem;\n}\n\n.card-header {\n padding: 0.75rem 1.25rem;\n margin-bottom: 0;\n background-color: rgba(0, 0, 0, 0.03);\n border-bottom: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-header:first-child {\n border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;\n}\n\n.card-header + .list-group .list-group-item:first-child {\n border-top: 0;\n}\n\n.card-footer {\n padding: 0.75rem 1.25rem;\n background-color: rgba(0, 0, 0, 0.03);\n border-top: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.card-footer:last-child {\n border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);\n}\n\n.card-header-tabs {\n margin-right: -0.625rem;\n margin-bottom: -0.75rem;\n margin-left: -0.625rem;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -0.625rem;\n margin-left: -0.625rem;\n}\n\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: 1.25rem;\n}\n\n.card-img {\n width: 100%;\n border-radius: calc(0.25rem - 1px);\n}\n\n.card-img-top {\n width: 100%;\n border-top-left-radius: calc(0.25rem - 1px);\n border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card-img-bottom {\n width: 100%;\n border-bottom-right-radius: calc(0.25rem - 1px);\n border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card-deck {\n display: flex;\n flex-direction: column;\n}\n\n.card-deck .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-deck {\n flex-flow: row wrap;\n margin-right: -15px;\n margin-left: -15px;\n }\n .card-deck .card {\n display: flex;\n flex: 1 0 0%;\n flex-direction: column;\n margin-right: 15px;\n margin-bottom: 0;\n margin-left: 15px;\n }\n}\n\n.card-group {\n display: flex;\n flex-direction: column;\n}\n\n.card-group > .card {\n margin-bottom: 15px;\n}\n\n@media (min-width: 576px) {\n .card-group {\n flex-flow: row wrap;\n }\n .card-group > .card {\n flex: 1 0 0%;\n margin-bottom: 0;\n }\n .card-group > .card + .card {\n margin-left: 0;\n border-left: 0;\n }\n .card-group > .card:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n .card-group > .card:not(:last-child) .card-img-top,\n .card-group > .card:not(:last-child) .card-header {\n border-top-right-radius: 0;\n }\n .card-group > .card:not(:last-child) .card-img-bottom,\n .card-group > .card:not(:last-child) .card-footer {\n border-bottom-right-radius: 0;\n }\n .card-group > .card:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .card-group > .card:not(:first-child) .card-img-top,\n .card-group > .card:not(:first-child) .card-header {\n border-top-left-radius: 0;\n }\n .card-group > .card:not(:first-child) .card-img-bottom,\n .card-group > .card:not(:first-child) .card-footer {\n border-bottom-left-radius: 0;\n }\n}\n\n.card-columns .card {\n margin-bottom: 0.75rem;\n}\n\n@media (min-width: 576px) {\n .card-columns {\n column-count: 3;\n column-gap: 1.25rem;\n orphans: 1;\n widows: 1;\n }\n .card-columns .card {\n display: inline-block;\n width: 100%;\n }\n}\n\n.accordion > .card {\n overflow: hidden;\n}\n\n.accordion > .card:not(:first-of-type) .card-header:first-child {\n border-radius: 0;\n}\n\n.accordion > .card:not(:first-of-type):not(:last-of-type) {\n border-bottom: 0;\n border-radius: 0;\n}\n\n.accordion > .card:first-of-type {\n border-bottom: 0;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.accordion > .card:last-of-type {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.accordion > .card .card-header {\n margin-bottom: -1px;\n}\n\n.breadcrumb {\n display: flex;\n flex-wrap: wrap;\n padding: 0.75rem 1rem;\n margin-bottom: 1rem;\n list-style: none;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.breadcrumb-item + .breadcrumb-item {\n padding-left: 0.5rem;\n}\n\n.breadcrumb-item + .breadcrumb-item::before {\n display: inline-block;\n padding-right: 0.5rem;\n color: #6c757d;\n content: \"/\";\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: underline;\n}\n\n.breadcrumb-item + .breadcrumb-item:hover::before {\n text-decoration: none;\n}\n\n.breadcrumb-item.active {\n color: #6c757d;\n}\n\n.pagination {\n display: flex;\n padding-left: 0;\n list-style: none;\n border-radius: 0.25rem;\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: 0.5rem 0.75rem;\n margin-left: -1px;\n line-height: 1.25;\n color: #007bff;\n background-color: #fff;\n border: 1px solid #dee2e6;\n}\n\n.page-link:hover {\n z-index: 2;\n color: #0056b3;\n text-decoration: none;\n background-color: #e9ecef;\n border-color: #dee2e6;\n}\n\n.page-link:focus {\n z-index: 2;\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n}\n\n.page-item:first-child .page-link {\n margin-left: 0;\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.page-item:last-child .page-link {\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n}\n\n.page-item.active .page-link {\n z-index: 1;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.page-item.disabled .page-link {\n color: #6c757d;\n pointer-events: none;\n cursor: auto;\n background-color: #fff;\n border-color: #dee2e6;\n}\n\n.pagination-lg .page-link {\n padding: 0.75rem 1.5rem;\n font-size: 1.25rem;\n line-height: 1.5;\n}\n\n.pagination-lg .page-item:first-child .page-link {\n border-top-left-radius: 0.3rem;\n border-bottom-left-radius: 0.3rem;\n}\n\n.pagination-lg .page-item:last-child .page-link {\n border-top-right-radius: 0.3rem;\n border-bottom-right-radius: 0.3rem;\n}\n\n.pagination-sm .page-link {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.pagination-sm .page-item:first-child .page-link {\n border-top-left-radius: 0.2rem;\n border-bottom-left-radius: 0.2rem;\n}\n\n.pagination-sm .page-item:last-child .page-link {\n border-top-right-radius: 0.2rem;\n border-bottom-right-radius: 0.2rem;\n}\n\n.badge {\n display: inline-block;\n padding: 0.25em 0.4em;\n font-size: 75%;\n font-weight: 700;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: 0.25rem;\n 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;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .badge {\n transition: none;\n }\n}\n\na.badge:hover, a.badge:focus {\n text-decoration: none;\n}\n\n.badge:empty {\n display: none;\n}\n\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n.badge-pill {\n padding-right: 0.6em;\n padding-left: 0.6em;\n border-radius: 10rem;\n}\n\n.badge-primary {\n color: #fff;\n background-color: #007bff;\n}\n\na.badge-primary:hover, a.badge-primary:focus {\n color: #fff;\n background-color: #0062cc;\n}\n\na.badge-primary:focus, a.badge-primary.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);\n}\n\n.badge-secondary {\n color: #fff;\n background-color: #6c757d;\n}\n\na.badge-secondary:hover, a.badge-secondary:focus {\n color: #fff;\n background-color: #545b62;\n}\n\na.badge-secondary:focus, a.badge-secondary.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5);\n}\n\n.badge-success {\n color: #fff;\n background-color: #28a745;\n}\n\na.badge-success:hover, a.badge-success:focus {\n color: #fff;\n background-color: #1e7e34;\n}\n\na.badge-success:focus, a.badge-success.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);\n}\n\n.badge-info {\n color: #fff;\n background-color: #17a2b8;\n}\n\na.badge-info:hover, a.badge-info:focus {\n color: #fff;\n background-color: #117a8b;\n}\n\na.badge-info:focus, a.badge-info.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);\n}\n\n.badge-warning {\n color: #212529;\n background-color: #ffc107;\n}\n\na.badge-warning:hover, a.badge-warning:focus {\n color: #212529;\n background-color: #d39e00;\n}\n\na.badge-warning:focus, a.badge-warning.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);\n}\n\n.badge-danger {\n color: #fff;\n background-color: #dc3545;\n}\n\na.badge-danger:hover, a.badge-danger:focus {\n color: #fff;\n background-color: #bd2130;\n}\n\na.badge-danger:focus, a.badge-danger.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);\n}\n\n.badge-light {\n color: #212529;\n background-color: #f8f9fa;\n}\n\na.badge-light:hover, a.badge-light:focus {\n color: #212529;\n background-color: #dae0e5;\n}\n\na.badge-light:focus, a.badge-light.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);\n}\n\n.badge-dark {\n color: #fff;\n background-color: #343a40;\n}\n\na.badge-dark:hover, a.badge-dark:focus {\n color: #fff;\n background-color: #1d2124;\n}\n\na.badge-dark:focus, a.badge-dark.focus {\n outline: 0;\n box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);\n}\n\n.jumbotron {\n padding: 2rem 1rem;\n margin-bottom: 2rem;\n background-color: #e9ecef;\n border-radius: 0.3rem;\n}\n\n@media (min-width: 576px) {\n .jumbotron {\n padding: 4rem 2rem;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n border-radius: 0;\n}\n\n.alert {\n position: relative;\n padding: 0.75rem 1.25rem;\n margin-bottom: 1rem;\n border: 1px solid transparent;\n border-radius: 0.25rem;\n}\n\n.alert-heading {\n color: inherit;\n}\n\n.alert-link {\n font-weight: 700;\n}\n\n.alert-dismissible {\n padding-right: 4rem;\n}\n\n.alert-dismissible .close {\n position: absolute;\n top: 0;\n right: 0;\n padding: 0.75rem 1.25rem;\n color: inherit;\n}\n\n.alert-primary {\n color: #004085;\n background-color: #cce5ff;\n border-color: #b8daff;\n}\n\n.alert-primary hr {\n border-top-color: #9fcdff;\n}\n\n.alert-primary .alert-link {\n color: #002752;\n}\n\n.alert-secondary {\n color: #383d41;\n background-color: #e2e3e5;\n border-color: #d6d8db;\n}\n\n.alert-secondary hr {\n border-top-color: #c8cbcf;\n}\n\n.alert-secondary .alert-link {\n color: #202326;\n}\n\n.alert-success {\n color: #155724;\n background-color: #d4edda;\n border-color: #c3e6cb;\n}\n\n.alert-success hr {\n border-top-color: #b1dfbb;\n}\n\n.alert-success .alert-link {\n color: #0b2e13;\n}\n\n.alert-info {\n color: #0c5460;\n background-color: #d1ecf1;\n border-color: #bee5eb;\n}\n\n.alert-info hr {\n border-top-color: #abdde5;\n}\n\n.alert-info .alert-link {\n color: #062c33;\n}\n\n.alert-warning {\n color: #856404;\n background-color: #fff3cd;\n border-color: #ffeeba;\n}\n\n.alert-warning hr {\n border-top-color: #ffe8a1;\n}\n\n.alert-warning .alert-link {\n color: #533f03;\n}\n\n.alert-danger {\n color: #721c24;\n background-color: #f8d7da;\n border-color: #f5c6cb;\n}\n\n.alert-danger hr {\n border-top-color: #f1b0b7;\n}\n\n.alert-danger .alert-link {\n color: #491217;\n}\n\n.alert-light {\n color: #818182;\n background-color: #fefefe;\n border-color: #fdfdfe;\n}\n\n.alert-light hr {\n border-top-color: #ececf6;\n}\n\n.alert-light .alert-link {\n color: #686868;\n}\n\n.alert-dark {\n color: #1b1e21;\n background-color: #d6d8d9;\n border-color: #c6c8ca;\n}\n\n.alert-dark hr {\n border-top-color: #b9bbbe;\n}\n\n.alert-dark .alert-link {\n color: #040505;\n}\n\n@keyframes progress-bar-stripes {\n from {\n background-position: 1rem 0;\n }\n to {\n background-position: 0 0;\n }\n}\n\n.progress {\n display: flex;\n height: 1rem;\n overflow: hidden;\n font-size: 0.75rem;\n background-color: #e9ecef;\n border-radius: 0.25rem;\n}\n\n.progress-bar {\n display: flex;\n flex-direction: column;\n justify-content: center;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n background-color: #007bff;\n transition: width 0.6s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .progress-bar {\n transition: none;\n }\n}\n\n.progress-bar-striped {\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 1rem 1rem;\n}\n\n.progress-bar-animated {\n animation: progress-bar-stripes 1s linear infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .progress-bar-animated {\n animation: none;\n }\n}\n\n.media {\n display: flex;\n align-items: flex-start;\n}\n\n.media-body {\n flex: 1;\n}\n\n.list-group {\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n}\n\n.list-group-item-action {\n width: 100%;\n color: #495057;\n text-align: inherit;\n}\n\n.list-group-item-action:hover, .list-group-item-action:focus {\n z-index: 1;\n color: #495057;\n text-decoration: none;\n background-color: #f8f9fa;\n}\n\n.list-group-item-action:active {\n color: #212529;\n background-color: #e9ecef;\n}\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 0.75rem 1.25rem;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid rgba(0, 0, 0, 0.125);\n}\n\n.list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-top-right-radius: 0.25rem;\n}\n\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.list-group-item.disabled, .list-group-item:disabled {\n color: #6c757d;\n pointer-events: none;\n background-color: #fff;\n}\n\n.list-group-item.active {\n z-index: 2;\n color: #fff;\n background-color: #007bff;\n border-color: #007bff;\n}\n\n.list-group-horizontal {\n flex-direction: row;\n}\n\n.list-group-horizontal .list-group-item {\n margin-right: -1px;\n margin-bottom: 0;\n}\n\n.list-group-horizontal .list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n}\n\n.list-group-horizontal .list-group-item:last-child {\n margin-right: 0;\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n}\n\n@media (min-width: 576px) {\n .list-group-horizontal-sm {\n flex-direction: row;\n }\n .list-group-horizontal-sm .list-group-item {\n margin-right: -1px;\n margin-bottom: 0;\n }\n .list-group-horizontal-sm .list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-sm .list-group-item:last-child {\n margin-right: 0;\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n}\n\n@media (min-width: 768px) {\n .list-group-horizontal-md {\n flex-direction: row;\n }\n .list-group-horizontal-md .list-group-item {\n margin-right: -1px;\n margin-bottom: 0;\n }\n .list-group-horizontal-md .list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-md .list-group-item:last-child {\n margin-right: 0;\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n}\n\n@media (min-width: 992px) {\n .list-group-horizontal-lg {\n flex-direction: row;\n }\n .list-group-horizontal-lg .list-group-item {\n margin-right: -1px;\n margin-bottom: 0;\n }\n .list-group-horizontal-lg .list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-lg .list-group-item:last-child {\n margin-right: 0;\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n}\n\n@media (min-width: 1200px) {\n .list-group-horizontal-xl {\n flex-direction: row;\n }\n .list-group-horizontal-xl .list-group-item {\n margin-right: -1px;\n margin-bottom: 0;\n }\n .list-group-horizontal-xl .list-group-item:first-child {\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n border-top-right-radius: 0;\n }\n .list-group-horizontal-xl .list-group-item:last-child {\n margin-right: 0;\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n border-bottom-left-radius: 0;\n }\n}\n\n.list-group-flush .list-group-item {\n border-right: 0;\n border-left: 0;\n border-radius: 0;\n}\n\n.list-group-flush .list-group-item:last-child {\n margin-bottom: -1px;\n}\n\n.list-group-flush:first-child .list-group-item:first-child {\n border-top: 0;\n}\n\n.list-group-flush:last-child .list-group-item:last-child {\n margin-bottom: 0;\n border-bottom: 0;\n}\n\n.list-group-item-primary {\n color: #004085;\n background-color: #b8daff;\n}\n\n.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {\n color: #004085;\n background-color: #9fcdff;\n}\n\n.list-group-item-primary.list-group-item-action.active {\n color: #fff;\n background-color: #004085;\n border-color: #004085;\n}\n\n.list-group-item-secondary {\n color: #383d41;\n background-color: #d6d8db;\n}\n\n.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {\n color: #383d41;\n background-color: #c8cbcf;\n}\n\n.list-group-item-secondary.list-group-item-action.active {\n color: #fff;\n background-color: #383d41;\n border-color: #383d41;\n}\n\n.list-group-item-success {\n color: #155724;\n background-color: #c3e6cb;\n}\n\n.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {\n color: #155724;\n background-color: #b1dfbb;\n}\n\n.list-group-item-success.list-group-item-action.active {\n color: #fff;\n background-color: #155724;\n border-color: #155724;\n}\n\n.list-group-item-info {\n color: #0c5460;\n background-color: #bee5eb;\n}\n\n.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {\n color: #0c5460;\n background-color: #abdde5;\n}\n\n.list-group-item-info.list-group-item-action.active {\n color: #fff;\n background-color: #0c5460;\n border-color: #0c5460;\n}\n\n.list-group-item-warning {\n color: #856404;\n background-color: #ffeeba;\n}\n\n.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {\n color: #856404;\n background-color: #ffe8a1;\n}\n\n.list-group-item-warning.list-group-item-action.active {\n color: #fff;\n background-color: #856404;\n border-color: #856404;\n}\n\n.list-group-item-danger {\n color: #721c24;\n background-color: #f5c6cb;\n}\n\n.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {\n color: #721c24;\n background-color: #f1b0b7;\n}\n\n.list-group-item-danger.list-group-item-action.active {\n color: #fff;\n background-color: #721c24;\n border-color: #721c24;\n}\n\n.list-group-item-light {\n color: #818182;\n background-color: #fdfdfe;\n}\n\n.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {\n color: #818182;\n background-color: #ececf6;\n}\n\n.list-group-item-light.list-group-item-action.active {\n color: #fff;\n background-color: #818182;\n border-color: #818182;\n}\n\n.list-group-item-dark {\n color: #1b1e21;\n background-color: #c6c8ca;\n}\n\n.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {\n color: #1b1e21;\n background-color: #b9bbbe;\n}\n\n.list-group-item-dark.list-group-item-action.active {\n color: #fff;\n background-color: #1b1e21;\n border-color: #1b1e21;\n}\n\n.close {\n float: right;\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n opacity: .5;\n}\n\n.close:hover {\n color: #000;\n text-decoration: none;\n}\n\n.close:not(:disabled):not(.disabled):hover, .close:not(:disabled):not(.disabled):focus {\n opacity: .75;\n}\n\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n appearance: none;\n}\n\na.close.disabled {\n pointer-events: none;\n}\n\n.toast {\n max-width: 350px;\n overflow: hidden;\n font-size: 0.875rem;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.1);\n box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1);\n backdrop-filter: blur(10px);\n opacity: 0;\n border-radius: 0.25rem;\n}\n\n.toast:not(:last-child) {\n margin-bottom: 0.75rem;\n}\n\n.toast.showing {\n opacity: 1;\n}\n\n.toast.show {\n display: block;\n opacity: 1;\n}\n\n.toast.hide {\n display: none;\n}\n\n.toast-header {\n display: flex;\n align-items: center;\n padding: 0.25rem 0.75rem;\n color: #6c757d;\n background-color: rgba(255, 255, 255, 0.85);\n background-clip: padding-box;\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n}\n\n.toast-body {\n padding: 0.75rem;\n}\n\n.modal-open {\n overflow: hidden;\n}\n\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.modal {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1050;\n display: none;\n width: 100%;\n height: 100%;\n overflow: hidden;\n outline: 0;\n}\n\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 0.5rem;\n pointer-events: none;\n}\n\n.modal.fade .modal-dialog {\n transition: transform 0.3s ease-out;\n transform: translate(0, -50px);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .modal.fade .modal-dialog {\n transition: none;\n }\n}\n\n.modal.show .modal-dialog {\n transform: none;\n}\n\n.modal-dialog-scrollable {\n display: flex;\n max-height: calc(100% - 1rem);\n}\n\n.modal-dialog-scrollable .modal-content {\n max-height: calc(100vh - 1rem);\n overflow: hidden;\n}\n\n.modal-dialog-scrollable .modal-header,\n.modal-dialog-scrollable .modal-footer {\n flex-shrink: 0;\n}\n\n.modal-dialog-scrollable .modal-body {\n overflow-y: auto;\n}\n\n.modal-dialog-centered {\n display: flex;\n align-items: center;\n min-height: calc(100% - 1rem);\n}\n\n.modal-dialog-centered::before {\n display: block;\n height: calc(100vh - 1rem);\n content: \"\";\n}\n\n.modal-dialog-centered.modal-dialog-scrollable {\n flex-direction: column;\n justify-content: center;\n height: 100%;\n}\n\n.modal-dialog-centered.modal-dialog-scrollable .modal-content {\n max-height: none;\n}\n\n.modal-dialog-centered.modal-dialog-scrollable::before {\n content: none;\n}\n\n.modal-content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n pointer-events: auto;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n outline: 0;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1040;\n width: 100vw;\n height: 100vh;\n background-color: #000;\n}\n\n.modal-backdrop.fade {\n opacity: 0;\n}\n\n.modal-backdrop.show {\n opacity: 0.5;\n}\n\n.modal-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 1rem 1rem;\n border-bottom: 1px solid #dee2e6;\n border-top-left-radius: 0.3rem;\n border-top-right-radius: 0.3rem;\n}\n\n.modal-header .close {\n padding: 1rem 1rem;\n margin: -1rem -1rem -1rem auto;\n}\n\n.modal-title {\n margin-bottom: 0;\n line-height: 1.5;\n}\n\n.modal-body {\n position: relative;\n flex: 1 1 auto;\n padding: 1rem;\n}\n\n.modal-footer {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n padding: 1rem;\n border-top: 1px solid #dee2e6;\n border-bottom-right-radius: 0.3rem;\n border-bottom-left-radius: 0.3rem;\n}\n\n.modal-footer > :not(:first-child) {\n margin-left: .25rem;\n}\n\n.modal-footer > :not(:last-child) {\n margin-right: .25rem;\n}\n\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n@media (min-width: 576px) {\n .modal-dialog {\n max-width: 500px;\n margin: 1.75rem auto;\n }\n .modal-dialog-scrollable {\n max-height: calc(100% - 3.5rem);\n }\n .modal-dialog-scrollable .modal-content {\n max-height: calc(100vh - 3.5rem);\n }\n .modal-dialog-centered {\n min-height: calc(100% - 3.5rem);\n }\n .modal-dialog-centered::before {\n height: calc(100vh - 3.5rem);\n }\n .modal-sm {\n max-width: 300px;\n }\n}\n\n@media (min-width: 992px) {\n .modal-lg,\n .modal-xl {\n max-width: 800px;\n }\n}\n\n@media (min-width: 1200px) {\n .modal-xl {\n max-width: 1140px;\n }\n}\n\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n opacity: 0;\n}\n\n.tooltip.show {\n opacity: 0.9;\n}\n\n.tooltip .arrow {\n position: absolute;\n display: block;\n width: 0.8rem;\n height: 0.4rem;\n}\n\n.tooltip .arrow::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-tooltip-top, .bs-tooltip-auto[x-placement^=\"top\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^=\"top\"] .arrow {\n bottom: 0;\n}\n\n.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^=\"top\"] .arrow::before {\n top: 0;\n border-width: 0.4rem 0.4rem 0;\n border-top-color: #000;\n}\n\n.bs-tooltip-right, .bs-tooltip-auto[x-placement^=\"right\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^=\"right\"] .arrow {\n left: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^=\"right\"] .arrow::before {\n right: 0;\n border-width: 0.4rem 0.4rem 0.4rem 0;\n border-right-color: #000;\n}\n\n.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^=\"bottom\"] {\n padding: 0.4rem 0;\n}\n\n.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow {\n top: 0;\n}\n\n.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^=\"bottom\"] .arrow::before {\n bottom: 0;\n border-width: 0 0.4rem 0.4rem;\n border-bottom-color: #000;\n}\n\n.bs-tooltip-left, .bs-tooltip-auto[x-placement^=\"left\"] {\n padding: 0 0.4rem;\n}\n\n.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^=\"left\"] .arrow {\n right: 0;\n width: 0.4rem;\n height: 0.8rem;\n}\n\n.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^=\"left\"] .arrow::before {\n left: 0;\n border-width: 0.4rem 0 0.4rem 0.4rem;\n border-left-color: #000;\n}\n\n.tooltip-inner {\n max-width: 200px;\n padding: 0.25rem 0.5rem;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 0.25rem;\n}\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: block;\n max-width: 276px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n font-size: 0.875rem;\n word-wrap: break-word;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 0.3rem;\n}\n\n.popover .arrow {\n position: absolute;\n display: block;\n width: 1rem;\n height: 0.5rem;\n margin: 0 0.3rem;\n}\n\n.popover .arrow::before, .popover .arrow::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-popover-top, .bs-popover-auto[x-placement^=\"top\"] {\n margin-bottom: 0.5rem;\n}\n\n.bs-popover-top > .arrow, .bs-popover-auto[x-placement^=\"top\"] > .arrow {\n bottom: calc((0.5rem + 1px) * -1);\n}\n\n.bs-popover-top > .arrow::before, .bs-popover-auto[x-placement^=\"top\"] > .arrow::before {\n bottom: 0;\n border-width: 0.5rem 0.5rem 0;\n border-top-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-top > .arrow::after, .bs-popover-auto[x-placement^=\"top\"] > .arrow::after {\n bottom: 1px;\n border-width: 0.5rem 0.5rem 0;\n border-top-color: #fff;\n}\n\n.bs-popover-right, .bs-popover-auto[x-placement^=\"right\"] {\n margin-left: 0.5rem;\n}\n\n.bs-popover-right > .arrow, .bs-popover-auto[x-placement^=\"right\"] > .arrow {\n left: calc((0.5rem + 1px) * -1);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-right > .arrow::before, .bs-popover-auto[x-placement^=\"right\"] > .arrow::before {\n left: 0;\n border-width: 0.5rem 0.5rem 0.5rem 0;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-right > .arrow::after, .bs-popover-auto[x-placement^=\"right\"] > .arrow::after {\n left: 1px;\n border-width: 0.5rem 0.5rem 0.5rem 0;\n border-right-color: #fff;\n}\n\n.bs-popover-bottom, .bs-popover-auto[x-placement^=\"bottom\"] {\n margin-top: 0.5rem;\n}\n\n.bs-popover-bottom > .arrow, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow {\n top: calc((0.5rem + 1px) * -1);\n}\n\n.bs-popover-bottom > .arrow::before, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow::before {\n top: 0;\n border-width: 0 0.5rem 0.5rem 0.5rem;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-bottom > .arrow::after, .bs-popover-auto[x-placement^=\"bottom\"] > .arrow::after {\n top: 1px;\n border-width: 0 0.5rem 0.5rem 0.5rem;\n border-bottom-color: #fff;\n}\n\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^=\"bottom\"] .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: 1rem;\n margin-left: -0.5rem;\n content: \"\";\n border-bottom: 1px solid #f7f7f7;\n}\n\n.bs-popover-left, .bs-popover-auto[x-placement^=\"left\"] {\n margin-right: 0.5rem;\n}\n\n.bs-popover-left > .arrow, .bs-popover-auto[x-placement^=\"left\"] > .arrow {\n right: calc((0.5rem + 1px) * -1);\n width: 0.5rem;\n height: 1rem;\n margin: 0.3rem 0;\n}\n\n.bs-popover-left > .arrow::before, .bs-popover-auto[x-placement^=\"left\"] > .arrow::before {\n right: 0;\n border-width: 0.5rem 0 0.5rem 0.5rem;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n\n.bs-popover-left > .arrow::after, .bs-popover-auto[x-placement^=\"left\"] > .arrow::after {\n right: 1px;\n border-width: 0.5rem 0 0.5rem 0.5rem;\n border-left-color: #fff;\n}\n\n.popover-header {\n padding: 0.5rem 0.75rem;\n margin-bottom: 0;\n font-size: 1rem;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-top-left-radius: calc(0.3rem - 1px);\n border-top-right-radius: calc(0.3rem - 1px);\n}\n\n.popover-header:empty {\n display: none;\n}\n\n.popover-body {\n padding: 0.5rem 0.75rem;\n color: #212529;\n}\n\n.carousel {\n position: relative;\n}\n\n.carousel.pointer-event {\n touch-action: pan-y;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n\n.carousel-inner::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.carousel-item {\n position: relative;\n display: none;\n float: left;\n width: 100%;\n margin-right: -100%;\n backface-visibility: hidden;\n transition: transform 0.6s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-item {\n transition: none;\n }\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next:not(.carousel-item-left),\n.active.carousel-item-right {\n transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-right),\n.active.carousel-item-left {\n transform: translateX(-100%);\n}\n\n.carousel-fade .carousel-item {\n opacity: 0;\n transition-property: opacity;\n transform: none;\n}\n\n.carousel-fade .carousel-item.active,\n.carousel-fade .carousel-item-next.carousel-item-left,\n.carousel-fade .carousel-item-prev.carousel-item-right {\n z-index: 1;\n opacity: 1;\n}\n\n.carousel-fade .active.carousel-item-left,\n.carousel-fade .active.carousel-item-right {\n z-index: 0;\n opacity: 0;\n transition: 0s 0.6s opacity;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-fade .active.carousel-item-left,\n .carousel-fade .active.carousel-item-right {\n transition: none;\n }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 15%;\n color: #fff;\n text-align: center;\n opacity: 0.5;\n transition: opacity 0.15s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-control-prev,\n .carousel-control-next {\n transition: none;\n }\n}\n\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n opacity: 0.9;\n}\n\n.carousel-control-prev {\n left: 0;\n}\n\n.carousel-control-next {\n right: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: 20px;\n height: 20px;\n background: no-repeat 50% / 100% 100%;\n}\n\n.carousel-control-prev-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e\");\n}\n\n.carousel-control-next-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e\");\n}\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 15;\n display: flex;\n justify-content: center;\n padding-left: 0;\n margin-right: 15%;\n margin-left: 15%;\n list-style: none;\n}\n\n.carousel-indicators li {\n box-sizing: content-box;\n flex: 0 1 auto;\n width: 30px;\n height: 3px;\n margin-right: 3px;\n margin-left: 3px;\n text-indent: -999px;\n cursor: pointer;\n background-color: #fff;\n background-clip: padding-box;\n border-top: 10px solid transparent;\n border-bottom: 10px solid transparent;\n opacity: .5;\n transition: opacity 0.6s ease;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .carousel-indicators li {\n transition: none;\n }\n}\n\n.carousel-indicators .active {\n opacity: 1;\n}\n\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n}\n\n@keyframes spinner-border {\n to {\n transform: rotate(360deg);\n }\n}\n\n.spinner-border {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n border: 0.25em solid currentColor;\n border-right-color: transparent;\n border-radius: 50%;\n animation: spinner-border .75s linear infinite;\n}\n\n.spinner-border-sm {\n width: 1rem;\n height: 1rem;\n border-width: 0.2em;\n}\n\n@keyframes spinner-grow {\n 0% {\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n }\n}\n\n.spinner-grow {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n vertical-align: text-bottom;\n background-color: currentColor;\n border-radius: 50%;\n opacity: 0;\n animation: spinner-grow .75s linear infinite;\n}\n\n.spinner-grow-sm {\n width: 1rem;\n height: 1rem;\n}\n\n.align-baseline {\n vertical-align: baseline !important;\n}\n\n.align-top {\n vertical-align: top !important;\n}\n\n.align-middle {\n vertical-align: middle !important;\n}\n\n.align-bottom {\n vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n vertical-align: text-top !important;\n}\n\n.bg-primary {\n background-color: #007bff !important;\n}\n\na.bg-primary:hover, a.bg-primary:focus,\nbutton.bg-primary:hover,\nbutton.bg-primary:focus {\n background-color: #0062cc !important;\n}\n\n.bg-secondary {\n background-color: #6c757d !important;\n}\n\na.bg-secondary:hover, a.bg-secondary:focus,\nbutton.bg-secondary:hover,\nbutton.bg-secondary:focus {\n background-color: #545b62 !important;\n}\n\n.bg-success {\n background-color: #28a745 !important;\n}\n\na.bg-success:hover, a.bg-success:focus,\nbutton.bg-success:hover,\nbutton.bg-success:focus {\n background-color: #1e7e34 !important;\n}\n\n.bg-info {\n background-color: #17a2b8 !important;\n}\n\na.bg-info:hover, a.bg-info:focus,\nbutton.bg-info:hover,\nbutton.bg-info:focus {\n background-color: #117a8b !important;\n}\n\n.bg-warning {\n background-color: #ffc107 !important;\n}\n\na.bg-warning:hover, a.bg-warning:focus,\nbutton.bg-warning:hover,\nbutton.bg-warning:focus {\n background-color: #d39e00 !important;\n}\n\n.bg-danger {\n background-color: #dc3545 !important;\n}\n\na.bg-danger:hover, a.bg-danger:focus,\nbutton.bg-danger:hover,\nbutton.bg-danger:focus {\n background-color: #bd2130 !important;\n}\n\n.bg-light {\n background-color: #f8f9fa !important;\n}\n\na.bg-light:hover, a.bg-light:focus,\nbutton.bg-light:hover,\nbutton.bg-light:focus {\n background-color: #dae0e5 !important;\n}\n\n.bg-dark {\n background-color: #343a40 !important;\n}\n\na.bg-dark:hover, a.bg-dark:focus,\nbutton.bg-dark:hover,\nbutton.bg-dark:focus {\n background-color: #1d2124 !important;\n}\n\n.bg-white {\n background-color: #fff !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n\n.border {\n border: 1px solid #dee2e6 !important;\n}\n\n.border-top {\n border-top: 1px solid #dee2e6 !important;\n}\n\n.border-right {\n border-right: 1px solid #dee2e6 !important;\n}\n\n.border-bottom {\n border-bottom: 1px solid #dee2e6 !important;\n}\n\n.border-left {\n border-left: 1px solid #dee2e6 !important;\n}\n\n.border-0 {\n border: 0 !important;\n}\n\n.border-top-0 {\n border-top: 0 !important;\n}\n\n.border-right-0 {\n border-right: 0 !important;\n}\n\n.border-bottom-0 {\n border-bottom: 0 !important;\n}\n\n.border-left-0 {\n border-left: 0 !important;\n}\n\n.border-primary {\n border-color: #007bff !important;\n}\n\n.border-secondary {\n border-color: #6c757d !important;\n}\n\n.border-success {\n border-color: #28a745 !important;\n}\n\n.border-info {\n border-color: #17a2b8 !important;\n}\n\n.border-warning {\n border-color: #ffc107 !important;\n}\n\n.border-danger {\n border-color: #dc3545 !important;\n}\n\n.border-light {\n border-color: #f8f9fa !important;\n}\n\n.border-dark {\n border-color: #343a40 !important;\n}\n\n.border-white {\n border-color: #fff !important;\n}\n\n.rounded-sm {\n border-radius: 0.2rem !important;\n}\n\n.rounded {\n border-radius: 0.25rem !important;\n}\n\n.rounded-top {\n border-top-left-radius: 0.25rem !important;\n border-top-right-radius: 0.25rem !important;\n}\n\n.rounded-right {\n border-top-right-radius: 0.25rem !important;\n border-bottom-right-radius: 0.25rem !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-left {\n border-top-left-radius: 0.25rem !important;\n border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-lg {\n border-radius: 0.3rem !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-pill {\n border-radius: 50rem !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n\n.clearfix::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.d-none {\n display: none !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-inline-flex {\n display: inline-flex !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-none {\n display: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 768px) {\n .d-md-none {\n display: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: flex !important;\n }\n .d-md-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 992px) {\n .d-lg-none {\n display: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media (min-width: 1200px) {\n .d-xl-none {\n display: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: inline-flex !important;\n }\n}\n\n@media print {\n .d-print-none {\n display: none !important;\n }\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: flex !important;\n }\n .d-print-inline-flex {\n display: inline-flex !important;\n }\n}\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n}\n\n.embed-responsive::before {\n display: block;\n content: \"\";\n}\n\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n\n.embed-responsive-21by9::before {\n padding-top: 42.857143%;\n}\n\n.embed-responsive-16by9::before {\n padding-top: 56.25%;\n}\n\n.embed-responsive-4by3::before {\n padding-top: 75%;\n}\n\n.embed-responsive-1by1::before {\n padding-top: 100%;\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n flex-direction: column-reverse !important;\n}\n\n.flex-wrap {\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n}\n\n.flex-fill {\n flex: 1 1 auto !important;\n}\n\n.flex-grow-0 {\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n flex-shrink: 1 !important;\n}\n\n.justify-content-start {\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n justify-content: center !important;\n}\n\n.justify-content-between {\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n justify-content: space-around !important;\n}\n\n.align-items-start {\n align-items: flex-start !important;\n}\n\n.align-items-end {\n align-items: flex-end !important;\n}\n\n.align-items-center {\n align-items: center !important;\n}\n\n.align-items-baseline {\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n align-items: stretch !important;\n}\n\n.align-content-start {\n align-content: flex-start !important;\n}\n\n.align-content-end {\n align-content: flex-end !important;\n}\n\n.align-content-center {\n align-content: center !important;\n}\n\n.align-content-between {\n align-content: space-between !important;\n}\n\n.align-content-around {\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n align-content: stretch !important;\n}\n\n.align-self-auto {\n align-self: auto !important;\n}\n\n.align-self-start {\n align-self: flex-start !important;\n}\n\n.align-self-end {\n align-self: flex-end !important;\n}\n\n.align-self-center {\n align-self: center !important;\n}\n\n.align-self-baseline {\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n align-self: stretch !important;\n}\n\n@media (min-width: 576px) {\n .flex-sm-row {\n flex-direction: row !important;\n }\n .flex-sm-column {\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-sm-wrap {\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-sm-fill {\n flex: 1 1 auto !important;\n }\n .flex-sm-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-sm-start {\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n justify-content: center !important;\n }\n .justify-content-sm-between {\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n justify-content: space-around !important;\n }\n .align-items-sm-start {\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n align-items: center !important;\n }\n .align-items-sm-baseline {\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n align-items: stretch !important;\n }\n .align-content-sm-start {\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n align-content: center !important;\n }\n .align-content-sm-between {\n align-content: space-between !important;\n }\n .align-content-sm-around {\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n align-self: auto !important;\n }\n .align-self-sm-start {\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n align-self: center !important;\n }\n .align-self-sm-baseline {\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 768px) {\n .flex-md-row {\n flex-direction: row !important;\n }\n .flex-md-column {\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-md-wrap {\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-md-fill {\n flex: 1 1 auto !important;\n }\n .flex-md-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-md-start {\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n justify-content: center !important;\n }\n .justify-content-md-between {\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n justify-content: space-around !important;\n }\n .align-items-md-start {\n align-items: flex-start !important;\n }\n .align-items-md-end {\n align-items: flex-end !important;\n }\n .align-items-md-center {\n align-items: center !important;\n }\n .align-items-md-baseline {\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n align-items: stretch !important;\n }\n .align-content-md-start {\n align-content: flex-start !important;\n }\n .align-content-md-end {\n align-content: flex-end !important;\n }\n .align-content-md-center {\n align-content: center !important;\n }\n .align-content-md-between {\n align-content: space-between !important;\n }\n .align-content-md-around {\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n align-content: stretch !important;\n }\n .align-self-md-auto {\n align-self: auto !important;\n }\n .align-self-md-start {\n align-self: flex-start !important;\n }\n .align-self-md-end {\n align-self: flex-end !important;\n }\n .align-self-md-center {\n align-self: center !important;\n }\n .align-self-md-baseline {\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 992px) {\n .flex-lg-row {\n flex-direction: row !important;\n }\n .flex-lg-column {\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-lg-wrap {\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-lg-fill {\n flex: 1 1 auto !important;\n }\n .flex-lg-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-lg-start {\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n justify-content: center !important;\n }\n .justify-content-lg-between {\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n justify-content: space-around !important;\n }\n .align-items-lg-start {\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n align-items: center !important;\n }\n .align-items-lg-baseline {\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n align-items: stretch !important;\n }\n .align-content-lg-start {\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n align-content: center !important;\n }\n .align-content-lg-between {\n align-content: space-between !important;\n }\n .align-content-lg-around {\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n align-self: auto !important;\n }\n .align-self-lg-start {\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n align-self: center !important;\n }\n .align-self-lg-baseline {\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n align-self: stretch !important;\n }\n}\n\n@media (min-width: 1200px) {\n .flex-xl-row {\n flex-direction: row !important;\n }\n .flex-xl-column {\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .flex-xl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .justify-content-xl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n justify-content: center !important;\n }\n .justify-content-xl-between {\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n justify-content: space-around !important;\n }\n .align-items-xl-start {\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n align-items: center !important;\n }\n .align-items-xl-baseline {\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n align-items: stretch !important;\n }\n .align-content-xl-start {\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n align-content: center !important;\n }\n .align-content-xl-between {\n align-content: space-between !important;\n }\n .align-content-xl-around {\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n align-self: auto !important;\n }\n .align-self-xl-start {\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n align-self: center !important;\n }\n .align-self-xl-baseline {\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n align-self: stretch !important;\n }\n}\n\n.float-left {\n float: left !important;\n}\n\n.float-right {\n float: right !important;\n}\n\n.float-none {\n float: none !important;\n}\n\n@media (min-width: 576px) {\n .float-sm-left {\n float: left !important;\n }\n .float-sm-right {\n float: right !important;\n }\n .float-sm-none {\n float: none !important;\n }\n}\n\n@media (min-width: 768px) {\n .float-md-left {\n float: left !important;\n }\n .float-md-right {\n float: right !important;\n }\n .float-md-none {\n float: none !important;\n }\n}\n\n@media (min-width: 992px) {\n .float-lg-left {\n float: left !important;\n }\n .float-lg-right {\n float: right !important;\n }\n .float-lg-none {\n float: none !important;\n }\n}\n\n@media (min-width: 1200px) {\n .float-xl-left {\n float: left !important;\n }\n .float-xl-right {\n float: right !important;\n }\n .float-xl-none {\n float: none !important;\n }\n}\n\n.overflow-auto {\n overflow: auto !important;\n}\n\n.overflow-hidden {\n overflow: hidden !important;\n}\n\n.position-static {\n position: static !important;\n}\n\n.position-relative {\n position: relative !important;\n}\n\n.position-absolute {\n position: absolute !important;\n}\n\n.position-fixed {\n position: fixed !important;\n}\n\n.position-sticky {\n position: sticky !important;\n}\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1030;\n}\n\n@supports (position: sticky) {\n .sticky-top {\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n}\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n}\n\n.shadow-sm {\n box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;\n}\n\n.shadow {\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;\n}\n\n.shadow-lg {\n box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important;\n}\n\n.shadow-none {\n box-shadow: none !important;\n}\n\n.w-25 {\n width: 25% !important;\n}\n\n.w-50 {\n width: 50% !important;\n}\n\n.w-75 {\n width: 75% !important;\n}\n\n.w-100 {\n width: 100% !important;\n}\n\n.w-auto {\n width: auto !important;\n}\n\n.h-25 {\n height: 25% !important;\n}\n\n.h-50 {\n height: 50% !important;\n}\n\n.h-75 {\n height: 75% !important;\n}\n\n.h-100 {\n height: 100% !important;\n}\n\n.h-auto {\n height: auto !important;\n}\n\n.mw-100 {\n max-width: 100% !important;\n}\n\n.mh-100 {\n max-height: 100% !important;\n}\n\n.min-vw-100 {\n min-width: 100vw !important;\n}\n\n.min-vh-100 {\n min-height: 100vh !important;\n}\n\n.vw-100 {\n width: 100vw !important;\n}\n\n.vh-100 {\n height: 100vh !important;\n}\n\n.stretched-link::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1;\n pointer-events: auto;\n content: \"\";\n background-color: rgba(0, 0, 0, 0);\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.mt-0,\n.my-0 {\n margin-top: 0 !important;\n}\n\n.mr-0,\n.mx-0 {\n margin-right: 0 !important;\n}\n\n.mb-0,\n.my-0 {\n margin-bottom: 0 !important;\n}\n\n.ml-0,\n.mx-0 {\n margin-left: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.mt-1,\n.my-1 {\n margin-top: 0.25rem !important;\n}\n\n.mr-1,\n.mx-1 {\n margin-right: 0.25rem !important;\n}\n\n.mb-1,\n.my-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.ml-1,\n.mx-1 {\n margin-left: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.mt-2,\n.my-2 {\n margin-top: 0.5rem !important;\n}\n\n.mr-2,\n.mx-2 {\n margin-right: 0.5rem !important;\n}\n\n.mb-2,\n.my-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.ml-2,\n.mx-2 {\n margin-left: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.mt-3,\n.my-3 {\n margin-top: 1rem !important;\n}\n\n.mr-3,\n.mx-3 {\n margin-right: 1rem !important;\n}\n\n.mb-3,\n.my-3 {\n margin-bottom: 1rem !important;\n}\n\n.ml-3,\n.mx-3 {\n margin-left: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.mt-4,\n.my-4 {\n margin-top: 1.5rem !important;\n}\n\n.mr-4,\n.mx-4 {\n margin-right: 1.5rem !important;\n}\n\n.mb-4,\n.my-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.ml-4,\n.mx-4 {\n margin-left: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.mt-5,\n.my-5 {\n margin-top: 3rem !important;\n}\n\n.mr-5,\n.mx-5 {\n margin-right: 3rem !important;\n}\n\n.mb-5,\n.my-5 {\n margin-bottom: 3rem !important;\n}\n\n.ml-5,\n.mx-5 {\n margin-left: 3rem !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.pt-0,\n.py-0 {\n padding-top: 0 !important;\n}\n\n.pr-0,\n.px-0 {\n padding-right: 0 !important;\n}\n\n.pb-0,\n.py-0 {\n padding-bottom: 0 !important;\n}\n\n.pl-0,\n.px-0 {\n padding-left: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.pt-1,\n.py-1 {\n padding-top: 0.25rem !important;\n}\n\n.pr-1,\n.px-1 {\n padding-right: 0.25rem !important;\n}\n\n.pb-1,\n.py-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pl-1,\n.px-1 {\n padding-left: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.pt-2,\n.py-2 {\n padding-top: 0.5rem !important;\n}\n\n.pr-2,\n.px-2 {\n padding-right: 0.5rem !important;\n}\n\n.pb-2,\n.py-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pl-2,\n.px-2 {\n padding-left: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.pt-3,\n.py-3 {\n padding-top: 1rem !important;\n}\n\n.pr-3,\n.px-3 {\n padding-right: 1rem !important;\n}\n\n.pb-3,\n.py-3 {\n padding-bottom: 1rem !important;\n}\n\n.pl-3,\n.px-3 {\n padding-left: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.pt-4,\n.py-4 {\n padding-top: 1.5rem !important;\n}\n\n.pr-4,\n.px-4 {\n padding-right: 1.5rem !important;\n}\n\n.pb-4,\n.py-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pl-4,\n.px-4 {\n padding-left: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.pt-5,\n.py-5 {\n padding-top: 3rem !important;\n}\n\n.pr-5,\n.px-5 {\n padding-right: 3rem !important;\n}\n\n.pb-5,\n.py-5 {\n padding-bottom: 3rem !important;\n}\n\n.pl-5,\n.px-5 {\n padding-left: 3rem !important;\n}\n\n.m-n1 {\n margin: -0.25rem !important;\n}\n\n.mt-n1,\n.my-n1 {\n margin-top: -0.25rem !important;\n}\n\n.mr-n1,\n.mx-n1 {\n margin-right: -0.25rem !important;\n}\n\n.mb-n1,\n.my-n1 {\n margin-bottom: -0.25rem !important;\n}\n\n.ml-n1,\n.mx-n1 {\n margin-left: -0.25rem !important;\n}\n\n.m-n2 {\n margin: -0.5rem !important;\n}\n\n.mt-n2,\n.my-n2 {\n margin-top: -0.5rem !important;\n}\n\n.mr-n2,\n.mx-n2 {\n margin-right: -0.5rem !important;\n}\n\n.mb-n2,\n.my-n2 {\n margin-bottom: -0.5rem !important;\n}\n\n.ml-n2,\n.mx-n2 {\n margin-left: -0.5rem !important;\n}\n\n.m-n3 {\n margin: -1rem !important;\n}\n\n.mt-n3,\n.my-n3 {\n margin-top: -1rem !important;\n}\n\n.mr-n3,\n.mx-n3 {\n margin-right: -1rem !important;\n}\n\n.mb-n3,\n.my-n3 {\n margin-bottom: -1rem !important;\n}\n\n.ml-n3,\n.mx-n3 {\n margin-left: -1rem !important;\n}\n\n.m-n4 {\n margin: -1.5rem !important;\n}\n\n.mt-n4,\n.my-n4 {\n margin-top: -1.5rem !important;\n}\n\n.mr-n4,\n.mx-n4 {\n margin-right: -1.5rem !important;\n}\n\n.mb-n4,\n.my-n4 {\n margin-bottom: -1.5rem !important;\n}\n\n.ml-n4,\n.mx-n4 {\n margin-left: -1.5rem !important;\n}\n\n.m-n5 {\n margin: -3rem !important;\n}\n\n.mt-n5,\n.my-n5 {\n margin-top: -3rem !important;\n}\n\n.mr-n5,\n.mx-n5 {\n margin-right: -3rem !important;\n}\n\n.mb-n5,\n.my-n5 {\n margin-bottom: -3rem !important;\n}\n\n.ml-n5,\n.mx-n5 {\n margin-left: -3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mt-auto,\n.my-auto {\n margin-top: auto !important;\n}\n\n.mr-auto,\n.mx-auto {\n margin-right: auto !important;\n}\n\n.mb-auto,\n.my-auto {\n margin-bottom: auto !important;\n}\n\n.ml-auto,\n.mx-auto {\n margin-left: auto !important;\n}\n\n@media (min-width: 576px) {\n .m-sm-0 {\n margin: 0 !important;\n }\n .mt-sm-0,\n .my-sm-0 {\n margin-top: 0 !important;\n }\n .mr-sm-0,\n .mx-sm-0 {\n margin-right: 0 !important;\n }\n .mb-sm-0,\n .my-sm-0 {\n margin-bottom: 0 !important;\n }\n .ml-sm-0,\n .mx-sm-0 {\n margin-left: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .mt-sm-1,\n .my-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mr-sm-1,\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n }\n .mb-sm-1,\n .my-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-sm-1,\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .mt-sm-2,\n .my-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mr-sm-2,\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n }\n .mb-sm-2,\n .my-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-sm-2,\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .mt-sm-3,\n .my-sm-3 {\n margin-top: 1rem !important;\n }\n .mr-sm-3,\n .mx-sm-3 {\n margin-right: 1rem !important;\n }\n .mb-sm-3,\n .my-sm-3 {\n margin-bottom: 1rem !important;\n }\n .ml-sm-3,\n .mx-sm-3 {\n margin-left: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .mt-sm-4,\n .my-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mr-sm-4,\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n }\n .mb-sm-4,\n .my-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-sm-4,\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .mt-sm-5,\n .my-sm-5 {\n margin-top: 3rem !important;\n }\n .mr-sm-5,\n .mx-sm-5 {\n margin-right: 3rem !important;\n }\n .mb-sm-5,\n .my-sm-5 {\n margin-bottom: 3rem !important;\n }\n .ml-sm-5,\n .mx-sm-5 {\n margin-left: 3rem !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .pt-sm-0,\n .py-sm-0 {\n padding-top: 0 !important;\n }\n .pr-sm-0,\n .px-sm-0 {\n padding-right: 0 !important;\n }\n .pb-sm-0,\n .py-sm-0 {\n padding-bottom: 0 !important;\n }\n .pl-sm-0,\n .px-sm-0 {\n padding-left: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .pt-sm-1,\n .py-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pr-sm-1,\n .px-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pb-sm-1,\n .py-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-sm-1,\n .px-sm-1 {\n padding-left: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .pt-sm-2,\n .py-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pr-sm-2,\n .px-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pb-sm-2,\n .py-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-sm-2,\n .px-sm-2 {\n padding-left: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .pt-sm-3,\n .py-sm-3 {\n padding-top: 1rem !important;\n }\n .pr-sm-3,\n .px-sm-3 {\n padding-right: 1rem !important;\n }\n .pb-sm-3,\n .py-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pl-sm-3,\n .px-sm-3 {\n padding-left: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .pt-sm-4,\n .py-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pr-sm-4,\n .px-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pb-sm-4,\n .py-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-sm-4,\n .px-sm-4 {\n padding-left: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .pt-sm-5,\n .py-sm-5 {\n padding-top: 3rem !important;\n }\n .pr-sm-5,\n .px-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-5,\n .py-sm-5 {\n padding-bottom: 3rem !important;\n }\n .pl-sm-5,\n .px-sm-5 {\n padding-left: 3rem !important;\n }\n .m-sm-n1 {\n margin: -0.25rem !important;\n }\n .mt-sm-n1,\n .my-sm-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-sm-n1,\n .mx-sm-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-sm-n1,\n .my-sm-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-sm-n1,\n .mx-sm-n1 {\n margin-left: -0.25rem !important;\n }\n .m-sm-n2 {\n margin: -0.5rem !important;\n }\n .mt-sm-n2,\n .my-sm-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-sm-n2,\n .mx-sm-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-sm-n2,\n .my-sm-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-sm-n2,\n .mx-sm-n2 {\n margin-left: -0.5rem !important;\n }\n .m-sm-n3 {\n margin: -1rem !important;\n }\n .mt-sm-n3,\n .my-sm-n3 {\n margin-top: -1rem !important;\n }\n .mr-sm-n3,\n .mx-sm-n3 {\n margin-right: -1rem !important;\n }\n .mb-sm-n3,\n .my-sm-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-sm-n3,\n .mx-sm-n3 {\n margin-left: -1rem !important;\n }\n .m-sm-n4 {\n margin: -1.5rem !important;\n }\n .mt-sm-n4,\n .my-sm-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-sm-n4,\n .mx-sm-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-sm-n4,\n .my-sm-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-sm-n4,\n .mx-sm-n4 {\n margin-left: -1.5rem !important;\n }\n .m-sm-n5 {\n margin: -3rem !important;\n }\n .mt-sm-n5,\n .my-sm-n5 {\n margin-top: -3rem !important;\n }\n .mr-sm-n5,\n .mx-sm-n5 {\n margin-right: -3rem !important;\n }\n .mb-sm-n5,\n .my-sm-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-sm-n5,\n .mx-sm-n5 {\n margin-left: -3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mt-sm-auto,\n .my-sm-auto {\n margin-top: auto !important;\n }\n .mr-sm-auto,\n .mx-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-auto,\n .my-sm-auto {\n margin-bottom: auto !important;\n }\n .ml-sm-auto,\n .mx-sm-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 768px) {\n .m-md-0 {\n margin: 0 !important;\n }\n .mt-md-0,\n .my-md-0 {\n margin-top: 0 !important;\n }\n .mr-md-0,\n .mx-md-0 {\n margin-right: 0 !important;\n }\n .mb-md-0,\n .my-md-0 {\n margin-bottom: 0 !important;\n }\n .ml-md-0,\n .mx-md-0 {\n margin-left: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .mt-md-1,\n .my-md-1 {\n margin-top: 0.25rem !important;\n }\n .mr-md-1,\n .mx-md-1 {\n margin-right: 0.25rem !important;\n }\n .mb-md-1,\n .my-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-md-1,\n .mx-md-1 {\n margin-left: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .mt-md-2,\n .my-md-2 {\n margin-top: 0.5rem !important;\n }\n .mr-md-2,\n .mx-md-2 {\n margin-right: 0.5rem !important;\n }\n .mb-md-2,\n .my-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-md-2,\n .mx-md-2 {\n margin-left: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .mt-md-3,\n .my-md-3 {\n margin-top: 1rem !important;\n }\n .mr-md-3,\n .mx-md-3 {\n margin-right: 1rem !important;\n }\n .mb-md-3,\n .my-md-3 {\n margin-bottom: 1rem !important;\n }\n .ml-md-3,\n .mx-md-3 {\n margin-left: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .mt-md-4,\n .my-md-4 {\n margin-top: 1.5rem !important;\n }\n .mr-md-4,\n .mx-md-4 {\n margin-right: 1.5rem !important;\n }\n .mb-md-4,\n .my-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-md-4,\n .mx-md-4 {\n margin-left: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .mt-md-5,\n .my-md-5 {\n margin-top: 3rem !important;\n }\n .mr-md-5,\n .mx-md-5 {\n margin-right: 3rem !important;\n }\n .mb-md-5,\n .my-md-5 {\n margin-bottom: 3rem !important;\n }\n .ml-md-5,\n .mx-md-5 {\n margin-left: 3rem !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .pt-md-0,\n .py-md-0 {\n padding-top: 0 !important;\n }\n .pr-md-0,\n .px-md-0 {\n padding-right: 0 !important;\n }\n .pb-md-0,\n .py-md-0 {\n padding-bottom: 0 !important;\n }\n .pl-md-0,\n .px-md-0 {\n padding-left: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .pt-md-1,\n .py-md-1 {\n padding-top: 0.25rem !important;\n }\n .pr-md-1,\n .px-md-1 {\n padding-right: 0.25rem !important;\n }\n .pb-md-1,\n .py-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-md-1,\n .px-md-1 {\n padding-left: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .pt-md-2,\n .py-md-2 {\n padding-top: 0.5rem !important;\n }\n .pr-md-2,\n .px-md-2 {\n padding-right: 0.5rem !important;\n }\n .pb-md-2,\n .py-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-md-2,\n .px-md-2 {\n padding-left: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .pt-md-3,\n .py-md-3 {\n padding-top: 1rem !important;\n }\n .pr-md-3,\n .px-md-3 {\n padding-right: 1rem !important;\n }\n .pb-md-3,\n .py-md-3 {\n padding-bottom: 1rem !important;\n }\n .pl-md-3,\n .px-md-3 {\n padding-left: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .pt-md-4,\n .py-md-4 {\n padding-top: 1.5rem !important;\n }\n .pr-md-4,\n .px-md-4 {\n padding-right: 1.5rem !important;\n }\n .pb-md-4,\n .py-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-md-4,\n .px-md-4 {\n padding-left: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .pt-md-5,\n .py-md-5 {\n padding-top: 3rem !important;\n }\n .pr-md-5,\n .px-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-5,\n .py-md-5 {\n padding-bottom: 3rem !important;\n }\n .pl-md-5,\n .px-md-5 {\n padding-left: 3rem !important;\n }\n .m-md-n1 {\n margin: -0.25rem !important;\n }\n .mt-md-n1,\n .my-md-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-md-n1,\n .mx-md-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-md-n1,\n .my-md-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-md-n1,\n .mx-md-n1 {\n margin-left: -0.25rem !important;\n }\n .m-md-n2 {\n margin: -0.5rem !important;\n }\n .mt-md-n2,\n .my-md-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-md-n2,\n .mx-md-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-md-n2,\n .my-md-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-md-n2,\n .mx-md-n2 {\n margin-left: -0.5rem !important;\n }\n .m-md-n3 {\n margin: -1rem !important;\n }\n .mt-md-n3,\n .my-md-n3 {\n margin-top: -1rem !important;\n }\n .mr-md-n3,\n .mx-md-n3 {\n margin-right: -1rem !important;\n }\n .mb-md-n3,\n .my-md-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-md-n3,\n .mx-md-n3 {\n margin-left: -1rem !important;\n }\n .m-md-n4 {\n margin: -1.5rem !important;\n }\n .mt-md-n4,\n .my-md-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-md-n4,\n .mx-md-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-md-n4,\n .my-md-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-md-n4,\n .mx-md-n4 {\n margin-left: -1.5rem !important;\n }\n .m-md-n5 {\n margin: -3rem !important;\n }\n .mt-md-n5,\n .my-md-n5 {\n margin-top: -3rem !important;\n }\n .mr-md-n5,\n .mx-md-n5 {\n margin-right: -3rem !important;\n }\n .mb-md-n5,\n .my-md-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-md-n5,\n .mx-md-n5 {\n margin-left: -3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mt-md-auto,\n .my-md-auto {\n margin-top: auto !important;\n }\n .mr-md-auto,\n .mx-md-auto {\n margin-right: auto !important;\n }\n .mb-md-auto,\n .my-md-auto {\n margin-bottom: auto !important;\n }\n .ml-md-auto,\n .mx-md-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 992px) {\n .m-lg-0 {\n margin: 0 !important;\n }\n .mt-lg-0,\n .my-lg-0 {\n margin-top: 0 !important;\n }\n .mr-lg-0,\n .mx-lg-0 {\n margin-right: 0 !important;\n }\n .mb-lg-0,\n .my-lg-0 {\n margin-bottom: 0 !important;\n }\n .ml-lg-0,\n .mx-lg-0 {\n margin-left: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .mt-lg-1,\n .my-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mr-lg-1,\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n }\n .mb-lg-1,\n .my-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-lg-1,\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .mt-lg-2,\n .my-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mr-lg-2,\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n }\n .mb-lg-2,\n .my-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-lg-2,\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .mt-lg-3,\n .my-lg-3 {\n margin-top: 1rem !important;\n }\n .mr-lg-3,\n .mx-lg-3 {\n margin-right: 1rem !important;\n }\n .mb-lg-3,\n .my-lg-3 {\n margin-bottom: 1rem !important;\n }\n .ml-lg-3,\n .mx-lg-3 {\n margin-left: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .mt-lg-4,\n .my-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mr-lg-4,\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n }\n .mb-lg-4,\n .my-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-lg-4,\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .mt-lg-5,\n .my-lg-5 {\n margin-top: 3rem !important;\n }\n .mr-lg-5,\n .mx-lg-5 {\n margin-right: 3rem !important;\n }\n .mb-lg-5,\n .my-lg-5 {\n margin-bottom: 3rem !important;\n }\n .ml-lg-5,\n .mx-lg-5 {\n margin-left: 3rem !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .pt-lg-0,\n .py-lg-0 {\n padding-top: 0 !important;\n }\n .pr-lg-0,\n .px-lg-0 {\n padding-right: 0 !important;\n }\n .pb-lg-0,\n .py-lg-0 {\n padding-bottom: 0 !important;\n }\n .pl-lg-0,\n .px-lg-0 {\n padding-left: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .pt-lg-1,\n .py-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pr-lg-1,\n .px-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pb-lg-1,\n .py-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-lg-1,\n .px-lg-1 {\n padding-left: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .pt-lg-2,\n .py-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pr-lg-2,\n .px-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pb-lg-2,\n .py-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-lg-2,\n .px-lg-2 {\n padding-left: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .pt-lg-3,\n .py-lg-3 {\n padding-top: 1rem !important;\n }\n .pr-lg-3,\n .px-lg-3 {\n padding-right: 1rem !important;\n }\n .pb-lg-3,\n .py-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pl-lg-3,\n .px-lg-3 {\n padding-left: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .pt-lg-4,\n .py-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pr-lg-4,\n .px-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pb-lg-4,\n .py-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-lg-4,\n .px-lg-4 {\n padding-left: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .pt-lg-5,\n .py-lg-5 {\n padding-top: 3rem !important;\n }\n .pr-lg-5,\n .px-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-5,\n .py-lg-5 {\n padding-bottom: 3rem !important;\n }\n .pl-lg-5,\n .px-lg-5 {\n padding-left: 3rem !important;\n }\n .m-lg-n1 {\n margin: -0.25rem !important;\n }\n .mt-lg-n1,\n .my-lg-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-lg-n1,\n .mx-lg-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-lg-n1,\n .my-lg-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-lg-n1,\n .mx-lg-n1 {\n margin-left: -0.25rem !important;\n }\n .m-lg-n2 {\n margin: -0.5rem !important;\n }\n .mt-lg-n2,\n .my-lg-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-lg-n2,\n .mx-lg-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-lg-n2,\n .my-lg-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-lg-n2,\n .mx-lg-n2 {\n margin-left: -0.5rem !important;\n }\n .m-lg-n3 {\n margin: -1rem !important;\n }\n .mt-lg-n3,\n .my-lg-n3 {\n margin-top: -1rem !important;\n }\n .mr-lg-n3,\n .mx-lg-n3 {\n margin-right: -1rem !important;\n }\n .mb-lg-n3,\n .my-lg-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-lg-n3,\n .mx-lg-n3 {\n margin-left: -1rem !important;\n }\n .m-lg-n4 {\n margin: -1.5rem !important;\n }\n .mt-lg-n4,\n .my-lg-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-lg-n4,\n .mx-lg-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-lg-n4,\n .my-lg-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-lg-n4,\n .mx-lg-n4 {\n margin-left: -1.5rem !important;\n }\n .m-lg-n5 {\n margin: -3rem !important;\n }\n .mt-lg-n5,\n .my-lg-n5 {\n margin-top: -3rem !important;\n }\n .mr-lg-n5,\n .mx-lg-n5 {\n margin-right: -3rem !important;\n }\n .mb-lg-n5,\n .my-lg-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-lg-n5,\n .mx-lg-n5 {\n margin-left: -3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mt-lg-auto,\n .my-lg-auto {\n margin-top: auto !important;\n }\n .mr-lg-auto,\n .mx-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-auto,\n .my-lg-auto {\n margin-bottom: auto !important;\n }\n .ml-lg-auto,\n .mx-lg-auto {\n margin-left: auto !important;\n }\n}\n\n@media (min-width: 1200px) {\n .m-xl-0 {\n margin: 0 !important;\n }\n .mt-xl-0,\n .my-xl-0 {\n margin-top: 0 !important;\n }\n .mr-xl-0,\n .mx-xl-0 {\n margin-right: 0 !important;\n }\n .mb-xl-0,\n .my-xl-0 {\n margin-bottom: 0 !important;\n }\n .ml-xl-0,\n .mx-xl-0 {\n margin-left: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .mt-xl-1,\n .my-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mr-xl-1,\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n }\n .mb-xl-1,\n .my-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .ml-xl-1,\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .mt-xl-2,\n .my-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mr-xl-2,\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n }\n .mb-xl-2,\n .my-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .ml-xl-2,\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .mt-xl-3,\n .my-xl-3 {\n margin-top: 1rem !important;\n }\n .mr-xl-3,\n .mx-xl-3 {\n margin-right: 1rem !important;\n }\n .mb-xl-3,\n .my-xl-3 {\n margin-bottom: 1rem !important;\n }\n .ml-xl-3,\n .mx-xl-3 {\n margin-left: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .mt-xl-4,\n .my-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mr-xl-4,\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n }\n .mb-xl-4,\n .my-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .ml-xl-4,\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .mt-xl-5,\n .my-xl-5 {\n margin-top: 3rem !important;\n }\n .mr-xl-5,\n .mx-xl-5 {\n margin-right: 3rem !important;\n }\n .mb-xl-5,\n .my-xl-5 {\n margin-bottom: 3rem !important;\n }\n .ml-xl-5,\n .mx-xl-5 {\n margin-left: 3rem !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .pt-xl-0,\n .py-xl-0 {\n padding-top: 0 !important;\n }\n .pr-xl-0,\n .px-xl-0 {\n padding-right: 0 !important;\n }\n .pb-xl-0,\n .py-xl-0 {\n padding-bottom: 0 !important;\n }\n .pl-xl-0,\n .px-xl-0 {\n padding-left: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .pt-xl-1,\n .py-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pr-xl-1,\n .px-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pb-xl-1,\n .py-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pl-xl-1,\n .px-xl-1 {\n padding-left: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .pt-xl-2,\n .py-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pr-xl-2,\n .px-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pb-xl-2,\n .py-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pl-xl-2,\n .px-xl-2 {\n padding-left: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .pt-xl-3,\n .py-xl-3 {\n padding-top: 1rem !important;\n }\n .pr-xl-3,\n .px-xl-3 {\n padding-right: 1rem !important;\n }\n .pb-xl-3,\n .py-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pl-xl-3,\n .px-xl-3 {\n padding-left: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .pt-xl-4,\n .py-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pr-xl-4,\n .px-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pb-xl-4,\n .py-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pl-xl-4,\n .px-xl-4 {\n padding-left: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .pt-xl-5,\n .py-xl-5 {\n padding-top: 3rem !important;\n }\n .pr-xl-5,\n .px-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-5,\n .py-xl-5 {\n padding-bottom: 3rem !important;\n }\n .pl-xl-5,\n .px-xl-5 {\n padding-left: 3rem !important;\n }\n .m-xl-n1 {\n margin: -0.25rem !important;\n }\n .mt-xl-n1,\n .my-xl-n1 {\n margin-top: -0.25rem !important;\n }\n .mr-xl-n1,\n .mx-xl-n1 {\n margin-right: -0.25rem !important;\n }\n .mb-xl-n1,\n .my-xl-n1 {\n margin-bottom: -0.25rem !important;\n }\n .ml-xl-n1,\n .mx-xl-n1 {\n margin-left: -0.25rem !important;\n }\n .m-xl-n2 {\n margin: -0.5rem !important;\n }\n .mt-xl-n2,\n .my-xl-n2 {\n margin-top: -0.5rem !important;\n }\n .mr-xl-n2,\n .mx-xl-n2 {\n margin-right: -0.5rem !important;\n }\n .mb-xl-n2,\n .my-xl-n2 {\n margin-bottom: -0.5rem !important;\n }\n .ml-xl-n2,\n .mx-xl-n2 {\n margin-left: -0.5rem !important;\n }\n .m-xl-n3 {\n margin: -1rem !important;\n }\n .mt-xl-n3,\n .my-xl-n3 {\n margin-top: -1rem !important;\n }\n .mr-xl-n3,\n .mx-xl-n3 {\n margin-right: -1rem !important;\n }\n .mb-xl-n3,\n .my-xl-n3 {\n margin-bottom: -1rem !important;\n }\n .ml-xl-n3,\n .mx-xl-n3 {\n margin-left: -1rem !important;\n }\n .m-xl-n4 {\n margin: -1.5rem !important;\n }\n .mt-xl-n4,\n .my-xl-n4 {\n margin-top: -1.5rem !important;\n }\n .mr-xl-n4,\n .mx-xl-n4 {\n margin-right: -1.5rem !important;\n }\n .mb-xl-n4,\n .my-xl-n4 {\n margin-bottom: -1.5rem !important;\n }\n .ml-xl-n4,\n .mx-xl-n4 {\n margin-left: -1.5rem !important;\n }\n .m-xl-n5 {\n margin: -3rem !important;\n }\n .mt-xl-n5,\n .my-xl-n5 {\n margin-top: -3rem !important;\n }\n .mr-xl-n5,\n .mx-xl-n5 {\n margin-right: -3rem !important;\n }\n .mb-xl-n5,\n .my-xl-n5 {\n margin-bottom: -3rem !important;\n }\n .ml-xl-n5,\n .mx-xl-n5 {\n margin-left: -3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mt-xl-auto,\n .my-xl-auto {\n margin-top: auto !important;\n }\n .mr-xl-auto,\n .mx-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-auto,\n .my-xl-auto {\n margin-bottom: auto !important;\n }\n .ml-xl-auto,\n .mx-xl-auto {\n margin-left: auto !important;\n }\n}\n\n.text-monospace {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !important;\n}\n\n.text-justify {\n text-align: justify !important;\n}\n\n.text-wrap {\n white-space: normal !important;\n}\n\n.text-nowrap {\n white-space: nowrap !important;\n}\n\n.text-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.text-left {\n text-align: left !important;\n}\n\n.text-right {\n text-align: right !important;\n}\n\n.text-center {\n text-align: center !important;\n}\n\n@media (min-width: 576px) {\n .text-sm-left {\n text-align: left !important;\n }\n .text-sm-right {\n text-align: right !important;\n }\n .text-sm-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 768px) {\n .text-md-left {\n text-align: left !important;\n }\n .text-md-right {\n text-align: right !important;\n }\n .text-md-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 992px) {\n .text-lg-left {\n text-align: left !important;\n }\n .text-lg-right {\n text-align: right !important;\n }\n .text-lg-center {\n text-align: center !important;\n }\n}\n\n@media (min-width: 1200px) {\n .text-xl-left {\n text-align: left !important;\n }\n .text-xl-right {\n text-align: right !important;\n }\n .text-xl-center {\n text-align: center !important;\n }\n}\n\n.text-lowercase {\n text-transform: lowercase !important;\n}\n\n.text-uppercase {\n text-transform: uppercase !important;\n}\n\n.text-capitalize {\n text-transform: capitalize !important;\n}\n\n.font-weight-light {\n font-weight: 300 !important;\n}\n\n.font-weight-lighter {\n font-weight: lighter !important;\n}\n\n.font-weight-normal {\n font-weight: 400 !important;\n}\n\n.font-weight-bold {\n font-weight: 700 !important;\n}\n\n.font-weight-bolder {\n font-weight: bolder !important;\n}\n\n.font-italic {\n font-style: italic !important;\n}\n\n.text-white {\n color: #fff !important;\n}\n\n.text-primary {\n color: #007bff !important;\n}\n\na.text-primary:hover, a.text-primary:focus {\n color: #0056b3 !important;\n}\n\n.text-secondary {\n color: #6c757d !important;\n}\n\na.text-secondary:hover, a.text-secondary:focus {\n color: #494f54 !important;\n}\n\n.text-success {\n color: #28a745 !important;\n}\n\na.text-success:hover, a.text-success:focus {\n color: #19692c !important;\n}\n\n.text-info {\n color: #17a2b8 !important;\n}\n\na.text-info:hover, a.text-info:focus {\n color: #0f6674 !important;\n}\n\n.text-warning {\n color: #ffc107 !important;\n}\n\na.text-warning:hover, a.text-warning:focus {\n color: #ba8b00 !important;\n}\n\n.text-danger {\n color: #dc3545 !important;\n}\n\na.text-danger:hover, a.text-danger:focus {\n color: #a71d2a !important;\n}\n\n.text-light {\n color: #f8f9fa !important;\n}\n\na.text-light:hover, a.text-light:focus {\n color: #cbd3da !important;\n}\n\n.text-dark {\n color: #343a40 !important;\n}\n\na.text-dark:hover, a.text-dark:focus {\n color: #121416 !important;\n}\n\n.text-body {\n color: #212529 !important;\n}\n\n.text-muted {\n color: #6c757d !important;\n}\n\n.text-black-50 {\n color: rgba(0, 0, 0, 0.5) !important;\n}\n\n.text-white-50 {\n color: rgba(255, 255, 255, 0.5) !important;\n}\n\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n.text-decoration-none {\n text-decoration: none !important;\n}\n\n.text-break {\n word-break: break-word !important;\n overflow-wrap: break-word !important;\n}\n\n.text-reset {\n color: inherit !important;\n}\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n\n@media print {\n *,\n *::before,\n *::after {\n text-shadow: none !important;\n box-shadow: none !important;\n }\n a:not(.btn) {\n text-decoration: underline;\n }\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: 1px solid #adb5bd;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n @page {\n size: a3;\n }\n body {\n min-width: 992px !important;\n }\n .container {\n min-width: 992px !important;\n }\n .navbar {\n display: none;\n }\n .badge {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #dee2e6 !important;\n }\n .table-dark {\n color: inherit;\n }\n .table-dark th,\n .table-dark td,\n .table-dark thead th,\n .table-dark tbody + tbody {\n border-color: #dee2e6;\n }\n .table .thead-dark th {\n color: inherit;\n border-color: #dee2e6;\n }\n}\n\n/*# sourceMappingURL=bootstrap.css.map */",":root {\n // Custom variable values only support SassScript inside `#{}`.\n @each $color, $value in $colors {\n --#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors {\n --#{$color}: #{$value};\n }\n\n @each $bp, $value in $grid-breakpoints {\n --breakpoint-#{$bp}: #{$value};\n }\n\n // Use `inspect` for lists so that quoted items keep the quotes.\n // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n --font-family-sans-serif: #{inspect($font-family-sans-serif)};\n --font-family-monospace: #{inspect($font-family-monospace)};\n}\n","// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Change the default tap highlight to be completely transparent in iOS.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box; // 1\n}\n\nhtml {\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -webkit-tap-highlight-color: rgba($black, 0); // 5\n}\n\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\n// TODO: remove in v5\n// stylelint-disable-next-line selector-list-comma-newline-after\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use\n// the `inherit` value on things like `<th>` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n @include font-size($font-size-base);\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Suppress the focus outline on elements that cannot be accessed via keyboard.\n// This prevents an unwanted focus outline from appearing around elements that\n// might still respond to pointer events.\n//\n// Credit: https://github.com/suitcss/base\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable-next-line selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `<p>`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Remove the bottom border in Firefox 39-.\n// 5. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-original-title] { // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 4\n text-decoration-skip-ink: none; // 5\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n\nsmall {\n @include font-size(80%); // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n @include font-size(75%);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n\n @include hover {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href)\n// which have not been made explicitly keyboard-focusable (without tabindex).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n\n @include hover-focus {\n color: inherit;\n text-decoration: none;\n }\n\n &:focus {\n outline: 0;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-monospace;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg {\n // Workaround for the SVG overflow bug in IE10/11 is still required.\n // See https://github.com/twbs/bootstrap/issues/26878\n overflow: hidden;\n vertical-align: middle;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $table-caption-color;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n // Matches default `<td>` alignment by inheriting from the `<body>`, or the\n // closest parent with a set `text-align`.\n text-align: inherit;\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: $label-margin-bottom;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n // stylelint-disable-next-line property-blacklist\n border-radius: 0;\n}\n\n// Work around a Firefox/IE bug where the transparent `button` background\n// results in a loss of the default `button` focus styles.\n//\n// Credit: https://github.com/suitcss/base/\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// Remove the inheritance of word-wrap in Safari.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24990\nselect {\n word-wrap: normal;\n}\n\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n// controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\nbutton,\n[type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; // 2\n}\n\n// Opinionated: add \"hand\" cursor to non-disabled button elements.\n@if $enable-pointer-cursor-for-buttons {\n button,\n [type=\"button\"],\n [type=\"reset\"],\n [type=\"submit\"] {\n &:not(:disabled) {\n cursor: pointer;\n }\n }\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box; // 1. Add the correct box sizing in IE 10-\n padding: 0; // 2. Remove the padding in IE 10-\n}\n\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n // Remove the default appearance of temporal inputs to avoid a Mobile Safari\n // bug where setting a custom line-height prevents text from being vertically\n // centered within the input.\n // See https://bugs.webkit.org/show_bug.cgi?id=139848\n // and https://github.com/twbs/bootstrap/issues/11266\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto; // Remove the default vertical scrollbar in IE.\n // Textareas should really only resize vertically so they don't break their (horizontal) containers.\n resize: vertical;\n}\n\nfieldset {\n // Browsers set a default `min-width: min-content;` on fieldsets,\n // unlike e.g. `<div>`s, which have `min-width: 0;` by default.\n // So we reset that to ensure fieldsets behave more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359\n // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n min-width: 0;\n // Reset the default outline behavior of fieldsets so they don't affect page layout.\n padding: 0;\n margin: 0;\n border: 0;\n}\n\n// 1. Correct the text wrapping in Edge and IE.\n// 2. Correct the color inheritance from `fieldset` elements in IE.\nlegend {\n display: block;\n width: 100%;\n max-width: 100%; // 1\n padding: 0;\n margin-bottom: .5rem;\n @include font-size(1.5rem);\n line-height: inherit;\n color: inherit; // 2\n white-space: normal; // 1\n}\n\nprogress {\n vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.\n}\n\n// Correct the cursor style of increment and decrement buttons in Chrome.\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n outline-offset: -2px; // 2. Correct the outline style in Safari.\n -webkit-appearance: none;\n}\n\n//\n// Remove the inner padding in Chrome and Safari on macOS.\n//\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// 1. Correct the inability to style clickable types in iOS and Safari.\n// 2. Change font properties to `inherit` in Safari.\n//\n\n::-webkit-file-upload-button {\n font: inherit; // 2\n -webkit-appearance: button; // 1\n}\n\n//\n// Correct element displays\n//\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item; // Add the correct display in all browsers\n cursor: pointer;\n}\n\ntemplate {\n display: none; // Add the correct display in IE\n}\n\n// Always hide an element with the `hidden` HTML attribute (from PureCSS).\n// Needed for proper display in IE 10-.\n[hidden] {\n display: none !important;\n}\n","// Variables\n//\n// Variables should follow the `$component-state-property-size` formula for\n// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.\n\n// Color system\n\n$white: #fff !default;\n$gray-100: #f8f9fa !default;\n$gray-200: #e9ecef !default;\n$gray-300: #dee2e6 !default;\n$gray-400: #ced4da !default;\n$gray-500: #adb5bd !default;\n$gray-600: #6c757d !default;\n$gray-700: #495057 !default;\n$gray-800: #343a40 !default;\n$gray-900: #212529 !default;\n$black: #000 !default;\n\n$grays: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$grays: map-merge(\n (\n \"100\": $gray-100,\n \"200\": $gray-200,\n \"300\": $gray-300,\n \"400\": $gray-400,\n \"500\": $gray-500,\n \"600\": $gray-600,\n \"700\": $gray-700,\n \"800\": $gray-800,\n \"900\": $gray-900\n ),\n $grays\n);\n\n$blue: #007bff !default;\n$indigo: #6610f2 !default;\n$purple: #6f42c1 !default;\n$pink: #e83e8c !default;\n$red: #dc3545 !default;\n$orange: #fd7e14 !default;\n$yellow: #ffc107 !default;\n$green: #28a745 !default;\n$teal: #20c997 !default;\n$cyan: #17a2b8 !default;\n\n$colors: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$colors: map-merge(\n (\n \"blue\": $blue,\n \"indigo\": $indigo,\n \"purple\": $purple,\n \"pink\": $pink,\n \"red\": $red,\n \"orange\": $orange,\n \"yellow\": $yellow,\n \"green\": $green,\n \"teal\": $teal,\n \"cyan\": $cyan,\n \"white\": $white,\n \"gray\": $gray-600,\n \"gray-dark\": $gray-800\n ),\n $colors\n);\n\n$primary: $blue !default;\n$secondary: $gray-600 !default;\n$success: $green !default;\n$info: $cyan !default;\n$warning: $yellow !default;\n$danger: $red !default;\n$light: $gray-100 !default;\n$dark: $gray-800 !default;\n\n$theme-colors: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$theme-colors: map-merge(\n (\n \"primary\": $primary,\n \"secondary\": $secondary,\n \"success\": $success,\n \"info\": $info,\n \"warning\": $warning,\n \"danger\": $danger,\n \"light\": $light,\n \"dark\": $dark\n ),\n $theme-colors\n);\n\n// Set a specific jump point for requesting color jumps\n$theme-color-interval: 8% !default;\n\n// The yiq lightness value that determines when the lightness of color changes from \"dark\" to \"light\". Acceptable values are between 0 and 255.\n$yiq-contrasted-threshold: 150 !default;\n\n// Customize the light and dark text colors for use in our YIQ color contrast function.\n$yiq-text-dark: $gray-900 !default;\n$yiq-text-light: $white !default;\n\n\n// Options\n//\n// Quickly modify global styling by enabling or disabling optional features.\n\n$enable-caret: true !default;\n$enable-rounded: true !default;\n$enable-shadows: false !default;\n$enable-gradients: false !default;\n$enable-transitions: true !default;\n$enable-prefers-reduced-motion-media-query: true !default;\n$enable-hover-media-query: false !default; // Deprecated, no longer affects any compiled CSS\n$enable-grid-classes: true !default;\n$enable-pointer-cursor-for-buttons: true !default;\n$enable-print-styles: true !default;\n$enable-responsive-font-sizes: false !default;\n$enable-validation-icons: true !default;\n$enable-deprecation-messages: true !default;\n\n\n// Spacing\n//\n// Control the default styling of most Bootstrap elements by modifying these\n// variables. Mostly focused on spacing.\n// You can add more entries to the $spacers map, should you need more variation.\n\n$spacer: 1rem !default;\n$spacers: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$spacers: map-merge(\n (\n 0: 0,\n 1: ($spacer * .25),\n 2: ($spacer * .5),\n 3: $spacer,\n 4: ($spacer * 1.5),\n 5: ($spacer * 3)\n ),\n $spacers\n);\n\n// This variable affects the `.h-*` and `.w-*` classes.\n$sizes: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$sizes: map-merge(\n (\n 25: 25%,\n 50: 50%,\n 75: 75%,\n 100: 100%,\n auto: auto\n ),\n $sizes\n);\n\n\n// Body\n//\n// Settings for the `<body>` element.\n\n$body-bg: $white !default;\n$body-color: $gray-900 !default;\n\n\n// Links\n//\n// Style anchor elements.\n\n$link-color: theme-color(\"primary\") !default;\n$link-decoration: none !default;\n$link-hover-color: darken($link-color, 15%) !default;\n$link-hover-decoration: underline !default;\n// Darken percentage for links with `.text-*` class (e.g. `.text-success`)\n$emphasized-link-hover-darken-percentage: 15% !default;\n\n// Paragraphs\n//\n// Style p element.\n\n$paragraph-margin-bottom: 1rem !default;\n\n\n// Grid breakpoints\n//\n// Define the minimum dimensions at which your layout will change,\n// adapting to different screen sizes, for use in media queries.\n\n$grid-breakpoints: (\n xs: 0,\n sm: 576px,\n md: 768px,\n lg: 992px,\n xl: 1200px\n) !default;\n\n@include _assert-ascending($grid-breakpoints, \"$grid-breakpoints\");\n@include _assert-starts-at-zero($grid-breakpoints, \"$grid-breakpoints\");\n\n\n// Grid containers\n//\n// Define the maximum width of `.container` for different screen sizes.\n\n$container-max-widths: (\n sm: 540px,\n md: 720px,\n lg: 960px,\n xl: 1140px\n) !default;\n\n@include _assert-ascending($container-max-widths, \"$container-max-widths\");\n\n\n// Grid columns\n//\n// Set the number of columns and specify the width of the gutters.\n\n$grid-columns: 12 !default;\n$grid-gutter-width: 30px !default;\n\n\n// Components\n//\n// Define common padding and border radius sizes and more.\n\n$line-height-lg: 1.5 !default;\n$line-height-sm: 1.5 !default;\n\n$border-width: 1px !default;\n$border-color: $gray-300 !default;\n\n$border-radius: .25rem !default;\n$border-radius-lg: .3rem !default;\n$border-radius-sm: .2rem !default;\n\n$rounded-pill: 50rem !default;\n\n$box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default;\n$box-shadow: 0 .5rem 1rem rgba($black, .15) !default;\n$box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default;\n\n$component-active-color: $white !default;\n$component-active-bg: theme-color(\"primary\") !default;\n\n$caret-width: .3em !default;\n$caret-vertical-align: $caret-width * .85 !default;\n$caret-spacing: $caret-width * .85 !default;\n\n$transition-base: all .2s ease-in-out !default;\n$transition-fade: opacity .15s linear !default;\n$transition-collapse: height .35s ease !default;\n\n$embed-responsive-aspect-ratios: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$embed-responsive-aspect-ratios: join(\n (\n (21 9),\n (16 9),\n (4 3),\n (1 1),\n ),\n $embed-responsive-aspect-ratios\n);\n\n// Typography\n//\n// Font, line-height, and color for body text, headings, and more.\n\n// stylelint-disable value-keyword-case\n$font-family-sans-serif: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\" !default;\n$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !default;\n$font-family-base: $font-family-sans-serif !default;\n// stylelint-enable value-keyword-case\n\n$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`\n$font-size-lg: $font-size-base * 1.25 !default;\n$font-size-sm: $font-size-base * .875 !default;\n\n$font-weight-lighter: lighter !default;\n$font-weight-light: 300 !default;\n$font-weight-normal: 400 !default;\n$font-weight-bold: 700 !default;\n$font-weight-bolder: bolder !default;\n\n$font-weight-base: $font-weight-normal !default;\n$line-height-base: 1.5 !default;\n\n$h1-font-size: $font-size-base * 2.5 !default;\n$h2-font-size: $font-size-base * 2 !default;\n$h3-font-size: $font-size-base * 1.75 !default;\n$h4-font-size: $font-size-base * 1.5 !default;\n$h5-font-size: $font-size-base * 1.25 !default;\n$h6-font-size: $font-size-base !default;\n\n$headings-margin-bottom: $spacer / 2 !default;\n$headings-font-family: null !default;\n$headings-font-weight: 500 !default;\n$headings-line-height: 1.2 !default;\n$headings-color: null !default;\n\n$display1-size: 6rem !default;\n$display2-size: 5.5rem !default;\n$display3-size: 4.5rem !default;\n$display4-size: 3.5rem !default;\n\n$display1-weight: 300 !default;\n$display2-weight: 300 !default;\n$display3-weight: 300 !default;\n$display4-weight: 300 !default;\n$display-line-height: $headings-line-height !default;\n\n$lead-font-size: $font-size-base * 1.25 !default;\n$lead-font-weight: 300 !default;\n\n$small-font-size: 80% !default;\n\n$text-muted: $gray-600 !default;\n\n$blockquote-small-color: $gray-600 !default;\n$blockquote-small-font-size: $small-font-size !default;\n$blockquote-font-size: $font-size-base * 1.25 !default;\n\n$hr-border-color: rgba($black, .1) !default;\n$hr-border-width: $border-width !default;\n\n$mark-padding: .2em !default;\n\n$dt-font-weight: $font-weight-bold !default;\n\n$kbd-box-shadow: inset 0 -.1rem 0 rgba($black, .25) !default;\n$nested-kbd-font-weight: $font-weight-bold !default;\n\n$list-inline-padding: .5rem !default;\n\n$mark-bg: #fcf8e3 !default;\n\n$hr-margin-y: $spacer !default;\n\n\n// Tables\n//\n// Customizes the `.table` component with basic values, each used across all table variations.\n\n$table-cell-padding: .75rem !default;\n$table-cell-padding-sm: .3rem !default;\n\n$table-color: $body-color !default;\n$table-bg: null !default;\n$table-accent-bg: rgba($black, .05) !default;\n$table-hover-color: $table-color !default;\n$table-hover-bg: rgba($black, .075) !default;\n$table-active-bg: $table-hover-bg !default;\n\n$table-border-width: $border-width !default;\n$table-border-color: $border-color !default;\n\n$table-head-bg: $gray-200 !default;\n$table-head-color: $gray-700 !default;\n\n$table-dark-color: $white !default;\n$table-dark-bg: $gray-800 !default;\n$table-dark-accent-bg: rgba($white, .05) !default;\n$table-dark-hover-color: $table-dark-color !default;\n$table-dark-hover-bg: rgba($white, .075) !default;\n$table-dark-border-color: lighten($table-dark-bg, 7.5%) !default;\n$table-dark-color: $white !default;\n\n$table-striped-order: odd !default;\n\n$table-caption-color: $text-muted !default;\n\n$table-bg-level: -9 !default;\n$table-border-level: -6 !default;\n\n\n// Buttons + Forms\n//\n// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.\n\n$input-btn-padding-y: .375rem !default;\n$input-btn-padding-x: .75rem !default;\n$input-btn-font-family: null !default;\n$input-btn-font-size: $font-size-base !default;\n$input-btn-line-height: $line-height-base !default;\n\n$input-btn-focus-width: .2rem !default;\n$input-btn-focus-color: rgba($component-active-bg, .25) !default;\n$input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color !default;\n\n$input-btn-padding-y-sm: .25rem !default;\n$input-btn-padding-x-sm: .5rem !default;\n$input-btn-font-size-sm: $font-size-sm !default;\n$input-btn-line-height-sm: $line-height-sm !default;\n\n$input-btn-padding-y-lg: .5rem !default;\n$input-btn-padding-x-lg: 1rem !default;\n$input-btn-font-size-lg: $font-size-lg !default;\n$input-btn-line-height-lg: $line-height-lg !default;\n\n$input-btn-border-width: $border-width !default;\n\n\n// Buttons\n//\n// For each of Bootstrap's buttons, define text, background, and border color.\n\n$btn-padding-y: $input-btn-padding-y !default;\n$btn-padding-x: $input-btn-padding-x !default;\n$btn-font-family: $input-btn-font-family !default;\n$btn-font-size: $input-btn-font-size !default;\n$btn-line-height: $input-btn-line-height !default;\n\n$btn-padding-y-sm: $input-btn-padding-y-sm !default;\n$btn-padding-x-sm: $input-btn-padding-x-sm !default;\n$btn-font-size-sm: $input-btn-font-size-sm !default;\n$btn-line-height-sm: $input-btn-line-height-sm !default;\n\n$btn-padding-y-lg: $input-btn-padding-y-lg !default;\n$btn-padding-x-lg: $input-btn-padding-x-lg !default;\n$btn-font-size-lg: $input-btn-font-size-lg !default;\n$btn-line-height-lg: $input-btn-line-height-lg !default;\n\n$btn-border-width: $input-btn-border-width !default;\n\n$btn-font-weight: $font-weight-normal !default;\n$btn-box-shadow: inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default;\n$btn-focus-width: $input-btn-focus-width !default;\n$btn-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$btn-disabled-opacity: .65 !default;\n$btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default;\n\n$btn-link-disabled-color: $gray-600 !default;\n\n$btn-block-spacing-y: .5rem !default;\n\n// Allows for customizing button radius independently from global border radius\n$btn-border-radius: $border-radius !default;\n$btn-border-radius-lg: $border-radius-lg !default;\n$btn-border-radius-sm: $border-radius-sm !default;\n\n$btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n\n// Forms\n\n$label-margin-bottom: .5rem !default;\n\n$input-padding-y: $input-btn-padding-y !default;\n$input-padding-x: $input-btn-padding-x !default;\n$input-font-family: $input-btn-font-family !default;\n$input-font-size: $input-btn-font-size !default;\n$input-font-weight: $font-weight-base !default;\n$input-line-height: $input-btn-line-height !default;\n\n$input-padding-y-sm: $input-btn-padding-y-sm !default;\n$input-padding-x-sm: $input-btn-padding-x-sm !default;\n$input-font-size-sm: $input-btn-font-size-sm !default;\n$input-line-height-sm: $input-btn-line-height-sm !default;\n\n$input-padding-y-lg: $input-btn-padding-y-lg !default;\n$input-padding-x-lg: $input-btn-padding-x-lg !default;\n$input-font-size-lg: $input-btn-font-size-lg !default;\n$input-line-height-lg: $input-btn-line-height-lg !default;\n\n$input-bg: $white !default;\n$input-disabled-bg: $gray-200 !default;\n\n$input-color: $gray-700 !default;\n$input-border-color: $gray-400 !default;\n$input-border-width: $input-btn-border-width !default;\n$input-box-shadow: inset 0 1px 1px rgba($black, .075) !default;\n\n$input-border-radius: $border-radius !default;\n$input-border-radius-lg: $border-radius-lg !default;\n$input-border-radius-sm: $border-radius-sm !default;\n\n$input-focus-bg: $input-bg !default;\n$input-focus-border-color: lighten($component-active-bg, 25%) !default;\n$input-focus-color: $input-color !default;\n$input-focus-width: $input-btn-focus-width !default;\n$input-focus-box-shadow: $input-btn-focus-box-shadow !default;\n\n$input-placeholder-color: $gray-600 !default;\n$input-plaintext-color: $body-color !default;\n\n$input-height-border: $input-border-width * 2 !default;\n\n$input-height-inner: calc(#{$input-line-height * 1em} + #{$input-padding-y * 2}) !default;\n$input-height-inner-half: calc(#{$input-line-height * .5em} + #{$input-padding-y}) !default;\n$input-height-inner-quarter: calc(#{$input-line-height * .25em} + #{$input-padding-y / 2}) !default;\n\n$input-height: calc(#{$input-line-height * 1em} + #{$input-padding-y * 2} + #{$input-height-border}) !default;\n$input-height-sm: calc(#{$input-line-height-sm * 1em} + #{$input-btn-padding-y-sm * 2} + #{$input-height-border}) !default;\n$input-height-lg: calc(#{$input-line-height-lg * 1em} + #{$input-btn-padding-y-lg * 2} + #{$input-height-border}) !default;\n\n$input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$form-text-margin-top: .25rem !default;\n\n$form-check-input-gutter: 1.25rem !default;\n$form-check-input-margin-y: .3rem !default;\n$form-check-input-margin-x: .25rem !default;\n\n$form-check-inline-margin-x: .75rem !default;\n$form-check-inline-input-margin-x: .3125rem !default;\n\n$form-grid-gutter-width: 10px !default;\n$form-group-margin-bottom: 1rem !default;\n\n$input-group-addon-color: $input-color !default;\n$input-group-addon-bg: $gray-200 !default;\n$input-group-addon-border-color: $input-border-color !default;\n\n$custom-forms-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$custom-control-gutter: .5rem !default;\n$custom-control-spacer-x: 1rem !default;\n\n$custom-control-indicator-size: 1rem !default;\n$custom-control-indicator-bg: $input-bg !default;\n\n$custom-control-indicator-bg-size: 50% 50% !default;\n$custom-control-indicator-box-shadow: $input-box-shadow !default;\n$custom-control-indicator-border-color: $gray-500 !default;\n$custom-control-indicator-border-width: $input-border-width !default;\n\n$custom-control-indicator-disabled-bg: $input-disabled-bg !default;\n$custom-control-label-disabled-color: $gray-600 !default;\n\n$custom-control-indicator-checked-color: $component-active-color !default;\n$custom-control-indicator-checked-bg: $component-active-bg !default;\n$custom-control-indicator-checked-disabled-bg: rgba(theme-color(\"primary\"), .5) !default;\n$custom-control-indicator-checked-box-shadow: none !default;\n$custom-control-indicator-checked-border-color: $custom-control-indicator-checked-bg !default;\n\n$custom-control-indicator-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-control-indicator-focus-border-color: $input-focus-border-color !default;\n\n$custom-control-indicator-active-color: $component-active-color !default;\n$custom-control-indicator-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-control-indicator-active-box-shadow: none !default;\n$custom-control-indicator-active-border-color: $custom-control-indicator-active-bg !default;\n\n$custom-checkbox-indicator-border-radius: $border-radius !default;\n$custom-checkbox-indicator-icon-checked: str-replace(url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='#{$custom-control-indicator-checked-color}' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e\"), \"#\", \"%23\") !default;\n\n$custom-checkbox-indicator-indeterminate-bg: $component-active-bg !default;\n$custom-checkbox-indicator-indeterminate-color: $custom-control-indicator-checked-color !default;\n$custom-checkbox-indicator-icon-indeterminate: str-replace(url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='#{$custom-checkbox-indicator-indeterminate-color}' d='M0 2h4'/%3e%3c/svg%3e\"), \"#\", \"%23\") !default;\n$custom-checkbox-indicator-indeterminate-box-shadow: none !default;\n$custom-checkbox-indicator-indeterminate-border-color: $custom-checkbox-indicator-indeterminate-bg !default;\n\n$custom-radio-indicator-border-radius: 50% !default;\n$custom-radio-indicator-icon-checked: str-replace(url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='#{$custom-control-indicator-checked-color}'/%3e%3c/svg%3e\"), \"#\", \"%23\") !default;\n\n$custom-switch-width: $custom-control-indicator-size * 1.75 !default;\n$custom-switch-indicator-border-radius: $custom-control-indicator-size / 2 !default;\n$custom-switch-indicator-size: calc(#{$custom-control-indicator-size} - #{$custom-control-indicator-border-width * 4}) !default;\n\n$custom-select-padding-y: $input-padding-y !default;\n$custom-select-padding-x: $input-padding-x !default;\n$custom-select-font-family: $input-font-family !default;\n$custom-select-font-size: $input-font-size !default;\n$custom-select-height: $input-height !default;\n$custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator\n$custom-select-font-weight: $input-font-weight !default;\n$custom-select-line-height: $input-line-height !default;\n$custom-select-color: $input-color !default;\n$custom-select-disabled-color: $gray-600 !default;\n$custom-select-bg: $input-bg !default;\n$custom-select-disabled-bg: $gray-200 !default;\n$custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions\n$custom-select-indicator-color: $gray-800 !default;\n$custom-select-indicator: str-replace(url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e\"), \"#\", \"%23\") !default;\n$custom-select-background: $custom-select-indicator no-repeat right $custom-select-padding-x center / $custom-select-bg-size !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon)\n\n$custom-select-feedback-icon-padding-right: calc((1em + #{2 * $custom-select-padding-y}) * 3 / 4 + #{$custom-select-padding-x + $custom-select-indicator-padding}) !default;\n$custom-select-feedback-icon-position: center right ($custom-select-padding-x + $custom-select-indicator-padding) !default;\n$custom-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default;\n\n$custom-select-border-width: $input-border-width !default;\n$custom-select-border-color: $input-border-color !default;\n$custom-select-border-radius: $border-radius !default;\n$custom-select-box-shadow: inset 0 1px 2px rgba($black, .075) !default;\n\n$custom-select-focus-border-color: $input-focus-border-color !default;\n$custom-select-focus-width: $input-focus-width !default;\n$custom-select-focus-box-shadow: 0 0 0 $custom-select-focus-width $input-btn-focus-color !default;\n\n$custom-select-padding-y-sm: $input-padding-y-sm !default;\n$custom-select-padding-x-sm: $input-padding-x-sm !default;\n$custom-select-font-size-sm: $input-font-size-sm !default;\n$custom-select-height-sm: $input-height-sm !default;\n\n$custom-select-padding-y-lg: $input-padding-y-lg !default;\n$custom-select-padding-x-lg: $input-padding-x-lg !default;\n$custom-select-font-size-lg: $input-font-size-lg !default;\n$custom-select-height-lg: $input-height-lg !default;\n\n$custom-range-track-width: 100% !default;\n$custom-range-track-height: .5rem !default;\n$custom-range-track-cursor: pointer !default;\n$custom-range-track-bg: $gray-300 !default;\n$custom-range-track-border-radius: 1rem !default;\n$custom-range-track-box-shadow: inset 0 .25rem .25rem rgba($black, .1) !default;\n\n$custom-range-thumb-width: 1rem !default;\n$custom-range-thumb-height: $custom-range-thumb-width !default;\n$custom-range-thumb-bg: $component-active-bg !default;\n$custom-range-thumb-border: 0 !default;\n$custom-range-thumb-border-radius: 1rem !default;\n$custom-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default;\n$custom-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default;\n$custom-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in IE/Edge\n$custom-range-thumb-active-bg: lighten($component-active-bg, 35%) !default;\n$custom-range-thumb-disabled-bg: $gray-500 !default;\n\n$custom-file-height: $input-height !default;\n$custom-file-height-inner: $input-height-inner !default;\n$custom-file-focus-border-color: $input-focus-border-color !default;\n$custom-file-focus-box-shadow: $input-focus-box-shadow !default;\n$custom-file-disabled-bg: $input-disabled-bg !default;\n\n$custom-file-padding-y: $input-padding-y !default;\n$custom-file-padding-x: $input-padding-x !default;\n$custom-file-line-height: $input-line-height !default;\n$custom-file-font-family: $input-font-family !default;\n$custom-file-font-weight: $input-font-weight !default;\n$custom-file-color: $input-color !default;\n$custom-file-bg: $input-bg !default;\n$custom-file-border-width: $input-border-width !default;\n$custom-file-border-color: $input-border-color !default;\n$custom-file-border-radius: $input-border-radius !default;\n$custom-file-box-shadow: $input-box-shadow !default;\n$custom-file-button-color: $custom-file-color !default;\n$custom-file-button-bg: $input-group-addon-bg !default;\n$custom-file-text: (\n en: \"Browse\"\n) !default;\n\n\n// Form validation\n\n$form-feedback-margin-top: $form-text-margin-top !default;\n$form-feedback-font-size: $small-font-size !default;\n$form-feedback-valid-color: theme-color(\"success\") !default;\n$form-feedback-invalid-color: theme-color(\"danger\") !default;\n\n$form-feedback-icon-valid-color: $form-feedback-valid-color !default;\n$form-feedback-icon-valid: str-replace(url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.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\"), \"#\", \"%23\") !default;\n$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default;\n$form-feedback-icon-invalid: str-replace(url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='#{$form-feedback-icon-invalid-color}' viewBox='-2 -2 7 7'%3e%3cpath stroke='#{$form-feedback-icon-invalid-color}' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E\"), \"#\", \"%23\") !default;\n\n$form-validation-states: () !default;\n// stylelint-disable-next-line scss/dollar-variable-default\n$form-validation-states: map-merge(\n (\n \"valid\": (\n \"color\": $form-feedback-valid-color,\n \"icon\": $form-feedback-icon-valid\n ),\n \"invalid\": (\n \"color\": $form-feedback-invalid-color,\n \"icon\": $form-feedback-icon-invalid\n ),\n ),\n $form-validation-states\n);\n\n// Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n\n$zindex-dropdown: 1000 !default;\n$zindex-sticky: 1020 !default;\n$zindex-fixed: 1030 !default;\n$zindex-modal-backdrop: 1040 !default;\n$zindex-modal: 1050 !default;\n$zindex-popover: 1060 !default;\n$zindex-tooltip: 1070 !default;\n\n\n// Navs\n\n$nav-link-padding-y: .5rem !default;\n$nav-link-padding-x: 1rem !default;\n$nav-link-disabled-color: $gray-600 !default;\n\n$nav-tabs-border-color: $gray-300 !default;\n$nav-tabs-border-width: $border-width !default;\n$nav-tabs-border-radius: $border-radius !default;\n$nav-tabs-link-hover-border-color: $gray-200 $gray-200 $nav-tabs-border-color !default;\n$nav-tabs-link-active-color: $gray-700 !default;\n$nav-tabs-link-active-bg: $body-bg !default;\n$nav-tabs-link-active-border-color: $gray-300 $gray-300 $nav-tabs-link-active-bg !default;\n\n$nav-pills-border-radius: $border-radius !default;\n$nav-pills-link-active-color: $component-active-color !default;\n$nav-pills-link-active-bg: $component-active-bg !default;\n\n$nav-divider-color: $gray-200 !default;\n$nav-divider-margin-y: $spacer / 2 !default;\n\n\n// Navbar\n\n$navbar-padding-y: $spacer / 2 !default;\n$navbar-padding-x: $spacer !default;\n\n$navbar-nav-link-padding-x: .5rem !default;\n\n$navbar-brand-font-size: $font-size-lg !default;\n// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link\n$nav-link-height: $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default;\n$navbar-brand-height: $navbar-brand-font-size * $line-height-base !default;\n$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) / 2 !default;\n\n$navbar-toggler-padding-y: .25rem !default;\n$navbar-toggler-padding-x: .75rem !default;\n$navbar-toggler-font-size: $font-size-lg !default;\n$navbar-toggler-border-radius: $btn-border-radius !default;\n\n$navbar-dark-color: rgba($white, .5) !default;\n$navbar-dark-hover-color: rgba($white, .75) !default;\n$navbar-dark-active-color: $white !default;\n$navbar-dark-disabled-color: rgba($white, .25) !default;\n$navbar-dark-toggler-icon-bg: str-replace(url(\"data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='#{$navbar-dark-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\"), \"#\", \"%23\") !default;\n$navbar-dark-toggler-border-color: rgba($white, .1) !default;\n\n$navbar-light-color: rgba($black, .5) !default;\n$navbar-light-hover-color: rgba($black, .7) !default;\n$navbar-light-active-color: rgba($black, .9) !default;\n$navbar-light-disabled-color: rgba($black, .3) !default;\n$navbar-light-toggler-icon-bg: str-replace(url(\"data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='#{$navbar-light-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\"), \"#\", \"%23\") !default;\n$navbar-light-toggler-border-color: rgba($black, .1) !default;\n\n$navbar-light-brand-color: $navbar-light-active-color !default;\n$navbar-light-brand-hover-color: $navbar-light-active-color !default;\n$navbar-dark-brand-color: $navbar-dark-active-color !default;\n$navbar-dark-brand-hover-color: $navbar-dark-active-color !default;\n\n\n// Dropdowns\n//\n// Dropdown menu container and contents.\n\n$dropdown-min-width: 10rem !default;\n$dropdown-padding-y: .5rem !default;\n$dropdown-spacer: .125rem !default;\n$dropdown-font-size: $font-size-base !default;\n$dropdown-color: $body-color !default;\n$dropdown-bg: $white !default;\n$dropdown-border-color: rgba($black, .15) !default;\n$dropdown-border-radius: $border-radius !default;\n$dropdown-border-width: $border-width !default;\n$dropdown-inner-border-radius: calc(#{$dropdown-border-radius} - #{$dropdown-border-width}) !default;\n$dropdown-divider-bg: $gray-200 !default;\n$dropdown-divider-margin-y: $nav-divider-margin-y !default;\n$dropdown-box-shadow: 0 .5rem 1rem rgba($black, .175) !default;\n\n$dropdown-link-color: $gray-900 !default;\n$dropdown-link-hover-color: darken($gray-900, 5%) !default;\n$dropdown-link-hover-bg: $gray-100 !default;\n\n$dropdown-link-active-color: $component-active-color !default;\n$dropdown-link-active-bg: $component-active-bg !default;\n\n$dropdown-link-disabled-color: $gray-600 !default;\n\n$dropdown-item-padding-y: .25rem !default;\n$dropdown-item-padding-x: 1.5rem !default;\n\n$dropdown-header-color: $gray-600 !default;\n\n\n// Pagination\n\n$pagination-padding-y: .5rem !default;\n$pagination-padding-x: .75rem !default;\n$pagination-padding-y-sm: .25rem !default;\n$pagination-padding-x-sm: .5rem !default;\n$pagination-padding-y-lg: .75rem !default;\n$pagination-padding-x-lg: 1.5rem !default;\n$pagination-line-height: 1.25 !default;\n\n$pagination-color: $link-color !default;\n$pagination-bg: $white !default;\n$pagination-border-width: $border-width !default;\n$pagination-border-color: $gray-300 !default;\n\n$pagination-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$pagination-focus-outline: 0 !default;\n\n$pagination-hover-color: $link-hover-color !default;\n$pagination-hover-bg: $gray-200 !default;\n$pagination-hover-border-color: $gray-300 !default;\n\n$pagination-active-color: $component-active-color !default;\n$pagination-active-bg: $component-active-bg !default;\n$pagination-active-border-color: $pagination-active-bg !default;\n\n$pagination-disabled-color: $gray-600 !default;\n$pagination-disabled-bg: $white !default;\n$pagination-disabled-border-color: $gray-300 !default;\n\n\n// Jumbotron\n\n$jumbotron-padding: 2rem !default;\n$jumbotron-color: null !default;\n$jumbotron-bg: $gray-200 !default;\n\n\n// Cards\n\n$card-spacer-y: .75rem !default;\n$card-spacer-x: 1.25rem !default;\n$card-border-width: $border-width !default;\n$card-border-radius: $border-radius !default;\n$card-border-color: rgba($black, .125) !default;\n$card-inner-border-radius: calc(#{$card-border-radius} - #{$card-border-width}) !default;\n$card-cap-bg: rgba($black, .03) !default;\n$card-cap-color: null !default;\n$card-color: null !default;\n$card-bg: $white !default;\n\n$card-img-overlay-padding: 1.25rem !default;\n\n$card-group-margin: $grid-gutter-width / 2 !default;\n$card-deck-margin: $card-group-margin !default;\n\n$card-columns-count: 3 !default;\n$card-columns-gap: 1.25rem !default;\n$card-columns-margin: $card-spacer-y !default;\n\n\n// Tooltips\n\n$tooltip-font-size: $font-size-sm !default;\n$tooltip-max-width: 200px !default;\n$tooltip-color: $white !default;\n$tooltip-bg: $black !default;\n$tooltip-border-radius: $border-radius !default;\n$tooltip-opacity: .9 !default;\n$tooltip-padding-y: .25rem !default;\n$tooltip-padding-x: .5rem !default;\n$tooltip-margin: 0 !default;\n\n$tooltip-arrow-width: .8rem !default;\n$tooltip-arrow-height: .4rem !default;\n$tooltip-arrow-color: $tooltip-bg !default;\n\n// Form tooltips must come after regular tooltips\n$form-feedback-tooltip-padding-y: $tooltip-padding-y !default;\n$form-feedback-tooltip-padding-x: $tooltip-padding-x !default;\n$form-feedback-tooltip-font-size: $tooltip-font-size !default;\n$form-feedback-tooltip-line-height: $line-height-base !default;\n$form-feedback-tooltip-opacity: $tooltip-opacity !default;\n$form-feedback-tooltip-border-radius: $tooltip-border-radius !default;\n\n\n// Popovers\n\n$popover-font-size: $font-size-sm !default;\n$popover-bg: $white !default;\n$popover-max-width: 276px !default;\n$popover-border-width: $border-width !default;\n$popover-border-color: rgba($black, .2) !default;\n$popover-border-radius: $border-radius-lg !default;\n$popover-box-shadow: 0 .25rem .5rem rgba($black, .2) !default;\n\n$popover-header-bg: darken($popover-bg, 3%) !default;\n$popover-header-color: $headings-color !default;\n$popover-header-padding-y: .5rem !default;\n$popover-header-padding-x: .75rem !default;\n\n$popover-body-color: $body-color !default;\n$popover-body-padding-y: $popover-header-padding-y !default;\n$popover-body-padding-x: $popover-header-padding-x !default;\n\n$popover-arrow-width: 1rem !default;\n$popover-arrow-height: .5rem !default;\n$popover-arrow-color: $popover-bg !default;\n\n$popover-arrow-outer-color: fade-in($popover-border-color, .05) !default;\n\n\n// Toasts\n\n$toast-max-width: 350px !default;\n$toast-padding-x: .75rem !default;\n$toast-padding-y: .25rem !default;\n$toast-font-size: .875rem !default;\n$toast-color: null !default;\n$toast-background-color: rgba($white, .85) !default;\n$toast-border-width: 1px !default;\n$toast-border-color: rgba(0, 0, 0, .1) !default;\n$toast-border-radius: .25rem !default;\n$toast-box-shadow: 0 .25rem .75rem rgba($black, .1) !default;\n\n$toast-header-color: $gray-600 !default;\n$toast-header-background-color: rgba($white, .85) !default;\n$toast-header-border-color: rgba(0, 0, 0, .05) !default;\n\n\n// Badges\n\n$badge-font-size: 75% !default;\n$badge-font-weight: $font-weight-bold !default;\n$badge-padding-y: .25em !default;\n$badge-padding-x: .4em !default;\n$badge-border-radius: $border-radius !default;\n\n$badge-transition: $btn-transition !default;\n$badge-focus-width: $input-btn-focus-width !default;\n\n$badge-pill-padding-x: .6em !default;\n// Use a higher than normal value to ensure completely rounded edges when\n// customizing padding or font-size on labels.\n$badge-pill-border-radius: 10rem !default;\n\n\n// Modals\n\n// Padding applied to the modal body\n$modal-inner-padding: 1rem !default;\n\n$modal-dialog-margin: .5rem !default;\n$modal-dialog-margin-y-sm-up: 1.75rem !default;\n\n$modal-title-line-height: $line-height-base !default;\n\n$modal-content-color: null !default;\n$modal-content-bg: $white !default;\n$modal-content-border-color: rgba($black, .2) !default;\n$modal-content-border-width: $border-width !default;\n$modal-content-border-radius: $border-radius-lg !default;\n$modal-content-box-shadow-xs: 0 .25rem .5rem rgba($black, .5) !default;\n$modal-content-box-shadow-sm-up: 0 .5rem 1rem rgba($black, .5) !default;\n\n$modal-backdrop-bg: $black !default;\n$modal-backdrop-opacity: .5 !default;\n$modal-header-border-color: $border-color !default;\n$modal-footer-border-color: $modal-header-border-color !default;\n$modal-header-border-width: $modal-content-border-width !default;\n$modal-footer-border-width: $modal-header-border-width !default;\n$modal-header-padding-y: 1rem !default;\n$modal-header-padding-x: 1rem !default;\n$modal-header-padding: $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility\n\n$modal-xl: 1140px !default;\n$modal-lg: 800px !default;\n$modal-md: 500px !default;\n$modal-sm: 300px !default;\n\n$modal-fade-transform: translate(0, -50px) !default;\n$modal-show-transform: none !default;\n$modal-transition: transform .3s ease-out !default;\n\n\n// Alerts\n//\n// Define alert colors, border radius, and padding.\n\n$alert-padding-y: .75rem !default;\n$alert-padding-x: 1.25rem !default;\n$alert-margin-bottom: 1rem !default;\n$alert-border-radius: $border-radius !default;\n$alert-link-font-weight: $font-weight-bold !default;\n$alert-border-width: $border-width !default;\n\n$alert-bg-level: -10 !default;\n$alert-border-level: -9 !default;\n$alert-color-level: 6 !default;\n\n\n// Progress bars\n\n$progress-height: 1rem !default;\n$progress-font-size: $font-size-base * .75 !default;\n$progress-bg: $gray-200 !default;\n$progress-border-radius: $border-radius !default;\n$progress-box-shadow: inset 0 .1rem .1rem rgba($black, .1) !default;\n$progress-bar-color: $white !default;\n$progress-bar-bg: theme-color(\"primary\") !default;\n$progress-bar-animation-timing: 1s linear infinite !default;\n$progress-bar-transition: width .6s ease !default;\n\n\n// List group\n\n$list-group-color: null !default;\n$list-group-bg: $white !default;\n$list-group-border-color: rgba($black, .125) !default;\n$list-group-border-width: $border-width !default;\n$list-group-border-radius: $border-radius !default;\n\n$list-group-item-padding-y: .75rem !default;\n$list-group-item-padding-x: 1.25rem !default;\n\n$list-group-hover-bg: $gray-100 !default;\n$list-group-active-color: $component-active-color !default;\n$list-group-active-bg: $component-active-bg !default;\n$list-group-active-border-color: $list-group-active-bg !default;\n\n$list-group-disabled-color: $gray-600 !default;\n$list-group-disabled-bg: $list-group-bg !default;\n\n$list-group-action-color: $gray-700 !default;\n$list-group-action-hover-color: $list-group-action-color !default;\n\n$list-group-action-active-color: $body-color !default;\n$list-group-action-active-bg: $gray-200 !default;\n\n\n// Image thumbnails\n\n$thumbnail-padding: .25rem !default;\n$thumbnail-bg: $body-bg !default;\n$thumbnail-border-width: $border-width !default;\n$thumbnail-border-color: $gray-300 !default;\n$thumbnail-border-radius: $border-radius !default;\n$thumbnail-box-shadow: 0 1px 2px rgba($black, .075) !default;\n\n\n// Figures\n\n$figure-caption-font-size: 90% !default;\n$figure-caption-color: $gray-600 !default;\n\n\n// Breadcrumbs\n\n$breadcrumb-padding-y: .75rem !default;\n$breadcrumb-padding-x: 1rem !default;\n$breadcrumb-item-padding: .5rem !default;\n\n$breadcrumb-margin-bottom: 1rem !default;\n\n$breadcrumb-bg: $gray-200 !default;\n$breadcrumb-divider-color: $gray-600 !default;\n$breadcrumb-active-color: $gray-600 !default;\n$breadcrumb-divider: quote(\"/\") !default;\n\n$breadcrumb-border-radius: $border-radius !default;\n\n\n// Carousel\n\n$carousel-control-color: $white !default;\n$carousel-control-width: 15% !default;\n$carousel-control-opacity: .5 !default;\n$carousel-control-hover-opacity: .9 !default;\n$carousel-control-transition: opacity .15s ease !default;\n\n$carousel-indicator-width: 30px !default;\n$carousel-indicator-height: 3px !default;\n$carousel-indicator-hit-area-height: 10px !default;\n$carousel-indicator-spacer: 3px !default;\n$carousel-indicator-active-bg: $white !default;\n$carousel-indicator-transition: opacity .6s ease !default;\n\n$carousel-caption-width: 70% !default;\n$carousel-caption-color: $white !default;\n\n$carousel-control-icon-width: 20px !default;\n\n$carousel-control-prev-icon-bg: str-replace(url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e\"), \"#\", \"%23\") !default;\n$carousel-control-next-icon-bg: str-replace(url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e\"), \"#\", \"%23\") !default;\n\n$carousel-transition-duration: .6s !default;\n$carousel-transition: transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)\n\n\n// Spinners\n\n$spinner-width: 2rem !default;\n$spinner-height: $spinner-width !default;\n$spinner-border-width: .25em !default;\n\n$spinner-width-sm: 1rem !default;\n$spinner-height-sm: $spinner-width-sm !default;\n$spinner-border-width-sm: .2em !default;\n\n\n// Close\n\n$close-font-size: $font-size-base * 1.5 !default;\n$close-font-weight: $font-weight-bold !default;\n$close-color: $black !default;\n$close-text-shadow: 0 1px 0 $white !default;\n\n\n// Code\n\n$code-font-size: 87.5% !default;\n$code-color: $pink !default;\n\n$kbd-padding-y: .2rem !default;\n$kbd-padding-x: .4rem !default;\n$kbd-font-size: $code-font-size !default;\n$kbd-color: $white !default;\n$kbd-bg: $gray-900 !default;\n\n$pre-color: $gray-900 !default;\n$pre-scrollable-max-height: 340px !default;\n\n\n// Utilities\n\n$displays: none, inline, inline-block, block, table, table-row, table-cell, flex, inline-flex !default;\n$overflows: auto, hidden !default;\n$positions: static, relative, absolute, fixed, sticky !default;\n\n\n// Printing\n\n$print-page-size: a3 !default;\n$print-body-min-width: map-get($grid-breakpoints, \"lg\") !default;\n","// stylelint-disable property-blacklist, scss/dollar-variable-default\n\n// SCSS RFS mixin\n//\n// Automated font-resizing\n//\n// See https://github.com/twbs/rfs\n\n// Configuration\n\n// Base font size\n$rfs-base-font-size: 1.25rem !default;\n$rfs-font-size-unit: rem !default;\n\n// Breakpoint at where font-size starts decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n// Resize font-size based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != \"number\" or $rfs-factor <= 1 {\n @error \"`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.\";\n}\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-responsive-font-sizes to false\n$enable-responsive-font-sizes: true !default;\n\n// Cache $rfs-base-font-size unit\n$rfs-base-font-size-unit: unit($rfs-base-font-size);\n\n// Remove px-unit from $rfs-base-font-size for calculations\n@if $rfs-base-font-size-unit == \"px\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1);\n}\n@else if $rfs-base-font-size-unit == \"rem\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1 / $rfs-rem-value);\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == \"px\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == \"rem\" or $rfs-breakpoint-unit-cache == \"em\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1 / $rfs-rem-value);\n}\n\n// Responsive font-size mixin\n@mixin rfs($fs, $important: false) {\n // Cache $fs unit\n $fs-unit: if(type-of($fs) == \"number\", unit($fs), false);\n\n // Add !important suffix if needed\n $rfs-suffix: if($important, \" !important\", \"\");\n\n // If $fs isn't a number (like inherit) or $fs has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n @if not $fs-unit or $fs-unit != \"\" and $fs-unit != \"px\" and $fs-unit != \"rem\" or $fs == 0 {\n font-size: #{$fs}#{$rfs-suffix};\n }\n @else {\n // Variables for storing static and fluid rescaling\n $rfs-static: null;\n $rfs-fluid: null;\n\n // Remove px-unit from $fs for calculations\n @if $fs-unit == \"px\" {\n $fs: $fs / ($fs * 0 + 1);\n }\n @else if $fs-unit == \"rem\" {\n $fs: $fs / ($fs * 0 + 1 / $rfs-rem-value);\n }\n\n // Set default font-size\n @if $rfs-font-size-unit == rem {\n $rfs-static: #{$fs / $rfs-rem-value}rem#{$rfs-suffix};\n }\n @else if $rfs-font-size-unit == px {\n $rfs-static: #{$fs}px#{$rfs-suffix};\n }\n @else {\n @error \"`#{$rfs-font-size-unit}` is not a valid unit for $rfs-font-size-unit. Use `px` or `rem`.\";\n }\n\n // Only add media query if font-size is bigger as the minimum font-size\n // If $rfs-factor == 1, no rescaling will take place\n @if $fs > $rfs-base-font-size and $enable-responsive-font-sizes {\n $min-width: null;\n $variable-unit: null;\n\n // Calculate minimum font-size for given font-size\n $fs-min: $rfs-base-font-size + ($fs - $rfs-base-font-size) / $rfs-factor;\n\n // Calculate difference between given font-size and minimum font-size for given font-size\n $fs-diff: $fs - $fs-min;\n\n // Base font-size formatting\n // No need to check if the unit is valid, because we did that before\n $min-width: if($rfs-font-size-unit == rem, #{$fs-min / $rfs-rem-value}rem, #{$fs-min}px);\n\n // If two-dimensional, use smallest of screen width and height\n $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n // Calculate the variable width between 0 and $rfs-breakpoint\n $variable-width: #{$fs-diff * 100 / $rfs-breakpoint}#{$variable-unit};\n\n // Set the calculated font-size.\n $rfs-fluid: calc(#{$min-width} + #{$variable-width}) #{$rfs-suffix};\n }\n\n // Rendering\n @if $rfs-fluid == null {\n // Only render static font-size if no fluid font-size is available\n font-size: $rfs-static;\n }\n @else {\n $mq-value: null;\n\n // RFS breakpoint formatting\n @if $rfs-breakpoint-unit == em or $rfs-breakpoint-unit == rem {\n $mq-value: #{$rfs-breakpoint / $rfs-rem-value}#{$rfs-breakpoint-unit};\n }\n @else if $rfs-breakpoint-unit == px {\n $mq-value: #{$rfs-breakpoint}px;\n }\n @else {\n @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n }\n\n @if $rfs-class == \"disable\" {\n // Adding an extra class increases specificity,\n // which prevents the media query to override the font size\n &,\n .disable-responsive-font-size &,\n &.disable-responsive-font-size {\n font-size: $rfs-static;\n }\n }\n @else {\n font-size: $rfs-static;\n }\n\n @if $rfs-two-dimensional {\n @media (max-width: #{$mq-value}), (max-height: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n @else {\n @media (max-width: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n }\n }\n}\n\n// The font-size & responsive-font-size mixin uses RFS to rescale font sizes\n@mixin font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n\n@mixin responsive-font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n","// Hover mixin and `$enable-hover-media-query` are deprecated.\n//\n// Originally added during our alphas and maintained during betas, this mixin was\n// designed to prevent `:hover` stickiness on iOS-an issue where hover styles\n// would persist after initial touch.\n//\n// For backward compatibility, we've kept these mixins and updated them to\n// always return their regular pseudo-classes instead of a shimmed media query.\n//\n// Issue: https://github.com/twbs/bootstrap/issues/25195\n\n@mixin hover {\n &:hover { @content; }\n}\n\n@mixin hover-focus {\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin plain-hover-focus {\n &,\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin hover-focus-active {\n &:hover,\n &:focus,\n &:active {\n @content;\n }\n}\n","// stylelint-disable declaration-no-important, selector-list-comma-newline-after\n\n//\n// Headings\n//\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n margin-bottom: $headings-margin-bottom;\n font-family: $headings-font-family;\n font-weight: $headings-font-weight;\n line-height: $headings-line-height;\n color: $headings-color;\n}\n\nh1, .h1 { @include font-size($h1-font-size); }\nh2, .h2 { @include font-size($h2-font-size); }\nh3, .h3 { @include font-size($h3-font-size); }\nh4, .h4 { @include font-size($h4-font-size); }\nh5, .h5 { @include font-size($h5-font-size); }\nh6, .h6 { @include font-size($h6-font-size); }\n\n.lead {\n @include font-size($lead-font-size);\n font-weight: $lead-font-weight;\n}\n\n// Type display classes\n.display-1 {\n @include font-size($display1-size);\n font-weight: $display1-weight;\n line-height: $display-line-height;\n}\n.display-2 {\n @include font-size($display2-size);\n font-weight: $display2-weight;\n line-height: $display-line-height;\n}\n.display-3 {\n @include font-size($display3-size);\n font-weight: $display3-weight;\n line-height: $display-line-height;\n}\n.display-4 {\n @include font-size($display4-size);\n font-weight: $display4-weight;\n line-height: $display-line-height;\n}\n\n\n//\n// Horizontal rules\n//\n\nhr {\n margin-top: $hr-margin-y;\n margin-bottom: $hr-margin-y;\n border: 0;\n border-top: $hr-border-width solid $hr-border-color;\n}\n\n\n//\n// Emphasis\n//\n\nsmall,\n.small {\n @include font-size($small-font-size);\n font-weight: $font-weight-normal;\n}\n\nmark,\n.mark {\n padding: $mark-padding;\n background-color: $mark-bg;\n}\n\n\n//\n// Lists\n//\n\n.list-unstyled {\n @include list-unstyled;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n @include list-unstyled;\n}\n.list-inline-item {\n display: inline-block;\n\n &:not(:last-child) {\n margin-right: $list-inline-padding;\n }\n}\n\n\n//\n// Misc\n//\n\n// Builds on `abbr`\n.initialism {\n @include font-size(90%);\n text-transform: uppercase;\n}\n\n// Blockquotes\n.blockquote {\n margin-bottom: $spacer;\n @include font-size($blockquote-font-size);\n}\n\n.blockquote-footer {\n display: block;\n @include font-size($blockquote-small-font-size);\n color: $blockquote-small-color;\n\n &::before {\n content: \"\\2014\\00A0\"; // em dash, nbsp\n }\n}\n","// Lists\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n@mixin list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n","// Responsive images (ensure images don't scale beyond their parents)\n//\n// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.\n// We previously tried the \"images are responsive by default\" approach in Bootstrap v2,\n// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)\n// which weren't expecting the images within themselves to be involuntarily resized.\n// See also https://github.com/twbs/bootstrap/issues/18178\n.img-fluid {\n @include img-fluid;\n}\n\n\n// Image thumbnails\n.img-thumbnail {\n padding: $thumbnail-padding;\n background-color: $thumbnail-bg;\n border: $thumbnail-border-width solid $thumbnail-border-color;\n @include border-radius($thumbnail-border-radius);\n @include box-shadow($thumbnail-box-shadow);\n\n // Keep them at most 100% wide\n @include img-fluid;\n}\n\n//\n// Figures\n//\n\n.figure {\n // Ensures the caption's text aligns with the image.\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: $spacer / 2;\n line-height: 1;\n}\n\n.figure-caption {\n @include font-size($figure-caption-font-size);\n color: $figure-caption-color;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n\n@mixin img-fluid {\n // Part 1: Set a maximum relative to the parent\n max-width: 100%;\n // Part 2: Override the height to auto, otherwise images will be stretched\n // when setting a width and height attribute on the img element.\n height: auto;\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size.\n\n@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {\n background-image: url($file-1x);\n\n // Autoprefixer takes care of adding -webkit-min-device-pixel-ratio and -o-min-device-pixel-ratio,\n // but doesn't convert dppx=>dpi.\n // There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard.\n // Compatibility info: https://caniuse.com/#feat=css-media-resolution\n @media only screen and (min-resolution: 192dpi), // IE9-11 don't support dppx\n only screen and (min-resolution: 2dppx) { // Standardized\n background-image: url($file-2x);\n background-size: $width-1x $height-1x;\n }\n @include deprecate(\"`img-retina()`\", \"v4.3.0\", \"v5\");\n}\n","// stylelint-disable property-blacklist\n// Single side border-radius\n\n@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {\n @if $enable-rounded {\n border-radius: $radius;\n }\n @else if $fallback-border-radius != false {\n border-radius: $fallback-border-radius;\n }\n}\n\n@mixin border-top-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-top-right-radius: $radius;\n }\n}\n\n@mixin border-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: $radius;\n border-bottom-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n\n@mixin border-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n\n@mixin border-top-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n }\n}\n\n@mixin border-top-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-right-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-left-radius($radius) {\n @if $enable-rounded {\n border-bottom-left-radius: $radius;\n }\n}\n","// Inline code\ncode {\n @include font-size($code-font-size);\n color: $code-color;\n word-break: break-word;\n\n // Streamline the style when inside anchors to avoid broken underline and more\n a > & {\n color: inherit;\n }\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: $kbd-padding-y $kbd-padding-x;\n @include font-size($kbd-font-size);\n color: $kbd-color;\n background-color: $kbd-bg;\n @include border-radius($border-radius-sm);\n @include box-shadow($kbd-box-shadow);\n\n kbd {\n padding: 0;\n @include font-size(100%);\n font-weight: $nested-kbd-font-weight;\n @include box-shadow(none);\n }\n}\n\n// Blocks of code\npre {\n display: block;\n @include font-size($code-font-size);\n color: $pre-color;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n @include font-size(inherit);\n color: inherit;\n word-break: normal;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: $pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-grid-classes {\n .container {\n @include make-container();\n @include make-container-max-widths();\n }\n}\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but with 100% width for\n// fluid, full width layouts.\n\n@if $enable-grid-classes {\n .container-fluid {\n @include make-container();\n }\n}\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n }\n\n // Remove the negative margin from default .row, then the horizontal padding\n // from all immediate children columns (to prevent runaway style inheritance).\n .no-gutters {\n margin-right: 0;\n margin-left: 0;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n }\n }\n}\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","/// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-container($gutter: $grid-gutter-width) {\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n margin-right: auto;\n margin-left: auto;\n}\n\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {\n @each $breakpoint, $container-max-width in $max-widths {\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n max-width: $container-max-width;\n }\n }\n}\n\n@mixin make-row($gutter: $grid-gutter-width) {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$gutter / 2;\n margin-left: -$gutter / 2;\n}\n\n@mixin make-col-ready($gutter: $grid-gutter-width) {\n position: relative;\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we use `flex` values\n // later on to override this initial width.\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n}\n\n@mixin make-col($size, $columns: $grid-columns) {\n flex: 0 0 percentage($size / $columns);\n // Add a `max-width` to ensure content within each column does not blow out\n // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari\n // do not appear to require this.\n max-width: percentage($size / $columns);\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: $size / $columns;\n margin-left: if($num == 0, 0, percentage($num));\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n // Common properties for all breakpoints\n %grid-column {\n position: relative;\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n }\n\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n // Allow columns to stretch full width below their breakpoints\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @extend %grid-column;\n }\n }\n .col#{$infix},\n .col#{$infix}-auto {\n @extend %grid-column;\n }\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex-basis: 0;\n flex-grow: 1;\n max-width: 100%;\n }\n .col#{$infix}-auto {\n flex: 0 0 auto;\n width: auto;\n max-width: 100%; // Reset earlier grid tiers\n }\n\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n\n .order#{$infix}-first { order: -1; }\n\n .order#{$infix}-last { order: $columns + 1; }\n\n @for $i from 0 through $columns {\n .order#{$infix}-#{$i} { order: $i; }\n }\n\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n }\n}\n","//\n// Basic Bootstrap table\n//\n\n.table {\n width: 100%;\n margin-bottom: $spacer;\n color: $table-color;\n background-color: $table-bg; // Reset for nesting within parents with `background-color`.\n\n th,\n td {\n padding: $table-cell-padding;\n vertical-align: top;\n border-top: $table-border-width solid $table-border-color;\n }\n\n thead th {\n vertical-align: bottom;\n border-bottom: (2 * $table-border-width) solid $table-border-color;\n }\n\n tbody + tbody {\n border-top: (2 * $table-border-width) solid $table-border-color;\n }\n}\n\n\n//\n// Condensed table w/ half padding\n//\n\n.table-sm {\n th,\n td {\n padding: $table-cell-padding-sm;\n }\n}\n\n\n// Border versions\n//\n// Add or remove borders all around the table and between all the columns.\n\n.table-bordered {\n border: $table-border-width solid $table-border-color;\n\n th,\n td {\n border: $table-border-width solid $table-border-color;\n }\n\n thead {\n th,\n td {\n border-bottom-width: 2 * $table-border-width;\n }\n }\n}\n\n.table-borderless {\n th,\n td,\n thead th,\n tbody + tbody {\n border: 0;\n }\n}\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n tbody tr:nth-of-type(#{$table-striped-order}) {\n background-color: $table-accent-bg;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n tbody tr {\n @include hover {\n color: $table-hover-color;\n background-color: $table-hover-bg;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n@each $color, $value in $theme-colors {\n @include table-row-variant($color, theme-color-level($color, $table-bg-level), theme-color-level($color, $table-border-level));\n}\n\n@include table-row-variant(active, $table-active-bg);\n\n\n// Dark styles\n//\n// Same table markup, but inverted color scheme: dark background and light text.\n\n// stylelint-disable-next-line no-duplicate-selectors\n.table {\n .thead-dark {\n th {\n color: $table-dark-color;\n background-color: $table-dark-bg;\n border-color: $table-dark-border-color;\n }\n }\n\n .thead-light {\n th {\n color: $table-head-color;\n background-color: $table-head-bg;\n border-color: $table-border-color;\n }\n }\n}\n\n.table-dark {\n color: $table-dark-color;\n background-color: $table-dark-bg;\n\n th,\n td,\n thead th {\n border-color: $table-dark-border-color;\n }\n\n &.table-bordered {\n border: 0;\n }\n\n &.table-striped {\n tbody tr:nth-of-type(odd) {\n background-color: $table-dark-accent-bg;\n }\n }\n\n &.table-hover {\n tbody tr {\n @include hover {\n color: $table-dark-hover-color;\n background-color: $table-dark-hover-bg;\n }\n }\n }\n}\n\n\n// Responsive tables\n//\n// Generate series of `.table-responsive-*` classes for configuring the screen\n// size of where your table will overflow.\n\n.table-responsive {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $next: breakpoint-next($breakpoint, $grid-breakpoints);\n $infix: breakpoint-infix($next, $grid-breakpoints);\n\n &#{$infix} {\n @include media-breakpoint-down($breakpoint) {\n display: block;\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n\n // Prevent double border on horizontal scroll due to use of `display: block;`\n > .table-bordered {\n border: 0;\n }\n }\n }\n }\n}\n","// Tables\n\n@mixin table-row-variant($state, $background, $border: null) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table-#{$state} {\n &,\n > th,\n > td {\n background-color: $background;\n }\n\n @if $border != null {\n th,\n td,\n thead th,\n tbody + tbody {\n border-color: $border;\n }\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover {\n $hover-background: darken($background, 5%);\n\n .table-#{$state} {\n @include hover {\n background-color: $hover-background;\n\n > td,\n > th {\n background-color: $hover-background;\n }\n }\n }\n }\n}\n","// Bootstrap functions\n//\n// Utility mixins and functions for evaluating source code across our variables, maps, and mixins.\n\n// Ascending\n// Used to evaluate Sass maps like our grid breakpoints.\n@mixin _assert-ascending($map, $map-name) {\n $prev-key: null;\n $prev-num: null;\n @each $key, $num in $map {\n @if $prev-num == null or unit($num) == \"%\" {\n // Do nothing\n } @else if not comparable($prev-num, $num) {\n @warn \"Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !\";\n } @else if $prev-num >= $num {\n @warn \"Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !\";\n }\n $prev-key: $key;\n $prev-num: $num;\n }\n}\n\n// Starts at zero\n// Used to ensure the min-width of the lowest breakpoint starts at 0.\n@mixin _assert-starts-at-zero($map, $map-name: \"$grid-breakpoints\") {\n $values: map-values($map);\n $first-value: nth($values, 1);\n @if $first-value != 0 {\n @warn \"First breakpoint in #{$map-name} must start at 0, but starts at #{$first-value}.\";\n }\n}\n\n// Replace `$search` with `$replace` in `$string`\n// Used on our SVG icon backgrounds for custom forms.\n//\n// @author Hugo Giraudel\n// @param {String} $string - Initial string\n// @param {String} $search - Substring to replace\n// @param {String} $replace ('') - New value\n// @return {String} - Updated string\n@function str-replace($string, $search, $replace: \"\") {\n $index: str-index($string, $search);\n\n @if $index {\n @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);\n }\n\n @return $string;\n}\n\n// Color contrast\n@function color-yiq($color, $dark: $yiq-text-dark, $light: $yiq-text-light) {\n $r: red($color);\n $g: green($color);\n $b: blue($color);\n\n $yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000;\n\n @if ($yiq >= $yiq-contrasted-threshold) {\n @return $dark;\n } @else {\n @return $light;\n }\n}\n\n// Retrieve color Sass maps\n@function color($key: \"blue\") {\n @return map-get($colors, $key);\n}\n\n@function theme-color($key: \"primary\") {\n @return map-get($theme-colors, $key);\n}\n\n@function gray($key: \"100\") {\n @return map-get($grays, $key);\n}\n\n// Request a theme color level\n@function theme-color-level($color-name: \"primary\", $level: 0) {\n $color: theme-color($color-name);\n $color-base: if($level > 0, $black, $white);\n $level: abs($level);\n\n @return mix($color-base, $color, $level * $theme-color-interval);\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Textual form controls\n//\n\n.form-control {\n display: block;\n width: 100%;\n height: $input-height;\n padding: $input-padding-y $input-padding-x;\n font-family: $input-font-family;\n @include font-size($input-font-size);\n font-weight: $input-font-weight;\n line-height: $input-line-height;\n color: $input-color;\n background-color: $input-bg;\n background-clip: padding-box;\n border: $input-border-width solid $input-border-color;\n\n // Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.\n @include border-radius($input-border-radius, 0);\n\n @include box-shadow($input-box-shadow);\n @include transition($input-transition);\n\n // Unstyle the caret on `<select>`s in IE10+.\n &::-ms-expand {\n background-color: transparent;\n border: 0;\n }\n\n // Customize the `:focus` state to imitate native WebKit styles.\n @include form-control-focus();\n\n // Placeholder\n &::placeholder {\n color: $input-placeholder-color;\n // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.\n opacity: 1;\n }\n\n // Disabled and read-only inputs\n //\n // HTML5 says that controls under a fieldset > legend:first-child won't be\n // disabled if the fieldset is disabled. Due to implementation difficulty, we\n // don't honor that edge case; we style them as disabled anyway.\n &:disabled,\n &[readonly] {\n background-color: $input-disabled-bg;\n // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.\n opacity: 1;\n }\n}\n\nselect.form-control {\n &:focus::-ms-value {\n // Suppress the nested default white text on blue background highlight given to\n // the selected option text when the (still closed) <select> receives focus\n // in IE and (under certain conditions) Edge, as it looks bad and cannot be made to\n // match the appearance of the native widget.\n // See https://github.com/twbs/bootstrap/issues/19398.\n color: $input-color;\n background-color: $input-bg;\n }\n}\n\n// Make file inputs better match text inputs by forcing them to new lines.\n.form-control-file,\n.form-control-range {\n display: block;\n width: 100%;\n}\n\n\n//\n// Labels\n//\n\n// For use with horizontal and inline forms, when you need the label (or legend)\n// text to align with the form controls.\n.col-form-label {\n padding-top: calc(#{$input-padding-y} + #{$input-border-width});\n padding-bottom: calc(#{$input-padding-y} + #{$input-border-width});\n margin-bottom: 0; // Override the `<label>/<legend>` default\n @include font-size(inherit); // Override the `<legend>` default\n line-height: $input-line-height;\n}\n\n.col-form-label-lg {\n padding-top: calc(#{$input-padding-y-lg} + #{$input-border-width});\n padding-bottom: calc(#{$input-padding-y-lg} + #{$input-border-width});\n @include font-size($input-font-size-lg);\n line-height: $input-line-height-lg;\n}\n\n.col-form-label-sm {\n padding-top: calc(#{$input-padding-y-sm} + #{$input-border-width});\n padding-bottom: calc(#{$input-padding-y-sm} + #{$input-border-width});\n @include font-size($input-font-size-sm);\n line-height: $input-line-height-sm;\n}\n\n\n// Readonly controls as plain text\n//\n// Apply class to a readonly input to make it appear like regular plain\n// text (without any border, background color, focus indicator)\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding-top: $input-padding-y;\n padding-bottom: $input-padding-y;\n margin-bottom: 0; // match inputs if this class comes on inputs with default margins\n line-height: $input-line-height;\n color: $input-plaintext-color;\n background-color: transparent;\n border: solid transparent;\n border-width: $input-border-width 0;\n\n &.form-control-sm,\n &.form-control-lg {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n//\n// Repeated in `_input_group.scss` to avoid Sass extend issues.\n\n.form-control-sm {\n height: $input-height-sm;\n padding: $input-padding-y-sm $input-padding-x-sm;\n @include font-size($input-font-size-sm);\n line-height: $input-line-height-sm;\n @include border-radius($input-border-radius-sm);\n}\n\n.form-control-lg {\n height: $input-height-lg;\n padding: $input-padding-y-lg $input-padding-x-lg;\n @include font-size($input-font-size-lg);\n line-height: $input-line-height-lg;\n @include border-radius($input-border-radius-lg);\n}\n\n// stylelint-disable-next-line no-duplicate-selectors\nselect.form-control {\n &[size],\n &[multiple] {\n height: auto;\n }\n}\n\ntextarea.form-control {\n height: auto;\n}\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: $form-group-margin-bottom;\n}\n\n.form-text {\n display: block;\n margin-top: $form-text-margin-top;\n}\n\n\n// Form grid\n//\n// Special replacement for our grid system's `.row` for tighter form layouts.\n\n.form-row {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$form-grid-gutter-width / 2;\n margin-left: -$form-grid-gutter-width / 2;\n\n > .col,\n > [class*=\"col-\"] {\n padding-right: $form-grid-gutter-width / 2;\n padding-left: $form-grid-gutter-width / 2;\n }\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.form-check {\n position: relative;\n display: block;\n padding-left: $form-check-input-gutter;\n}\n\n.form-check-input {\n position: absolute;\n margin-top: $form-check-input-margin-y;\n margin-left: -$form-check-input-gutter;\n\n &:disabled ~ .form-check-label {\n color: $text-muted;\n }\n}\n\n.form-check-label {\n margin-bottom: 0; // Override default `<label>` bottom margin\n}\n\n.form-check-inline {\n display: inline-flex;\n align-items: center;\n padding-left: 0; // Override base .form-check\n margin-right: $form-check-inline-margin-x;\n\n // Undo .form-check-input defaults and add some `margin-right`.\n .form-check-input {\n position: static;\n margin-top: 0;\n margin-right: $form-check-inline-input-margin-x;\n margin-left: 0;\n }\n}\n\n\n// Form validation\n//\n// Provide feedback to users when form field values are valid or invalid. Works\n// primarily for client-side validation via scoped `:invalid` and `:valid`\n// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for\n// server side validation.\n\n@each $state, $data in $form-validation-states {\n @include form-validation-state($state, map-get($data, color), map-get($data, icon));\n}\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n\n.form-inline {\n display: flex;\n flex-flow: row wrap;\n align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)\n\n // Because we use flex, the initial sizing of checkboxes is collapsed and\n // doesn't occupy the full-width (which is what we want for xs grid tier),\n // so we force that here.\n .form-check {\n width: 100%;\n }\n\n // Kick in the inline\n @include media-breakpoint-up(sm) {\n label {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 0;\n }\n\n // Inline-block all the things for \"inline\"\n .form-group {\n display: flex;\n flex: 0 0 auto;\n flex-flow: row wrap;\n align-items: center;\n margin-bottom: 0;\n }\n\n // Allow folks to *not* use `.form-group`\n .form-control {\n display: inline-block;\n width: auto; // Prevent labels from stacking above inputs in `.form-group`\n vertical-align: middle;\n }\n\n // Make static controls behave like regular ones\n .form-control-plaintext {\n display: inline-block;\n }\n\n .input-group,\n .custom-select {\n width: auto;\n }\n\n // Remove default margin on radios/checkboxes that were used for stacking, and\n // then undo the floating of radios and checkboxes to match.\n .form-check {\n display: flex;\n align-items: center;\n justify-content: center;\n width: auto;\n padding-left: 0;\n }\n .form-check-input {\n position: relative;\n flex-shrink: 0;\n margin-top: 0;\n margin-right: $form-check-input-margin-x;\n margin-left: 0;\n }\n\n .custom-control {\n align-items: center;\n justify-content: center;\n }\n .custom-control-label {\n margin-bottom: 0;\n }\n }\n}\n","// stylelint-disable property-blacklist\n@mixin transition($transition...) {\n @if $enable-transitions {\n @if length($transition) == 0 {\n transition: $transition-base;\n } @else {\n transition: $transition;\n }\n }\n\n @if $enable-prefers-reduced-motion-media-query {\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n }\n}\n","// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `$input-focus-border-color` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n@mixin form-control-focus() {\n &:focus {\n color: $input-focus-color;\n background-color: $input-focus-bg;\n border-color: $input-focus-border-color;\n outline: 0;\n // Avoid using mixin so we can pass custom focus shadow properly\n @if $enable-shadows {\n box-shadow: $input-box-shadow, $input-focus-box-shadow;\n } @else {\n box-shadow: $input-focus-box-shadow;\n }\n }\n}\n\n\n@mixin form-validation-state($state, $color, $icon) {\n .#{$state}-feedback {\n display: none;\n width: 100%;\n margin-top: $form-feedback-margin-top;\n @include font-size($form-feedback-font-size);\n color: $color;\n }\n\n .#{$state}-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%; // Contain to parent when possible\n padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;\n margin-top: .1rem;\n @include font-size($form-feedback-tooltip-font-size);\n line-height: $form-feedback-tooltip-line-height;\n color: color-yiq($color);\n background-color: rgba($color, $form-feedback-tooltip-opacity);\n @include border-radius($form-feedback-tooltip-border-radius);\n }\n\n .form-control {\n .was-validated &:#{$state},\n &.is-#{$state} {\n border-color: $color;\n\n @if $enable-validation-icons {\n padding-right: $input-height-inner;\n background-image: $icon;\n background-repeat: no-repeat;\n background-position: center right $input-height-inner-quarter;\n background-size: $input-height-inner-half $input-height-inner-half;\n }\n\n &:focus {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n }\n\n // stylelint-disable-next-line selector-no-qualifying-type\n textarea.form-control {\n .was-validated &:#{$state},\n &.is-#{$state} {\n @if $enable-validation-icons {\n padding-right: $input-height-inner;\n background-position: top $input-height-inner-quarter right $input-height-inner-quarter;\n }\n }\n }\n\n .custom-select {\n .was-validated &:#{$state},\n &.is-#{$state} {\n border-color: $color;\n\n @if $enable-validation-icons {\n padding-right: $custom-select-feedback-icon-padding-right;\n background: $custom-select-background, $icon $custom-select-bg no-repeat $custom-select-feedback-icon-position / $custom-select-feedback-icon-size;\n }\n\n &:focus {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n }\n\n\n .form-control-file {\n .was-validated &:#{$state},\n &.is-#{$state} {\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n }\n\n .form-check-input {\n .was-validated &:#{$state},\n &.is-#{$state} {\n ~ .form-check-label {\n color: $color;\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n }\n }\n\n .custom-control-input {\n .was-validated &:#{$state},\n &.is-#{$state} {\n ~ .custom-control-label {\n color: $color;\n\n &::before {\n border-color: $color;\n }\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n\n &:checked {\n ~ .custom-control-label::before {\n border-color: lighten($color, 10%);\n @include gradient-bg(lighten($color, 10%));\n }\n }\n\n &:focus {\n ~ .custom-control-label::before {\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n\n &:not(:checked) ~ .custom-control-label::before {\n border-color: $color;\n }\n }\n }\n }\n\n // custom file\n .custom-file-input {\n .was-validated &:#{$state},\n &.is-#{$state} {\n ~ .custom-file-label {\n border-color: $color;\n }\n\n ~ .#{$state}-feedback,\n ~ .#{$state}-tooltip {\n display: block;\n }\n\n &:focus {\n ~ .custom-file-label {\n border-color: $color;\n box-shadow: 0 0 0 $input-focus-width rgba($color, .25);\n }\n }\n }\n }\n}\n","// Gradients\n\n@mixin gradient-bg($color) {\n @if $enable-gradients {\n background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x;\n } @else {\n background-color: $color;\n }\n}\n\n// Horizontal gradient, from left to right\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {\n background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);\n background-repeat: repeat-x;\n}\n\n// Vertical gradient, from top to bottom\n//\n// Creates two color stops, start and end, by specifying a color and position for each color stop.\n@mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {\n background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);\n background-repeat: repeat-x;\n}\n\n@mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) {\n background-image: linear-gradient($deg, $start-color, $end-color);\n background-repeat: repeat-x;\n}\n@mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {\n background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) {\n background-image: radial-gradient(circle, $inner-color, $outer-color);\n background-repeat: no-repeat;\n}\n@mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) {\n background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Base styles\n//\n\n.btn {\n display: inline-block;\n font-family: $btn-font-family;\n font-weight: $btn-font-weight;\n color: $body-color;\n text-align: center;\n vertical-align: middle;\n user-select: none;\n background-color: transparent;\n border: $btn-border-width solid transparent;\n @include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-line-height, $btn-border-radius);\n @include transition($btn-transition);\n\n @include hover {\n color: $body-color;\n text-decoration: none;\n }\n\n &:focus,\n &.focus {\n outline: 0;\n box-shadow: $btn-focus-box-shadow;\n }\n\n // Disabled comes first so active can properly restyle\n &.disabled,\n &:disabled {\n opacity: $btn-disabled-opacity;\n @include box-shadow(none);\n }\n\n &:not(:disabled):not(.disabled):active,\n &:not(:disabled):not(.disabled).active {\n @include box-shadow($btn-active-box-shadow);\n\n &:focus {\n @include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);\n }\n }\n}\n\n// Future-proof disabling of clicks on `<a>` elements\na.btn.disabled,\nfieldset:disabled a.btn {\n pointer-events: none;\n}\n\n\n//\n// Alternate buttons\n//\n\n@each $color, $value in $theme-colors {\n .btn-#{$color} {\n @include button-variant($value, $value);\n }\n}\n\n@each $color, $value in $theme-colors {\n .btn-outline-#{$color} {\n @include button-outline-variant($value);\n }\n}\n\n\n//\n// Link buttons\n//\n\n// Make a button look and behave like a link\n.btn-link {\n font-weight: $font-weight-normal;\n color: $link-color;\n text-decoration: $link-decoration;\n\n @include hover {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n\n &:focus,\n &.focus {\n text-decoration: $link-hover-decoration;\n box-shadow: none;\n }\n\n &:disabled,\n &.disabled {\n color: $btn-link-disabled-color;\n pointer-events: none;\n }\n\n // No need for an active state here\n}\n\n\n//\n// Button Sizes\n//\n\n.btn-lg {\n @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-line-height-lg, $btn-border-radius-lg);\n}\n\n.btn-sm {\n @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-line-height-sm, $btn-border-radius-sm);\n}\n\n\n//\n// Block button\n//\n\n.btn-block {\n display: block;\n width: 100%;\n\n // Vertically space out multiple block buttons\n + .btn-block {\n margin-top: $btn-block-spacing-y;\n }\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n@mixin button-variant($background, $border, $hover-background: darken($background, 7.5%), $hover-border: darken($border, 10%), $active-background: darken($background, 10%), $active-border: darken($border, 12.5%)) {\n color: color-yiq($background);\n @include gradient-bg($background);\n border-color: $border;\n @include box-shadow($btn-box-shadow);\n\n @include hover {\n color: color-yiq($hover-background);\n @include gradient-bg($hover-background);\n border-color: $hover-border;\n }\n\n &:focus,\n &.focus {\n // Avoid using mixin so we can pass custom focus shadow properly\n @if $enable-shadows {\n box-shadow: $btn-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);\n } @else {\n box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);\n }\n }\n\n // Disabled comes first so active can properly restyle\n &.disabled,\n &:disabled {\n color: color-yiq($background);\n background-color: $background;\n border-color: $border;\n // Remove CSS gradients if they're enabled\n @if $enable-gradients {\n background-image: none;\n }\n }\n\n &:not(:disabled):not(.disabled):active,\n &:not(:disabled):not(.disabled).active,\n .show > &.dropdown-toggle {\n color: color-yiq($active-background);\n background-color: $active-background;\n @if $enable-gradients {\n background-image: none; // Remove the gradient for the pressed/active state\n }\n border-color: $active-border;\n\n &:focus {\n // Avoid using mixin so we can pass custom focus shadow properly\n @if $enable-shadows and $btn-active-box-shadow != none {\n box-shadow: $btn-active-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);\n } @else {\n box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);\n }\n }\n }\n}\n\n@mixin button-outline-variant($color, $color-hover: color-yiq($color), $active-background: $color, $active-border: $color) {\n color: $color;\n border-color: $color;\n\n @include hover {\n color: $color-hover;\n background-color: $active-background;\n border-color: $active-border;\n }\n\n &:focus,\n &.focus {\n box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n }\n\n &.disabled,\n &:disabled {\n color: $color;\n background-color: transparent;\n }\n\n &:not(:disabled):not(.disabled):active,\n &:not(:disabled):not(.disabled).active,\n .show > &.dropdown-toggle {\n color: color-yiq($active-background);\n background-color: $active-background;\n border-color: $active-border;\n\n &:focus {\n // Avoid using mixin so we can pass custom focus shadow properly\n @if $enable-shadows and $btn-active-box-shadow != none {\n box-shadow: $btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5);\n } @else {\n box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);\n }\n }\n }\n}\n\n// Button sizes\n@mixin button-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {\n padding: $padding-y $padding-x;\n @include font-size($font-size);\n line-height: $line-height;\n // Manually declare to provide an override to the browser default\n @include border-radius($border-radius, 0);\n}\n",".fade {\n @include transition($transition-fade);\n\n &:not(.show) {\n opacity: 0;\n }\n}\n\n.collapse {\n &:not(.show) {\n display: none;\n }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n @include transition($transition-collapse);\n}\n","// The dropdown wrapper (`<div>`)\n.dropup,\n.dropright,\n.dropdown,\n.dropleft {\n position: relative;\n}\n\n.dropdown-toggle {\n white-space: nowrap;\n\n // Generate the caret automatically\n @include caret;\n}\n\n// The dropdown menu\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: $zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: $dropdown-min-width;\n padding: $dropdown-padding-y 0;\n margin: $dropdown-spacer 0 0; // override default ul\n @include font-size($dropdown-font-size);\n color: $dropdown-color;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n list-style: none;\n background-color: $dropdown-bg;\n background-clip: padding-box;\n border: $dropdown-border-width solid $dropdown-border-color;\n @include border-radius($dropdown-border-radius);\n @include box-shadow($dropdown-box-shadow);\n}\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .dropdown-menu#{$infix}-left {\n right: auto;\n left: 0;\n }\n\n .dropdown-menu#{$infix}-right {\n right: 0;\n left: auto;\n }\n }\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n// Just add .dropup after the standard .dropdown class and you're set.\n.dropup {\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-top: 0;\n margin-bottom: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(up);\n }\n}\n\n.dropright {\n .dropdown-menu {\n top: 0;\n right: auto;\n left: 100%;\n margin-top: 0;\n margin-left: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(right);\n &::after {\n vertical-align: 0;\n }\n }\n}\n\n.dropleft {\n .dropdown-menu {\n top: 0;\n right: 100%;\n left: auto;\n margin-top: 0;\n margin-right: $dropdown-spacer;\n }\n\n .dropdown-toggle {\n @include caret(left);\n &::before {\n vertical-align: 0;\n }\n }\n}\n\n// When enabled Popper.js, reset basic dropdown position\n// stylelint-disable-next-line no-duplicate-selectors\n.dropdown-menu {\n &[x-placement^=\"top\"],\n &[x-placement^=\"right\"],\n &[x-placement^=\"bottom\"],\n &[x-placement^=\"left\"] {\n right: auto;\n bottom: auto;\n }\n}\n\n// Dividers (basically an `<hr>`) within the dropdown\n.dropdown-divider {\n @include nav-divider($dropdown-divider-bg, $dropdown-divider-margin-y);\n}\n\n// Links, buttons, and more within the dropdown menu\n//\n// `<button>`-specific styles are denoted with `// For <button>s`\n.dropdown-item {\n display: block;\n width: 100%; // For `<button>`s\n padding: $dropdown-item-padding-y $dropdown-item-padding-x;\n clear: both;\n font-weight: $font-weight-normal;\n color: $dropdown-link-color;\n text-align: inherit; // For `<button>`s\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n background-color: transparent; // For `<button>`s\n border: 0; // For `<button>`s\n\n // Prevent dropdown overflow if there's no padding\n // See https://github.com/twbs/bootstrap/pull/27703\n @if $dropdown-padding-y == 0 {\n &:first-child {\n @include border-top-radius($dropdown-inner-border-radius);\n }\n\n &:last-child {\n @include border-bottom-radius($dropdown-inner-border-radius);\n }\n }\n\n @include hover-focus {\n color: $dropdown-link-hover-color;\n text-decoration: none;\n @include gradient-bg($dropdown-link-hover-bg);\n }\n\n &.active,\n &:active {\n color: $dropdown-link-active-color;\n text-decoration: none;\n @include gradient-bg($dropdown-link-active-bg);\n }\n\n &.disabled,\n &:disabled {\n color: $dropdown-link-disabled-color;\n pointer-events: none;\n background-color: transparent;\n // Remove CSS gradients if they're enabled\n @if $enable-gradients {\n background-image: none;\n }\n }\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: $dropdown-padding-y $dropdown-item-padding-x;\n margin-bottom: 0; // for use with heading elements\n @include font-size($font-size-sm);\n color: $dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n\n// Dropdown text\n.dropdown-item-text {\n display: block;\n padding: $dropdown-item-padding-y $dropdown-item-padding-x;\n color: $dropdown-link-color;\n}\n","@mixin caret-down {\n border-top: $caret-width solid;\n border-right: $caret-width solid transparent;\n border-bottom: 0;\n border-left: $caret-width solid transparent;\n}\n\n@mixin caret-up {\n border-top: 0;\n border-right: $caret-width solid transparent;\n border-bottom: $caret-width solid;\n border-left: $caret-width solid transparent;\n}\n\n@mixin caret-right {\n border-top: $caret-width solid transparent;\n border-right: 0;\n border-bottom: $caret-width solid transparent;\n border-left: $caret-width solid;\n}\n\n@mixin caret-left {\n border-top: $caret-width solid transparent;\n border-right: $caret-width solid;\n border-bottom: $caret-width solid transparent;\n}\n\n@mixin caret($direction: down) {\n @if $enable-caret {\n &::after {\n display: inline-block;\n margin-left: $caret-spacing;\n vertical-align: $caret-vertical-align;\n content: \"\";\n @if $direction == down {\n @include caret-down;\n } @else if $direction == up {\n @include caret-up;\n } @else if $direction == right {\n @include caret-right;\n }\n }\n\n @if $direction == left {\n &::after {\n display: none;\n }\n\n &::before {\n display: inline-block;\n margin-right: $caret-spacing;\n vertical-align: $caret-vertical-align;\n content: \"\";\n @include caret-left;\n }\n }\n\n &:empty::after {\n margin-left: 0;\n }\n }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n@mixin nav-divider($color: $nav-divider-color, $margin-y: $nav-divider-margin-y) {\n height: 0;\n margin: $margin-y 0;\n overflow: hidden;\n border-top: 1px solid $color;\n}\n","// stylelint-disable selector-no-qualifying-type\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-flex;\n vertical-align: middle; // match .btn alignment given font-size hack above\n\n > .btn {\n position: relative;\n flex: 1 1 auto;\n\n // Bring the hover, focused, and \"active\" buttons to the front to overlay\n // the borders properly\n @include hover {\n z-index: 1;\n }\n &:focus,\n &:active,\n &.active {\n z-index: 1;\n }\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-start;\n\n .input-group {\n width: auto;\n }\n}\n\n.btn-group {\n // Prevent double borders when buttons are next to each other\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) {\n margin-left: -$btn-border-width;\n }\n\n // Reset rounded corners\n > .btn:not(:last-child):not(.dropdown-toggle),\n > .btn-group:not(:last-child) > .btn {\n @include border-right-radius(0);\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) > .btn {\n @include border-left-radius(0);\n }\n}\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-sm > .btn { @extend .btn-sm; }\n.btn-group-lg > .btn { @extend .btn-lg; }\n\n\n//\n// Split button dropdowns\n//\n\n.dropdown-toggle-split {\n padding-right: $btn-padding-x * .75;\n padding-left: $btn-padding-x * .75;\n\n &::after,\n .dropup &::after,\n .dropright &::after {\n margin-left: 0;\n }\n\n .dropleft &::before {\n margin-right: 0;\n }\n}\n\n.btn-sm + .dropdown-toggle-split {\n padding-right: $btn-padding-x-sm * .75;\n padding-left: $btn-padding-x-sm * .75;\n}\n\n.btn-lg + .dropdown-toggle-split {\n padding-right: $btn-padding-x-lg * .75;\n padding-left: $btn-padding-x-lg * .75;\n}\n\n\n// The clickable button for toggling the menu\n// Set the same inset shadow as the :active state\n.btn-group.show .dropdown-toggle {\n @include box-shadow($btn-active-box-shadow);\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n @include box-shadow(none);\n }\n}\n\n\n//\n// Vertical button groups\n//\n\n.btn-group-vertical {\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n\n > .btn,\n > .btn-group {\n width: 100%;\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) {\n margin-top: -$btn-border-width;\n }\n\n // Reset rounded corners\n > .btn:not(:last-child):not(.dropdown-toggle),\n > .btn-group:not(:last-child) > .btn {\n @include border-bottom-radius(0);\n }\n\n > .btn:not(:first-child),\n > .btn-group:not(:first-child) > .btn {\n @include border-top-radius(0);\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n.btn-group-toggle {\n > .btn,\n > .btn-group > .btn {\n margin-bottom: 0; // Override default `<label>` value\n\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n }\n }\n}\n","// stylelint-disable selector-no-qualifying-type\n\n//\n// Base styles\n//\n\n.input-group {\n position: relative;\n display: flex;\n flex-wrap: wrap; // For form validation feedback\n align-items: stretch;\n width: 100%;\n\n > .form-control,\n > .form-control-plaintext,\n > .custom-select,\n > .custom-file {\n position: relative; // For focus state's z-index\n flex: 1 1 auto;\n // Add width 1% and flex-basis auto to ensure that button will not wrap out\n // the column. Applies to IE Edge+ and Firefox. Chrome does not require this.\n width: 1%;\n margin-bottom: 0;\n\n + .form-control,\n + .custom-select,\n + .custom-file {\n margin-left: -$input-border-width;\n }\n }\n\n // Bring the \"active\" form control to the top of surrounding elements\n > .form-control:focus,\n > .custom-select:focus,\n > .custom-file .custom-file-input:focus ~ .custom-file-label {\n z-index: 3;\n }\n\n // Bring the custom file input above the label\n > .custom-file .custom-file-input:focus {\n z-index: 4;\n }\n\n > .form-control,\n > .custom-select {\n &:not(:last-child) { @include border-right-radius(0); }\n &:not(:first-child) { @include border-left-radius(0); }\n }\n\n // Custom file inputs have more complex markup, thus requiring different\n // border-radius overrides.\n > .custom-file {\n display: flex;\n align-items: center;\n\n &:not(:last-child) .custom-file-label,\n &:not(:last-child) .custom-file-label::after { @include border-right-radius(0); }\n &:not(:first-child) .custom-file-label { @include border-left-radius(0); }\n }\n}\n\n\n// Prepend and append\n//\n// While it requires one extra layer of HTML for each, dedicated prepend and\n// append elements allow us to 1) be less clever, 2) simplify our selectors, and\n// 3) support HTML5 form validation.\n\n.input-group-prepend,\n.input-group-append {\n display: flex;\n\n // Ensure buttons are always above inputs for more visually pleasing borders.\n // This isn't needed for `.input-group-text` since it shares the same border-color\n // as our inputs.\n .btn {\n position: relative;\n z-index: 2;\n\n &:focus {\n z-index: 3;\n }\n }\n\n .btn + .btn,\n .btn + .input-group-text,\n .input-group-text + .input-group-text,\n .input-group-text + .btn {\n margin-left: -$input-border-width;\n }\n}\n\n.input-group-prepend { margin-right: -$input-border-width; }\n.input-group-append { margin-left: -$input-border-width; }\n\n\n// Textual addons\n//\n// Serves as a catch-all element for any text or radio/checkbox input you wish\n// to prepend or append to an input.\n\n.input-group-text {\n display: flex;\n align-items: center;\n padding: $input-padding-y $input-padding-x;\n margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom\n @include font-size($input-font-size); // Match inputs\n font-weight: $font-weight-normal;\n line-height: $input-line-height;\n color: $input-group-addon-color;\n text-align: center;\n white-space: nowrap;\n background-color: $input-group-addon-bg;\n border: $input-border-width solid $input-group-addon-border-color;\n @include border-radius($input-border-radius);\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n\n// Sizing\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control:not(textarea),\n.input-group-lg > .custom-select {\n height: $input-height-lg;\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .custom-select,\n.input-group-lg > .input-group-prepend > .input-group-text,\n.input-group-lg > .input-group-append > .input-group-text,\n.input-group-lg > .input-group-prepend > .btn,\n.input-group-lg > .input-group-append > .btn {\n padding: $input-padding-y-lg $input-padding-x-lg;\n @include font-size($input-font-size-lg);\n line-height: $input-line-height-lg;\n @include border-radius($input-border-radius-lg);\n}\n\n.input-group-sm > .form-control:not(textarea),\n.input-group-sm > .custom-select {\n height: $input-height-sm;\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .custom-select,\n.input-group-sm > .input-group-prepend > .input-group-text,\n.input-group-sm > .input-group-append > .input-group-text,\n.input-group-sm > .input-group-prepend > .btn,\n.input-group-sm > .input-group-append > .btn {\n padding: $input-padding-y-sm $input-padding-x-sm;\n @include font-size($input-font-size-sm);\n line-height: $input-line-height-sm;\n @include border-radius($input-border-radius-sm);\n}\n\n.input-group-lg > .custom-select,\n.input-group-sm > .custom-select {\n padding-right: $custom-select-padding-x + $custom-select-indicator-padding;\n}\n\n\n// Prepend and append rounded corners\n//\n// These rulesets must come after the sizing ones to properly override sm and lg\n// border-radius values when extending. They're more specific than we'd like\n// with the `.input-group >` part, but without it, we cannot override the sizing.\n\n\n.input-group > .input-group-prepend > .btn,\n.input-group > .input-group-prepend > .input-group-text,\n.input-group > .input-group-append:not(:last-child) > .btn,\n.input-group > .input-group-append:not(:last-child) > .input-group-text,\n.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {\n @include border-right-radius(0);\n}\n\n.input-group > .input-group-append > .btn,\n.input-group > .input-group-append > .input-group-text,\n.input-group > .input-group-prepend:not(:first-child) > .btn,\n.input-group > .input-group-prepend:not(:first-child) > .input-group-text,\n.input-group > .input-group-prepend:first-child > .btn:not(:first-child),\n.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {\n @include border-left-radius(0);\n}\n","// Embedded icons from Open Iconic.\n// Released under MIT and copyright 2014 Waybury.\n// https://useiconic.com/open\n\n\n// Checkboxes and radios\n//\n// Base class takes care of all the key behavioral aspects.\n\n.custom-control {\n position: relative;\n display: block;\n min-height: $font-size-base * $line-height-base;\n padding-left: $custom-control-gutter + $custom-control-indicator-size;\n}\n\n.custom-control-inline {\n display: inline-flex;\n margin-right: $custom-control-spacer-x;\n}\n\n.custom-control-input {\n position: absolute;\n z-index: -1; // Put the input behind the label so it doesn't overlay text\n opacity: 0;\n\n &:checked ~ .custom-control-label::before {\n color: $custom-control-indicator-checked-color;\n border-color: $custom-control-indicator-checked-border-color;\n @include gradient-bg($custom-control-indicator-checked-bg);\n @include box-shadow($custom-control-indicator-checked-box-shadow);\n }\n\n &:focus ~ .custom-control-label::before {\n // the mixin is not used here to make sure there is feedback\n @if $enable-shadows {\n box-shadow: $input-box-shadow, $input-focus-box-shadow;\n } @else {\n box-shadow: $custom-control-indicator-focus-box-shadow;\n }\n }\n\n &:focus:not(:checked) ~ .custom-control-label::before {\n border-color: $custom-control-indicator-focus-border-color;\n }\n\n &:not(:disabled):active ~ .custom-control-label::before {\n color: $custom-control-indicator-active-color;\n background-color: $custom-control-indicator-active-bg;\n border-color: $custom-control-indicator-active-border-color;\n @include box-shadow($custom-control-indicator-active-box-shadow);\n }\n\n &:disabled {\n ~ .custom-control-label {\n color: $custom-control-label-disabled-color;\n\n &::before {\n background-color: $custom-control-indicator-disabled-bg;\n }\n }\n }\n}\n\n// Custom control indicators\n//\n// Build the custom controls out of pseudo-elements.\n\n.custom-control-label {\n position: relative;\n margin-bottom: 0;\n vertical-align: top;\n\n // Background-color and (when enabled) gradient\n &::before {\n position: absolute;\n top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;\n left: -($custom-control-gutter + $custom-control-indicator-size);\n display: block;\n width: $custom-control-indicator-size;\n height: $custom-control-indicator-size;\n pointer-events: none;\n content: \"\";\n background-color: $custom-control-indicator-bg;\n border: $custom-control-indicator-border-color solid $custom-control-indicator-border-width;\n @include box-shadow($custom-control-indicator-box-shadow);\n }\n\n // Foreground (icon)\n &::after {\n position: absolute;\n top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;\n left: -($custom-control-gutter + $custom-control-indicator-size);\n display: block;\n width: $custom-control-indicator-size;\n height: $custom-control-indicator-size;\n content: \"\";\n background: no-repeat 50% / #{$custom-control-indicator-bg-size};\n }\n}\n\n\n// Checkboxes\n//\n// Tweak just a few things for checkboxes.\n\n.custom-checkbox {\n .custom-control-label::before {\n @include border-radius($custom-checkbox-indicator-border-radius);\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-image: $custom-checkbox-indicator-icon-checked;\n }\n }\n\n .custom-control-input:indeterminate ~ .custom-control-label {\n &::before {\n border-color: $custom-checkbox-indicator-indeterminate-border-color;\n @include gradient-bg($custom-checkbox-indicator-indeterminate-bg);\n @include box-shadow($custom-checkbox-indicator-indeterminate-box-shadow);\n }\n &::after {\n background-image: $custom-checkbox-indicator-icon-indeterminate;\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n background-color: $custom-control-indicator-checked-disabled-bg;\n }\n &:indeterminate ~ .custom-control-label::before {\n background-color: $custom-control-indicator-checked-disabled-bg;\n }\n }\n}\n\n// Radios\n//\n// Tweak just a few things for radios.\n\n.custom-radio {\n .custom-control-label::before {\n // stylelint-disable-next-line property-blacklist\n border-radius: $custom-radio-indicator-border-radius;\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-image: $custom-radio-indicator-icon-checked;\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n background-color: $custom-control-indicator-checked-disabled-bg;\n }\n }\n}\n\n\n// switches\n//\n// Tweak a few things for switches\n\n.custom-switch {\n padding-left: $custom-switch-width + $custom-control-gutter;\n\n .custom-control-label {\n &::before {\n left: -($custom-switch-width + $custom-control-gutter);\n width: $custom-switch-width;\n pointer-events: all;\n // stylelint-disable-next-line property-blacklist\n border-radius: $custom-switch-indicator-border-radius;\n }\n\n &::after {\n top: calc(#{(($font-size-base * $line-height-base - $custom-control-indicator-size) / 2)} + #{$custom-control-indicator-border-width * 2});\n left: calc(#{-($custom-switch-width + $custom-control-gutter)} + #{$custom-control-indicator-border-width * 2});\n width: $custom-switch-indicator-size;\n height: $custom-switch-indicator-size;\n background-color: $custom-control-indicator-border-color;\n // stylelint-disable-next-line property-blacklist\n border-radius: $custom-switch-indicator-border-radius;\n @include transition(transform .15s ease-in-out, $custom-forms-transition);\n }\n }\n\n .custom-control-input:checked ~ .custom-control-label {\n &::after {\n background-color: $custom-control-indicator-bg;\n transform: translateX($custom-switch-width - $custom-control-indicator-size);\n }\n }\n\n .custom-control-input:disabled {\n &:checked ~ .custom-control-label::before {\n background-color: $custom-control-indicator-checked-disabled-bg;\n }\n }\n}\n\n\n// Select\n//\n// Replaces the browser default select with a custom one, mostly pulled from\n// https://primer.github.io/.\n//\n\n.custom-select {\n display: inline-block;\n width: 100%;\n height: $custom-select-height;\n padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x;\n font-family: $custom-select-font-family;\n @include font-size($custom-select-font-size);\n font-weight: $custom-select-font-weight;\n line-height: $custom-select-line-height;\n color: $custom-select-color;\n vertical-align: middle;\n background: $custom-select-background;\n background-color: $custom-select-bg;\n border: $custom-select-border-width solid $custom-select-border-color;\n @include border-radius($custom-select-border-radius, 0);\n @include box-shadow($custom-select-box-shadow);\n appearance: none;\n\n &:focus {\n border-color: $custom-select-focus-border-color;\n outline: 0;\n @if $enable-shadows {\n box-shadow: $custom-select-box-shadow, $custom-select-focus-box-shadow;\n } @else {\n box-shadow: $custom-select-focus-box-shadow;\n }\n\n &::-ms-value {\n // For visual consistency with other platforms/browsers,\n // suppress the default white text on blue background highlight given to\n // the selected option text when the (still closed) <select> receives focus\n // in IE and (under certain conditions) Edge.\n // See https://github.com/twbs/bootstrap/issues/19398.\n color: $input-color;\n background-color: $input-bg;\n }\n }\n\n &[multiple],\n &[size]:not([size=\"1\"]) {\n height: auto;\n padding-right: $custom-select-padding-x;\n background-image: none;\n }\n\n &:disabled {\n color: $custom-select-disabled-color;\n background-color: $custom-select-disabled-bg;\n }\n\n // Hides the default caret in IE11\n &::-ms-expand {\n display: none;\n }\n}\n\n.custom-select-sm {\n height: $custom-select-height-sm;\n padding-top: $custom-select-padding-y-sm;\n padding-bottom: $custom-select-padding-y-sm;\n padding-left: $custom-select-padding-x-sm;\n @include font-size($custom-select-font-size-sm);\n}\n\n.custom-select-lg {\n height: $custom-select-height-lg;\n padding-top: $custom-select-padding-y-lg;\n padding-bottom: $custom-select-padding-y-lg;\n padding-left: $custom-select-padding-x-lg;\n @include font-size($custom-select-font-size-lg);\n}\n\n\n// File\n//\n// Custom file input.\n\n.custom-file {\n position: relative;\n display: inline-block;\n width: 100%;\n height: $custom-file-height;\n margin-bottom: 0;\n}\n\n.custom-file-input {\n position: relative;\n z-index: 2;\n width: 100%;\n height: $custom-file-height;\n margin: 0;\n opacity: 0;\n\n &:focus ~ .custom-file-label {\n border-color: $custom-file-focus-border-color;\n box-shadow: $custom-file-focus-box-shadow;\n }\n\n &:disabled ~ .custom-file-label {\n background-color: $custom-file-disabled-bg;\n }\n\n @each $lang, $value in $custom-file-text {\n &:lang(#{$lang}) ~ .custom-file-label::after {\n content: $value;\n }\n }\n\n ~ .custom-file-label[data-browse]::after {\n content: attr(data-browse);\n }\n}\n\n.custom-file-label {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1;\n height: $custom-file-height;\n padding: $custom-file-padding-y $custom-file-padding-x;\n font-family: $custom-file-font-family;\n font-weight: $custom-file-font-weight;\n line-height: $custom-file-line-height;\n color: $custom-file-color;\n background-color: $custom-file-bg;\n border: $custom-file-border-width solid $custom-file-border-color;\n @include border-radius($custom-file-border-radius);\n @include box-shadow($custom-file-box-shadow);\n\n &::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 3;\n display: block;\n height: $custom-file-height-inner;\n padding: $custom-file-padding-y $custom-file-padding-x;\n line-height: $custom-file-line-height;\n color: $custom-file-button-color;\n content: \"Browse\";\n @include gradient-bg($custom-file-button-bg);\n border-left: inherit;\n @include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0);\n }\n}\n\n// Range\n//\n// Style range inputs the same across browsers. Vendor-specific rules for pseudo\n// elements cannot be mixed. As such, there are no shared styles for focus or\n// active states on prefixed selectors.\n\n.custom-range {\n width: 100%;\n height: calc(#{$custom-range-thumb-height} + #{$custom-range-thumb-focus-box-shadow-width * 2});\n padding: 0; // Need to reset padding\n background-color: transparent;\n appearance: none;\n\n &:focus {\n outline: none;\n\n // Pseudo-elements must be split across multiple rulesets to have an effect.\n // No box-shadow() mixin for focus accessibility.\n &::-webkit-slider-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n &::-moz-range-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n &::-ms-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }\n }\n\n &::-moz-focus-outer {\n border: 0;\n }\n\n &::-webkit-slider-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n margin-top: ($custom-range-track-height - $custom-range-thumb-height) / 2; // Webkit specific\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-webkit-slider-runnable-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent; // Why?\n cursor: $custom-range-track-cursor;\n background-color: $custom-range-track-bg;\n border-color: transparent;\n @include border-radius($custom-range-track-border-radius);\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-moz-range-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-moz-range-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent;\n cursor: $custom-range-track-cursor;\n background-color: $custom-range-track-bg;\n border-color: transparent; // Firefox specific?\n @include border-radius($custom-range-track-border-radius);\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-ms-thumb {\n width: $custom-range-thumb-width;\n height: $custom-range-thumb-height;\n margin-top: 0; // Edge specific\n margin-right: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.\n margin-left: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.\n @include gradient-bg($custom-range-thumb-bg);\n border: $custom-range-thumb-border;\n @include border-radius($custom-range-thumb-border-radius);\n @include box-shadow($custom-range-thumb-box-shadow);\n @include transition($custom-forms-transition);\n appearance: none;\n\n &:active {\n @include gradient-bg($custom-range-thumb-active-bg);\n }\n }\n\n &::-ms-track {\n width: $custom-range-track-width;\n height: $custom-range-track-height;\n color: transparent;\n cursor: $custom-range-track-cursor;\n background-color: transparent;\n border-color: transparent;\n border-width: $custom-range-thumb-height / 2;\n @include box-shadow($custom-range-track-box-shadow);\n }\n\n &::-ms-fill-lower {\n background-color: $custom-range-track-bg;\n @include border-radius($custom-range-track-border-radius);\n }\n\n &::-ms-fill-upper {\n margin-right: 15px; // arbitrary?\n background-color: $custom-range-track-bg;\n @include border-radius($custom-range-track-border-radius);\n }\n\n &:disabled {\n &::-webkit-slider-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n\n &::-webkit-slider-runnable-track {\n cursor: default;\n }\n\n &::-moz-range-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n\n &::-moz-range-track {\n cursor: default;\n }\n\n &::-ms-thumb {\n background-color: $custom-range-thumb-disabled-bg;\n }\n }\n}\n\n.custom-control-label::before,\n.custom-file-label,\n.custom-select {\n @include transition($custom-forms-transition);\n}\n","// Base class\n//\n// Kickstart any navigation component with a set of style resets. Works with\n// `<nav>`s or `<ul>`s.\n\n.nav {\n display: flex;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: $nav-link-padding-y $nav-link-padding-x;\n\n @include hover-focus {\n text-decoration: none;\n }\n\n // Disabled state lightens text\n &.disabled {\n color: $nav-link-disabled-color;\n pointer-events: none;\n cursor: default;\n }\n}\n\n//\n// Tabs\n//\n\n.nav-tabs {\n border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;\n\n .nav-item {\n margin-bottom: -$nav-tabs-border-width;\n }\n\n .nav-link {\n border: $nav-tabs-border-width solid transparent;\n @include border-top-radius($nav-tabs-border-radius);\n\n @include hover-focus {\n border-color: $nav-tabs-link-hover-border-color;\n }\n\n &.disabled {\n color: $nav-link-disabled-color;\n background-color: transparent;\n border-color: transparent;\n }\n }\n\n .nav-link.active,\n .nav-item.show .nav-link {\n color: $nav-tabs-link-active-color;\n background-color: $nav-tabs-link-active-bg;\n border-color: $nav-tabs-link-active-border-color;\n }\n\n .dropdown-menu {\n // Make dropdown border overlap tab border\n margin-top: -$nav-tabs-border-width;\n // Remove the top rounded corners here since there is a hard edge above the menu\n @include border-top-radius(0);\n }\n}\n\n\n//\n// Pills\n//\n\n.nav-pills {\n .nav-link {\n @include border-radius($nav-pills-border-radius);\n }\n\n .nav-link.active,\n .show > .nav-link {\n color: $nav-pills-link-active-color;\n background-color: $nav-pills-link-active-bg;\n }\n}\n\n\n//\n// Justified variants\n//\n\n.nav-fill {\n .nav-item {\n flex: 1 1 auto;\n text-align: center;\n }\n}\n\n.nav-justified {\n .nav-item {\n flex-basis: 0;\n flex-grow: 1;\n text-align: center;\n }\n}\n\n\n// Tabbable tabs\n//\n// Hide tabbable panes to start, show them when `.active`\n\n.tab-content {\n > .tab-pane {\n display: none;\n }\n > .active {\n display: block;\n }\n}\n","// Contents\n//\n// Navbar\n// Navbar brand\n// Navbar nav\n// Navbar text\n// Navbar divider\n// Responsive navbar\n// Navbar position\n// Navbar themes\n\n\n// Navbar\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n display: flex;\n flex-wrap: wrap; // allow us to do the line break for collapsing content\n align-items: center;\n justify-content: space-between; // space out brand from logo\n padding: $navbar-padding-y $navbar-padding-x;\n\n // Because flex properties aren't inherited, we need to redeclare these first\n // few properties so that content nested within behave properly.\n > .container,\n > .container-fluid {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n }\n}\n\n\n// Navbar brand\n//\n// Used for brand, project, or site names.\n\n.navbar-brand {\n display: inline-block;\n padding-top: $navbar-brand-padding-y;\n padding-bottom: $navbar-brand-padding-y;\n margin-right: $navbar-padding-x;\n @include font-size($navbar-brand-font-size);\n line-height: inherit;\n white-space: nowrap;\n\n @include hover-focus {\n text-decoration: none;\n }\n}\n\n\n// Navbar nav\n//\n// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).\n\n.navbar-nav {\n display: flex;\n flex-direction: column; // cannot use `inherit` to get the `.navbar`s value\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n\n .nav-link {\n padding-right: 0;\n padding-left: 0;\n }\n\n .dropdown-menu {\n position: static;\n float: none;\n }\n}\n\n\n// Navbar text\n//\n//\n\n.navbar-text {\n display: inline-block;\n padding-top: $nav-link-padding-y;\n padding-bottom: $nav-link-padding-y;\n}\n\n\n// Responsive navbar\n//\n// Custom styles for responsive collapsing and toggling of navbar contents.\n// Powered by the collapse Bootstrap JavaScript plugin.\n\n// When collapsed, prevent the toggleable navbar contents from appearing in\n// the default flexbox row orientation. Requires the use of `flex-wrap: wrap`\n// on the `.navbar` parent.\n.navbar-collapse {\n flex-basis: 100%;\n flex-grow: 1;\n // For always expanded or extra full navbars, ensure content aligns itself\n // properly vertically. Can be easily overridden with flex utilities.\n align-items: center;\n}\n\n// Button for toggling the navbar when in its collapsed state\n.navbar-toggler {\n padding: $navbar-toggler-padding-y $navbar-toggler-padding-x;\n @include font-size($navbar-toggler-font-size);\n line-height: 1;\n background-color: transparent; // remove default button style\n border: $border-width solid transparent; // remove default button style\n @include border-radius($navbar-toggler-border-radius);\n\n @include hover-focus {\n text-decoration: none;\n }\n}\n\n// Keep as a separate element so folks can easily override it with another icon\n// or image file as needed.\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n content: \"\";\n background: no-repeat center center;\n background-size: 100% 100%;\n}\n\n// Generate series of `.navbar-expand-*` responsive classes for configuring\n// where your navbar collapses.\n.navbar-expand {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $next: breakpoint-next($breakpoint, $grid-breakpoints);\n $infix: breakpoint-infix($next, $grid-breakpoints);\n\n &#{$infix} {\n @include media-breakpoint-down($breakpoint) {\n > .container,\n > .container-fluid {\n padding-right: 0;\n padding-left: 0;\n }\n }\n\n @include media-breakpoint-up($next) {\n flex-flow: row nowrap;\n justify-content: flex-start;\n\n .navbar-nav {\n flex-direction: row;\n\n .dropdown-menu {\n position: absolute;\n }\n\n .nav-link {\n padding-right: $navbar-nav-link-padding-x;\n padding-left: $navbar-nav-link-padding-x;\n }\n }\n\n // For nesting containers, have to redeclare for alignment purposes\n > .container,\n > .container-fluid {\n flex-wrap: nowrap;\n }\n\n .navbar-collapse {\n display: flex !important; // stylelint-disable-line declaration-no-important\n\n // Changes flex-bases to auto because of an IE10 bug\n flex-basis: auto;\n }\n\n .navbar-toggler {\n display: none;\n }\n }\n }\n }\n}\n\n\n// Navbar themes\n//\n// Styles for switching between navbars with light or dark background.\n\n// Dark links against a light background\n.navbar-light {\n .navbar-brand {\n color: $navbar-light-brand-color;\n\n @include hover-focus {\n color: $navbar-light-brand-hover-color;\n }\n }\n\n .navbar-nav {\n .nav-link {\n color: $navbar-light-color;\n\n @include hover-focus {\n color: $navbar-light-hover-color;\n }\n\n &.disabled {\n color: $navbar-light-disabled-color;\n }\n }\n\n .show > .nav-link,\n .active > .nav-link,\n .nav-link.show,\n .nav-link.active {\n color: $navbar-light-active-color;\n }\n }\n\n .navbar-toggler {\n color: $navbar-light-color;\n border-color: $navbar-light-toggler-border-color;\n }\n\n .navbar-toggler-icon {\n background-image: $navbar-light-toggler-icon-bg;\n }\n\n .navbar-text {\n color: $navbar-light-color;\n a {\n color: $navbar-light-active-color;\n\n @include hover-focus {\n color: $navbar-light-active-color;\n }\n }\n }\n}\n\n// White links against a dark background\n.navbar-dark {\n .navbar-brand {\n color: $navbar-dark-brand-color;\n\n @include hover-focus {\n color: $navbar-dark-brand-hover-color;\n }\n }\n\n .navbar-nav {\n .nav-link {\n color: $navbar-dark-color;\n\n @include hover-focus {\n color: $navbar-dark-hover-color;\n }\n\n &.disabled {\n color: $navbar-dark-disabled-color;\n }\n }\n\n .show > .nav-link,\n .active > .nav-link,\n .nav-link.show,\n .nav-link.active {\n color: $navbar-dark-active-color;\n }\n }\n\n .navbar-toggler {\n color: $navbar-dark-color;\n border-color: $navbar-dark-toggler-border-color;\n }\n\n .navbar-toggler-icon {\n background-image: $navbar-dark-toggler-icon-bg;\n }\n\n .navbar-text {\n color: $navbar-dark-color;\n a {\n color: $navbar-dark-active-color;\n\n @include hover-focus {\n color: $navbar-dark-active-color;\n }\n }\n }\n}\n","//\n// Base styles\n//\n\n.card {\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106\n word-wrap: break-word;\n background-color: $card-bg;\n background-clip: border-box;\n border: $card-border-width solid $card-border-color;\n @include border-radius($card-border-radius);\n\n > hr {\n margin-right: 0;\n margin-left: 0;\n }\n\n > .list-group:first-child {\n .list-group-item:first-child {\n @include border-top-radius($card-border-radius);\n }\n }\n\n > .list-group:last-child {\n .list-group-item:last-child {\n @include border-bottom-radius($card-border-radius);\n }\n }\n}\n\n.card-body {\n // Enable `flex-grow: 1` for decks and groups so that card blocks take up\n // as much space as possible, ensuring footers are aligned to the bottom.\n flex: 1 1 auto;\n padding: $card-spacer-x;\n color: $card-color;\n}\n\n.card-title {\n margin-bottom: $card-spacer-y;\n}\n\n.card-subtitle {\n margin-top: -$card-spacer-y / 2;\n margin-bottom: 0;\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link {\n @include hover {\n text-decoration: none;\n }\n\n + .card-link {\n margin-left: $card-spacer-x;\n }\n}\n\n//\n// Optional textual caps\n//\n\n.card-header {\n padding: $card-spacer-y $card-spacer-x;\n margin-bottom: 0; // Removes the default margin-bottom of <hN>\n color: $card-cap-color;\n background-color: $card-cap-bg;\n border-bottom: $card-border-width solid $card-border-color;\n\n &:first-child {\n @include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);\n }\n\n + .list-group {\n .list-group-item:first-child {\n border-top: 0;\n }\n }\n}\n\n.card-footer {\n padding: $card-spacer-y $card-spacer-x;\n background-color: $card-cap-bg;\n border-top: $card-border-width solid $card-border-color;\n\n &:last-child {\n @include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);\n }\n}\n\n\n//\n// Header navs\n//\n\n.card-header-tabs {\n margin-right: -$card-spacer-x / 2;\n margin-bottom: -$card-spacer-y;\n margin-left: -$card-spacer-x / 2;\n border-bottom: 0;\n}\n\n.card-header-pills {\n margin-right: -$card-spacer-x / 2;\n margin-left: -$card-spacer-x / 2;\n}\n\n// Card image\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: $card-img-overlay-padding;\n}\n\n.card-img {\n width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch\n @include border-radius($card-inner-border-radius);\n}\n\n// Card image caps\n.card-img-top {\n width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch\n @include border-top-radius($card-inner-border-radius);\n}\n\n.card-img-bottom {\n width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch\n @include border-bottom-radius($card-inner-border-radius);\n}\n\n\n// Card deck\n\n.card-deck {\n display: flex;\n flex-direction: column;\n\n .card {\n margin-bottom: $card-deck-margin;\n }\n\n @include media-breakpoint-up(sm) {\n flex-flow: row wrap;\n margin-right: -$card-deck-margin;\n margin-left: -$card-deck-margin;\n\n .card {\n display: flex;\n // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n flex: 1 0 0%;\n flex-direction: column;\n margin-right: $card-deck-margin;\n margin-bottom: 0; // Override the default\n margin-left: $card-deck-margin;\n }\n }\n}\n\n\n//\n// Card groups\n//\n\n.card-group {\n display: flex;\n flex-direction: column;\n\n // The child selector allows nested `.card` within `.card-group`\n // to display properly.\n > .card {\n margin-bottom: $card-group-margin;\n }\n\n @include media-breakpoint-up(sm) {\n flex-flow: row wrap;\n // The child selector allows nested `.card` within `.card-group`\n // to display properly.\n > .card {\n // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n flex: 1 0 0%;\n margin-bottom: 0;\n\n + .card {\n margin-left: 0;\n border-left: 0;\n }\n\n // Handle rounded corners\n @if $enable-rounded {\n &:not(:last-child) {\n @include border-right-radius(0);\n\n .card-img-top,\n .card-header {\n // stylelint-disable-next-line property-blacklist\n border-top-right-radius: 0;\n }\n .card-img-bottom,\n .card-footer {\n // stylelint-disable-next-line property-blacklist\n border-bottom-right-radius: 0;\n }\n }\n\n &:not(:first-child) {\n @include border-left-radius(0);\n\n .card-img-top,\n .card-header {\n // stylelint-disable-next-line property-blacklist\n border-top-left-radius: 0;\n }\n .card-img-bottom,\n .card-footer {\n // stylelint-disable-next-line property-blacklist\n border-bottom-left-radius: 0;\n }\n }\n }\n }\n }\n}\n\n\n//\n// Columns\n//\n\n.card-columns {\n .card {\n margin-bottom: $card-columns-margin;\n }\n\n @include media-breakpoint-up(sm) {\n column-count: $card-columns-count;\n column-gap: $card-columns-gap;\n orphans: 1;\n widows: 1;\n\n .card {\n display: inline-block; // Don't let them vertically span multiple columns\n width: 100%; // Don't let their width change\n }\n }\n}\n\n\n//\n// Accordion\n//\n\n.accordion {\n > .card {\n overflow: hidden;\n\n &:not(:first-of-type) {\n .card-header:first-child {\n @include border-radius(0);\n }\n\n &:not(:last-of-type) {\n border-bottom: 0;\n @include border-radius(0);\n }\n }\n\n &:first-of-type {\n border-bottom: 0;\n @include border-bottom-radius(0);\n }\n\n &:last-of-type {\n @include border-top-radius(0);\n }\n\n .card-header {\n margin-bottom: -$card-border-width;\n }\n }\n}\n",".breadcrumb {\n display: flex;\n flex-wrap: wrap;\n padding: $breadcrumb-padding-y $breadcrumb-padding-x;\n margin-bottom: $breadcrumb-margin-bottom;\n list-style: none;\n background-color: $breadcrumb-bg;\n @include border-radius($breadcrumb-border-radius);\n}\n\n.breadcrumb-item {\n // The separator between breadcrumbs (by default, a forward-slash: \"/\")\n + .breadcrumb-item {\n padding-left: $breadcrumb-item-padding;\n\n &::before {\n display: inline-block; // Suppress underlining of the separator in modern browsers\n padding-right: $breadcrumb-item-padding;\n color: $breadcrumb-divider-color;\n content: $breadcrumb-divider;\n }\n }\n\n // IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built\n // without `<ul>`s. The `::before` pseudo-element generates an element\n // *within* the .breadcrumb-item and thereby inherits the `text-decoration`.\n //\n // To trick IE into suppressing the underline, we give the pseudo-element an\n // underline and then immediately remove it.\n + .breadcrumb-item:hover::before {\n text-decoration: underline;\n }\n // stylelint-disable-next-line no-duplicate-selectors\n + .breadcrumb-item:hover::before {\n text-decoration: none;\n }\n\n &.active {\n color: $breadcrumb-active-color;\n }\n}\n",".pagination {\n display: flex;\n @include list-unstyled();\n @include border-radius();\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: $pagination-padding-y $pagination-padding-x;\n margin-left: -$pagination-border-width;\n line-height: $pagination-line-height;\n color: $pagination-color;\n background-color: $pagination-bg;\n border: $pagination-border-width solid $pagination-border-color;\n\n &:hover {\n z-index: 2;\n color: $pagination-hover-color;\n text-decoration: none;\n background-color: $pagination-hover-bg;\n border-color: $pagination-hover-border-color;\n }\n\n &:focus {\n z-index: 2;\n outline: $pagination-focus-outline;\n box-shadow: $pagination-focus-box-shadow;\n }\n}\n\n.page-item {\n &:first-child {\n .page-link {\n margin-left: 0;\n @include border-left-radius($border-radius);\n }\n }\n &:last-child {\n .page-link {\n @include border-right-radius($border-radius);\n }\n }\n\n &.active .page-link {\n z-index: 1;\n color: $pagination-active-color;\n background-color: $pagination-active-bg;\n border-color: $pagination-active-border-color;\n }\n\n &.disabled .page-link {\n color: $pagination-disabled-color;\n pointer-events: none;\n // Opinionated: remove the \"hand\" cursor set previously for .page-link\n cursor: auto;\n background-color: $pagination-disabled-bg;\n border-color: $pagination-disabled-border-color;\n }\n}\n\n\n//\n// Sizing\n//\n\n.pagination-lg {\n @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $border-radius-lg);\n}\n\n.pagination-sm {\n @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $border-radius-sm);\n}\n","// Pagination\n\n@mixin pagination-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {\n .page-link {\n padding: $padding-y $padding-x;\n @include font-size($font-size);\n line-height: $line-height;\n }\n\n .page-item {\n &:first-child {\n .page-link {\n @include border-left-radius($border-radius);\n }\n }\n &:last-child {\n .page-link {\n @include border-right-radius($border-radius);\n }\n }\n }\n}\n","// Base class\n//\n// Requires one of the contextual, color modifier classes for `color` and\n// `background-color`.\n\n.badge {\n display: inline-block;\n padding: $badge-padding-y $badge-padding-x;\n @include font-size($badge-font-size);\n font-weight: $badge-font-weight;\n line-height: 1;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n @include border-radius($badge-border-radius);\n @include transition($badge-transition);\n\n @at-root a#{&} {\n @include hover-focus {\n text-decoration: none;\n }\n }\n\n // Empty badges collapse automatically\n &:empty {\n display: none;\n }\n}\n\n// Quick fix for badges in buttons\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n// Pill badges\n//\n// Make them extra rounded with a modifier to replace v3's badges.\n\n.badge-pill {\n padding-right: $badge-pill-padding-x;\n padding-left: $badge-pill-padding-x;\n @include border-radius($badge-pill-border-radius);\n}\n\n// Colors\n//\n// Contextual variations (linked badges get darker on :hover).\n\n@each $color, $value in $theme-colors {\n .badge-#{$color} {\n @include badge-variant($value);\n }\n}\n","@mixin badge-variant($bg) {\n color: color-yiq($bg);\n background-color: $bg;\n\n @at-root a#{&} {\n @include hover-focus {\n color: color-yiq($bg);\n background-color: darken($bg, 10%);\n }\n\n &:focus,\n &.focus {\n outline: 0;\n box-shadow: 0 0 0 $badge-focus-width rgba($bg, .5);\n }\n }\n}\n",".jumbotron {\n padding: $jumbotron-padding ($jumbotron-padding / 2);\n margin-bottom: $jumbotron-padding;\n color: $jumbotron-color;\n background-color: $jumbotron-bg;\n @include border-radius($border-radius-lg);\n\n @include media-breakpoint-up(sm) {\n padding: ($jumbotron-padding * 2) $jumbotron-padding;\n }\n}\n\n.jumbotron-fluid {\n padding-right: 0;\n padding-left: 0;\n @include border-radius(0);\n}\n","//\n// Base styles\n//\n\n.alert {\n position: relative;\n padding: $alert-padding-y $alert-padding-x;\n margin-bottom: $alert-margin-bottom;\n border: $alert-border-width solid transparent;\n @include border-radius($alert-border-radius);\n}\n\n// Headings for larger alerts\n.alert-heading {\n // Specified to prevent conflicts of changing $headings-color\n color: inherit;\n}\n\n// Provide class for links that match alerts\n.alert-link {\n font-weight: $alert-link-font-weight;\n}\n\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissible {\n padding-right: $close-font-size + $alert-padding-x * 2;\n\n // Adjust close link position\n .close {\n position: absolute;\n top: 0;\n right: 0;\n padding: $alert-padding-y $alert-padding-x;\n color: inherit;\n }\n}\n\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n@each $color, $value in $theme-colors {\n .alert-#{$color} {\n @include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));\n }\n}\n","@mixin alert-variant($background, $border, $color) {\n color: $color;\n @include gradient-bg($background);\n border-color: $border;\n\n hr {\n border-top-color: darken($border, 5%);\n }\n\n .alert-link {\n color: darken($color, 10%);\n }\n}\n","// Disable animation if transitions are disabled\n@if $enable-transitions {\n @keyframes progress-bar-stripes {\n from { background-position: $progress-height 0; }\n to { background-position: 0 0; }\n }\n}\n\n.progress {\n display: flex;\n height: $progress-height;\n overflow: hidden; // force rounded corners by cropping it\n @include font-size($progress-font-size);\n background-color: $progress-bg;\n @include border-radius($progress-border-radius);\n @include box-shadow($progress-box-shadow);\n}\n\n.progress-bar {\n display: flex;\n flex-direction: column;\n justify-content: center;\n color: $progress-bar-color;\n text-align: center;\n white-space: nowrap;\n background-color: $progress-bar-bg;\n @include transition($progress-bar-transition);\n}\n\n.progress-bar-striped {\n @include gradient-striped();\n background-size: $progress-height $progress-height;\n}\n\n@if $enable-transitions {\n .progress-bar-animated {\n animation: progress-bar-stripes $progress-bar-animation-timing;\n\n @media (prefers-reduced-motion: reduce) {\n animation: none;\n }\n }\n}\n",".media {\n display: flex;\n align-items: flex-start;\n}\n\n.media-body {\n flex: 1;\n}\n","// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n\n.list-group {\n display: flex;\n flex-direction: column;\n\n // No need to set list-style: none; since .list-group-item is block level\n padding-left: 0; // reset padding because ul and ol\n margin-bottom: 0;\n}\n\n\n// Interactive list items\n//\n// Use anchor or button elements instead of `li`s or `div`s to create interactive\n// list items. Includes an extra `.active` modifier class for selected items.\n\n.list-group-item-action {\n width: 100%; // For `<button>`s (anchors become 100% by default though)\n color: $list-group-action-color;\n text-align: inherit; // For `<button>`s (anchors inherit)\n\n // Hover state\n @include hover-focus {\n z-index: 1; // Place hover/focus items above their siblings for proper border styling\n color: $list-group-action-hover-color;\n text-decoration: none;\n background-color: $list-group-hover-bg;\n }\n\n &:active {\n color: $list-group-action-active-color;\n background-color: $list-group-action-active-bg;\n }\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: $list-group-item-padding-y $list-group-item-padding-x;\n // Place the border on the list items and negative margin up for better styling\n margin-bottom: -$list-group-border-width;\n color: $list-group-color;\n background-color: $list-group-bg;\n border: $list-group-border-width solid $list-group-border-color;\n\n &:first-child {\n @include border-top-radius($list-group-border-radius);\n }\n\n &:last-child {\n margin-bottom: 0;\n @include border-bottom-radius($list-group-border-radius);\n }\n\n &.disabled,\n &:disabled {\n color: $list-group-disabled-color;\n pointer-events: none;\n background-color: $list-group-disabled-bg;\n }\n\n // Include both here for `<a>`s and `<button>`s\n &.active {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: $list-group-active-color;\n background-color: $list-group-active-bg;\n border-color: $list-group-active-border-color;\n }\n}\n\n\n// Horizontal\n//\n// Change the layout of list group items from vertical (default) to horizontal.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .list-group-horizontal#{$infix} {\n flex-direction: row;\n\n .list-group-item {\n margin-right: -$list-group-border-width;\n margin-bottom: 0;\n\n &:first-child {\n @include border-left-radius($list-group-border-radius);\n @include border-top-right-radius(0);\n }\n\n &:last-child {\n margin-right: 0;\n @include border-right-radius($list-group-border-radius);\n @include border-bottom-left-radius(0);\n }\n }\n }\n }\n}\n\n\n// Flush list items\n//\n// Remove borders and border-radius to keep list group items edge-to-edge. Most\n// useful within other components (e.g., cards).\n\n.list-group-flush {\n .list-group-item {\n border-right: 0;\n border-left: 0;\n @include border-radius(0);\n\n &:last-child {\n margin-bottom: -$list-group-border-width;\n }\n }\n\n &:first-child {\n .list-group-item:first-child {\n border-top: 0;\n }\n }\n\n &:last-child {\n .list-group-item:last-child {\n margin-bottom: 0;\n border-bottom: 0;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n@each $color, $value in $theme-colors {\n @include list-group-item-variant($color, theme-color-level($color, -9), theme-color-level($color, 6));\n}\n","// List Groups\n\n@mixin list-group-item-variant($state, $background, $color) {\n .list-group-item-#{$state} {\n color: $color;\n background-color: $background;\n\n &.list-group-item-action {\n @include hover-focus {\n color: $color;\n background-color: darken($background, 5%);\n }\n\n &.active {\n color: $white;\n background-color: $color;\n border-color: $color;\n }\n }\n }\n}\n",".close {\n float: right;\n @include font-size($close-font-size);\n font-weight: $close-font-weight;\n line-height: 1;\n color: $close-color;\n text-shadow: $close-text-shadow;\n opacity: .5;\n\n // Override <a>'s hover style\n @include hover {\n color: $close-color;\n text-decoration: none;\n }\n\n &:not(:disabled):not(.disabled) {\n @include hover-focus {\n opacity: .75;\n }\n }\n}\n\n// Additional properties for button version\n// iOS requires the button element instead of an anchor tag.\n// If you want the anchor version, it requires `href=\"#\"`.\n// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n// stylelint-disable-next-line selector-no-qualifying-type\nbutton.close {\n padding: 0;\n background-color: transparent;\n border: 0;\n appearance: none;\n}\n\n// Future-proof disabling of clicks on `<a>` elements\n\n// stylelint-disable-next-line selector-no-qualifying-type\na.close.disabled {\n pointer-events: none;\n}\n",".toast {\n max-width: $toast-max-width;\n overflow: hidden; // cheap rounded corners on nested items\n @include font-size($toast-font-size);\n color: $toast-color;\n background-color: $toast-background-color;\n background-clip: padding-box;\n border: $toast-border-width solid $toast-border-color;\n box-shadow: $toast-box-shadow;\n backdrop-filter: blur(10px);\n opacity: 0;\n @include border-radius($toast-border-radius);\n\n &:not(:last-child) {\n margin-bottom: $toast-padding-x;\n }\n\n &.showing {\n opacity: 1;\n }\n\n &.show {\n display: block;\n opacity: 1;\n }\n\n &.hide {\n display: none;\n }\n}\n\n.toast-header {\n display: flex;\n align-items: center;\n padding: $toast-padding-y $toast-padding-x;\n color: $toast-header-color;\n background-color: $toast-header-background-color;\n background-clip: padding-box;\n border-bottom: $toast-border-width solid $toast-header-border-color;\n}\n\n.toast-body {\n padding: $toast-padding-x; // apply to both vertical and horizontal\n}\n","// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and stuff\n\n\n.modal-open {\n // Kill the scroll on the body\n overflow: hidden;\n\n .modal {\n overflow-x: hidden;\n overflow-y: auto;\n }\n}\n\n// Container that the modal scrolls within\n.modal {\n position: fixed;\n top: 0;\n left: 0;\n z-index: $zindex-modal;\n display: none;\n width: 100%;\n height: 100%;\n overflow: hidden;\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a\n // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342\n // See also https://github.com/twbs/bootstrap/issues/17695\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: $modal-dialog-margin;\n // allow clicks to pass through for custom click handling to close modal\n pointer-events: none;\n\n // When fading in the modal, animate it to slide down\n .modal.fade & {\n @include transition($modal-transition);\n transform: $modal-fade-transform;\n }\n .modal.show & {\n transform: $modal-show-transform;\n }\n}\n\n.modal-dialog-scrollable {\n display: flex; // IE10/11\n max-height: calc(100% - #{$modal-dialog-margin * 2});\n\n .modal-content {\n max-height: calc(100vh - #{$modal-dialog-margin * 2}); // IE10/11\n overflow: hidden;\n }\n\n .modal-header,\n .modal-footer {\n flex-shrink: 0;\n }\n\n .modal-body {\n overflow-y: auto;\n }\n}\n\n.modal-dialog-centered {\n display: flex;\n align-items: center;\n min-height: calc(100% - #{$modal-dialog-margin * 2});\n\n // Ensure `modal-dialog-centered` extends the full height of the view (IE10/11)\n &::before {\n display: block; // IE10\n height: calc(100vh - #{$modal-dialog-margin * 2});\n content: \"\";\n }\n\n // Ensure `.modal-body` shows scrollbar (IE10/11)\n &.modal-dialog-scrollable {\n flex-direction: column;\n justify-content: center;\n height: 100%;\n\n .modal-content {\n max-height: none;\n }\n\n &::before {\n content: none;\n }\n }\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`\n // counteract the pointer-events: none; in the .modal-dialog\n color: $modal-content-color;\n pointer-events: auto;\n background-color: $modal-content-bg;\n background-clip: padding-box;\n border: $modal-content-border-width solid $modal-content-border-color;\n @include border-radius($modal-content-border-radius);\n @include box-shadow($modal-content-box-shadow-xs);\n // Remove focus outline from opened modal\n outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n z-index: $zindex-modal-backdrop;\n width: 100vw;\n height: 100vh;\n background-color: $modal-backdrop-bg;\n\n // Fade for backdrop\n &.fade { opacity: 0; }\n &.show { opacity: $modal-backdrop-opacity; }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n display: flex;\n align-items: flex-start; // so the close btn always stays on the upper right corner\n justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends\n padding: $modal-header-padding;\n border-bottom: $modal-header-border-width solid $modal-header-border-color;\n @include border-top-radius($modal-content-border-radius);\n\n .close {\n padding: $modal-header-padding;\n // auto on the left force icon to the right even when there is no .modal-title\n margin: (-$modal-header-padding-y) (-$modal-header-padding-x) (-$modal-header-padding-y) auto;\n }\n}\n\n// Title text within header\n.modal-title {\n margin-bottom: 0;\n line-height: $modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n // Enable `flex-grow: 1` so that the body take up as much space as possible\n // when should there be a fixed height on `.modal-dialog`.\n flex: 1 1 auto;\n padding: $modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n display: flex;\n align-items: center; // vertically center\n justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items\n padding: $modal-inner-padding;\n border-top: $modal-footer-border-width solid $modal-footer-border-color;\n @include border-bottom-radius($modal-content-border-radius);\n\n // Easily place margin between footer elements\n > :not(:first-child) { margin-left: .25rem; }\n > :not(:last-child) { margin-right: .25rem; }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n// Scale up the modal\n@include media-breakpoint-up(sm) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n max-width: $modal-md;\n margin: $modal-dialog-margin-y-sm-up auto;\n }\n\n .modal-dialog-scrollable {\n max-height: calc(100% - #{$modal-dialog-margin-y-sm-up * 2});\n\n .modal-content {\n max-height: calc(100vh - #{$modal-dialog-margin-y-sm-up * 2});\n }\n }\n\n .modal-dialog-centered {\n min-height: calc(100% - #{$modal-dialog-margin-y-sm-up * 2});\n\n &::before {\n height: calc(100vh - #{$modal-dialog-margin-y-sm-up * 2});\n }\n }\n\n .modal-content {\n @include box-shadow($modal-content-box-shadow-sm-up);\n }\n\n .modal-sm { max-width: $modal-sm; }\n}\n\n@include media-breakpoint-up(lg) {\n .modal-lg,\n .modal-xl {\n max-width: $modal-lg;\n }\n}\n\n@include media-breakpoint-up(xl) {\n .modal-xl { max-width: $modal-xl; }\n}\n","// Base class\n.tooltip {\n position: absolute;\n z-index: $zindex-tooltip;\n display: block;\n margin: $tooltip-margin;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n @include reset-text();\n @include font-size($tooltip-font-size);\n // Allow breaking very long words so they don't overflow the tooltip's bounds\n word-wrap: break-word;\n opacity: 0;\n\n &.show { opacity: $tooltip-opacity; }\n\n .arrow {\n position: absolute;\n display: block;\n width: $tooltip-arrow-width;\n height: $tooltip-arrow-height;\n\n &::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n }\n }\n}\n\n.bs-tooltip-top {\n padding: $tooltip-arrow-height 0;\n\n .arrow {\n bottom: 0;\n\n &::before {\n top: 0;\n border-width: $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;\n border-top-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-right {\n padding: 0 $tooltip-arrow-height;\n\n .arrow {\n left: 0;\n width: $tooltip-arrow-height;\n height: $tooltip-arrow-width;\n\n &::before {\n right: 0;\n border-width: ($tooltip-arrow-width / 2) $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;\n border-right-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-bottom {\n padding: $tooltip-arrow-height 0;\n\n .arrow {\n top: 0;\n\n &::before {\n bottom: 0;\n border-width: 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;\n border-bottom-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-left {\n padding: 0 $tooltip-arrow-height;\n\n .arrow {\n right: 0;\n width: $tooltip-arrow-height;\n height: $tooltip-arrow-width;\n\n &::before {\n left: 0;\n border-width: ($tooltip-arrow-width / 2) 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;\n border-left-color: $tooltip-arrow-color;\n }\n }\n}\n\n.bs-tooltip-auto {\n &[x-placement^=\"top\"] {\n @extend .bs-tooltip-top;\n }\n &[x-placement^=\"right\"] {\n @extend .bs-tooltip-right;\n }\n &[x-placement^=\"bottom\"] {\n @extend .bs-tooltip-bottom;\n }\n &[x-placement^=\"left\"] {\n @extend .bs-tooltip-left;\n }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: $tooltip-max-width;\n padding: $tooltip-padding-y $tooltip-padding-x;\n color: $tooltip-color;\n text-align: center;\n background-color: $tooltip-bg;\n @include border-radius($tooltip-border-radius);\n}\n","@mixin reset-text {\n font-family: $font-family-base;\n // We deliberately do NOT reset font-size or word-wrap.\n font-style: normal;\n font-weight: $font-weight-normal;\n line-height: $line-height-base;\n text-align: left; // Fallback for where `start` is not supported\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n white-space: normal;\n line-break: auto;\n}\n",".popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: $zindex-popover;\n display: block;\n max-width: $popover-max-width;\n // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.\n // So reset our font and text properties to avoid inheriting weird values.\n @include reset-text();\n @include font-size($popover-font-size);\n // Allow breaking very long words so they don't overflow the popover's bounds\n word-wrap: break-word;\n background-color: $popover-bg;\n background-clip: padding-box;\n border: $popover-border-width solid $popover-border-color;\n @include border-radius($popover-border-radius);\n @include box-shadow($popover-box-shadow);\n\n .arrow {\n position: absolute;\n display: block;\n width: $popover-arrow-width;\n height: $popover-arrow-height;\n margin: 0 $border-radius-lg;\n\n &::before,\n &::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n }\n }\n}\n\n.bs-popover-top {\n margin-bottom: $popover-arrow-height;\n\n > .arrow {\n bottom: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);\n\n &::before {\n bottom: 0;\n border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-top-color: $popover-arrow-outer-color;\n }\n\n &::after {\n bottom: $popover-border-width;\n border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-top-color: $popover-arrow-color;\n }\n }\n}\n\n.bs-popover-right {\n margin-left: $popover-arrow-height;\n\n > .arrow {\n left: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);\n width: $popover-arrow-height;\n height: $popover-arrow-width;\n margin: $border-radius-lg 0; // make sure the arrow does not touch the popover's rounded corners\n\n &::before {\n left: 0;\n border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-right-color: $popover-arrow-outer-color;\n }\n\n &::after {\n left: $popover-border-width;\n border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;\n border-right-color: $popover-arrow-color;\n }\n }\n}\n\n.bs-popover-bottom {\n margin-top: $popover-arrow-height;\n\n > .arrow {\n top: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);\n\n &::before {\n top: 0;\n border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);\n border-bottom-color: $popover-arrow-outer-color;\n }\n\n &::after {\n top: $popover-border-width;\n border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);\n border-bottom-color: $popover-arrow-color;\n }\n }\n\n // This will remove the popover-header's border just below the arrow\n .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: $popover-arrow-width;\n margin-left: -$popover-arrow-width / 2;\n content: \"\";\n border-bottom: $popover-border-width solid $popover-header-bg;\n }\n}\n\n.bs-popover-left {\n margin-right: $popover-arrow-height;\n\n > .arrow {\n right: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);\n width: $popover-arrow-height;\n height: $popover-arrow-width;\n margin: $border-radius-lg 0; // make sure the arrow does not touch the popover's rounded corners\n\n &::before {\n right: 0;\n border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;\n border-left-color: $popover-arrow-outer-color;\n }\n\n &::after {\n right: $popover-border-width;\n border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;\n border-left-color: $popover-arrow-color;\n }\n }\n}\n\n.bs-popover-auto {\n &[x-placement^=\"top\"] {\n @extend .bs-popover-top;\n }\n &[x-placement^=\"right\"] {\n @extend .bs-popover-right;\n }\n &[x-placement^=\"bottom\"] {\n @extend .bs-popover-bottom;\n }\n &[x-placement^=\"left\"] {\n @extend .bs-popover-left;\n }\n}\n\n\n// Offset the popover to account for the popover arrow\n.popover-header {\n padding: $popover-header-padding-y $popover-header-padding-x;\n margin-bottom: 0; // Reset the default from Reboot\n @include font-size($font-size-base);\n color: $popover-header-color;\n background-color: $popover-header-bg;\n border-bottom: $popover-border-width solid darken($popover-header-bg, 5%);\n $offset-border-width: calc(#{$border-radius-lg} - #{$popover-border-width});\n @include border-top-radius($offset-border-width);\n\n &:empty {\n display: none;\n }\n}\n\n.popover-body {\n padding: $popover-body-padding-y $popover-body-padding-x;\n color: $popover-body-color;\n}\n","// Notes on the classes:\n//\n// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)\n// even when their scroll action started on a carousel, but for compatibility (with Firefox)\n// we're preventing all actions instead\n// 2. The .carousel-item-left and .carousel-item-right is used to indicate where\n// the active slide is heading.\n// 3. .active.carousel-item is the current slide.\n// 4. .active.carousel-item-left and .active.carousel-item-right is the current\n// slide in its in-transition state. Only one of these occurs at a time.\n// 5. .carousel-item-next.carousel-item-left and .carousel-item-prev.carousel-item-right\n// is the upcoming slide in transition.\n\n.carousel {\n position: relative;\n}\n\n.carousel.pointer-event {\n touch-action: pan-y;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n @include clearfix();\n}\n\n.carousel-item {\n position: relative;\n display: none;\n float: left;\n width: 100%;\n margin-right: -100%;\n backface-visibility: hidden;\n @include transition($carousel-transition);\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next:not(.carousel-item-left),\n.active.carousel-item-right {\n transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-right),\n.active.carousel-item-left {\n transform: translateX(-100%);\n}\n\n\n//\n// Alternate transitions\n//\n\n.carousel-fade {\n .carousel-item {\n opacity: 0;\n transition-property: opacity;\n transform: none;\n }\n\n .carousel-item.active,\n .carousel-item-next.carousel-item-left,\n .carousel-item-prev.carousel-item-right {\n z-index: 1;\n opacity: 1;\n }\n\n .active.carousel-item-left,\n .active.carousel-item-right {\n z-index: 0;\n opacity: 0;\n @include transition(0s $carousel-transition-duration opacity);\n }\n}\n\n\n//\n// Left/right controls for nav\n//\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n z-index: 1;\n // Use flex for alignment (1-3)\n display: flex; // 1. allow flex styles\n align-items: center; // 2. vertically center contents\n justify-content: center; // 3. horizontally center contents\n width: $carousel-control-width;\n color: $carousel-control-color;\n text-align: center;\n opacity: $carousel-control-opacity;\n @include transition($carousel-control-transition);\n\n // Hover/focus state\n @include hover-focus {\n color: $carousel-control-color;\n text-decoration: none;\n outline: 0;\n opacity: $carousel-control-hover-opacity;\n }\n}\n.carousel-control-prev {\n left: 0;\n @if $enable-gradients {\n background: linear-gradient(90deg, rgba($black, .25), rgba($black, .001));\n }\n}\n.carousel-control-next {\n right: 0;\n @if $enable-gradients {\n background: linear-gradient(270deg, rgba($black, .25), rgba($black, .001));\n }\n}\n\n// Icons for within\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: $carousel-control-icon-width;\n height: $carousel-control-icon-width;\n background: no-repeat 50% / 100% 100%;\n}\n.carousel-control-prev-icon {\n background-image: $carousel-control-prev-icon-bg;\n}\n.carousel-control-next-icon {\n background-image: $carousel-control-next-icon-bg;\n}\n\n\n// Optional indicator pips\n//\n// Add an ordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 15;\n display: flex;\n justify-content: center;\n padding-left: 0; // override <ol> default\n // Use the .carousel-control's width as margin so we don't overlay those\n margin-right: $carousel-control-width;\n margin-left: $carousel-control-width;\n list-style: none;\n\n li {\n box-sizing: content-box;\n flex: 0 1 auto;\n width: $carousel-indicator-width;\n height: $carousel-indicator-height;\n margin-right: $carousel-indicator-spacer;\n margin-left: $carousel-indicator-spacer;\n text-indent: -999px;\n cursor: pointer;\n background-color: $carousel-indicator-active-bg;\n background-clip: padding-box;\n // Use transparent borders to increase the hit area by 10px on top and bottom.\n border-top: $carousel-indicator-hit-area-height solid transparent;\n border-bottom: $carousel-indicator-hit-area-height solid transparent;\n opacity: .5;\n @include transition($carousel-indicator-transition);\n }\n\n .active {\n opacity: 1;\n }\n}\n\n\n// Optional captions\n//\n//\n\n.carousel-caption {\n position: absolute;\n right: (100% - $carousel-caption-width) / 2;\n bottom: 20px;\n left: (100% - $carousel-caption-width) / 2;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: $carousel-caption-color;\n text-align: center;\n}\n","@mixin clearfix() {\n &::after {\n display: block;\n clear: both;\n content: \"\";\n }\n}\n","//\n// Rotating border\n//\n\n@keyframes spinner-border {\n to { transform: rotate(360deg); }\n}\n\n.spinner-border {\n display: inline-block;\n width: $spinner-width;\n height: $spinner-height;\n vertical-align: text-bottom;\n border: $spinner-border-width solid currentColor;\n border-right-color: transparent;\n // stylelint-disable-next-line property-blacklist\n border-radius: 50%;\n animation: spinner-border .75s linear infinite;\n}\n\n.spinner-border-sm {\n width: $spinner-width-sm;\n height: $spinner-height-sm;\n border-width: $spinner-border-width-sm;\n}\n\n//\n// Growing circle\n//\n\n@keyframes spinner-grow {\n 0% {\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n }\n}\n\n.spinner-grow {\n display: inline-block;\n width: $spinner-width;\n height: $spinner-height;\n vertical-align: text-bottom;\n background-color: currentColor;\n // stylelint-disable-next-line property-blacklist\n border-radius: 50%;\n opacity: 0;\n animation: spinner-grow .75s linear infinite;\n}\n\n.spinner-grow-sm {\n width: $spinner-width-sm;\n height: $spinner-height-sm;\n}\n","// stylelint-disable declaration-no-important\n\n.align-baseline { vertical-align: baseline !important; } // Browser default\n.align-top { vertical-align: top !important; }\n.align-middle { vertical-align: middle !important; }\n.align-bottom { vertical-align: bottom !important; }\n.align-text-bottom { vertical-align: text-bottom !important; }\n.align-text-top { vertical-align: text-top !important; }\n","// stylelint-disable declaration-no-important\n\n// Contextual backgrounds\n\n@mixin bg-variant($parent, $color) {\n #{$parent} {\n background-color: $color !important;\n }\n a#{$parent},\n button#{$parent} {\n @include hover-focus {\n background-color: darken($color, 10%) !important;\n }\n }\n}\n\n@mixin bg-gradient-variant($parent, $color) {\n #{$parent} {\n background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important;\n }\n}\n","// stylelint-disable declaration-no-important\n\n@each $color, $value in $theme-colors {\n @include bg-variant(\".bg-#{$color}\", $value);\n}\n\n@if $enable-gradients {\n @each $color, $value in $theme-colors {\n @include bg-gradient-variant(\".bg-gradient-#{$color}\", $value);\n }\n}\n\n.bg-white {\n background-color: $white !important;\n}\n\n.bg-transparent {\n background-color: transparent !important;\n}\n","// stylelint-disable property-blacklist, declaration-no-important\n\n//\n// Border\n//\n\n.border { border: $border-width solid $border-color !important; }\n.border-top { border-top: $border-width solid $border-color !important; }\n.border-right { border-right: $border-width solid $border-color !important; }\n.border-bottom { border-bottom: $border-width solid $border-color !important; }\n.border-left { border-left: $border-width solid $border-color !important; }\n\n.border-0 { border: 0 !important; }\n.border-top-0 { border-top: 0 !important; }\n.border-right-0 { border-right: 0 !important; }\n.border-bottom-0 { border-bottom: 0 !important; }\n.border-left-0 { border-left: 0 !important; }\n\n@each $color, $value in $theme-colors {\n .border-#{$color} {\n border-color: $value !important;\n }\n}\n\n.border-white {\n border-color: $white !important;\n}\n\n//\n// Border-radius\n//\n\n.rounded-sm {\n border-radius: $border-radius-sm !important;\n}\n\n.rounded {\n border-radius: $border-radius !important;\n}\n\n.rounded-top {\n border-top-left-radius: $border-radius !important;\n border-top-right-radius: $border-radius !important;\n}\n\n.rounded-right {\n border-top-right-radius: $border-radius !important;\n border-bottom-right-radius: $border-radius !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: $border-radius !important;\n border-bottom-left-radius: $border-radius !important;\n}\n\n.rounded-left {\n border-top-left-radius: $border-radius !important;\n border-bottom-left-radius: $border-radius !important;\n}\n\n.rounded-lg {\n border-radius: $border-radius-lg !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-pill {\n border-radius: $rounded-pill !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Utilities for common `display` values\n//\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $value in $displays {\n .d#{$infix}-#{$value} { display: $value !important; }\n }\n }\n}\n\n\n//\n// Utilities for toggling `display` in print\n//\n\n@media print {\n @each $value in $displays {\n .d-print-#{$value} { display: $value !important; }\n }\n}\n","// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n position: relative;\n display: block;\n width: 100%;\n padding: 0;\n overflow: hidden;\n\n &::before {\n display: block;\n content: \"\";\n }\n\n .embed-responsive-item,\n iframe,\n embed,\n object,\n video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n }\n}\n\n@each $embed-responsive-aspect-ratio in $embed-responsive-aspect-ratios {\n $embed-responsive-aspect-ratio-x: nth($embed-responsive-aspect-ratio, 1);\n $embed-responsive-aspect-ratio-y: nth($embed-responsive-aspect-ratio, 2);\n\n .embed-responsive-#{$embed-responsive-aspect-ratio-x}by#{$embed-responsive-aspect-ratio-y} {\n &::before {\n padding-top: percentage($embed-responsive-aspect-ratio-y / $embed-responsive-aspect-ratio-x);\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Flex variation\n//\n// Custom styles for additional flex alignment options.\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .flex#{$infix}-row { flex-direction: row !important; }\n .flex#{$infix}-column { flex-direction: column !important; }\n .flex#{$infix}-row-reverse { flex-direction: row-reverse !important; }\n .flex#{$infix}-column-reverse { flex-direction: column-reverse !important; }\n\n .flex#{$infix}-wrap { flex-wrap: wrap !important; }\n .flex#{$infix}-nowrap { flex-wrap: nowrap !important; }\n .flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; }\n .flex#{$infix}-fill { flex: 1 1 auto !important; }\n .flex#{$infix}-grow-0 { flex-grow: 0 !important; }\n .flex#{$infix}-grow-1 { flex-grow: 1 !important; }\n .flex#{$infix}-shrink-0 { flex-shrink: 0 !important; }\n .flex#{$infix}-shrink-1 { flex-shrink: 1 !important; }\n\n .justify-content#{$infix}-start { justify-content: flex-start !important; }\n .justify-content#{$infix}-end { justify-content: flex-end !important; }\n .justify-content#{$infix}-center { justify-content: center !important; }\n .justify-content#{$infix}-between { justify-content: space-between !important; }\n .justify-content#{$infix}-around { justify-content: space-around !important; }\n\n .align-items#{$infix}-start { align-items: flex-start !important; }\n .align-items#{$infix}-end { align-items: flex-end !important; }\n .align-items#{$infix}-center { align-items: center !important; }\n .align-items#{$infix}-baseline { align-items: baseline !important; }\n .align-items#{$infix}-stretch { align-items: stretch !important; }\n\n .align-content#{$infix}-start { align-content: flex-start !important; }\n .align-content#{$infix}-end { align-content: flex-end !important; }\n .align-content#{$infix}-center { align-content: center !important; }\n .align-content#{$infix}-between { align-content: space-between !important; }\n .align-content#{$infix}-around { align-content: space-around !important; }\n .align-content#{$infix}-stretch { align-content: stretch !important; }\n\n .align-self#{$infix}-auto { align-self: auto !important; }\n .align-self#{$infix}-start { align-self: flex-start !important; }\n .align-self#{$infix}-end { align-self: flex-end !important; }\n .align-self#{$infix}-center { align-self: center !important; }\n .align-self#{$infix}-baseline { align-self: baseline !important; }\n .align-self#{$infix}-stretch { align-self: stretch !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .float#{$infix}-left { float: left !important; }\n .float#{$infix}-right { float: right !important; }\n .float#{$infix}-none { float: none !important; }\n }\n}\n","// stylelint-disable declaration-no-important\n\n@each $value in $overflows {\n .overflow-#{$value} { overflow: $value !important; }\n}\n","// stylelint-disable declaration-no-important\n\n// Common values\n@each $position in $positions {\n .position-#{$position} { position: $position !important; }\n}\n\n// Shorthand\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: $zindex-fixed;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: $zindex-fixed;\n}\n\n.sticky-top {\n @supports (position: sticky) {\n position: sticky;\n top: 0;\n z-index: $zindex-sticky;\n }\n}\n","//\n// Screenreaders\n//\n\n.sr-only {\n @include sr-only();\n}\n\n.sr-only-focusable {\n @include sr-only-focusable();\n}\n","// Only display content to screen readers\n//\n// See: https://a11yproject.com/posts/how-to-hide-content/\n// See: https://hugogiraudel.com/2016/10/13/css-hide-and-seek/\n\n@mixin sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n//\n// Useful for \"Skip to main content\" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n//\n// Credit: HTML5 Boilerplate\n\n@mixin sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n overflow: visible;\n clip: auto;\n white-space: normal;\n }\n}\n","// stylelint-disable declaration-no-important\n\n.shadow-sm { box-shadow: $box-shadow-sm !important; }\n.shadow { box-shadow: $box-shadow !important; }\n.shadow-lg { box-shadow: $box-shadow-lg !important; }\n.shadow-none { box-shadow: none !important; }\n","// stylelint-disable declaration-no-important\n\n// Width and height\n\n@each $prop, $abbrev in (width: w, height: h) {\n @each $size, $length in $sizes {\n .#{$abbrev}-#{$size} { #{$prop}: $length !important; }\n }\n}\n\n.mw-100 { max-width: 100% !important; }\n.mh-100 { max-height: 100% !important; }\n\n// Viewport additional helpers\n\n.min-vw-100 { min-width: 100vw !important; }\n.min-vh-100 { min-height: 100vh !important; }\n\n.vw-100 { width: 100vw !important; }\n.vh-100 { height: 100vh !important; }\n","//\n// Stretched link\n//\n\n.stretched-link {\n &::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1;\n // Just in case `pointer-events: none` is set on a parent\n pointer-events: auto;\n content: \"\";\n // IE10 bugfix, see https://stackoverflow.com/questions/16947967/ie10-hover-pseudo-class-doesnt-work-without-background-color\n background-color: rgba(0, 0, 0, 0);\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Margin and Padding\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @each $prop, $abbrev in (margin: m, padding: p) {\n @each $size, $length in $spacers {\n .#{$abbrev}#{$infix}-#{$size} { #{$prop}: $length !important; }\n .#{$abbrev}t#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-top: $length !important;\n }\n .#{$abbrev}r#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-right: $length !important;\n }\n .#{$abbrev}b#{$infix}-#{$size},\n .#{$abbrev}y#{$infix}-#{$size} {\n #{$prop}-bottom: $length !important;\n }\n .#{$abbrev}l#{$infix}-#{$size},\n .#{$abbrev}x#{$infix}-#{$size} {\n #{$prop}-left: $length !important;\n }\n }\n }\n\n // Negative margins (e.g., where `.mb-n1` is negative version of `.mb-1`)\n @each $size, $length in $spacers {\n @if $size != 0 {\n .m#{$infix}-n#{$size} { margin: -$length !important; }\n .mt#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-top: -$length !important;\n }\n .mr#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-right: -$length !important;\n }\n .mb#{$infix}-n#{$size},\n .my#{$infix}-n#{$size} {\n margin-bottom: -$length !important;\n }\n .ml#{$infix}-n#{$size},\n .mx#{$infix}-n#{$size} {\n margin-left: -$length !important;\n }\n }\n }\n\n // Some special margin utils\n .m#{$infix}-auto { margin: auto !important; }\n .mt#{$infix}-auto,\n .my#{$infix}-auto {\n margin-top: auto !important;\n }\n .mr#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-right: auto !important;\n }\n .mb#{$infix}-auto,\n .my#{$infix}-auto {\n margin-bottom: auto !important;\n }\n .ml#{$infix}-auto,\n .mx#{$infix}-auto {\n margin-left: auto !important;\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Text\n//\n\n.text-monospace { font-family: $font-family-monospace !important; }\n\n// Alignment\n\n.text-justify { text-align: justify !important; }\n.text-wrap { white-space: normal !important; }\n.text-nowrap { white-space: nowrap !important; }\n.text-truncate { @include text-truncate; }\n\n// Responsive alignment\n\n@each $breakpoint in map-keys($grid-breakpoints) {\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n .text#{$infix}-left { text-align: left !important; }\n .text#{$infix}-right { text-align: right !important; }\n .text#{$infix}-center { text-align: center !important; }\n }\n}\n\n// Transformation\n\n.text-lowercase { text-transform: lowercase !important; }\n.text-uppercase { text-transform: uppercase !important; }\n.text-capitalize { text-transform: capitalize !important; }\n\n// Weight and italics\n\n.font-weight-light { font-weight: $font-weight-light !important; }\n.font-weight-lighter { font-weight: $font-weight-lighter !important; }\n.font-weight-normal { font-weight: $font-weight-normal !important; }\n.font-weight-bold { font-weight: $font-weight-bold !important; }\n.font-weight-bolder { font-weight: $font-weight-bolder !important; }\n.font-italic { font-style: italic !important; }\n\n// Contextual colors\n\n.text-white { color: $white !important; }\n\n@each $color, $value in $theme-colors {\n @include text-emphasis-variant(\".text-#{$color}\", $value);\n}\n\n.text-body { color: $body-color !important; }\n.text-muted { color: $text-muted !important; }\n\n.text-black-50 { color: rgba($black, .5) !important; }\n.text-white-50 { color: rgba($white, .5) !important; }\n\n// Misc\n\n.text-hide {\n @include text-hide($ignore-warning: true);\n}\n\n.text-decoration-none { text-decoration: none !important; }\n\n.text-break {\n word-break: break-word !important; // IE & < Edge 18\n overflow-wrap: break-word !important;\n}\n\n// Reset\n\n.text-reset { color: inherit !important; }\n","// Text truncate\n// Requires inline-block or block for proper styling\n\n@mixin text-truncate() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","// stylelint-disable declaration-no-important\n\n// Typography\n\n@mixin text-emphasis-variant($parent, $color) {\n #{$parent} {\n color: $color !important;\n }\n @if $emphasized-link-hover-darken-percentage != 0 {\n a#{$parent} {\n @include hover-focus {\n color: darken($color, $emphasized-link-hover-darken-percentage) !important;\n }\n }\n }\n}\n","// CSS image replacement\n@mixin text-hide($ignore-warning: false) {\n // stylelint-disable-next-line font-family-no-missing-generic-family-keyword\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n\n @include deprecate(\"`text-hide()`\", \"v4.1.0\", \"v5\", $ignore-warning);\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Visibility utilities\n//\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type\n\n// Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request:\n// https://www.phpied.com/delay-loading-your-print-css/\n// ==========================================================================\n\n@if $enable-print-styles {\n @media print {\n *,\n *::before,\n *::after {\n // Bootstrap specific; comment out `color` and `background`\n //color: $black !important; // Black prints faster\n text-shadow: none !important;\n //background: transparent !important;\n box-shadow: none !important;\n }\n\n a {\n &:not(.btn) {\n text-decoration: underline;\n }\n }\n\n // Bootstrap specific; comment the following selector out\n //a[href]::after {\n // content: \" (\" attr(href) \")\";\n //}\n\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n\n // Bootstrap specific; comment the following selector out\n //\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n //\n\n //a[href^=\"#\"]::after,\n //a[href^=\"javascript:\"]::after {\n // content: \"\";\n //}\n\n pre {\n white-space: pre-wrap !important;\n }\n pre,\n blockquote {\n border: $border-width solid $gray-500; // Bootstrap custom code; using `$border-width` instead of 1px\n page-break-inside: avoid;\n }\n\n //\n // Printing Tables:\n // http://css-discuss.incutio.com/wiki/Printing_Tables\n //\n\n thead {\n display: table-header-group;\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Specify a size and min-width to make printing closer across browsers.\n // We don't set margin here because it breaks `size` in Chrome. We also\n // don't use `!important` on `size` as it breaks in Chrome.\n @page {\n size: $print-page-size;\n }\n body {\n min-width: $print-body-min-width !important;\n }\n .container {\n min-width: $print-body-min-width !important;\n }\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .badge {\n border: $border-width solid $black;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: $white !important;\n }\n }\n\n .table-bordered {\n th,\n td {\n border: 1px solid $gray-300 !important;\n }\n }\n\n .table-dark {\n color: inherit;\n\n th,\n td,\n thead th,\n tbody + tbody {\n border-color: $table-border-color;\n }\n }\n\n .table .thead-dark th {\n color: inherit;\n border-color: $table-border-color;\n }\n\n // Bootstrap specific changes end\n }\n}\n"]}
|
css/switchery.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.switchery{background-color:#fff;border:1px solid #dfdfdf;border-radius:20px;cursor:pointer;display:inline-block;height:30px;position:relative;vertical-align:middle;width:50px;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;box-sizing:content-box;background-clip:content-box}.switchery>small{background:#fff;border-radius:100%;box-shadow:0 1px 3px rgba(0,0,0
|
1 |
+
.switchery{background-color:#fff;border:1px solid #dfdfdf;border-radius:20px;cursor:pointer;display:inline-block;height:30px;position:relative;vertical-align:middle;width:50px;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;box-sizing:content-box;background-clip:content-box}.switchery>small{background:#fff;border-radius:100%;box-shadow:0 1px 3px rgba(0,0,0,0.4);height:30px;position:absolute;top:0;width:30px}.switchery-small{border-radius:20px;height:20px;width:33px}.switchery-small>small{height:20px;width:20px}.switchery-large{border-radius:40px;height:40px;width:66px}.switchery-large>small{height:40px;width:40px}
|
css/themes/classic.css
CHANGED
@@ -697,9 +697,7 @@ input#nifty_ratings_comment {
|
|
697 |
float: left;
|
698 |
display: block;
|
699 |
height: 60px;
|
700 |
-
padding-left: 10px;
|
701 |
padding-right: 10px;
|
702 |
-
width: 80px;
|
703 |
}
|
704 |
|
705 |
.wplc_hovercard_content_right {
|
697 |
float: left;
|
698 |
display: block;
|
699 |
height: 60px;
|
|
|
700 |
padding-right: 10px;
|
|
|
701 |
}
|
702 |
|
703 |
.wplc_hovercard_content_right {
|
css/themes/modern.css
CHANGED
@@ -133,8 +133,7 @@
|
|
133 |
/* max-height: 500px; */
|
134 |
width: 368px;
|
135 |
max-width: 100%;
|
136 |
-
|
137 |
-
top: 10%;
|
138 |
border-top-left-radius: 15px;
|
139 |
border-top-right-radius: 15px;
|
140 |
box-shadow: 0 0 40px 0 rgba(150, 165, 190, .14);
|
@@ -207,7 +206,7 @@
|
|
207 |
overflow: hidden;
|
208 |
text-align: center;
|
209 |
margin: 0 auto;
|
210 |
-
padding: 16px;
|
211 |
color: #fff;
|
212 |
}
|
213 |
|
@@ -341,6 +340,7 @@
|
|
341 |
text-align: center;
|
342 |
padding: 16px;
|
343 |
font-size: 12pt;
|
|
|
344 |
}
|
345 |
|
346 |
#wp-live-chat-inner-image-div {
|
@@ -602,9 +602,7 @@ span.tcx_pullup.up {
|
|
602 |
float: left;
|
603 |
display: block;
|
604 |
/*height: 60px;*/
|
605 |
-
padding-left: 10px;
|
606 |
padding-right: 10px;
|
607 |
-
width: 80px;
|
608 |
font-weight: normal;
|
609 |
}
|
610 |
|
@@ -625,10 +623,6 @@ span.tcx_pullup.up {
|
|
625 |
border-radius: 30px;
|
626 |
}
|
627 |
|
628 |
-
#wplc_message_div {
|
629 |
-
margin-top: 20px;
|
630 |
-
}
|
631 |
-
|
632 |
#wp-live-chat-2-inner #wplc_start_chat_btn {
|
633 |
width: 100%;
|
634 |
display: block;
|
133 |
/* max-height: 500px; */
|
134 |
width: 368px;
|
135 |
max-width: 100%;
|
136 |
+
height: 70%;
|
|
|
137 |
border-top-left-radius: 15px;
|
138 |
border-top-right-radius: 15px;
|
139 |
box-shadow: 0 0 40px 0 rgba(150, 165, 190, .14);
|
206 |
overflow: hidden;
|
207 |
text-align: center;
|
208 |
margin: 0 auto;
|
209 |
+
padding: 4px 0px 16px 0px;
|
210 |
color: #fff;
|
211 |
}
|
212 |
|
340 |
text-align: center;
|
341 |
padding: 16px;
|
342 |
font-size: 12pt;
|
343 |
+
margin-top: 20px;
|
344 |
}
|
345 |
|
346 |
#wp-live-chat-inner-image-div {
|
602 |
float: left;
|
603 |
display: block;
|
604 |
/*height: 60px;*/
|
|
|
605 |
padding-right: 10px;
|
|
|
606 |
font-weight: normal;
|
607 |
}
|
608 |
|
623 |
border-radius: 30px;
|
624 |
}
|
625 |
|
|
|
|
|
|
|
|
|
626 |
#wp-live-chat-2-inner #wplc_start_chat_btn {
|
627 |
width: 100%;
|
628 |
display: block;
|
functions.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
|
3 |
if ( ! defined( 'ABSPATH' ) ) {
|
4 |
-
|
5 |
}
|
6 |
|
7 |
$wplc_images='jpg|jpeg|png|gif|bmp';
|
@@ -77,6 +77,7 @@ function wplc_log_user_on_page($name,$email,$session, $is_mobile = false) {
|
|
77 |
return $lastid;
|
78 |
|
79 |
}
|
|
|
80 |
function wplc_update_user_on_page($cid, $status = 5,$session) {
|
81 |
global $wpdb;
|
82 |
global $wplc_tblname_chats;
|
@@ -175,10 +176,9 @@ function wplc_record_chat_msg($from, $cid, $msg, $rest_check = false, $aid = fal
|
|
175 |
|
176 |
|
177 |
if ($from == "2" && $rest_check == false) {
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
} else { return "security issue"; }
|
182 |
}
|
183 |
|
184 |
if ($from == "1") {
|
@@ -207,19 +207,17 @@ function wplc_record_chat_msg($from, $cid, $msg, $rest_check = false, $aid = fal
|
|
207 |
$msg = apply_filters("wplc_filter_message_control",$msg);
|
208 |
|
209 |
if (!$aid) {
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
$other_data = '';
|
216 |
-
}
|
217 |
} else {
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
}
|
224 |
|
225 |
$wpdb->insert(
|
@@ -245,20 +243,8 @@ function wplc_record_chat_msg($from, $cid, $msg, $rest_check = false, $aid = fal
|
|
245 |
'%s'
|
246 |
)
|
247 |
);
|
248 |
-
|
249 |
-
$data = array(
|
250 |
-
'cid' => $cid,
|
251 |
-
'from' => $from,
|
252 |
-
'msg' => $orig_msg,
|
253 |
-
'orig' => $orig
|
254 |
-
);
|
255 |
-
//do_action("wplc_hook_message_sent",$data);
|
256 |
-
|
257 |
wplc_update_active_timestamp(sanitize_text_field($cid));
|
258 |
-
|
259 |
-
|
260 |
return true;
|
261 |
-
|
262 |
}
|
263 |
|
264 |
function wplc_update_active_timestamp($cid) {
|
@@ -405,40 +391,42 @@ add_filter("wplc_filter_list_chats_actions","wplc_filter_control_list_chats_acti
|
|
405 |
* @version 6.0.04 Updated to ensure those with the correct access can access this function
|
406 |
*/
|
407 |
function wplc_filter_control_list_chats_actions($actions,$result,$post_data) {
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
|
|
|
|
|
|
413 |
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
if ( !isset( $result->agent_id ) || $wplc_current_user == $result->agent_id ) { //Added backwards compat checks
|
423 |
-
$actions = "<a href=\"".$url."\" class=\"wplc_open_chat button button-primary\" window-title=\"WP_Live_Chat_".$result->id."\">".__("Open Chat",'wp-live-chat-support')."</a>";
|
424 |
-
} else {
|
425 |
-
$actions = "<span class=\"wplc-chat-in-progress\">" . __( "In progress with another agent", 'wp-live-chat-support') . "</span>";
|
426 |
-
}
|
427 |
-
}
|
428 |
-
else if (intval($result->status) == 2) {
|
429 |
-
$url_params = "&action=ac&cid=".$result->id.$aid;
|
430 |
-
$url = admin_url( 'admin.php?page=wplivechat-menu'.$url_params);
|
431 |
-
$actions = "<a href=\"".$url."\" class=\"wplc_open_chat button button-primary\" window-title=\"WP_Live_Chat_".$result->id."\">".__("Accept Chat",'wp-live-chat-support')."</a>";
|
432 |
-
}
|
433 |
-
else if (intval($result->status) == 12 ) {
|
434 |
-
$url_params = "&action=ac&cid=".$result->id.$aid;
|
435 |
-
$url = admin_url( 'admin.php?page=wplivechat-menu'.$url_params);
|
436 |
-
$actions = "<a href=\"".$url."\" class=\"wplc_open_chat button button-primary\" window-title=\"WP_Live_Chat_".$result->id."\">".__("Open Chat",'wp-live-chat-support')."</a>";
|
437 |
}
|
438 |
-
|
439 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
440 |
}
|
441 |
-
|
|
|
|
|
|
|
442 |
}
|
443 |
|
444 |
function wplc_list_chats($post_data) {
|
@@ -704,7 +692,7 @@ function wplc_return_chat_messages($cid, $transcript = false, $html = true, $wpl
|
|
704 |
} else if ($result->originates == 0 || $result->originates == 3) {
|
705 |
$system_notification = true;
|
706 |
$cuid = get_current_user_id();
|
707 |
-
$is_agent =
|
708 |
if ($is_agent && $result->originates == 3 ) {
|
709 |
/* this user is an agent and the notification is meant for an agent, therefore display it */
|
710 |
$display_notification = true;
|
@@ -886,8 +874,7 @@ function wplc_mark_as_read_agent_chat_messages($cid, $aid) {
|
|
886 |
}
|
887 |
|
888 |
function wplc_return_admin_chat_messages($cid) {
|
889 |
-
|
890 |
-
if (get_user_meta( $wplc_current_user, 'wplc_ma_agent', true)) {
|
891 |
global $wpdb;
|
892 |
global $wplc_tblname_msgs;
|
893 |
/**
|
@@ -915,15 +902,12 @@ function wplc_return_admin_chat_messages($cid) {
|
|
915 |
// system notifications from version 7
|
916 |
$system_notification = true;
|
917 |
}
|
918 |
-
|
919 |
if (!$system_notification) {
|
920 |
/* this is a normal message */
|
921 |
if (function_exists('wplc_encrypt_decrypt_msg')) {
|
922 |
$msg = wplc_encrypt_decrypt_msg($msg);
|
923 |
}
|
924 |
-
|
925 |
$msg_array = maybe_unserialize( $msg );
|
926 |
-
|
927 |
if (is_array( $msg_array)) {
|
928 |
$msg = $msg_array['m'];
|
929 |
}
|
@@ -934,10 +918,9 @@ function wplc_return_admin_chat_messages($cid) {
|
|
934 |
$msg_hist[$id]['msg'] = $msg;
|
935 |
$msg_hist[$id]['originates'] = intval($result->originates);
|
936 |
$msg_hist[$id]['other'] = $other_data;
|
937 |
-
|
938 |
} else {
|
939 |
/* add the system notification to the list */
|
940 |
-
|
941 |
$msg_hist[$id]['msg'] = $msg;
|
942 |
$msg_hist[$id]['other'] = $other_data;
|
943 |
$msg_hist[$id]['originates'] = intval($result->originates);
|
@@ -956,31 +939,23 @@ function wplc_return_admin_chat_messages($cid) {
|
|
956 |
* @return string "ok"
|
957 |
*/
|
958 |
function wplc_mark_as_read_admin_chat_messages( $mid ) {
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
array('%d'),
|
972 |
-
array('%d')
|
973 |
-
);
|
974 |
-
|
975 |
-
} else { return "security issue"; }
|
976 |
-
|
977 |
return "ok";
|
|
|
|
|
978 |
}
|
979 |
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
function wplc_return_chat_session_variable($cid) {
|
985 |
global $wpdb;
|
986 |
global $wplc_tblname_chats;
|
@@ -1731,33 +1706,29 @@ function wplc_advanced_settings_above_performance_control($wplc_settings) {
|
|
1731 |
* Reverse of wplc_return_chat_id_by_rel
|
1732 |
*/
|
1733 |
function wplc_return_chat_rel_by_id($cid) {
|
1734 |
-
|
1735 |
-
|
1736 |
-
|
1737 |
-
|
1738 |
-
|
1739 |
-
|
1740 |
-
|
1741 |
-
|
1742 |
-
} else {
|
1743 |
-
return $cid;
|
1744 |
-
}
|
1745 |
-
}
|
1746 |
-
} else {
|
1747 |
return $cid;
|
|
|
1748 |
}
|
1749 |
-
|
|
|
|
|
1750 |
}
|
1751 |
|
1752 |
function wplc_all_avatars() {
|
1753 |
-
|
1754 |
-
|
1755 |
-
|
1756 |
-
$avatars =
|
1757 |
-
|
1758 |
-
|
1759 |
-
}
|
1760 |
-
return $avatars;
|
1761 |
}
|
1762 |
|
1763 |
function wplc_get_avatar($id) {
|
@@ -1846,43 +1817,19 @@ function wplc_display_chat_contents() {
|
|
1846 |
|
1847 |
add_action("admin_init","wplc_control_logged_in_mrg");
|
1848 |
function wplc_control_logged_in_mrg() {
|
1849 |
-
|
1850 |
-
|
1851 |
-
|
1852 |
-
update_user_meta($userid, "wplc_chat_agent_online", time());
|
1853 |
-
}
|
1854 |
-
|
1855 |
}
|
1856 |
|
1857 |
add_action("init","wplc_control_logged_out_mrg");
|
1858 |
function wplc_control_logged_out_mrg() {
|
1859 |
-
|
1860 |
-
|
1861 |
-
|
1862 |
-
|
1863 |
-
|
1864 |
-
|
1865 |
-
if ($check) {
|
1866 |
-
foreach ($check as $wplcuser) {
|
1867 |
-
$check = get_user_meta($wplcuser->ID, "wplc_chat_agent_online");
|
1868 |
-
if (isset($check[0])) {
|
1869 |
-
$last_logged_in_time = $check[0];
|
1870 |
-
if ($last_logged_in_time > 0) {
|
1871 |
-
if ((time() - $last_logged_in_time) < 120) {
|
1872 |
-
/* do nothing, they are online */
|
1873 |
-
} else {
|
1874 |
-
/* this user has not sent a heartbeat in over 120 seconds */
|
1875 |
-
delete_user_meta($wplcuser->ID, "wplc_chat_agent_online");
|
1876 |
-
}
|
1877 |
-
}
|
1878 |
-
}
|
1879 |
-
}
|
1880 |
-
} else {
|
1881 |
-
return false;
|
1882 |
-
}
|
1883 |
-
} else {
|
1884 |
-
return false;
|
1885 |
-
}
|
1886 |
}
|
1887 |
|
1888 |
/**
|
@@ -1985,7 +1932,7 @@ function wplc_mrg_update_db( $networkwide = false ) {
|
|
1985 |
$admins->add_cap('wplc_ma_agent');
|
1986 |
$uid = get_current_user_id();
|
1987 |
update_user_meta($uid, 'wplc_ma_agent', 1);
|
1988 |
-
|
1989 |
}
|
1990 |
|
1991 |
|
@@ -2100,7 +2047,7 @@ function wplc_quick_response_manage_number_column_mrg( $column, $post_id ) {
|
|
2100 |
}
|
2101 |
|
2102 |
function wplc_quick_response_add_agent_caps_mrg() {
|
2103 |
-
if (
|
2104 |
$user_id = get_current_user_id();
|
2105 |
$user = new WP_User($user_id);
|
2106 |
$user->add_cap('edit_wplc_quick_response');
|
@@ -2362,10 +2309,9 @@ function wplc_choose_hook_control_chat_dashboard_above() {
|
|
2362 |
if (!$wplc_settings['wplc_allow_agents_set_status']) {
|
2363 |
return;
|
2364 |
}
|
2365 |
-
$status = wplc_get_agent_status(get_current_user_id());
|
2366 |
?>
|
2367 |
<div class="wplc_admin_chat_switchery_a">
|
2368 |
-
<input type="checkbox" class="wplc_switchery" name="wplc_agent_status" id="wplc_agent_status" <?php if (
|
2369 |
<div id="wplc_agent_status_text"></div>
|
2370 |
</div>
|
2371 |
<?php
|
@@ -2379,7 +2325,7 @@ function wplc_choose_hook_control_chat_dashboard_above() {
|
|
2379 |
*/
|
2380 |
add_filter("wplc_filter_control_set_transient","wplc_choose_filter_control_set_set_transient",10,1);
|
2381 |
function wplc_choose_filter_control_set_set_transient($set_transient) {
|
2382 |
-
return
|
2383 |
}
|
2384 |
|
2385 |
/**
|
@@ -2390,121 +2336,106 @@ function wplc_choose_filter_control_set_set_transient($set_transient) {
|
|
2390 |
*/
|
2391 |
add_filter("wplc_final_loggedin_control","wplc_choose_final_loggedin_control",10,2);
|
2392 |
function wplc_choose_final_loggedin_control($logged_in,$logged_in_via_app) {
|
2393 |
-
|
2394 |
-
|
2395 |
-
|
2396 |
-
|
2397 |
-
|
2398 |
-
|
2399 |
-
|
2400 |
-
|
2401 |
-
|
2402 |
-
$last_logged_in_time = $check[0];
|
2403 |
-
if ($last_logged_in_time > 0) {
|
2404 |
-
if ((time() - $last_logged_in_time) < 70) {
|
2405 |
-
$logged_in = true;
|
2406 |
-
$one_logged_in = true;
|
2407 |
-
}
|
2408 |
-
}
|
2409 |
-
}
|
2410 |
-
if (!$logged_in) {
|
2411 |
-
wplc_set_agent_status($wplc_user->ID, false);
|
2412 |
-
}
|
2413 |
-
}
|
2414 |
-
return $one_logged_in;
|
2415 |
}
|
2416 |
|
2417 |
/**
|
2418 |
* Latch onto the original callback for this plugin's ajax requests
|
2419 |
* @return void
|
2420 |
*/
|
2421 |
-
|
2422 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2423 |
|
2424 |
-
|
2425 |
-
|
2426 |
-
|
2427 |
-
|
2428 |
-
|
2429 |
-
|
|
|
|
|
2430 |
|
2431 |
-
|
2432 |
-
|
2433 |
-
|
2434 |
-
|
2435 |
-
delete_transient('wplc_is_admin_logged_in');
|
2436 |
-
echo "done";
|
2437 |
-
}
|
2438 |
|
2439 |
-
|
2440 |
-
|
2441 |
-
|
2442 |
-
|
2443 |
-
}
|
2444 |
}
|
2445 |
}
|
|
|
|
|
2446 |
|
2447 |
-
|
2448 |
-
|
2449 |
-
|
2450 |
-
|
2451 |
-
|
2452 |
-
|
2453 |
-
|
2454 |
-
|
2455 |
-
|
2456 |
-
|
2457 |
-
|
2458 |
-
|
2459 |
-
|
2460 |
-
|
2461 |
-
|
2462 |
-
|
2463 |
-
|
2464 |
-
|
2465 |
-
|
2466 |
-
|
2467 |
-
|
2468 |
-
|
2469 |
-
|
2470 |
-
|
2471 |
-
|
2472 |
-
|
2473 |
-
|
2474 |
-
|
2475 |
-
|
2476 |
-
|
2477 |
-
|
2478 |
-
|
2479 |
-
|
2480 |
-
|
2481 |
-
|
2482 |
-
|
2483 |
-
|
2484 |
-
|
2485 |
-
|
2486 |
-
|
2487 |
-
|
2488 |
-
|
2489 |
-
|
2490 |
-
|
2491 |
-
|
2492 |
-
|
2493 |
-
|
2494 |
-
|
2495 |
-
|
2496 |
-
|
2497 |
-
}
|
2498 |
-
}
|
2499 |
-
}else {
|
2500 |
-
echo "ERROR: Chat ID Tampering Detected.";
|
2501 |
-
}
|
2502 |
-
}else {
|
2503 |
-
echo "ERROR: Upload failed. Invalid Chat ID.";
|
2504 |
-
}
|
2505 |
-
wp_die();
|
2506 |
}
|
2507 |
-
|
|
|
2508 |
}
|
2509 |
|
2510 |
function wplc_typing_mrg($user,$cid,$type) {
|
@@ -2556,13 +2487,17 @@ function wplc_choose_admin_scripts() {
|
|
2556 |
'accepting_status' => __('Status (Online)', 'wp-live-chat-support'),
|
2557 |
'accepting_chats' => __('Online', 'wp-live-chat-support'),
|
2558 |
'not_accepting_chats' => __('Offline', 'wp-live-chat-support'),
|
2559 |
-
'not_accepting_status' => __('Status (Offline)', 'wp-live-chat-support')
|
|
|
|
|
2560 |
);
|
|
|
2561 |
wp_localize_script('wplc-choose-script', 'wplc_choose_admin_strings', $wpc_admin_js_strings);
|
|
|
2562 |
|
2563 |
$wplc_current_user_id = get_current_user_id();
|
2564 |
|
2565 |
-
if (
|
2566 |
/* user is online */
|
2567 |
wp_localize_script('wplc-choose-script', 'wplc_choose_accept_chats', array('value'=>true));
|
2568 |
} else {
|
@@ -2796,35 +2731,12 @@ function wplc_ic_filter_control_run_override($ret) {
|
|
2796 |
* @return void
|
2797 |
*
|
2798 |
*/
|
2799 |
-
|
2800 |
-
|
2801 |
-
|
2802 |
-
|
2803 |
-
|
2804 |
-
|
2805 |
-
}
|
2806 |
-
return $data_array;
|
2807 |
-
|
2808 |
-
}
|
2809 |
-
}
|
2810 |
-
|
2811 |
-
/**
|
2812 |
-
* Check if the user is an agent
|
2813 |
-
*
|
2814 |
-
* @since 1.0.0
|
2815 |
-
* @param
|
2816 |
-
* @return string
|
2817 |
-
*
|
2818 |
-
*/
|
2819 |
-
if (!function_exists("wplc_ic_check_if_user_is_agent")) {
|
2820 |
-
function wplc_ic_check_if_user_is_agent(){
|
2821 |
-
$user_id = get_current_user_id();
|
2822 |
-
if (sanitize_text_field(get_the_author_meta('wplc_ma_agent', $user_id ) ) === "1"){
|
2823 |
-
return $user_id;
|
2824 |
-
} else {
|
2825 |
-
return "not_user_agent";
|
2826 |
-
}
|
2827 |
-
}
|
2828 |
}
|
2829 |
|
2830 |
/**
|
@@ -2951,20 +2863,14 @@ function wplc_hook_control_wplc_draw_chat_area($result) {
|
|
2951 |
*/
|
2952 |
if (!function_exists("wplc_ma_hook_control_admin_meny_layout_display_top")) {
|
2953 |
function wplc_ma_hook_control_admin_meny_layout_display_top() {
|
2954 |
-
|
2955 |
-
|
2956 |
-
|
2957 |
-
|
2958 |
-
|
2959 |
-
}
|
2960 |
-
return;
|
2961 |
}
|
2962 |
}
|
2963 |
|
2964 |
-
|
2965 |
-
|
2966 |
-
|
2967 |
-
|
2968 |
/**
|
2969 |
* Assign the chat to the agent
|
2970 |
*
|
@@ -2992,29 +2898,6 @@ if (!function_exists("wplc_maa_update_agent_id")) {
|
|
2992 |
}
|
2993 |
}
|
2994 |
|
2995 |
-
|
2996 |
-
|
2997 |
-
/**
|
2998 |
-
* Check if the user is an agent
|
2999 |
-
*
|
3000 |
-
* @since 1.0.0
|
3001 |
-
* @param
|
3002 |
-
* @return string
|
3003 |
-
*
|
3004 |
-
*/
|
3005 |
-
if (!function_exists("wplc_maa_check_if_user_is_agent")) {
|
3006 |
-
function wplc_maa_check_if_user_is_agent(){
|
3007 |
-
$user_id = get_current_user_id();
|
3008 |
-
if (sanitize_text_field(get_the_author_meta('wplc_ma_agent', $user_id ) ) == "1"){
|
3009 |
-
return $user_id;
|
3010 |
-
} else {
|
3011 |
-
return "not_user_agent";
|
3012 |
-
}
|
3013 |
-
}
|
3014 |
-
}
|
3015 |
-
|
3016 |
-
|
3017 |
-
|
3018 |
/**
|
3019 |
* Check if the chat has been answered by another chat agent
|
3020 |
* @since 1.0.0
|
@@ -3090,7 +2973,7 @@ if (!function_exists("wplc_ma_first_time_install")) {
|
|
3090 |
$admins->add_cap('wplc_ma_agent');
|
3091 |
$uid = get_current_user_id();
|
3092 |
update_user_meta($uid, 'wplc_ma_agent', 1);
|
3093 |
-
|
3094 |
}
|
3095 |
}
|
3096 |
|
@@ -3118,8 +3001,8 @@ if (!function_exists("wplc_maa_set_user_as_agent")) {
|
|
3118 |
|
3119 |
if ($_POST['wplc_ma_agent'] == '1') {
|
3120 |
$wplc_ma_user = new WP_User( $user_id );
|
3121 |
-
|
3122 |
-
|
3123 |
} else {
|
3124 |
$wplc_ma_user = new WP_User( $user_id );
|
3125 |
$wplc_ma_user->remove_cap( 'wplc_ma_agent' );
|
@@ -3400,20 +3283,17 @@ if (!function_exists("wplc_ma_hook_control_accept_chat_url")) {
|
|
3400 |
}
|
3401 |
}
|
3402 |
|
3403 |
-
|
3404 |
if (!function_exists("wplc_filter_control_aid_in_action")) {
|
3405 |
-
|
3406 |
-
|
3407 |
-
|
3408 |
-
|
3409 |
-
|
3410 |
-
|
3411 |
-
|
3412 |
-
|
3413 |
-
}
|
3414 |
}
|
3415 |
|
3416 |
-
|
3417 |
/**
|
3418 |
*
|
3419 |
*
|
@@ -3425,19 +3305,13 @@ if (!function_exists("wplc_filter_control_aid_in_action")) {
|
|
3425 |
if (!function_exists("wplc_ma_filter_control_admin_javascript")) {
|
3426 |
add_filter("wplc_filter_admin_javascript","wplc_ma_filter_control_admin_javascript");
|
3427 |
function wplc_ma_filter_control_admin_javascript($data_array) {
|
3428 |
-
|
3429 |
-
|
3430 |
-
|
3431 |
-
|
3432 |
-
return $data_array;
|
3433 |
-
|
3434 |
}
|
3435 |
}
|
3436 |
|
3437 |
-
|
3438 |
-
|
3439 |
-
|
3440 |
-
|
3441 |
/**
|
3442 |
* Control the content below the visitor count
|
3443 |
* @return void
|
@@ -3445,35 +3319,12 @@ if (!function_exists("wplc_ma_filter_control_admin_javascript")) {
|
|
3445 |
if (!function_exists("wplc_ma_filter_control_chat_dashboard_visitors_online_bottom")) {
|
3446 |
add_action("wplc_filter_chat_dahsboard_visitors_online_bottom","wplc_ma_filter_control_chat_dashboard_visitors_online_bottom",11);
|
3447 |
function wplc_ma_filter_control_chat_dashboard_visitors_online_bottom($text) {
|
3448 |
-
$text = " <span class='wplc_agents_online'>".
|
3449 |
$text .= __("Agent(s) online",'wp-live-chat-support');
|
3450 |
return $text;
|
3451 |
}
|
3452 |
}
|
3453 |
|
3454 |
-
/**
|
3455 |
-
* Count how many agents are online
|
3456 |
-
* @return int number of agents
|
3457 |
-
*/
|
3458 |
-
function wplc_maa_total_agents_online() {
|
3459 |
-
$user_array = get_users(array(
|
3460 |
-
'meta_key'=> 'wplc_chat_agent_online',
|
3461 |
-
));
|
3462 |
-
$wplc_settings = wplc_get_options();
|
3463 |
-
if ($wplc_settings['wplc_allow_agents_set_status']) {
|
3464 |
-
$agent_status = wplc_get_all_agent_status();
|
3465 |
-
$count = 0;
|
3466 |
-
foreach($user_array as $v) {
|
3467 |
-
if (isset($agent_status[$v->ID]) && $agent_status[$v->ID]) {
|
3468 |
-
$count++;
|
3469 |
-
}
|
3470 |
-
}
|
3471 |
-
return $count;
|
3472 |
-
} else {
|
3473 |
-
return count($user_array);
|
3474 |
-
}
|
3475 |
-
}
|
3476 |
-
|
3477 |
add_action('admin_bar_menu', 'wplc_maa_online_agents', 100);
|
3478 |
function wplc_maa_online_agents() {
|
3479 |
if (!current_user_can('wplc_ma_agent', array(null))) {
|
@@ -3494,9 +3345,27 @@ function wplc_maa_online_agents() {
|
|
3494 |
.wplc_green_circle{
|
3495 |
background:rgb(103, 213, 82);
|
3496 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3497 |
</style>
|
3498 |
<?php
|
3499 |
-
$
|
|
|
3500 |
if ($agent_count>0) {
|
3501 |
$circle_class = "wplc_green_circle";
|
3502 |
if ($agent_count==1) {
|
@@ -3512,22 +3381,28 @@ function wplc_maa_online_agents() {
|
|
3512 |
global $wp_admin_bar;
|
3513 |
$wp_admin_bar->add_menu( array(
|
3514 |
'id' => 'wplc_ma_online_agents',
|
3515 |
-
'title' => '<span class="wplc_circle '.$circle_class.'" id="wplc_ma_online_agents_circle"></span><span id="wplc_ma_online_agents_count">'.$agent_count.'</span> '.$chat_agents,
|
3516 |
'href' => false
|
3517 |
));
|
3518 |
|
3519 |
-
|
3520 |
-
$
|
3521 |
-
|
3522 |
-
|
3523 |
-
|
3524 |
-
|
3525 |
-
|
3526 |
-
|
3527 |
-
|
3528 |
-
|
3529 |
-
|
3530 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
3531 |
}
|
3532 |
}
|
3533 |
|
@@ -3569,7 +3444,7 @@ if (!function_exists("wplc_maa_hook_control_head")) {
|
|
3569 |
if (!function_exists("wplc_maa_filter_control_check_if_logged_in")) {
|
3570 |
add_filter("wplc_filter_is_admin_logged_in","wplc_maa_filter_control_check_if_logged_in",10,1);
|
3571 |
function wplc_maa_filter_control_check_if_logged_in($logged_in) {
|
3572 |
-
$logged_in['site'] =
|
3573 |
return $logged_in;
|
3574 |
}
|
3575 |
}
|
@@ -3583,21 +3458,10 @@ if (!function_exists("wplc_maa_filter_control_check_if_logged_in")) {
|
|
3583 |
if (!function_exists("wplc_maa_agent_logout")) {
|
3584 |
add_action('wp_logout', 'wplc_maa_agent_logout');
|
3585 |
function wplc_maa_agent_logout(){
|
3586 |
-
|
3587 |
-
delete_user_meta($user_id, "wplc_chat_agent_online");
|
3588 |
}
|
3589 |
}
|
3590 |
|
3591 |
-
/**
|
3592 |
-
* Is there at least one agent online?
|
3593 |
-
* @return bool
|
3594 |
-
* @since 1.0.00
|
3595 |
-
*/
|
3596 |
-
|
3597 |
-
function wplc_maa_is_agent_online() {
|
3598 |
-
return wplc_maa_total_agents_online()>0;
|
3599 |
-
}
|
3600 |
-
|
3601 |
/**
|
3602 |
* Add the JS file to the admin screen
|
3603 |
* @return void
|
@@ -3624,20 +3488,18 @@ if (!function_exists("wplc_control_admin_javascript")) {
|
|
3624 |
do_action("wplc_maa_hook_head");
|
3625 |
}
|
3626 |
|
3627 |
-
if (!function_exists("wplc_ma_hook_control_action_callback")) {
|
3628 |
-
|
3629 |
-
|
3630 |
-
|
3631 |
-
|
3632 |
-
|
3633 |
-
|
3634 |
-
|
3635 |
-
|
3636 |
-
|
3637 |
-
}
|
3638 |
}
|
3639 |
|
3640 |
-
|
3641 |
if (!function_exists("wplc_ma_hook_control_remove_transient")) {
|
3642 |
add_action("wplc_hook_remove_transient","wplc_ma_hook_control_remove_transient",9);
|
3643 |
function wplc_ma_hook_control_remove_transient() {
|
@@ -3651,91 +3513,82 @@ if (!function_exists("wplc_ma_hook_control_remove_transient")) {
|
|
3651 |
* @return void
|
3652 |
* @since 1.0.00
|
3653 |
*/
|
3654 |
-
|
3655 |
-
|
3656 |
-
|
3657 |
-
|
3658 |
-
|
3659 |
-
|
3660 |
-
|
3661 |
-
|
3662 |
-
|
3663 |
-
|
3664 |
-
|
3665 |
-
|
3666 |
-
|
3667 |
-
|
3668 |
-
|
3669 |
-
|
3670 |
-
|
3671 |
-
|
3672 |
-
|
3673 |
-
|
3674 |
-
|
3675 |
-
|
3676 |
-
|
3677 |
-
|
3678 |
-
|
3679 |
-
|
3680 |
-
|
3681 |
-
if ($_POST['action'] == "wplc_macro") {
|
3682 |
-
if(wplc_ic_check_if_user_is_agent() !== "not_user_agent") {
|
3683 |
-
if (isset($_POST['postid'])) {
|
3684 |
-
$post_id = sanitize_text_field($_POST['postid']);
|
3685 |
-
} else {
|
3686 |
-
return false;
|
3687 |
-
}
|
3688 |
|
3689 |
-
|
3690 |
-
|
3691 |
-
|
3692 |
-
|
3693 |
-
|
3694 |
-
|
3695 |
-
|
3696 |
-
|
3697 |
-
|
3698 |
-
|
3699 |
-
|
3700 |
-
|
3701 |
-
|
3702 |
-
|
3703 |
-
die();
|
3704 |
-
}
|
3705 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3706 |
|
3707 |
-
|
3708 |
-
|
3709 |
-
|
3710 |
-
|
3711 |
-
|
3712 |
-
|
3713 |
-
|
3714 |
-
|
3715 |
-
|
3716 |
-
|
3717 |
-
|
3718 |
-
|
3719 |
-
|
3720 |
-
|
3721 |
-
|
3722 |
-
|
3723 |
-
|
3724 |
-
|
3725 |
-
|
3726 |
-
|
3727 |
-
|
3728 |
-
|
3729 |
-
|
3730 |
-
|
3731 |
-
}
|
3732 |
-
}else {
|
3733 |
-
echo "There was an error sending your chat rating. Please contact support";
|
3734 |
-
wp_die();
|
3735 |
-
}
|
3736 |
-
}
|
3737 |
-
|
3738 |
-
}
|
3739 |
}
|
3740 |
|
3741 |
/**
|
@@ -3743,28 +3596,13 @@ if (!function_exists("wplc_ma_hook_control_action_callback")) {
|
|
3743 |
* @return void
|
3744 |
* @since 1.0.00
|
3745 |
*/
|
3746 |
-
|
3747 |
-
if (
|
3748 |
-
|
3749 |
-
|
3750 |
-
|
3751 |
-
|
3752 |
-
update_user_meta($user_id, "wplc_chat_agent_online", time());
|
3753 |
-
}
|
3754 |
-
$users = get_users(array(
|
3755 |
-
'meta_key'=> 'wplc_chat_agent_online',
|
3756 |
-
));
|
3757 |
-
foreach($users as $user){
|
3758 |
-
$time = get_user_meta($user->ID, "wplc_chat_agent_online", true);
|
3759 |
-
$diff = time() - $time;
|
3760 |
-
if($diff > 125){
|
3761 |
-
delete_user_meta($user->ID, "wplc_chat_agent_online");
|
3762 |
-
}
|
3763 |
-
}
|
3764 |
-
}
|
3765 |
}
|
3766 |
|
3767 |
-
|
3768 |
/* WPLC Social Icons Filter*/
|
3769 |
// add_filter("wplc_filter_chat_header_above","wplc_chat_social_div_mrg",5,2);
|
3770 |
// add_filter("wplc_filter_chat_4th_layer_below_input","wplc_chat_social_div_mrg",5,2);
|
@@ -3992,128 +3830,64 @@ function wplc_reporting_tabs_filter_experience_ratings_control_mrg($tabs_array){
|
|
3992 |
|
3993 |
|
3994 |
add_filter('wplc_reporting_tab_content', 'wplc_reporting_tab_content_filter_experience_ratings_control_mrg', 10, 1);
|
3995 |
-
function wplc_reporting_tab_content_filter_experience_ratings_control_mrg($tabs_array){
|
3996 |
-
|
3997 |
-
|
3998 |
-
|
3999 |
-
|
4000 |
-
|
4001 |
-
|
4002 |
-
|
4003 |
-
|
4004 |
-
|
4005 |
-
|
4006 |
-
|
4007 |
-
|
4008 |
-
|
4009 |
-
|
4010 |
-
|
4011 |
-
|
4012 |
-
|
4013 |
-
|
4014 |
-
|
4015 |
-
|
4016 |
-
|
4017 |
-
|
4018 |
-
|
4019 |
-
|
4020 |
-
|
4021 |
-
|
4022 |
-
$
|
4023 |
-
|
4024 |
-
$
|
4025 |
-
|
4026 |
-
|
4027 |
-
|
4028 |
-
|
4029 |
-
|
4030 |
-
|
4031 |
-
|
4032 |
-
|
4033 |
-
|
4034 |
-
|
4035 |
-
$ratings .= "<div class='wplc_agent_card_details'>";
|
4036 |
-
$ratings .= "<strong>" . $user->display_name . "</strong><br>";
|
4037 |
-
$ratings .= "<small>" . $user->user_email . "</small><br>";
|
4038 |
-
$ratings .= "<hr>";
|
4039 |
-
$ratings .= "<small><strong>".__("Satisfaction Rating", 'wp-live-chat-support').":</strong> " . (is_bool($rating_stats) && $rating_stats == false ? "--" : $rating_stats['percentage'] ). "%</small><br>";
|
4040 |
-
$ratings .= "<small><strong>".__("Rating Count", 'wp-live-chat-support').":</strong> " . (is_bool($rating_stats) && $rating_stats == false ? "0" : $rating_stats['total_ratings'])." (".__("Good",'wp-live-chat-support').": ".(is_bool($rating_stats) && $rating_stats == false ? "0" : $rating_stats['good_count']). " || ".__("Bad",'wp-live-chat-support').": ".(is_bool($rating_stats) && $rating_stats == false ? "0" : $rating_stats['bad_count']). ")</small>";
|
4041 |
-
$ratings .= "</div>";
|
4042 |
-
$ratings .= "</div>";
|
4043 |
-
|
4044 |
-
/** Removed as of 07-2019 */
|
4045 |
-
/*$ratings .= "<div class='wplc_agent_data'>";
|
4046 |
-
|
4047 |
-
if(is_bool($rating_stats) && $rating_stats == false){
|
4048 |
-
$ratings .= "<div style='width:90%;display: inline-block; min-height: 30px;'>";
|
4049 |
-
$ratings .= "<i>".__("No Ratings for this agent", 'wp-live-chat-support')."</i>";
|
4050 |
-
$ratings .= "</div>";
|
4051 |
-
}else{
|
4052 |
-
$ratings_for_agent = $rating_stats[$user->ID];
|
4053 |
-
foreach ($ratings_for_agent as $id => $rate) {
|
4054 |
-
$cid = $rate['cid'];
|
4055 |
-
$date = substr($rate['time'], 0, strpos($rate['time'], ' '));
|
4056 |
-
$ratings .= "<div style='width:70%;display: inline-block; min-height: 30px;'>";
|
4057 |
-
$ratings .= "<small style='display:inline-block; height: unset'>$date</small>" . " - <strong style='".(intval($rate['rating']) == 1 ? "color:#439134;": "color:#ac1d1d;")."'>".(intval($rate['rating']) == 1 ? __("Good", 'wp-live-chat-support') : __("Bad", 'wp-live-chat-support') )."</strong>";
|
4058 |
-
$ratings .= " - <i style='width:auto;'>\"" . $rate['comment'] . "\"</i>";
|
4059 |
-
$ratings .= "</div>";
|
4060 |
-
$ratings .= " <a style='float:right' class='button' href='?page=wplivechat-menu&action=history&cid=".$cid."&wplc_history_nonce=" . $hist_nonce . "' target='_blank'>" . __("View", 'wp-live-chat-support') . "</a>";
|
4061 |
-
|
4062 |
-
}
|
4063 |
-
}
|
4064 |
-
|
4065 |
-
$ratings .= "</div>";*/
|
4066 |
-
$ratings .= "</div>";
|
4067 |
-
|
4068 |
-
}
|
4069 |
-
|
4070 |
-
$rating_stats = nifty_get_rating_report_mrg(0);
|
4071 |
-
if(!empty($rating_stats[0]) && $rating_stats[0] !== false){
|
4072 |
-
$ratings .= "<div class='wplc_agent_container'>";
|
4073 |
-
$ratings .= "<div class='wplc_agent_card'>";
|
4074 |
-
$ratings .= "<div class='wplc_agent_card_details'>";
|
4075 |
-
$ratings .= "<strong>No Agent</strong><br>";
|
4076 |
-
$ratings .= "<small>Reviewed before agent joined, or with multiple agents</small><br>";
|
4077 |
-
$ratings .= "<hr>";
|
4078 |
-
$ratings .= "<small><strong>".__("Satisfaction Rating", 'wp-live-chat-support').":</strong> " . (is_bool($rating_stats) && $rating_stats == false ? "--" : $rating_stats['percentage'] ). "%</small><br>";
|
4079 |
-
$ratings .= "<small><strong>".__("Rating Count", 'wp-live-chat-support').":</strong> " . (is_bool($rating_stats) && $rating_stats == false ? "0" : $rating_stats['total_ratings'])." (".__("Good",'wp-live-chat-support').": ".(is_bool($rating_stats) && $rating_stats == false ? "0" : $rating_stats['good_count']). " || ".__("Bad",'wp-live-chat-support').": ".(is_bool($rating_stats) && $rating_stats == false ? "0" : $rating_stats['bad_count']). ")</small>";
|
4080 |
-
$ratings .= "</div>";
|
4081 |
-
$ratings .= "</div>";
|
4082 |
-
|
4083 |
-
/** Removed as of 07-2019*/
|
4084 |
-
/*
|
4085 |
-
$ratings .= "<div class='wplc_agent_data'>";
|
4086 |
-
|
4087 |
-
if(is_bool($rating_stats) && $rating_stats == false){
|
4088 |
-
$ratings .= "<div style='width:90%;display: inline-block; min-height: 30px;'>";
|
4089 |
-
$ratings .= "<i>".__("No Ratings for this agent", 'wp-live-chat-support')."</i>";
|
4090 |
-
$ratings .= "</div>";
|
4091 |
-
}else{
|
4092 |
-
$ratings_for_agent = $rating_stats[0];
|
4093 |
-
foreach ($ratings_for_agent as $id => $rate) {
|
4094 |
-
$cid = $rate['cid'];
|
4095 |
-
$date = substr($rate['time'], 0, strpos($rate['time'], ' '));
|
4096 |
-
|
4097 |
-
$ratings .= "<div style='width:70%;display: inline-block; min-height: 30px;'>";
|
4098 |
-
$ratings .= "<small style='display:inline-block; height: unset'>$date</small>" . " - <strong style='".(intval($rate['rating']) == 1 ? "color:#439134;": "color:#ac1d1d;")."'>".(intval($rate['rating']) == 1 ? __("Good", 'wp-live-chat-support') : __("Bad", 'wp-live-chat-support') )."</strong>";
|
4099 |
-
$ratings .= " - <i style='width:auto;'>\"" . $rate['comment'] . "\"</i>";
|
4100 |
-
$ratings .= "</div>";
|
4101 |
-
$ratings .= " <a style='float:right' class='button' href='?page=wplivechat-menu&action=history&cid=".$cid."&wplc_history_nonce=" . $hist_nonce . "' target='_blank'>" . __("View", 'wp-live-chat-support') . "</a>";
|
4102 |
-
|
4103 |
-
}
|
4104 |
-
}
|
4105 |
-
|
4106 |
-
$ratings .= "</div>";
|
4107 |
-
*/
|
4108 |
-
$ratings .= "</div>";
|
4109 |
-
}
|
4110 |
|
4111 |
-
|
4112 |
-
|
4113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4114 |
|
4115 |
-
|
4116 |
-
|
4117 |
}
|
4118 |
|
4119 |
add_action('admin_enqueue_scripts', 'wplc_reporting_scripts_mrg');
|
@@ -4746,7 +4520,7 @@ add_action('wplc_hook_initiate_chat', 'wplc_mrg_chat_notification_extender', 99,
|
|
4746 |
function wplc_register_common_node() {
|
4747 |
global $wplc_allowed_extensions;
|
4748 |
$wplc_settings = wplc_get_options();
|
4749 |
-
wp_register_script('wplc-admin-js-agent-common', WPLC_PLUGIN_URL.'
|
4750 |
$current_user=wp_get_current_user();
|
4751 |
$date_days=array();
|
4752 |
for($i=0;$i<7;$i++) {
|
@@ -5155,9 +4929,149 @@ function wplc_cleanup_old_options($wplc_settings) {
|
|
5155 |
return $wplc_settings;
|
5156 |
}
|
5157 |
|
5158 |
-
function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5159 |
$wplc_settings = wplc_get_options();
|
5160 |
-
$choose_array =
|
5161 |
if (!isset($choose_array[$uid])) {
|
5162 |
$choose_array[$uid]=true;
|
5163 |
update_option("WPLC_CHOOSE_ACCEPTING", $choose_array);
|
@@ -5169,15 +5083,15 @@ function wplc_get_agent_status($uid) {
|
|
5169 |
return $choose_array[$uid];
|
5170 |
}
|
5171 |
|
5172 |
-
function
|
5173 |
-
$choose_array =
|
5174 |
if (!isset($choose_array[$uid]) || $choose_array[$uid]!=boolval($online)) {
|
5175 |
$choose_array[$uid]=boolval($online);
|
5176 |
update_option("WPLC_CHOOSE_ACCEPTING", $choose_array);
|
5177 |
}
|
5178 |
}
|
5179 |
|
5180 |
-
function
|
5181 |
$choose_array = get_option("WPLC_CHOOSE_ACCEPTING");
|
5182 |
if (!is_array($choose_array)) {
|
5183 |
$choose_array = array();
|
@@ -5185,36 +5099,10 @@ function wplc_get_all_agent_status() {
|
|
5185 |
return $choose_array;
|
5186 |
}
|
5187 |
|
5188 |
-
function
|
5189 |
-
|
5190 |
-
|
5191 |
-
$
|
5192 |
-
|
5193 |
-
|
5194 |
-
|
5195 |
-
if($action === "wplc_generate_new_node_token") {
|
5196 |
-
if(wp_verify_nonce( $nonce, 'generate_new_token')) {
|
5197 |
-
$res = wplc_node_server_token_get(true);
|
5198 |
-
echo $res;
|
5199 |
-
}else {
|
5200 |
-
$error = true;
|
5201 |
-
}
|
5202 |
-
}elseif ($action === "wplc_new_secret_key") {
|
5203 |
-
if(wp_verify_nonce( $nonce, 'generate_new_secret_token')) {
|
5204 |
-
$user_token = wplc_api_s_key_create();
|
5205 |
-
update_option("wplc_api_secret_token", $user_token);
|
5206 |
-
echo $user_token;
|
5207 |
-
}else {
|
5208 |
-
$error = true;
|
5209 |
-
}
|
5210 |
-
}
|
5211 |
-
|
5212 |
-
if($error === true){
|
5213 |
-
_e("You do not have permission to perform this action",'wp-live-chat-support');
|
5214 |
-
}
|
5215 |
-
|
5216 |
-
}else {
|
5217 |
-
_e("You do not have permission to perform this action",'wp-live-chat-support');
|
5218 |
-
}
|
5219 |
-
wp_die();
|
5220 |
-
}
|
1 |
<?php
|
2 |
|
3 |
if ( ! defined( 'ABSPATH' ) ) {
|
4 |
+
exit;
|
5 |
}
|
6 |
|
7 |
$wplc_images='jpg|jpeg|png|gif|bmp';
|
77 |
return $lastid;
|
78 |
|
79 |
}
|
80 |
+
|
81 |
function wplc_update_user_on_page($cid, $status = 5,$session) {
|
82 |
global $wpdb;
|
83 |
global $wplc_tblname_chats;
|
176 |
|
177 |
|
178 |
if ($from == "2" && $rest_check == false) {
|
179 |
+
if (!wplc_user_is_agent()) {
|
180 |
+
return "security issue";
|
181 |
+
}
|
|
|
182 |
}
|
183 |
|
184 |
if ($from == "1") {
|
207 |
$msg = apply_filters("wplc_filter_message_control",$msg);
|
208 |
|
209 |
if (!$aid) {
|
210 |
+
if (wplc_user_is_agent()) {
|
211 |
+
$other_data = array('aid'=>get_current_user_id());
|
212 |
+
} else {
|
213 |
+
$other_data = '';
|
214 |
+
}
|
|
|
|
|
215 |
} else {
|
216 |
+
if (wplc_user_is_agent($aid)) {
|
217 |
+
$other_data = array('aid'=>$aid);
|
218 |
+
} else {
|
219 |
+
$other_data = '';
|
220 |
+
}
|
221 |
}
|
222 |
|
223 |
$wpdb->insert(
|
243 |
'%s'
|
244 |
)
|
245 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
246 |
wplc_update_active_timestamp(sanitize_text_field($cid));
|
|
|
|
|
247 |
return true;
|
|
|
248 |
}
|
249 |
|
250 |
function wplc_update_active_timestamp($cid) {
|
391 |
* @version 6.0.04 Updated to ensure those with the correct access can access this function
|
392 |
*/
|
393 |
function wplc_filter_control_list_chats_actions($actions,$result,$post_data) {
|
394 |
+
$aid = apply_filters("wplc_filter_aid_in_action","");
|
395 |
+
if (wplc_user_is_agent()) {
|
396 |
+
switch (intval($result->status)) {
|
397 |
+
case 2:
|
398 |
+
$url_params = "&action=ac&cid=".$result->id.$aid;
|
399 |
+
$url = admin_url( 'admin.php?page=wplivechat-menu'.$url_params);
|
400 |
+
$actions = "<a href=\"".$url."\" class=\"wplc_open_chat button button-primary\" window-title=\"WP_Live_Chat_".$result->id."\">". apply_filters("wplc_accept_chat_button_filter", __("Accept Chat",'wp-live-chat-support'), $result->id)."</a>";
|
401 |
+
break;
|
402 |
|
403 |
+
case 3:
|
404 |
+
case 10:
|
405 |
+
$url_params = "&action=ac&cid=".$result->id.$aid;
|
406 |
+
$url = admin_url( 'admin.php?page=wplivechat-menu'.$url_params);
|
407 |
+
if (!isset( $result->agent_id ) || get_current_user_id() == $result->agent_id ) { //Added backwards compat checks
|
408 |
+
$actions = "<a href=\"".$url."\" class=\"wplc_open_chat button button-primary\" window-title=\"WP_Live_Chat_".$result->id."\">".__("Open Chat",'wp-live-chat-support')."</a>";
|
409 |
+
} else {
|
410 |
+
$actions = "<span class=\"wplc-chat-in-progress\">" . __( "In progress with another agent", 'wp-live-chat-support') . "</span>";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
411 |
}
|
412 |
+
break;
|
413 |
+
|
414 |
+
case 2:
|
415 |
+
$url_params = "&action=ac&cid=".$result->id.$aid;
|
416 |
+
$url = admin_url( 'admin.php?page=wplivechat-menu'.$url_params);
|
417 |
+
$actions = "<a href=\"".$url."\" class=\"wplc_open_chat button button-primary\" window-title=\"WP_Live_Chat_".$result->id."\">".__("Accept Chat",'wp-live-chat-support')."</a>";
|
418 |
+
break;
|
419 |
+
|
420 |
+
case 12:
|
421 |
+
$url_params = "&action=ac&cid=".$result->id.$aid;
|
422 |
+
$url = admin_url( 'admin.php?page=wplivechat-menu'.$url_params);
|
423 |
+
$actions = "<a href=\"".$url."\" class=\"wplc_open_chat button button-primary\" window-title=\"WP_Live_Chat_".$result->id."\">".__("Open Chat",'wp-live-chat-support')."</a>";
|
424 |
+
break;
|
425 |
}
|
426 |
+
} else {
|
427 |
+
$actions = "<a href='#'>".__( 'Only chat agents can accept chats', 'wp-live-chat-support')."</a>";
|
428 |
+
}
|
429 |
+
return $actions;
|
430 |
}
|
431 |
|
432 |
function wplc_list_chats($post_data) {
|
692 |
} else if ($result->originates == 0 || $result->originates == 3) {
|
693 |
$system_notification = true;
|
694 |
$cuid = get_current_user_id();
|
695 |
+
$is_agent = wplc_user_is_agent($cuid);
|
696 |
if ($is_agent && $result->originates == 3 ) {
|
697 |
/* this user is an agent and the notification is meant for an agent, therefore display it */
|
698 |
$display_notification = true;
|
874 |
}
|
875 |
|
876 |
function wplc_return_admin_chat_messages($cid) {
|
877 |
+
if (wplc_user_is_agent()) {
|
|
|
878 |
global $wpdb;
|
879 |
global $wplc_tblname_msgs;
|
880 |
/**
|
902 |
// system notifications from version 7
|
903 |
$system_notification = true;
|
904 |
}
|
|
|
905 |
if (!$system_notification) {
|
906 |
/* this is a normal message */
|
907 |
if (function_exists('wplc_encrypt_decrypt_msg')) {
|
908 |
$msg = wplc_encrypt_decrypt_msg($msg);
|
909 |
}
|
|
|
910 |
$msg_array = maybe_unserialize( $msg );
|
|
|
911 |
if (is_array( $msg_array)) {
|
912 |
$msg = $msg_array['m'];
|
913 |
}
|
918 |
$msg_hist[$id]['msg'] = $msg;
|
919 |
$msg_hist[$id]['originates'] = intval($result->originates);
|
920 |
$msg_hist[$id]['other'] = $other_data;
|
|
|
921 |
} else {
|
922 |
/* add the system notification to the list */
|
923 |
+
if ( isset( $msg_hist[$id] ) ) { $msg_hist[$id] = array(); }
|
924 |
$msg_hist[$id]['msg'] = $msg;
|
925 |
$msg_hist[$id]['other'] = $other_data;
|
926 |
$msg_hist[$id]['originates'] = intval($result->originates);
|
939 |
* @return string "ok"
|
940 |
*/
|
941 |
function wplc_mark_as_read_admin_chat_messages( $mid ) {
|
942 |
+
if (wplc_user_is_agent()) {
|
943 |
+
global $wpdb;
|
944 |
+
global $wplc_tblname_msgs;
|
945 |
+
$wpdb->update(
|
946 |
+
$wplc_tblname_msgs,
|
947 |
+
array(
|
948 |
+
'status' => 1
|
949 |
+
),
|
950 |
+
array('id' => $mid),
|
951 |
+
array('%d'),
|
952 |
+
array('%d')
|
953 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
954 |
return "ok";
|
955 |
+
}
|
956 |
+
return "security issue";
|
957 |
}
|
958 |
|
|
|
|
|
|
|
|
|
959 |
function wplc_return_chat_session_variable($cid) {
|
960 |
global $wpdb;
|
961 |
global $wplc_tblname_chats;
|
1706 |
* Reverse of wplc_return_chat_id_by_rel
|
1707 |
*/
|
1708 |
function wplc_return_chat_rel_by_id($cid) {
|
1709 |
+
global $wpdb;
|
1710 |
+
global $wplc_tblname_chats;
|
1711 |
+
$results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wplc_tblname_chats WHERE `id` = %s LIMIT 1", $cid));
|
1712 |
+
if ($results) {
|
1713 |
+
foreach ($results as $result) {
|
1714 |
+
if (isset($result->rel)) {
|
1715 |
+
return $result->rel;
|
1716 |
+
} else {
|
|
|
|
|
|
|
|
|
|
|
1717 |
return $cid;
|
1718 |
+
}
|
1719 |
}
|
1720 |
+
} else {
|
1721 |
+
return $cid;
|
1722 |
+
}
|
1723 |
}
|
1724 |
|
1725 |
function wplc_all_avatars() {
|
1726 |
+
$users = wplc_get_agent_users();
|
1727 |
+
$avatars = array();
|
1728 |
+
foreach ($users as $user) {
|
1729 |
+
$avatars[$user->data->ID] = wplc_get_avatar($user->data->ID);
|
1730 |
+
}
|
1731 |
+
return $avatars;
|
|
|
|
|
1732 |
}
|
1733 |
|
1734 |
function wplc_get_avatar($id) {
|
1817 |
|
1818 |
add_action("admin_init","wplc_control_logged_in_mrg");
|
1819 |
function wplc_control_logged_in_mrg() {
|
1820 |
+
if (wplc_user_is_agent()) {
|
1821 |
+
wplc_update_agent_time();
|
1822 |
+
}
|
|
|
|
|
|
|
1823 |
}
|
1824 |
|
1825 |
add_action("init","wplc_control_logged_out_mrg");
|
1826 |
function wplc_control_logged_out_mrg() {
|
1827 |
+
if (!isset($_GET['role'])) {
|
1828 |
+
add_action('pre_get_users', 'wplc_advanced_access_manager_compatibility_mrg', 1000);
|
1829 |
+
wplc_check_agents_timeout();
|
1830 |
+
} else {
|
1831 |
+
return false;
|
1832 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1833 |
}
|
1834 |
|
1835 |
/**
|
1932 |
$admins->add_cap('wplc_ma_agent');
|
1933 |
$uid = get_current_user_id();
|
1934 |
update_user_meta($uid, 'wplc_ma_agent', 1);
|
1935 |
+
wplc_update_agent_time($uid);
|
1936 |
}
|
1937 |
|
1938 |
|
2047 |
}
|
2048 |
|
2049 |
function wplc_quick_response_add_agent_caps_mrg() {
|
2050 |
+
if (wplc_user_is_agent()) {
|
2051 |
$user_id = get_current_user_id();
|
2052 |
$user = new WP_User($user_id);
|
2053 |
$user->add_cap('edit_wplc_quick_response');
|
2309 |
if (!$wplc_settings['wplc_allow_agents_set_status']) {
|
2310 |
return;
|
2311 |
}
|
|
|
2312 |
?>
|
2313 |
<div class="wplc_admin_chat_switchery_a">
|
2314 |
+
<input type="checkbox" class="wplc_switchery" name="wplc_agent_status" id="wplc_agent_status" <?php if (wplc_get_agent_accepting(get_current_user_id())) { echo 'checked'; } ?> />
|
2315 |
<div id="wplc_agent_status_text"></div>
|
2316 |
</div>
|
2317 |
<?php
|
2325 |
*/
|
2326 |
add_filter("wplc_filter_control_set_transient","wplc_choose_filter_control_set_set_transient",10,1);
|
2327 |
function wplc_choose_filter_control_set_set_transient($set_transient) {
|
2328 |
+
return wplc_get_agent_accepting(get_current_user_id());
|
2329 |
}
|
2330 |
|
2331 |
/**
|
2336 |
*/
|
2337 |
add_filter("wplc_final_loggedin_control","wplc_choose_final_loggedin_control",10,2);
|
2338 |
function wplc_choose_final_loggedin_control($logged_in,$logged_in_via_app) {
|
2339 |
+
return wplc_get_online_agent_users_count()>0;
|
2340 |
+
}
|
2341 |
+
|
2342 |
+
function wplc_return_online_agents_array() {
|
2343 |
+
$result = array(
|
2344 |
+
'result' => true,
|
2345 |
+
'agents' => wplc_get_online_agents_list()
|
2346 |
+
);
|
2347 |
+
return json_encode($result);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2348 |
}
|
2349 |
|
2350 |
/**
|
2351 |
* Latch onto the original callback for this plugin's ajax requests
|
2352 |
* @return void
|
2353 |
*/
|
2354 |
+
function wplc_choose_hook_control_action_callback() {
|
2355 |
+
if ($_POST['action'] == 'wplc_choose_accepting') {
|
2356 |
+
$user_id = get_current_user_id();
|
2357 |
+
wplc_set_agent_accepting($user_id, true);
|
2358 |
+
do_action("wplc_hook_set_transient");
|
2359 |
+
echo wplc_return_online_agents_array();
|
2360 |
+
return;
|
2361 |
+
}
|
2362 |
|
2363 |
+
if ($_POST['action'] == 'wplc_choose_not_accepting') {
|
2364 |
+
$user_id = get_current_user_id();
|
2365 |
+
wplc_set_agent_accepting($user_id, false);
|
2366 |
+
delete_user_meta($user_id, "wplc_chat_agent_online");
|
2367 |
+
delete_transient('wplc_is_admin_logged_in');
|
2368 |
+
echo wplc_return_online_agents_array();
|
2369 |
+
return;
|
2370 |
+
}
|
2371 |
|
2372 |
+
if ($_POST['action'] == 'wplc_agent_list') {
|
2373 |
+
echo wplc_return_online_agents_array();
|
2374 |
+
return;
|
2375 |
+
}
|
|
|
|
|
|
|
2376 |
|
2377 |
+
if ($_POST['action'] == "wplc_typing") {
|
2378 |
+
if (isset($_POST['cid']) && isset($_POST['user']) && isset($_POST['type'])) {
|
2379 |
+
if ((!wplc_user_is_agent() && wplc_check_user_request($_POST['cid'])) || wplc_user_is_agent()) {
|
2380 |
+
echo wplc_typing_mrg(sanitize_text_field($_POST['user']), intval($_POST['cid']), sanitize_text_field($_POST['type']));
|
|
|
2381 |
}
|
2382 |
}
|
2383 |
+
return;
|
2384 |
+
}
|
2385 |
|
2386 |
+
if ($_POST['action'] == 'wplc_upload_file') {
|
2387 |
+
$upload_dir = wp_upload_dir();
|
2388 |
+
$user_dirname = $upload_dir['basedir'];
|
2389 |
+
$cid=0;
|
2390 |
+
$u_id_check=0;
|
2391 |
+
if (isset($_POST['cid'])) {
|
2392 |
+
if (!wplc_user_is_agent()) {
|
2393 |
+
if (wplc_check_user_request($_POST['cid'])) {
|
2394 |
+
$u_id_check = 1;
|
2395 |
+
}
|
2396 |
+
} else {
|
2397 |
+
$u_id_check = 1;
|
2398 |
+
}
|
2399 |
+
if ($u_id_check === 1) {
|
2400 |
+
$cid = sanitize_text_field($_POST['cid']);
|
2401 |
+
if (!filter_var($cid, FILTER_VALIDATE_INT)) {
|
2402 |
+
/* We need to identify if this CID is a node CID, and if so, return the WP CID */
|
2403 |
+
$cid = wplc_return_chat_id_by_rel($cid);
|
2404 |
+
}
|
2405 |
+
$cid = intval($cid);
|
2406 |
+
if (!file_exists( $user_dirname."/wp_live_chat/")) {
|
2407 |
+
@mkdir($user_dirname.'/wp_live_chat/');
|
2408 |
+
}
|
2409 |
+
if (!realpath($user_dirname."/wp_live_chat/" . $cid)) {
|
2410 |
+
@mkdir( $user_dirname.'/wp_live_chat/'. $cid );
|
2411 |
+
}
|
2412 |
+
if (isset($_FILES['file']) && isset($_POST['timestamp'])) {
|
2413 |
+
$file_name = strtolower( sanitize_file_name($_FILES['file']['name']) );
|
2414 |
+
$file_name = basename($file_name); //This prevents traversal
|
2415 |
+
if (wplc_check_file_name_for_safe_extension($file_name) && wplc_check_file_mime_type($_FILES['file']['tmp_name'])) {
|
2416 |
+
$upload_file_name = $file_name;
|
2417 |
+
while (file_exists($user_dirname . "/wp_live_chat/" . $cid . "/" . $upload_file_name)) {
|
2418 |
+
$upload_file_name = substr($file_name,0,strrpos($file_name, '.')).mt_rand(1000,9999).substr($file_name,strrpos($file_name, '.'));
|
2419 |
+
}
|
2420 |
+
if (move_uploaded_file($_FILES['file']['tmp_name'], $user_dirname."/wp_live_chat/" . $cid . "/" . $upload_file_name)) {
|
2421 |
+
//File has been uploaded, let's now go ahead and check the mime type
|
2422 |
+
$response = $upload_dir['baseurl']."/wp_live_chat/" . $cid . "/" . $upload_file_name;
|
2423 |
+
echo $response;
|
2424 |
+
} else {
|
2425 |
+
echo "ERROR: Upload failed";
|
2426 |
+
}
|
2427 |
+
} else {
|
2428 |
+
echo "ERROR: Security Violation";
|
2429 |
+
}
|
2430 |
+
}
|
2431 |
+
} else {
|
2432 |
+
echo "ERROR: Chat ID Tampering Detected.";
|
2433 |
+
}
|
2434 |
+
} else {
|
2435 |
+
echo "ERROR: Upload failed. Invalid Chat ID.";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2436 |
}
|
2437 |
+
wp_die();
|
2438 |
+
}
|
2439 |
}
|
2440 |
|
2441 |
function wplc_typing_mrg($user,$cid,$type) {
|
2487 |
'accepting_status' => __('Status (Online)', 'wp-live-chat-support'),
|
2488 |
'accepting_chats' => __('Online', 'wp-live-chat-support'),
|
2489 |
'not_accepting_chats' => __('Offline', 'wp-live-chat-support'),
|
2490 |
+
'not_accepting_status' => __('Status (Offline)', 'wp-live-chat-support'),
|
2491 |
+
'agent_online_singular' => __('Chat Agent Online', 'wp-live-chat-support'),
|
2492 |
+
'agent_online_plural' => __('Chat Agents Online', 'wp-live-chat-support')
|
2493 |
);
|
2494 |
+
|
2495 |
wp_localize_script('wplc-choose-script', 'wplc_choose_admin_strings', $wpc_admin_js_strings);
|
2496 |
+
wplc_register_common_node();
|
2497 |
|
2498 |
$wplc_current_user_id = get_current_user_id();
|
2499 |
|
2500 |
+
if (wplc_get_agent_accepting($wplc_current_user_id)) {
|
2501 |
/* user is online */
|
2502 |
wp_localize_script('wplc-choose-script', 'wplc_choose_accept_chats', array('value'=>true));
|
2503 |
} else {
|
2731 |
* @return void
|
2732 |
*
|
2733 |
*/
|
2734 |
+
add_filter("wplc_filter_admin_javascript","wplc_ic_filter_control_admin_javascript");
|
2735 |
+
function wplc_ic_filter_control_admin_javascript($data_array) {
|
2736 |
+
if (wplc_user_is_agent()) {
|
2737 |
+
$data_array['agent_id'] = get_current_user_id();
|
2738 |
+
}
|
2739 |
+
return $data_array;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2740 |
}
|
2741 |
|
2742 |
/**
|
2863 |
*/
|
2864 |
if (!function_exists("wplc_ma_hook_control_admin_meny_layout_display_top")) {
|
2865 |
function wplc_ma_hook_control_admin_meny_layout_display_top() {
|
2866 |
+
if (!wplc_user_is_agent()) {
|
2867 |
+
$warning = "<p style='color: red;'><b>".__('You are not a chat agent. Please make yourself a chat agent before trying to chat to visitors', 'wp-live-chat-support-multiple-agents')."</b></p>";
|
2868 |
+
echo $warning;
|
2869 |
+
}
|
2870 |
+
return;
|
|
|
|
|
2871 |
}
|
2872 |
}
|
2873 |
|
|
|
|
|
|
|
|
|
2874 |
/**
|
2875 |
* Assign the chat to the agent
|
2876 |
*
|
2898 |
}
|
2899 |
}
|
2900 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2901 |
/**
|
2902 |
* Check if the chat has been answered by another chat agent
|
2903 |
* @since 1.0.0
|
2973 |
$admins->add_cap('wplc_ma_agent');
|
2974 |
$uid = get_current_user_id();
|
2975 |
update_user_meta($uid, 'wplc_ma_agent', 1);
|
2976 |
+
wplc_update_agent_time($uid);
|
2977 |
}
|
2978 |
}
|
2979 |
|
3001 |
|
3002 |
if ($_POST['wplc_ma_agent'] == '1') {
|
3003 |
$wplc_ma_user = new WP_User( $user_id );
|
3004 |
+
$wplc_ma_user->add_cap( 'wplc_ma_agent' );
|
3005 |
+
wplc_update_agent_time($user_id);
|
3006 |
} else {
|
3007 |
$wplc_ma_user = new WP_User( $user_id );
|
3008 |
$wplc_ma_user->remove_cap( 'wplc_ma_agent' );
|
3283 |
}
|
3284 |
}
|
3285 |
|
|
|
3286 |
if (!function_exists("wplc_filter_control_aid_in_action")) {
|
3287 |
+
add_filter("wplc_filter_aid_in_action","wplc_filter_control_aid_in_action");
|
3288 |
+
function wplc_filter_control_aid_in_action() {
|
3289 |
+
$aid = "";
|
3290 |
+
if (wplc_user_is_agent()) {
|
3291 |
+
$aid = "&aid=".get_current_user_id();
|
3292 |
+
}
|
3293 |
+
return $aid;
|
3294 |
+
}
|
|
|
3295 |
}
|
3296 |
|
|
|
3297 |
/**
|
3298 |
*
|
3299 |
*
|
3305 |
if (!function_exists("wplc_ma_filter_control_admin_javascript")) {
|
3306 |
add_filter("wplc_filter_admin_javascript","wplc_ma_filter_control_admin_javascript");
|
3307 |
function wplc_ma_filter_control_admin_javascript($data_array) {
|
3308 |
+
if (wplc_user_is_agent()) {
|
3309 |
+
$data_array['agent_id'] = get_current_user_id();
|
3310 |
+
}
|
3311 |
+
return $data_array;
|
|
|
|
|
3312 |
}
|
3313 |
}
|
3314 |
|
|
|
|
|
|
|
|
|
3315 |
/**
|
3316 |
* Control the content below the visitor count
|
3317 |
* @return void
|
3319 |
if (!function_exists("wplc_ma_filter_control_chat_dashboard_visitors_online_bottom")) {
|
3320 |
add_action("wplc_filter_chat_dahsboard_visitors_online_bottom","wplc_ma_filter_control_chat_dashboard_visitors_online_bottom",11);
|
3321 |
function wplc_ma_filter_control_chat_dashboard_visitors_online_bottom($text) {
|
3322 |
+
$text = " <span class='wplc_agents_online'>".wplc_get_online_agent_users_count()."</span> ";
|
3323 |
$text .= __("Agent(s) online",'wp-live-chat-support');
|
3324 |
return $text;
|
3325 |
}
|
3326 |
}
|
3327 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3328 |
add_action('admin_bar_menu', 'wplc_maa_online_agents', 100);
|
3329 |
function wplc_maa_online_agents() {
|
3330 |
if (!current_user_can('wplc_ma_agent', array(null))) {
|
3345 |
.wplc_green_circle{
|
3346 |
background:rgb(103, 213, 82);
|
3347 |
}
|
3348 |
+
.wplc_online_topbar_switch:before {
|
3349 |
+
color: #000 !important;
|
3350 |
+
}
|
3351 |
+
|
3352 |
+
.wplc_online_topbar_switch {
|
3353 |
+
width: 9px !important;
|
3354 |
+
height: 14px !important;
|
3355 |
+
margin-top: -1px !important;
|
3356 |
+
border: 1px solid #dedede !important;
|
3357 |
+
}
|
3358 |
+
.wplc_online_topbar_switch_online {
|
3359 |
+
background-color: rgb(96, 202, 76) !important;
|
3360 |
+
}
|
3361 |
+
.wplc_online_topbar_switch_offline {
|
3362 |
+
background-color: #de1b1b !important;
|
3363 |
+
}
|
3364 |
+
|
3365 |
</style>
|
3366 |
<?php
|
3367 |
+
$user_array = wplc_get_online_agent_users();
|
3368 |
+
$agent_count = count($user_array);
|
3369 |
if ($agent_count>0) {
|
3370 |
$circle_class = "wplc_green_circle";
|
3371 |
if ($agent_count==1) {
|
3381 |
global $wp_admin_bar;
|
3382 |
$wp_admin_bar->add_menu( array(
|
3383 |
'id' => 'wplc_ma_online_agents',
|
3384 |
+
'title' => '<span class="wplc_circle '.$circle_class.'" id="wplc_ma_online_agents_circle"></span><span id="wplc_ma_online_agents_count">'.$agent_count.'</span> <span id="wplc_ma_online_agents_label">'.$chat_agents.'</span>',
|
3385 |
'href' => false
|
3386 |
));
|
3387 |
|
3388 |
+
foreach($user_array as $user) {
|
3389 |
+
$wp_admin_bar->add_menu(array(
|
3390 |
+
'id' => 'wplc_user_online_'.$user->ID,
|
3391 |
+
'parent' => 'wplc_ma_online_agents',
|
3392 |
+
'title' => $user->display_name,
|
3393 |
+
'href' => false,
|
3394 |
+
));
|
3395 |
+
}
|
3396 |
+
|
3397 |
+
if (is_admin()) {
|
3398 |
+
$wp_admin_bar->add_node( array(
|
3399 |
+
'id' => 'wplc_ma_online_switch',
|
3400 |
+
'meta' => array('class' => 'wplc_online_switch_'.(wplc_get_agent_accepting() ? 'online' : 'offline')),
|
3401 |
+
'title' => '<input type="checkbox" id="wplc_online_topbar_switch" '.(wplc_get_agent_accepting() ? 'checked="checked"' : '').' class="wplc_online_topbar_switch wplc_online_topbar_switch_'.(wplc_get_agent_accepting() ? 'online' : 'offline').'" />
|
3402 |
+
<span id="wplc_ma_online_agent_text">'.(wplc_get_agent_accepting() ? __('Online', 'wp-live-chat-support') : __('Offline','wp-live-chat-support')).'
|
3403 |
+
</span>',
|
3404 |
+
'href' => false
|
3405 |
+
));
|
3406 |
}
|
3407 |
}
|
3408 |
|
3444 |
if (!function_exists("wplc_maa_filter_control_check_if_logged_in")) {
|
3445 |
add_filter("wplc_filter_is_admin_logged_in","wplc_maa_filter_control_check_if_logged_in",10,1);
|
3446 |
function wplc_maa_filter_control_check_if_logged_in($logged_in) {
|
3447 |
+
$logged_in['site'] = wplc_one_agent_is_online();
|
3448 |
return $logged_in;
|
3449 |
}
|
3450 |
}
|
3458 |
if (!function_exists("wplc_maa_agent_logout")) {
|
3459 |
add_action('wp_logout', 'wplc_maa_agent_logout');
|
3460 |
function wplc_maa_agent_logout(){
|
3461 |
+
delete_user_meta(get_current_user_id(), "wplc_chat_agent_online");
|
|
|
3462 |
}
|
3463 |
}
|
3464 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3465 |
/**
|
3466 |
* Add the JS file to the admin screen
|
3467 |
* @return void
|
3488 |
do_action("wplc_maa_hook_head");
|
3489 |
}
|
3490 |
|
3491 |
+
if (!function_exists("wplc_ma_hook_control_action_callback")) { // TODO: unclear
|
3492 |
+
add_action("wplc_hook_set_transient","wplc_ma_hook_control_set_transient",9);
|
3493 |
+
function wplc_ma_hook_control_set_transient() {
|
3494 |
+
$should_set_transient = apply_filters("wplc_filter_control_set_transient",true);
|
3495 |
+
if ($should_set_transient) {
|
3496 |
+
if (isset($_POST['user_id'])) { $user_id = sanitize_text_field($_POST['user_id']); } else { $user_id = get_current_user_id(); }
|
3497 |
+
wplc_update_agent_time($user_id);
|
3498 |
+
}
|
3499 |
+
remove_action("wplc_hook_set_transient","wplc_hook_control_set_transient");
|
3500 |
+
}
|
|
|
3501 |
}
|
3502 |
|
|
|
3503 |
if (!function_exists("wplc_ma_hook_control_remove_transient")) {
|
3504 |
add_action("wplc_hook_remove_transient","wplc_ma_hook_control_remove_transient",9);
|
3505 |
function wplc_ma_hook_control_remove_transient() {
|
3513 |
* @return void
|
3514 |
* @since 1.0.00
|
3515 |
*/
|
3516 |
+
add_action("wplc_hook_action_callback","wplc_ma_hook_control_action_callback");
|
3517 |
+
function wplc_ma_hook_control_action_callback() {
|
3518 |
+
|
3519 |
+
if ($_POST['action'] == "wplc_add_agent") {
|
3520 |
+
if (current_user_can("manage_options")) {
|
3521 |
+
$uid = sanitize_text_field(intval($_POST['uid']));
|
3522 |
+
if (isset($uid)) {
|
3523 |
+
update_user_meta($uid, 'wplc_ma_agent', true);
|
3524 |
+
echo "1";
|
3525 |
+
} else {
|
3526 |
+
echo "0";
|
3527 |
+
}
|
3528 |
+
}
|
3529 |
+
}
|
3530 |
+
|
3531 |
+
if ($_POST['action'] == "wplc_remove_agent") {
|
3532 |
+
if (current_user_can("manage_options")) {
|
3533 |
+
$uid = sanitize_text_field(intval($_POST['uid']));
|
3534 |
+
if (isset($uid)) {
|
3535 |
+
delete_user_meta($uid, 'wplc_ma_agent');
|
3536 |
+
echo "1";
|
3537 |
+
} else {
|
3538 |
+
echo "0";
|
3539 |
+
}
|
3540 |
+
}
|
3541 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3542 |
|
3543 |
+
if ($_POST['action'] == "wplc_macro") {
|
3544 |
+
if (wplc_user_is_agent()) {
|
3545 |
+
if (isset($_POST['postid'])) {
|
3546 |
+
$post_id = sanitize_text_field($_POST['postid']);
|
3547 |
+
} else {
|
3548 |
+
return false;
|
3549 |
+
}
|
3550 |
+
if ($post_id > 0) {
|
3551 |
+
$post_details = get_post($post_id);
|
3552 |
+
if ($post_details) {
|
3553 |
+
echo json_encode(nl2br($post_details->post_content));
|
3554 |
+
} else {
|
3555 |
+
echo json_encode("No post with that ID");
|
3556 |
+
die();
|
|
|
|
|
3557 |
}
|
3558 |
+
} else {
|
3559 |
+
echo json_encode("No macro with that ID");
|
3560 |
+
die();
|
3561 |
+
}
|
3562 |
+
} else {
|
3563 |
+
echo json_encode("You do not have permission to perform this action.");
|
3564 |
+
die();
|
3565 |
+
}
|
3566 |
+
}
|
3567 |
|
3568 |
+
if ($_POST['action'] == 'wplc_record_chat_rating' ) {
|
3569 |
+
$rating_id = sanitize_text_field($_POST['cid']);
|
3570 |
+
$rating_score = sanitize_text_field($_POST['rating']);
|
3571 |
+
$u_id_check=0;
|
3572 |
+
if (wplc_check_user_request($_POST['cid'])) {
|
3573 |
+
$u_id_check = 1;
|
3574 |
+
}
|
3575 |
+
if ($u_id_check === 1) {
|
3576 |
+
if (!filter_var($rating_id, FILTER_VALIDATE_INT)) {
|
3577 |
+
/* We need to identify if this CID is a node CID, and if so, return the WP CID */
|
3578 |
+
$rating_id = wplc_return_chat_id_by_rel($rating_id);
|
3579 |
+
}
|
3580 |
+
$nifty_record_rating = nifty_record_rating_mrg($rating_id, $rating_score);
|
3581 |
+
if ($nifty_record_rating) {
|
3582 |
+
echo 'rating added';
|
3583 |
+
} else {
|
3584 |
+
echo "There was an error sending your chat message. Please contact support";
|
3585 |
+
}
|
3586 |
+
wp_die();
|
3587 |
+
} else {
|
3588 |
+
echo "There was an error sending your chat rating. Please contact support";
|
3589 |
+
wp_die();
|
3590 |
+
}
|
3591 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3592 |
}
|
3593 |
|
3594 |
/**
|
3596 |
* @return void
|
3597 |
* @since 1.0.00
|
3598 |
*/
|
3599 |
+
function wplc_maa_set_agents_online($user_id) {
|
3600 |
+
if (wplc_user_is_agent($user_id)) {
|
3601 |
+
wplc_update_agent_time($user_id);
|
3602 |
+
}
|
3603 |
+
wplc_check_agents_timeout();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3604 |
}
|
3605 |
|
|
|
3606 |
/* WPLC Social Icons Filter*/
|
3607 |
// add_filter("wplc_filter_chat_header_above","wplc_chat_social_div_mrg",5,2);
|
3608 |
// add_filter("wplc_filter_chat_4th_layer_below_input","wplc_chat_social_div_mrg",5,2);
|
3830 |
|
3831 |
|
3832 |
add_filter('wplc_reporting_tab_content', 'wplc_reporting_tab_content_filter_experience_ratings_control_mrg', 10, 1);
|
3833 |
+
function wplc_reporting_tab_content_filter_experience_ratings_control_mrg($tabs_array) {
|
3834 |
+
$ratings = "<h3>".__("Agent Statistics", 'wp-live-chat-support')."</h3>";
|
3835 |
+
$user_array = wplc_get_agent_users();
|
3836 |
+
$ratings .= "<style>";
|
3837 |
+
$ratings .= ".wplc_agent_grav_report { display:inline-block; }";
|
3838 |
+
$ratings .= ".wplc_agent_card_details { display:inline-block; margin-left: 5px;}";
|
3839 |
+
$ratings .= ".wplc_agent_card { width:100%; }";
|
3840 |
+
$ratings .= ".wplc_agent_container {
|
3841 |
+
width: 30%;
|
3842 |
+
padding: 5px;
|
3843 |
+
border-radius: 7px;
|
3844 |
+
box-shadow: 0px 0px 5px 2px #9999992b;
|
3845 |
+
display: inline-block;
|
3846 |
+
margin-right: 13px;
|
3847 |
+
vertical-align: top;
|
3848 |
+
margin-bottom:10px;
|
3849 |
+
}";
|
3850 |
+
$ratings .= ".wplc_agent_data {
|
3851 |
+
max-height: 200px;
|
3852 |
+
overflow-y: auto;
|
3853 |
+
padding: 5px;
|
3854 |
+
border: 1px lightgrey solid;
|
3855 |
+
}";
|
3856 |
+
$ratings .= "</style>";
|
3857 |
+
|
3858 |
+
foreach ($user_array as $user) {
|
3859 |
+
$ratings .= "<div class='wplc_agent_container'>";
|
3860 |
+
$rating_stats = nifty_get_rating_report_mrg($user->ID);
|
3861 |
+
$ratings .= "<div class='wplc_agent_card'>";
|
3862 |
+
$ratings .= "<img class='wplc_agent_grav_report' src=\"//www.gravatar.com/avatar/" . md5($user->user_email) . "?s=80&d=mm\" />";
|
3863 |
+
$ratings .= "<div class='wplc_agent_card_details'>";
|
3864 |
+
$ratings .= "<strong>" . $user->display_name . "</strong><br>";
|
3865 |
+
$ratings .= "<small>" . $user->user_email . "</small><br>";
|
3866 |
+
$ratings .= "<hr>";
|
3867 |
+
$ratings .= "<small><strong>".__("Satisfaction Rating", 'wp-live-chat-support').":</strong> " . (is_bool($rating_stats) && $rating_stats == false ? "--" : $rating_stats['percentage'] ). "%</small><br>";
|
3868 |
+
$ratings .= "<small><strong>".__("Rating Count", 'wp-live-chat-support').":</strong> " . (is_bool($rating_stats) && $rating_stats == false ? "0" : $rating_stats['total_ratings'])." (".__("Good",'wp-live-chat-support').": ".(is_bool($rating_stats) && $rating_stats == false ? "0" : $rating_stats['good_count']). " || ".__("Bad",'wp-live-chat-support').": ".(is_bool($rating_stats) && $rating_stats == false ? "0" : $rating_stats['bad_count']). ")</small>";
|
3869 |
+
$ratings .= "</div>";
|
3870 |
+
$ratings .= "</div>";
|
3871 |
+
$ratings .= "</div>";
|
3872 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3873 |
|
3874 |
+
$rating_stats = nifty_get_rating_report_mrg(0);
|
3875 |
+
if (!empty($rating_stats[0]) && $rating_stats[0] !== false) {
|
3876 |
+
$ratings .= "<div class='wplc_agent_container'>";
|
3877 |
+
$ratings .= "<div class='wplc_agent_card'>";
|
3878 |
+
$ratings .= "<div class='wplc_agent_card_details'>";
|
3879 |
+
$ratings .= "<strong>No Agent</strong><br>";
|
3880 |
+
$ratings .= "<small>Reviewed before agent joined, or with multiple agents</small><br>";
|
3881 |
+
$ratings .= "<hr>";
|
3882 |
+
$ratings .= "<small><strong>".__("Satisfaction Rating", 'wp-live-chat-support').":</strong> " . (is_bool($rating_stats) && $rating_stats == false ? "--" : $rating_stats['percentage'] ). "%</small><br>";
|
3883 |
+
$ratings .= "<small><strong>".__("Rating Count", 'wp-live-chat-support').":</strong> " . (is_bool($rating_stats) && $rating_stats == false ? "0" : $rating_stats['total_ratings'])." (".__("Good",'wp-live-chat-support').": ".(is_bool($rating_stats) && $rating_stats == false ? "0" : $rating_stats['good_count']). " || ".__("Bad",'wp-live-chat-support').": ".(is_bool($rating_stats) && $rating_stats == false ? "0" : $rating_stats['bad_count']). ")</small>";
|
3884 |
+
$ratings .= "</div>";
|
3885 |
+
$ratings .= "</div>";
|
3886 |
+
$ratings .= "</div>";
|
3887 |
+
}
|
3888 |
|
3889 |
+
$tabs_array['ux_ratings'] = $ratings;
|
3890 |
+
return $tabs_array;
|
3891 |
}
|
3892 |
|
3893 |
add_action('admin_enqueue_scripts', 'wplc_reporting_scripts_mrg');
|
4520 |
function wplc_register_common_node() {
|
4521 |
global $wplc_allowed_extensions;
|
4522 |
$wplc_settings = wplc_get_options();
|
4523 |
+
wp_register_script('wplc-admin-js-agent-common', WPLC_PLUGIN_URL.'js/wplc_common_node.js', null, WPLC_PLUGIN_VERSION, false);
|
4524 |
$current_user=wp_get_current_user();
|
4525 |
$date_days=array();
|
4526 |
for($i=0;$i<7;$i++) {
|
4929 |
return $wplc_settings;
|
4930 |
}
|
4931 |
|
4932 |
+
function wplc_ajax_generate_new_tokens() {
|
4933 |
+
if (isset($_POST['action']) && ($_POST['action'] === "wplc_generate_new_node_token" || $_POST['action'] === "wplc_new_secret_key") && isset($_POST['nonce']) && wplc_user_is_agent()) {
|
4934 |
+
$nonce = $_POST['nonce'];
|
4935 |
+
$action = $_POST['action'];
|
4936 |
+
$error = false;
|
4937 |
+
switch($action) {
|
4938 |
+
case 'wplc_generate_new_node_token':
|
4939 |
+
if (wp_verify_nonce( $nonce, 'generate_new_token')) {
|
4940 |
+
$res = wplc_node_server_token_get(true);
|
4941 |
+
echo $res;
|
4942 |
+
} else {
|
4943 |
+
$error = true;
|
4944 |
+
}
|
4945 |
+
break;
|
4946 |
+
|
4947 |
+
case 'wplc_new_secret_key':
|
4948 |
+
if (wp_verify_nonce( $nonce, 'generate_new_secret_token')) {
|
4949 |
+
$user_token = wplc_api_s_key_create();
|
4950 |
+
update_option("wplc_api_secret_token", $user_token);
|
4951 |
+
echo $user_token;
|
4952 |
+
} else {
|
4953 |
+
$error = true;
|
4954 |
+
}
|
4955 |
+
break;
|
4956 |
+
}
|
4957 |
+
if ($error) {
|
4958 |
+
_e("You do not have permission to perform this action",'wp-live-chat-support');
|
4959 |
+
}
|
4960 |
+
} else {
|
4961 |
+
_e("You do not have permission to perform this action",'wp-live-chat-support');
|
4962 |
+
}
|
4963 |
+
wp_die();
|
4964 |
+
}
|
4965 |
+
|
4966 |
+
// **********************************
|
4967 |
+
// Agents functions
|
4968 |
+
// **********************************
|
4969 |
+
|
4970 |
+
/**
|
4971 |
+
* Checks if specified user is an agent. Default is get_current_user_id
|
4972 |
+
* @return bool
|
4973 |
+
*/
|
4974 |
+
function wplc_user_is_agent($uid=0) {
|
4975 |
+
if (empty($uid)) {
|
4976 |
+
$uid=get_current_user_id();
|
4977 |
+
}
|
4978 |
+
return !empty(get_user_meta(intval($uid), 'wplc_ma_agent', true));
|
4979 |
+
}
|
4980 |
+
|
4981 |
+
/**
|
4982 |
+
* Returns a list of users with agent attribute
|
4983 |
+
* @return array(WPuser)
|
4984 |
+
*/
|
4985 |
+
function wplc_get_agent_users() {
|
4986 |
+
return get_users(array('meta_key' => 'wplc_ma_agent'));
|
4987 |
+
}
|
4988 |
+
|
4989 |
+
/**
|
4990 |
+
* Returns a list of online agents
|
4991 |
+
* @return array(WPuser)
|
4992 |
+
*/
|
4993 |
+
function wplc_get_online_agent_users() {
|
4994 |
+
$agents = wplc_internal_get_all_agents_users_online();
|
4995 |
+
$online_agents = array();
|
4996 |
+
foreach($agents as $v) {
|
4997 |
+
if (wplc_get_agent_accepting($v->ID)) {
|
4998 |
+
$online_agents[]=$v;
|
4999 |
+
}
|
5000 |
+
}
|
5001 |
+
return $online_agents;
|
5002 |
+
}
|
5003 |
+
|
5004 |
+
function wplc_update_agent_time($uid=0) {
|
5005 |
+
if (empty($uid)) {
|
5006 |
+
$uid=get_current_user_id();
|
5007 |
+
}
|
5008 |
+
update_user_meta($uid, "wplc_chat_agent_online", time());
|
5009 |
+
}
|
5010 |
+
|
5011 |
+
/**
|
5012 |
+
* Checks if a specified agent is online. Default is get_current_user_id
|
5013 |
+
* @return bool
|
5014 |
+
*/
|
5015 |
+
function wplc_agent_is_online($uid) {
|
5016 |
+
$agents = wplc_get_online_agent_users();
|
5017 |
+
foreach($agents as $agent) {
|
5018 |
+
if ($agent->ID == $uid) {
|
5019 |
+
return true;
|
5020 |
+
}
|
5021 |
+
}
|
5022 |
+
return false;
|
5023 |
+
}
|
5024 |
+
|
5025 |
+
// return number of online agents
|
5026 |
+
function wplc_get_online_agent_users_count() {
|
5027 |
+
return count(wplc_get_online_agent_users());
|
5028 |
+
}
|
5029 |
+
|
5030 |
+
/**
|
5031 |
+
* Checks if there at least one agent online
|
5032 |
+
* @return bool
|
5033 |
+
*/
|
5034 |
+
function wplc_one_agent_is_online() {
|
5035 |
+
return wplc_get_online_agent_users_count()>0;
|
5036 |
+
}
|
5037 |
+
|
5038 |
+
// check if agents are really online by checking heartbeat on wplc_chat_agent_online meta
|
5039 |
+
function wplc_check_agents_timeout() {
|
5040 |
+
$agents = wplc_get_agent_users();
|
5041 |
+
foreach ($agents as $user) {
|
5042 |
+
$check = get_user_meta($user->ID, "wplc_chat_agent_online");
|
5043 |
+
if (isset($check[0])) {
|
5044 |
+
$last_logged_in_time = $check[0];
|
5045 |
+
if ($last_logged_in_time > 0) {
|
5046 |
+
if ((time() - $last_logged_in_time) < 120) {
|
5047 |
+
/* do nothing, they are online */
|
5048 |
+
} else {
|
5049 |
+
/* this user has not sent a heartbeat in over 120 seconds */
|
5050 |
+
delete_user_meta($user->ID, "wplc_chat_agent_online");
|
5051 |
+
}
|
5052 |
+
}
|
5053 |
+
}
|
5054 |
+
}
|
5055 |
+
}
|
5056 |
+
|
5057 |
+
function wplc_get_online_agents_list() {
|
5058 |
+
$agents = wplc_internal_get_all_agents_users_online();
|
5059 |
+
$accepting = wplc_internal_get_all_agents_accepting();
|
5060 |
+
$result = array();
|
5061 |
+
foreach($agents as $agent) {
|
5062 |
+
if (!empty($accepting[$agent->ID])) {
|
5063 |
+
$result[]=array('name'=> $agent->display_name);
|
5064 |
+
}
|
5065 |
+
}
|
5066 |
+
return $result;
|
5067 |
+
}
|
5068 |
+
|
5069 |
+
function wplc_get_agent_accepting($uid=0) {
|
5070 |
+
if (empty($uid)) {
|
5071 |
+
$uid=get_current_user_id();
|
5072 |
+
}
|
5073 |
$wplc_settings = wplc_get_options();
|
5074 |
+
$choose_array = wplc_internal_get_all_agents_accepting();
|
5075 |
if (!isset($choose_array[$uid])) {
|
5076 |
$choose_array[$uid]=true;
|
5077 |
update_option("WPLC_CHOOSE_ACCEPTING", $choose_array);
|
5083 |
return $choose_array[$uid];
|
5084 |
}
|
5085 |
|
5086 |
+
function wplc_set_agent_accepting($uid, $online) {
|
5087 |
+
$choose_array = wplc_internal_get_all_agents_accepting();
|
5088 |
if (!isset($choose_array[$uid]) || $choose_array[$uid]!=boolval($online)) {
|
5089 |
$choose_array[$uid]=boolval($online);
|
5090 |
update_option("WPLC_CHOOSE_ACCEPTING", $choose_array);
|
5091 |
}
|
5092 |
}
|
5093 |
|
5094 |
+
function wplc_internal_get_all_agents_accepting() {
|
5095 |
$choose_array = get_option("WPLC_CHOOSE_ACCEPTING");
|
5096 |
if (!is_array($choose_array)) {
|
5097 |
$choose_array = array();
|
5099 |
return $choose_array;
|
5100 |
}
|
5101 |
|
5102 |
+
function wplc_internal_get_all_agents_users_online() {
|
5103 |
+
$agents = get_users(array('meta_key'=> 'wplc_chat_agent_online'));
|
5104 |
+
if (!is_array($agents)) {
|
5105 |
+
$agents = array();
|
5106 |
+
}
|
5107 |
+
return $agents;
|
5108 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/dashboard_page.php
CHANGED
@@ -46,7 +46,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
46 |
<div class="wplc_panel_heading"><i class="fa fa-tasks" aria-hidden="true"></i> <?php _e("Dashboard",'wp-live-chat-support'); ?></div>
|
47 |
<div class="wplc_material_panel">
|
48 |
<div class="wplc_dashboard_activity">
|
49 |
-
<h3><?php printf( __( 'Hi %s! Current activity: %s Active Visitor(s) and %s Active Agent(s).', 'wp-live-chat-support'), $user->display_name, '<span id=\'totalVisitors\' class="wplc_dashboard_activity_numbers">...</span>', '<span class="wplc_dashboard_activity_numbers">'.
|
50 |
</div>
|
51 |
<div class="wplc_panel_col wplc_dashboard_buttons_outer">
|
52 |
<div class="wplc_dashboard_button_item">
|
46 |
<div class="wplc_panel_heading"><i class="fa fa-tasks" aria-hidden="true"></i> <?php _e("Dashboard",'wp-live-chat-support'); ?></div>
|
47 |
<div class="wplc_material_panel">
|
48 |
<div class="wplc_dashboard_activity">
|
49 |
+
<h3><?php printf( __( 'Hi %s! Current activity: %s Active Visitor(s) and %s Active Agent(s).', 'wp-live-chat-support'), $user->display_name, '<span id=\'totalVisitors\' class="wplc_dashboard_activity_numbers">...</span>', '<span class="wplc_dashboard_activity_numbers">'.wplc_get_online_agent_users_count().'</span>'); ?></h3>
|
50 |
</div>
|
51 |
<div class="wplc_panel_col wplc_dashboard_buttons_outer">
|
52 |
<div class="wplc_dashboard_button_item">
|
includes/settings_page.php
CHANGED
@@ -185,14 +185,6 @@ $wplc_settings = wplc_get_options();
|
|
185 |
<textarea cols="45" rows="5" name="wplc_user_alternative_text" ><?php echo esc_textarea($wplc_settings['wplc_user_alternative_text']); ?></textarea>
|
186 |
</td>
|
187 |
</tr>
|
188 |
-
<tr>
|
189 |
-
<td width='300' valign='top'>
|
190 |
-
<?php _e("Use Logged In User Details",'wp-live-chat-support')?>: <i class="fa fa-question-circle wplc_light_grey wplc_settings_tooltip" title="<?php _e("A user's Name and Email Address will be used by default if they are logged in.", 'wp-live-chat-support') ?>"></i>
|
191 |
-
</td>
|
192 |
-
<td valign='top'>
|
193 |
-
<input type="checkbox" value="1" name="wplc_loggedin_user_info"<?php echo ($wplc_settings['wplc_loggedin_user_info'] ? ' checked' : '');?> />
|
194 |
-
</td>
|
195 |
-
</tr>
|
196 |
<tr>
|
197 |
<td width='200' valign='top'>
|
198 |
<?php _e("Enable On Mobile Devices","wplivechat"); ?>: <i class="fa fa-question-circle wplc_light_grey wplc_settings_tooltip" title="<?php _e("Disabling this will mean that the Chat Box will not be displayed on mobile devices. (Smartphones and Tablets)", "wplivechat") ?>"></i>
|
@@ -414,6 +406,21 @@ $wplc_settings = wplc_get_options();
|
|
414 |
</select>
|
415 |
</td>
|
416 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
417 |
<tr>
|
418 |
<td width='300'>
|
419 |
<?php _e("Automatic Chatbox Pop-Up",'wp-live-chat-support') ?> <i class="fa fa-question-circle wplc_light_grey wplc_settings_tooltip" title="<?php _e("Expand the chat box automatically (prompts the user to enter their name and email address).",'wp-live-chat-support') ?>"></i>
|
@@ -454,6 +461,14 @@ $wplc_settings = wplc_get_options();
|
|
454 |
<input type="checkbox" name="wplc_display_to_loggedin_only" value="1"<?php echo ($wplc_settings['wplc_display_to_loggedin_only'] ? ' checked' : ''); ?>/>
|
455 |
</td>
|
456 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
457 |
<tr>
|
458 |
<td>
|
459 |
<?php _e("Display a timestamp in the chat window:", 'wp-live-chat-support') ?>
|
@@ -484,7 +499,7 @@ $wplc_settings = wplc_get_options();
|
|
484 |
</td>
|
485 |
<td>
|
486 |
<input type="checkbox" name="wplc_disable_emojis"<?php if ($wplc_settings['wplc_disable_emojis']) {echo ' checked="checked"';} ?>/>
|
487 |
-
|
488 |
<?php
|
489 |
}
|
490 |
?>
|
@@ -583,7 +598,6 @@ $wplc_settings = wplc_get_options();
|
|
583 |
<input id="wplc_btn_upload_icon" name="wplc_btn_upload_icon" type="button" value="<?php _e("Upload Icon", 'wp-live-chat-support') ?>" />
|
584 |
<input id="wplc_btn_select_default_icon" name="wplc_btn_select_default_icon" type="button" value="<?php _e("Select Default Icon", 'wp-live-chat-support') ?>" />
|
585 |
<br/>
|
586 |
-
<input id="wplc_btn_remove_icon" name="wplc_btn_remove_icon" type="button" value="<?php _e("Remove Icon", 'wp-live-chat-support') ?>" />
|
587 |
<?php _e("Recommended Size 50px x 50px", 'wp-live-chat-support') ?>
|
588 |
|
589 |
<div id="wplc_default_chat_icons" style="display: none">
|
@@ -630,14 +644,16 @@ $wplc_settings = wplc_get_options();
|
|
630 |
<?php _e("Picture", 'wp-live-chat-support') ?>:
|
631 |
</td>
|
632 |
<td>
|
633 |
-
<div style="display:block" id="wplc_pic_area">
|
634 |
<img src="<?php echo urldecode($wplc_settings['wplc_chat_pic']); ?>" width="60px"/>
|
635 |
</div>
|
636 |
<input id="wplc_upload_pic" name="wplc_upload_pic" type="hidden" size="35" class="regular-text" maxlength="700" value=""/>
|
637 |
<br/>
|
638 |
-
|
|
|
|
|
639 |
<br/>
|
640 |
-
<input id="wplc_btn_remove_pic" name="wplc_btn_remove_pic" type="button" value="<?php _e("Remove Image", 'wp-live-chat-support') ?>" />
|
641 |
<?php _e("Recommended Size 60px x 60px", 'wp-live-chat-support') ?>
|
642 |
</td>
|
643 |
</tr>
|
@@ -655,7 +671,7 @@ $wplc_settings = wplc_get_options();
|
|
655 |
<br/>
|
656 |
<input id="wplc_btn_upload_logo" name="wplc_btn_upload_logo" type="button" value="<?php _e("Upload Logo", 'wp-live-chat-support') ?>" />
|
657 |
<br/>
|
658 |
-
<input id="wplc_btn_remove_logo" name="wplc_btn_remove_logo" type="button" value="<?php _e("Remove Logo", 'wp-live-chat-support') ?>" />
|
659 |
<?php _e("Recommended Size 250px x 40px", 'wp-live-chat-support') ?>
|
660 |
</td>
|
661 |
</tr>
|
@@ -1152,37 +1168,31 @@ $wplc_settings = wplc_get_options();
|
|
1152 |
|
1153 |
|
1154 |
<?php
|
1155 |
-
|
1156 |
-
$user_array = get_users(array(
|
1157 |
-
'meta_key' => 'wplc_ma_agent',
|
1158 |
-
));
|
1159 |
|
1160 |
echo "<h3>".__('Chat Agents', 'wp-live-chat-support')."</h3>";
|
1161 |
|
1162 |
$wplc_agents = "<div class='wplc_agent_container'><ul>";
|
1163 |
|
1164 |
-
|
1165 |
-
foreach ($user_array as $user) {
|
1166 |
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
$wplc_agents .= "<small>" . esc_html($user->user_email) . "</small>";
|
1176 |
|
1177 |
-
|
1178 |
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
}
|
1186 |
echo $wplc_agents;
|
1187 |
?>
|
1188 |
<li style='width:150px;' id='wplc_add_new_agent_box'>
|
@@ -1194,20 +1204,17 @@ $wplc_settings = wplc_get_options();
|
|
1194 |
$blogusers = get_users( array( 'role' => 'administrator', 'fields' => array( 'display_name','ID','user_email' ) ) );
|
1195 |
// Array of stdClass objects.
|
1196 |
foreach ( $blogusers as $user ) {
|
1197 |
-
$
|
1198 |
-
if(!$is_agent){ echo '<option id="wplc_selected_agent_'. intval( $user->ID ) .'" em="' . md5(sanitize_email( $user->user_email )) . '" uid="' . intval( $user->ID ) . '" em2="' . esc_attr( $user->user_email ) . '" name="' . esc_attr( $user->display_name ) . '" value="' . intval( $user->ID ) . '">' . esc_html( $user->display_name ) . ' ('.__('Administrator','wp-live-chat-support').')</option>'; }
|
1199 |
}
|
1200 |
$blogusers = get_users( array( 'role' => 'editor', 'fields' => array( 'display_name','ID','user_email' ) ) );
|
1201 |
// Array of stdClass objects.
|
1202 |
foreach ( $blogusers as $user ) {
|
1203 |
-
$
|
1204 |
-
if(!$is_agent){ echo '<option id="wplc_selected_agent_'. intval( $user->ID ) .'" em="' . md5(sanitize_email( $user->user_email )) . '" uid="' . intval( $user->ID ) . '" em2="' . esc_attr( $user->user_email ) . '" name="' . esc_attr( $user->display_name ) . '" value="' . intval( $user->ID ) . '">' . esc_html( $user->display_name ) . ' ('.__('Editor','wp-live-chat-support').')</option>'; }
|
1205 |
}
|
1206 |
$blogusers = get_users( array( 'role' => 'author', 'fields' => array( 'display_name','ID','user_email' ) ) );
|
1207 |
// Array of stdClass objects.
|
1208 |
foreach ( $blogusers as $user ) {
|
1209 |
-
$
|
1210 |
-
if(!$is_agent){ echo '<option id="wplc_selected_agent_'. intval( $user->ID ) .'" em="' . md5(sanitize_email( $user->user_email )) . '" uid="' . intval( $user->ID ) . '" em2="' . esc_attr( $user->user_email ) . '" name="' . esc_attr( $user->display_name ) . '" value="' . intval( $user->ID ) . '">' . esc_html( $user->display_name ) . ' ('.__('Author','wp-live-chat-support').')</option>'; }
|
1211 |
}
|
1212 |
?>
|
1213 |
</select>
|
185 |
<textarea cols="45" rows="5" name="wplc_user_alternative_text" ><?php echo esc_textarea($wplc_settings['wplc_user_alternative_text']); ?></textarea>
|
186 |
</td>
|
187 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
<tr>
|
189 |
<td width='200' valign='top'>
|
190 |
<?php _e("Enable On Mobile Devices","wplivechat"); ?>: <i class="fa fa-question-circle wplc_light_grey wplc_settings_tooltip" title="<?php _e("Disabling this will mean that the Chat Box will not be displayed on mobile devices. (Smartphones and Tablets)", "wplivechat") ?>"></i>
|
406 |
</select>
|
407 |
</td>
|
408 |
</tr>
|
409 |
+
<tr>
|
410 |
+
<td>
|
411 |
+
<?php
|
412 |
+
_e('Chat box height (percent of the page)', 'wp-live-chat-support');
|
413 |
+
?>
|
414 |
+
</td>
|
415 |
+
<td>
|
416 |
+
<select id='wplc_chatbox_height' name='wplc_chatbox_height'>
|
417 |
+
<?php
|
418 |
+
for($i=30;$i<90;$i=$i+10) {
|
419 |
+
echo '<option value="'.$i.'" '.($wplc_settings['wplc_chatbox_height']==$i ? 'selected' : '').'>'.$i.'%</option>';
|
420 |
+
}
|
421 |
+
?>
|
422 |
+
</select>
|
423 |
+
</tr>
|
424 |
<tr>
|
425 |
<td width='300'>
|
426 |
<?php _e("Automatic Chatbox Pop-Up",'wp-live-chat-support') ?> <i class="fa fa-question-circle wplc_light_grey wplc_settings_tooltip" title="<?php _e("Expand the chat box automatically (prompts the user to enter their name and email address).",'wp-live-chat-support') ?>"></i>
|
461 |
<input type="checkbox" name="wplc_display_to_loggedin_only" value="1"<?php echo ($wplc_settings['wplc_display_to_loggedin_only'] ? ' checked' : ''); ?>/>
|
462 |
</td>
|
463 |
</tr>
|
464 |
+
<tr>
|
465 |
+
<td width='300' valign='top'>
|
466 |
+
<?php _e("Use Logged In User Details",'wp-live-chat-support')?>: <i class="fa fa-question-circle wplc_light_grey wplc_settings_tooltip" title="<?php _e("A user's Name and Email Address will be used by default if they are logged in.", 'wp-live-chat-support') ?>"></i>
|
467 |
+
</td>
|
468 |
+
<td valign='top'>
|
469 |
+
<input type="checkbox" value="1" name="wplc_loggedin_user_info"<?php echo ($wplc_settings['wplc_loggedin_user_info'] ? ' checked' : '');?> />
|
470 |
+
</td>
|
471 |
+
</tr>
|
472 |
<tr>
|
473 |
<td>
|
474 |
<?php _e("Display a timestamp in the chat window:", 'wp-live-chat-support') ?>
|
499 |
</td>
|
500 |
<td>
|
501 |
<input type="checkbox" name="wplc_disable_emojis"<?php if ($wplc_settings['wplc_disable_emojis']) {echo ' checked="checked"';} ?>/>
|
502 |
+
</tr>
|
503 |
<?php
|
504 |
}
|
505 |
?>
|
598 |
<input id="wplc_btn_upload_icon" name="wplc_btn_upload_icon" type="button" value="<?php _e("Upload Icon", 'wp-live-chat-support') ?>" />
|
599 |
<input id="wplc_btn_select_default_icon" name="wplc_btn_select_default_icon" type="button" value="<?php _e("Select Default Icon", 'wp-live-chat-support') ?>" />
|
600 |
<br/>
|
|
|
601 |
<?php _e("Recommended Size 50px x 50px", 'wp-live-chat-support') ?>
|
602 |
|
603 |
<div id="wplc_default_chat_icons" style="display: none">
|
644 |
<?php _e("Picture", 'wp-live-chat-support') ?>:
|
645 |
</td>
|
646 |
<td>
|
647 |
+
<div style="display:block" id="wplc_pic_area" default="<?php echo $wplc_default_settings_array['wplc_chat_pic'];?>">
|
648 |
<img src="<?php echo urldecode($wplc_settings['wplc_chat_pic']); ?>" width="60px"/>
|
649 |
</div>
|
650 |
<input id="wplc_upload_pic" name="wplc_upload_pic" type="hidden" size="35" class="regular-text" maxlength="700" value=""/>
|
651 |
<br/>
|
652 |
+
<input id="wplc_btn_upload_pic" name="wplc_btn_upload_pic" type="button" value="<?php _e("Upload Image", 'wp-live-chat-support') ?>" />
|
653 |
+
<input id="wplc_btn_select_default_pic" name="wplc_btn_select_default_pic" type="button" value="<?php _e("Select Default Image", 'wp-live-chat-support') ?>" />
|
654 |
+
|
655 |
<br/>
|
656 |
+
<input id="wplc_btn_remove_pic" name="wplc_btn_remove_pic" type="button" value="<?php _e("Remove Image", 'wp-live-chat-support') ?>" /><br/>
|
657 |
<?php _e("Recommended Size 60px x 60px", 'wp-live-chat-support') ?>
|
658 |
</td>
|
659 |
</tr>
|
671 |
<br/>
|
672 |
<input id="wplc_btn_upload_logo" name="wplc_btn_upload_logo" type="button" value="<?php _e("Upload Logo", 'wp-live-chat-support') ?>" />
|
673 |
<br/>
|
674 |
+
<input id="wplc_btn_remove_logo" name="wplc_btn_remove_logo" type="button" value="<?php _e("Remove Logo", 'wp-live-chat-support') ?>" /><br/>
|
675 |
<?php _e("Recommended Size 250px x 40px", 'wp-live-chat-support') ?>
|
676 |
</td>
|
677 |
</tr>
|
1168 |
|
1169 |
|
1170 |
<?php
|
1171 |
+
$user_array = wplc_get_agent_users();
|
|
|
|
|
|
|
1172 |
|
1173 |
echo "<h3>".__('Chat Agents', 'wp-live-chat-support')."</h3>";
|
1174 |
|
1175 |
$wplc_agents = "<div class='wplc_agent_container'><ul>";
|
1176 |
|
1177 |
+
foreach ($user_array as $user) {
|
|
|
1178 |
|
1179 |
+
$wplc_agents .= "<li id=\"wplc_agent_li_".$user->ID."\">";
|
1180 |
+
$wplc_agents .= "<p><img src=\"//www.gravatar.com/avatar/" . md5($user->user_email) . "?s=60&d=mm\" /></p>";
|
1181 |
+
if (wplc_agent_is_online($user->ID)) {
|
1182 |
+
$wplc_agents .= "<span class='wplc_status_box wplc_type_returning'>".__("Logged In",'wp-live-chat-support')."</span>";
|
1183 |
+
}
|
1184 |
+
$wplc_agents .= "<h3>" . esc_html($user->display_name) . "</h3>";
|
1185 |
+
|
1186 |
+
$wplc_agents .= "<small>" . esc_html($user->user_email) . "</small>";
|
|
|
1187 |
|
1188 |
+
$wplc_agents .= apply_filters("wplc_pro_agent_list_before_button_filter", "", $user);
|
1189 |
|
1190 |
+
if (get_current_user_id() == $user->ID) {
|
1191 |
+
} else {
|
1192 |
+
$wplc_agents .= "<p><button class='button button-secondary wplc_remove_agent' id='wplc_remove_agent_".$user->ID."' uid='".$user->ID."'>".__("Remove",'wp-live-chat-support')."</button></p>";
|
1193 |
+
}
|
1194 |
+
$wplc_agents .= "</li>";
|
1195 |
+
}
|
|
|
1196 |
echo $wplc_agents;
|
1197 |
?>
|
1198 |
<li style='width:150px;' id='wplc_add_new_agent_box'>
|
1204 |
$blogusers = get_users( array( 'role' => 'administrator', 'fields' => array( 'display_name','ID','user_email' ) ) );
|
1205 |
// Array of stdClass objects.
|
1206 |
foreach ( $blogusers as $user ) {
|
1207 |
+
if (wplc_user_is_agent($user->ID)) {echo '<option id="wplc_selected_agent_'. intval( $user->ID ) .'" em="' . md5(sanitize_email( $user->user_email )) . '" uid="' . intval( $user->ID ) . '" em2="' . esc_attr( $user->user_email ) . '" name="' . esc_attr( $user->display_name ) . '" value="' . intval( $user->ID ) . '">' . esc_html( $user->display_name ) . ' ('.__('Administrator','wp-live-chat-support').')</option>'; }
|
|
|
1208 |
}
|
1209 |
$blogusers = get_users( array( 'role' => 'editor', 'fields' => array( 'display_name','ID','user_email' ) ) );
|
1210 |
// Array of stdClass objects.
|
1211 |
foreach ( $blogusers as $user ) {
|
1212 |
+
if (wplc_user_is_agent($user->ID)) { echo '<option id="wplc_selected_agent_'. intval( $user->ID ) .'" em="' . md5(sanitize_email( $user->user_email )) . '" uid="' . intval( $user->ID ) . '" em2="' . esc_attr( $user->user_email ) . '" name="' . esc_attr( $user->display_name ) . '" value="' . intval( $user->ID ) . '">' . esc_html( $user->display_name ) . ' ('.__('Editor','wp-live-chat-support').')</option>'; }
|
|
|
1213 |
}
|
1214 |
$blogusers = get_users( array( 'role' => 'author', 'fields' => array( 'display_name','ID','user_email' ) ) );
|
1215 |
// Array of stdClass objects.
|
1216 |
foreach ( $blogusers as $user ) {
|
1217 |
+
if (wplc_user_is_agent($user->ID)) { echo '<option id="wplc_selected_agent_'. intval( $user->ID ) .'" em="' . md5(sanitize_email( $user->user_email )) . '" uid="' . intval( $user->ID ) . '" em2="' . esc_attr( $user->user_email ) . '" name="' . esc_attr( $user->display_name ) . '" value="' . intval( $user->ID ) . '">' . esc_html( $user->display_name ) . ' ('.__('Author','wp-live-chat-support').')</option>'; }
|
|
|
1218 |
}
|
1219 |
?>
|
1220 |
</select>
|
includes/wplc_custom_fields.php
CHANGED
@@ -506,52 +506,44 @@ function wplc_custom_field_rest_end_points_mrg(){
|
|
506 |
}
|
507 |
|
508 |
function wplc_custom_field_rest_get_info_mrg(WP_REST_Request $request){
|
509 |
-
|
510 |
-
|
511 |
-
if(isset($request)){
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
$cid = wplc_return_chat_id_by_rel($cid);
|
520 |
-
}
|
521 |
-
|
522 |
-
$html = wplc_advanced_info_custom_fields_mrg("", $cid, "", false);
|
523 |
-
|
524 |
-
$return_array['response'] = "Success";
|
525 |
-
$return_array['code'] = "200";
|
526 |
-
$return_array['data'] = $html;
|
527 |
-
}else {
|
528 |
-
$return_array['response'] = "You do not have permission to perform this action.";
|
529 |
-
$return_array['code'] = "401";
|
530 |
-
$return_array['requirements'] = array("security" => "YOUR_SECRET_TOKEN",
|
531 |
-
"cid" => "Chat ID");
|
532 |
-
}
|
533 |
-
} else {
|
534 |
-
$return_array['response'] = "No 'cid' found";
|
535 |
-
$return_array['code'] = "401";
|
536 |
-
$return_array['requirements'] = array("security" => "YOUR_SECRET_TOKEN",
|
537 |
-
"cid" => "Chat ID");
|
538 |
-
}
|
539 |
-
} else {
|
540 |
-
$return_array['response'] = "Nonce is invalid";
|
541 |
-
$return_array['code'] = "401";
|
542 |
}
|
543 |
-
|
544 |
-
$return_array['response'] = "
|
|
|
|
|
|
|
|
|
545 |
$return_array['code'] = "401";
|
546 |
-
$return_array['requirements'] = array("security" => "YOUR_SECRET_TOKEN",
|
547 |
-
|
|
|
|
|
|
|
|
|
548 |
}
|
549 |
-
|
550 |
-
$return_array['response'] = "
|
551 |
-
$return_array['code'] = "
|
552 |
-
|
553 |
-
|
|
|
|
|
|
|
554 |
}
|
555 |
-
|
556 |
-
|
|
|
|
|
|
|
|
|
557 |
}
|
506 |
}
|
507 |
|
508 |
function wplc_custom_field_rest_get_info_mrg(WP_REST_Request $request){
|
509 |
+
$return_array = array();
|
510 |
+
if (isset($request)) {
|
511 |
+
if (isset($request['security'])) {
|
512 |
+
$check_token = get_option('wplc_api_secret_token');
|
513 |
+
if ($check_token !== false && $request['server_token'] === $check_token) {
|
514 |
+
if (isset($request['cid'])) {
|
515 |
+
if (wplc_user_is_agent()) {
|
516 |
+
$cid = $request['cid'];
|
517 |
+
if (!filter_var($cid, FILTER_VALIDATE_INT)) {
|
518 |
+
$cid = wplc_return_chat_id_by_rel($cid);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
519 |
}
|
520 |
+
$html = wplc_advanced_info_custom_fields_mrg("", $cid, "", false);
|
521 |
+
$return_array['response'] = "Success";
|
522 |
+
$return_array['code'] = "200";
|
523 |
+
$return_array['data'] = $html;
|
524 |
+
} else {
|
525 |
+
$return_array['response'] = "You do not have permission to perform this action.";
|
526 |
$return_array['code'] = "401";
|
527 |
+
$return_array['requirements'] = array("security" => "YOUR_SECRET_TOKEN", "cid" => "Chat ID");
|
528 |
+
}
|
529 |
+
} else {
|
530 |
+
$return_array['response'] = "No 'cid' found";
|
531 |
+
$return_array['code'] = "401";
|
532 |
+
$return_array['requirements'] = array("security" => "YOUR_SECRET_TOKEN", "cid" => "Chat ID");
|
533 |
}
|
534 |
+
} else {
|
535 |
+
$return_array['response'] = "Nonce is invalid";
|
536 |
+
$return_array['code'] = "401";
|
537 |
+
}
|
538 |
+
} else {
|
539 |
+
$return_array['response'] = "No 'security' found";
|
540 |
+
$return_array['code'] = "401";
|
541 |
+
$return_array['requirements'] = array("security" => "YOUR_SECRET_TOKEN", "cid" => "Chat ID");
|
542 |
}
|
543 |
+
} else {
|
544 |
+
$return_array['response'] = "No request data found";
|
545 |
+
$return_array['code'] = "400";
|
546 |
+
$return_array['requirements'] = array("security" => "YOUR_SECRET_TOKEN", "cid" => "Chat ID");
|
547 |
+
}
|
548 |
+
return $return_array;
|
549 |
}
|
includes/wplc_departments.php
CHANGED
@@ -73,36 +73,35 @@ add_action("wplc_pro_custom_user_profile_field_after_content_hook", "wplc_mrg_de
|
|
73 |
* @return void
|
74 |
*/
|
75 |
function wplc_mrg_department_user_profile_departments($user){
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
}
|
106 |
}
|
107 |
|
108 |
add_action("wplc_pro_set_user_hook", "wplc_mrg_department_save", 10, 1);
|
73 |
* @return void
|
74 |
*/
|
75 |
function wplc_mrg_department_user_profile_departments($user){
|
76 |
+
if (wplc_user_is_agent($user->ID)) {
|
77 |
+
$selected_department = intval(get_user_meta($user->ID, "wplc_user_department", true));
|
78 |
+
if (current_user_can('manage_options', array(null))) {
|
79 |
+
?>
|
80 |
+
<table class="form-table">
|
81 |
+
<tr>
|
82 |
+
<th>
|
83 |
+
<label for="wplc_user_department"><?php _e('Chat Department', 'wp-live-chat-support'); ?></label>
|
84 |
+
</th>
|
85 |
+
<td>
|
86 |
+
<select id="wplc_user_department" name="wplc_user_department">
|
87 |
+
<option value="-1"><?php _e("No Department", 'wp-live-chat-support'); ?></option>
|
88 |
+
<?php
|
89 |
+
$departments = wplc_get_all_deparments_mrg();
|
90 |
+
if ($departments) {
|
91 |
+
foreach($departments as $dep) {
|
92 |
+
?>
|
93 |
+
<option value="<?php echo $dep->id;?>" <?php echo ($selected_department === intval($dep->id) ? "SELECTED" : "" ); ?> ><?php echo sanitize_text_field($dep->name); ?></option>
|
94 |
+
<?php
|
95 |
+
}
|
96 |
+
}
|
97 |
+
?>
|
98 |
+
</select>
|
99 |
+
</td>
|
100 |
+
</tr>
|
101 |
+
</table>
|
102 |
+
<?php
|
103 |
+
}
|
104 |
+
}
|
|
|
105 |
}
|
106 |
|
107 |
add_action("wplc_pro_set_user_hook", "wplc_mrg_department_save", 10, 1);
|
includes/wplc_transfer_chats.php
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
-
<?php
|
2 |
/*
|
3 |
* Handles the transferring of a chat
|
4 |
*/
|
5 |
|
6 |
-
if (
|
7 |
-
|
8 |
}
|
9 |
|
10 |
add_filter("wplc_admin_chat_area_before_end_chat_button", "wplc_mrg_admin_transfer_tools", 15, 1);
|
@@ -12,9 +12,10 @@ add_filter("wplc_admin_chat_area_before_end_chat_button", "wplc_mrg_admin_transf
|
|
12 |
* Outputs (echo) the 'Transfer' button
|
13 |
*
|
14 |
* @return void
|
15 |
-
*/
|
16 |
-
function wplc_mrg_admin_transfer_tools($chat_data)
|
17 |
-
|
|
|
18 |
}
|
19 |
|
20 |
|
@@ -23,88 +24,89 @@ add_filter("wplc_hook_admin_below_chat_box", "wplc_mrg_admin_transfer_tools_moda
|
|
23 |
* Outputs (echo) the 'Transfer' modal
|
24 |
*
|
25 |
* @return void
|
26 |
-
*/
|
27 |
-
function wplc_mrg_admin_transfer_tools_modals($chat_data)
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
|
|
34 |
}
|
35 |
|
36 |
/**
|
37 |
* Returns content for the transfer Modal
|
38 |
*
|
39 |
* @return string (html)
|
40 |
-
*/
|
41 |
-
function wplc_mrg_admin_transfer_tools_modal_content($chat_data)
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
|
|
66 |
}
|
67 |
|
68 |
/**
|
69 |
* Returns dropdown (html) of all online agent
|
70 |
*
|
71 |
* @return string (html)
|
72 |
-
*/
|
73 |
-
function wplc_mrg_admin_transfer_agent_selection()
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
$content .= "<select>";
|
85 |
-
return $content;
|
86 |
}
|
87 |
|
88 |
/**
|
89 |
* Returns dropdown (html) of all departments agent
|
90 |
*
|
91 |
* @return string (html)
|
92 |
-
*/
|
93 |
-
function wplc_mrg_admin_transfer_department_selection()
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
|
|
108 |
}
|
109 |
|
110 |
|
@@ -112,180 +114,181 @@ function wplc_mrg_admin_transfer_department_selection(){
|
|
112 |
* Outputs inline JavaScript for Transfer Modal
|
113 |
*
|
114 |
* @return void
|
115 |
-
*/
|
116 |
-
function wplc_mrg_admin_transfer_tools_js()
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
|
|
253 |
|
254 |
function wplc_modal_transfer_ajax(req_data, on_succcess, on_error) {
|
255 |
jQuery.ajax({
|
256 |
-
url
|
257 |
-
type
|
258 |
-
data
|
259 |
-
success
|
260 |
-
if(typeof on_succcess === "function"){
|
261 |
-
on_succcess(return_data);
|
262 |
}
|
263 |
},
|
264 |
-
error
|
265 |
-
if(typeof on_error === "function"){
|
266 |
-
on_error();
|
267 |
}
|
268 |
}
|
269 |
});
|
270 |
}
|
271 |
|
272 |
function wplc_modal_transfer_confirm() {
|
273 |
-
if(wplc_online_check_complete) {
|
274 |
-
if(wplc_to_agent !== null) {
|
275 |
<?php
|
276 |
$cid = intval($_GET['cid']);
|
277 |
-
|
278 |
-
if(wplc_to_agent == true) {
|
279 |
//Send to agent
|
280 |
var aid = jQuery("#wplc_transfer_modal_agent_selection").val();
|
281 |
var data = {
|
282 |
-
action
|
283 |
-
cid
|
284 |
-
agent_id
|
285 |
};
|
286 |
-
|
287 |
-
wplc_modal_transfer_ajax(data, function(return_data){
|
288 |
-
if(return_data == "true") {
|
289 |
jQuery("#wplc_transfer_to_agent_check").text(wplc_transfer_complete_string);
|
290 |
setTimeout(function() {
|
291 |
window.close();
|
@@ -293,20 +296,20 @@ function wplc_mrg_admin_transfer_tools_js(){
|
|
293 |
} else {
|
294 |
jQuery("#wplc_transfer_to_agent_check").text(wplc_transfer_fail_string);
|
295 |
}
|
296 |
-
}, function(){
|
297 |
jQuery("#wplc_transfer_to_agent_check").text(wplc_transfer_fail_string);
|
298 |
});
|
299 |
} else {
|
300 |
//Send to department
|
301 |
var depid = jQuery("#wplc_transfer_modal_department_selection").val();
|
302 |
var data = {
|
303 |
-
action
|
304 |
-
cid
|
305 |
-
dep_id
|
306 |
};
|
307 |
|
308 |
-
wplc_modal_transfer_ajax(data, function(return_data){
|
309 |
-
if(return_data == "true") {
|
310 |
jQuery("#wplc_transfer_to_department_check").text(wplc_transfer_complete_string);
|
311 |
setTimeout(function() {
|
312 |
window.close();
|
@@ -314,7 +317,7 @@ function wplc_mrg_admin_transfer_tools_js(){
|
|
314 |
} else {
|
315 |
jQuery("#wplc_transfer_to_department_check").text(wplc_transfer_fail_string);
|
316 |
}
|
317 |
-
}, function(){
|
318 |
jQuery("#wplc_transfer_to_department_check").text(wplc_transfer_fail_string);
|
319 |
});
|
320 |
}
|
@@ -324,27 +327,29 @@ function wplc_mrg_admin_transfer_tools_js(){
|
|
324 |
}
|
325 |
}
|
326 |
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
}
|
334 |
|
335 |
/**
|
336 |
* Outputs inline css for Transfer Modal
|
337 |
*
|
338 |
* @return void
|
339 |
-
*/
|
340 |
-
function wplc_mrg_admin_transfer_tools_css()
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
|
|
|
|
348 |
}
|
349 |
|
350 |
add_filter("wplc_accept_chat_button_filter", "wplc_mrg_admin_accept_chat_button_text", 10, 2);
|
@@ -352,44 +357,45 @@ add_filter("wplc_accept_chat_button_filter", "wplc_mrg_admin_accept_chat_button_
|
|
352 |
* Changes 'Accept Chat' to 'Accept Transfer'
|
353 |
*
|
354 |
* @return string
|
355 |
-
*/
|
356 |
-
function wplc_mrg_admin_accept_chat_button_text($content, $cid)
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
$agent_info = get_userdata(intval($chat_data->agent_id));
|
373 |
-
|
374 |
-
return __("Transfer for", 'wp-live-chat-support') . " " . $agent_info->display_name;
|
375 |
-
} else {
|
376 |
-
//Department
|
377 |
-
return __("Accept Transfer", 'wp-live-chat-support');
|
378 |
-
}
|
379 |
-
} else if ( (isset($other_data['unanswered']) && $other_data['unanswered'] == true) ){
|
380 |
-
// Initial chat request -> Should still check timer
|
381 |
-
if(isset($other_data['agent_transfer_time'])){
|
382 |
-
//Check the time difference
|
383 |
-
$seconds = time() - $other_data['agent_transfer_time'];
|
384 |
-
if(intval($seconds) > $max_wait_time){
|
385 |
-
do_action("wplc_pro_admin_transfer_agent_exceeded_accept_time", $cid, -1); //Transfer to the next agent
|
386 |
-
}
|
387 |
-
}
|
388 |
-
return $content;
|
389 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
390 |
}
|
|
|
391 |
|
392 |
-
|
393 |
}
|
394 |
|
395 |
add_filter("wplc_start_chat_hook_other_data_hook", "wplc_mrg_admin_transfer_add_initial_transfer_time", 10, 1);
|
@@ -397,10 +403,11 @@ add_filter("wplc_start_chat_hook_other_data_hook", "wplc_mrg_admin_transfer_add_
|
|
397 |
* Adds an initial 'agent transfer time' value to the other data of the chat - On Chat Request
|
398 |
*
|
399 |
* @return array
|
400 |
-
*/
|
401 |
-
function wplc_mrg_admin_transfer_add_initial_transfer_time($other_data)
|
402 |
-
|
403 |
-
|
|
|
404 |
}
|
405 |
|
406 |
add_action("wplc_pro_admin_transfer_agent_exceeded_accept_time", "wplc_mrg_admin_transfer_to_next_available_agent", 10, 2);
|
@@ -408,225 +415,226 @@ add_action("wplc_pro_admin_transfer_agent_exceeded_accept_time", "wplc_mrg_admin
|
|
408 |
* Transfers chat to the next available agetn
|
409 |
*
|
410 |
* @return void
|
411 |
-
*/
|
412 |
-
function wplc_mrg_admin_transfer_to_next_available_agent($chat_id, $current_agent)
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
}
|
427 |
-
}
|
428 |
-
}
|
429 |
-
|
430 |
-
if($identified_candidate !== false){
|
431 |
-
wplc_mrg_admin_transfer_to_agent($chat_id, $identified_candidate, true);
|
432 |
-
}
|
433 |
|
|
|
|
|
|
|
434 |
}
|
435 |
|
436 |
|
437 |
-
add_action("wplc_hook_chat_notification","wplc_filter_control_chat_notification_department_transfer_mrg",10,3);
|
438 |
/**
|
439 |
* Handles 'Transfer' system notification
|
440 |
*
|
441 |
* @return string
|
442 |
-
*/
|
443 |
-
function wplc_filter_control_chat_notification_department_transfer_mrg($type
|
|
|
444 |
if ($type == "transfer") {
|
445 |
global $wpdb;
|
446 |
global $wplc_tblname_msgs;
|
447 |
$user_info = get_userdata(intval($data['aid']));
|
448 |
$agent = "";
|
449 |
-
if ($user_info
|
450 |
-
$agent = $user_info->display_name;
|
451 |
-
}
|
452 |
if (isset($data["auto_transfer"]) && $data["auto_transfer"] == true) {
|
453 |
if (intval($data['aid']) === 0) {
|
454 |
//Came from a department originally
|
455 |
-
$msg=__("Department took too long to respond, we are transferring this chat to the next available agent.",'wp-live-chat-support');
|
456 |
} else {
|
457 |
-
$msg = $agent." ".__("took too long to respond, we are transferring this chat to the next available agent.",'wp-live-chat-support');
|
458 |
}
|
459 |
} else {
|
460 |
-
$msg = $agent." ".__("has transferred the chat.",'wp-live-chat-support');
|
461 |
}
|
462 |
|
463 |
$wpdb->insert( // for user
|
464 |
-
$wplc_tblname_msgs,
|
465 |
-
array(
|
466 |
-
'chat_sess_id' => $cid,
|
467 |
'timestamp' => current_time('mysql'),
|
468 |
-
'msgfrom' => __('System notification','wp-live-chat-support'),
|
469 |
'msg' => $msg,
|
470 |
'status' => 0,
|
471 |
'originates' => 0
|
472 |
-
),
|
473 |
-
array(
|
474 |
-
'%s',
|
475 |
'%s',
|
476 |
'%s',
|
477 |
'%s',
|
478 |
'%d',
|
479 |
'%d'
|
480 |
-
)
|
481 |
);
|
482 |
|
483 |
-
$msg="*".__("User received this message", 'wp-live-chat-support') . ":* "
|
484 |
$wpdb->insert( // for agent
|
485 |
-
$wplc_tblname_msgs,
|
486 |
-
array(
|
487 |
-
'chat_sess_id' => $cid,
|
488 |
'timestamp' => current_time('mysql'),
|
489 |
-
'msgfrom' => __('System notification','wp-live-chat-support'),
|
490 |
'msg' => $msg,
|
491 |
'status' => 0,
|
492 |
'originates' => 3
|
493 |
-
),
|
494 |
-
array(
|
495 |
-
'%s',
|
496 |
'%s',
|
497 |
'%s',
|
498 |
'%s',
|
499 |
'%d',
|
500 |
'%d'
|
501 |
-
)
|
502 |
);
|
503 |
}
|
504 |
}
|
505 |
|
506 |
-
add_action("wplc_hook_chat_notification","wplc_filter_control_chat_notification_auto_department_transfer_mrg",10,3);
|
507 |
/**
|
508 |
* Handles 'Transfer' system notification
|
509 |
*
|
510 |
* @return string
|
511 |
-
*/
|
512 |
-
function wplc_filter_control_chat_notification_auto_department_transfer_mrg($type
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
$from_department = null;
|
518 |
-
$to_department = null;
|
519 |
-
|
520 |
-
if(isset($data['to_dep_id']) && isset($data['from_dep_id'])){
|
521 |
-
if(function_exists("wplc_get_department_mrg")){
|
522 |
-
$from_department = wplc_get_department_mrg(intval($data['from_dep_id']));
|
523 |
-
$to_department = wplc_get_department_mrg(intval($data['to_dep_id']));
|
524 |
-
}
|
525 |
-
}
|
526 |
|
|
|
|
|
527 |
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
}
|
535 |
-
}
|
536 |
-
$msg .= ", " . __("automatically transferring you to", 'wp-live-chat-support') . " ";
|
537 |
-
if($to_department === null){
|
538 |
-
$msg .= __("the next available department", 'wp-live-chat-support');
|
539 |
-
} else {
|
540 |
-
if(!empty($to_department[0]) && !empty($to_department[0]->name)){
|
541 |
-
$msg .= $to_department[0]->name;
|
542 |
-
}
|
543 |
-
}
|
544 |
-
$msg .= ".";
|
545 |
-
|
546 |
-
$wpdb->insert(
|
547 |
-
$wplc_tblname_msgs,
|
548 |
-
array(
|
549 |
-
'chat_sess_id' => $cid,
|
550 |
-
'timestamp' => current_time('mysql'),
|
551 |
-
'msgfrom' => __('System notification','wp-live-chat-support'),
|
552 |
-
'msg' => $msg,
|
553 |
-
'status' => 0,
|
554 |
-
'originates' => 0
|
555 |
-
),
|
556 |
-
array(
|
557 |
-
'%s',
|
558 |
-
'%s',
|
559 |
-
'%s',
|
560 |
-
'%s',
|
561 |
-
'%d',
|
562 |
-
'%d'
|
563 |
-
)
|
564 |
-
);
|
565 |
-
|
566 |
-
$msg = __("User has been transferred from",'wp-live-chat-support') . " ";
|
567 |
-
if($from_department === null){
|
568 |
-
$msg .= __("department", 'wp-live-chat-support');
|
569 |
-
} else {
|
570 |
-
if(!empty($from_department[0]) && !empty($from_department[0]->name)){
|
571 |
-
$msg .= $from_department[0]->name;
|
572 |
-
}
|
573 |
-
}
|
574 |
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
601 |
}
|
602 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
603 |
}
|
604 |
|
605 |
-
add_action("wplc_hook_change_status_on_answer","wplc_mrg_clear_transfer_request_if_set",10,2);
|
606 |
/**
|
607 |
* Unsets the transfer request once it is answered
|
608 |
*
|
609 |
* @return int (response code)
|
610 |
-
*/
|
611 |
-
function wplc_mrg_clear_transfer_request_if_set($get_data, $chat_data = false)
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
|
|
|
|
629 |
}
|
|
|
630 |
}
|
631 |
|
632 |
add_filter("wplc_pro_department_update_filter", "wplc_mrg_admin_transfer_department_online_check", 10, 2);
|
@@ -634,40 +642,38 @@ add_filter("wplc_pro_department_update_filter", "wplc_mrg_admin_transfer_departm
|
|
634 |
* Unsets the transfer request once it is answered
|
635 |
*
|
636 |
* @return int (response code)
|
637 |
-
*/
|
638 |
-
function wplc_mrg_admin_transfer_department_online_check($department_id, $cid)
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
}
|
670 |
-
}
|
671 |
}
|
672 |
|
673 |
/**
|
@@ -676,35 +682,36 @@ function wplc_mrg_admin_transfer_department_online_check($department_id, $cid) {
|
|
676 |
* @param int $chat_id Chat ID
|
677 |
* @param int $agent_id Agent ID
|
678 |
* @return boolean
|
679 |
-
*/
|
680 |
-
function wplc_mrg_admin_transfer_to_agent($chat_id, $agent_id, $auto_transfer)
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
|
|
695 |
|
696 |
-
|
697 |
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
}
|
706 |
}
|
707 |
-
|
|
|
708 |
}
|
709 |
|
710 |
/**
|
@@ -713,30 +720,31 @@ function wplc_mrg_admin_transfer_to_agent($chat_id, $agent_id, $auto_transfer){
|
|
713 |
* @param int $chat_id Chat ID
|
714 |
* @param int $dep_id Department ID
|
715 |
* @return boolean
|
716 |
-
*/
|
717 |
-
function wplc_mrg_admin_transfer_to_department($chat_id, $dep_id)
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
}
|
|
|
738 |
|
739 |
-
|
740 |
}
|
741 |
|
742 |
add_action('wp_ajax_wplc_admin_transfer_check_agent_online', 'wplc_mrg_admin_transfer_ajax');
|
@@ -747,75 +755,65 @@ add_action('wp_ajax_wplc_admin_transfer_to_department', 'wplc_mrg_admin_transfer
|
|
747 |
* Handles the ajax calls for transfers
|
748 |
*
|
749 |
* @return string (response status)
|
750 |
-
*/
|
751 |
-
function wplc_mrg_admin_transfer_ajax(){
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
echo "true";
|
813 |
-
exit();
|
814 |
-
} else {
|
815 |
-
echo "false";
|
816 |
-
exit();
|
817 |
-
}
|
818 |
-
}
|
819 |
-
}
|
820 |
-
}
|
821 |
-
}
|
1 |
+
<?php
|
2 |
/*
|
3 |
* Handles the transferring of a chat
|
4 |
*/
|
5 |
|
6 |
+
if (!defined('ABSPATH')) {
|
7 |
+
exit;
|
8 |
}
|
9 |
|
10 |
add_filter("wplc_admin_chat_area_before_end_chat_button", "wplc_mrg_admin_transfer_tools", 15, 1);
|
12 |
* Outputs (echo) the 'Transfer' button
|
13 |
*
|
14 |
* @return void
|
15 |
+
*/
|
16 |
+
function wplc_mrg_admin_transfer_tools($chat_data)
|
17 |
+
{
|
18 |
+
echo wplc_create_modal_trigger_button_open("transfer", __("Transfer", 'wp-live-chat-support'));
|
19 |
}
|
20 |
|
21 |
|
24 |
* Outputs (echo) the 'Transfer' modal
|
25 |
*
|
26 |
* @return void
|
27 |
+
*/
|
28 |
+
function wplc_mrg_admin_transfer_tools_modals($chat_data)
|
29 |
+
{
|
30 |
+
if (function_exists('wplc_create_modal_window')) {
|
31 |
+
echo wplc_create_modal_window("transfer", __("Transfer Chat", 'wp-live-chat-support'), wplc_mrg_admin_transfer_tools_modal_content($chat_data));
|
32 |
+
|
33 |
+
wplc_mrg_admin_transfer_tools_css();
|
34 |
+
wplc_mrg_admin_transfer_tools_js();
|
35 |
+
}
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
* Returns content for the transfer Modal
|
40 |
*
|
41 |
* @return string (html)
|
42 |
+
*/
|
43 |
+
function wplc_mrg_admin_transfer_tools_modal_content($chat_data)
|
44 |
+
{
|
45 |
+
$content = "<div id='wplc_transfer_modal_step_one_container'>";
|
46 |
+
$content .= "<span>" . __("Would you like to transfer this chat to", 'wp-live-chat-support') . "</span><br><br>";
|
47 |
+
$content .= "<a href='javascript:void(0);' class='button' id='wplc_pro_tranfer_to_agent_btn'>" . __("Agent", 'wp-live-chat-support') . "</a> ";
|
48 |
+
$content .= "<a href='javascript:void(0);' class='button button-primary' id='wplc_pro_tranfer_to_department_btn'>" . __("Department", 'wp-live-chat-support') . "</a> ";
|
49 |
+
$content .= "</div>";
|
50 |
+
|
51 |
+
$content .= "<div id='wplc_transfer_modal_step_two_container'>";
|
52 |
+
$content .= "<div id='wplc_transfer_modal_step_two_agent'>";
|
53 |
+
$content .= "<span>" . __("Please select an agent to transfer to", 'wp-live-chat-support') . "</span><br><br>";
|
54 |
+
$content .= wplc_mrg_admin_transfer_agent_selection() . "<br><br>";
|
55 |
+
|
56 |
+
$content .= "<span id='wplc_transfer_to_agent_check'></span>";
|
57 |
+
|
58 |
+
$content .= "</div>";
|
59 |
+
$content .= "<div id='wplc_transfer_modal_step_two_department'>";
|
60 |
+
$content .= "<span>" . __("Please select a department to transfer to", 'wp-live-chat-support') . "</span><br><br>";
|
61 |
+
$content .= wplc_mrg_admin_transfer_department_selection() . "<br><br>";
|
62 |
+
|
63 |
+
$content .= "<span id='wplc_transfer_to_department_check'></span>";
|
64 |
+
|
65 |
+
$content .= "</div>";
|
66 |
+
$content .= "</div>";
|
67 |
+
|
68 |
+
return $content;
|
69 |
}
|
70 |
|
71 |
/**
|
72 |
* Returns dropdown (html) of all online agent
|
73 |
*
|
74 |
* @return string (html)
|
75 |
+
*/
|
76 |
+
function wplc_mrg_admin_transfer_agent_selection()
|
77 |
+
{
|
78 |
+
$content = "<select id='wplc_transfer_modal_agent_selection'>";
|
79 |
+
$content .= "<option value=''>" . __("No Agent", 'wp-live-chat-support') . "</option>";
|
80 |
+
$my_id = get_current_user_id();
|
81 |
+
$user_array = wplc_get_online_agent_users();
|
82 |
+
foreach ($user_array as $user) {
|
83 |
+
$content .= "<option value='" . $user->ID . "'>" . $user->display_name . ($user->ID == $my_id ? "(" . __("You", 'wp-live-chat-support') . ")" : "") . "</option>";
|
84 |
+
}
|
85 |
+
$content .= "<select>";
|
86 |
+
return $content;
|
|
|
|
|
87 |
}
|
88 |
|
89 |
/**
|
90 |
* Returns dropdown (html) of all departments agent
|
91 |
*
|
92 |
* @return string (html)
|
93 |
+
*/
|
94 |
+
function wplc_mrg_admin_transfer_department_selection()
|
95 |
+
{
|
96 |
+
if (function_exists("wplc_get_all_deparments_mrg")) {
|
97 |
+
$content = "<select id='wplc_transfer_modal_department_selection'>";
|
98 |
+
$content .= "<option value='-1'>" . __("No Department", 'wp-live-chat-support') . "</option>";
|
99 |
+
$departments = wplc_get_all_deparments_mrg();
|
100 |
+
if ($departments) {
|
101 |
+
foreach ($departments as $dep) {
|
102 |
+
$content .= "<option value=" . $dep->id . ">" . $dep->name . "</option>";
|
103 |
+
}
|
104 |
+
}
|
105 |
+
$content .= "<select>";
|
106 |
+
} else {
|
107 |
+
$content = "Version error";
|
108 |
+
}
|
109 |
+
return $content;
|
110 |
}
|
111 |
|
112 |
|
114 |
* Outputs inline JavaScript for Transfer Modal
|
115 |
*
|
116 |
* @return void
|
117 |
+
*/
|
118 |
+
function wplc_mrg_admin_transfer_tools_js()
|
119 |
+
{
|
120 |
+
?>
|
121 |
+
<script>
|
122 |
+
var wplc_to_agent = null;
|
123 |
+
var wplc_online_check_complete = false;
|
124 |
+
|
125 |
+
var wplc_transfer_checking_agent_string = "<?php _e('Checking if agent is online', 'wp-live-chat-support'); ?>";
|
126 |
+
var wplc_transfer_error_agent_string = "<?php _e('Agent is not online, transfer cannot be made', 'wp-live-chat-support'); ?>";
|
127 |
+
|
128 |
+
var wplc_transfer_checking_department_string = "<?php _e('Checking if agents in department are online', 'wp-live-chat-support'); ?>";
|
129 |
+
var wplc_transfer_error_department_string = "<?php _e('No agent within the department are available to accept the transfer, transfer cannot be made', 'wp-live-chat-support'); ?>";
|
130 |
+
|
131 |
+
var wplc_transfer_success_string = "<?php _e('Agent(s) available, safe to transfer', 'wp-live-chat-support'); ?>";
|
132 |
+
|
133 |
+
var wplc_transfer_complete_string = "<?php _e('Transfer Complete. Closing Window...', 'wp-live-chat-support'); ?>";
|
134 |
+
var wplc_transfer_fail_string = "<?php _e('Transfer Failed. Please try again later...', 'wp-live-chat-support'); ?>";
|
135 |
+
|
136 |
+
jQuery(function() {
|
137 |
+
if (typeof wplc_modal_initialize !== "undefined" && typeof wplc_modal_initialize === "function") {
|
138 |
+
wplc_modal_initialize(wplc_modal_transfer_open_modal, wplc_modal_transfer_confirm, wplc_modal_transfer_cancel, false);
|
139 |
+
}
|
140 |
+
|
141 |
+
jQuery("body").on("click", "#wplc_pro_tranfer_to_agent_btn", function() {
|
142 |
+
jQuery("#wplc_transfer_modal_step_one_container").hide();
|
143 |
+
jQuery("#wplc_transfer_modal_step_two_container").show();
|
144 |
+
jQuery("#wplc_transfer_modal_step_two_agent").show();
|
145 |
+
jQuery("#wplc_modal_inner_actions_transfer").show();
|
146 |
+
wplc_to_agent = true;
|
147 |
+
});
|
148 |
+
|
149 |
+
jQuery("body").on("click", "#wplc_pro_tranfer_to_department_btn", function() {
|
150 |
+
jQuery("#wplc_transfer_modal_step_one_container").hide();
|
151 |
+
jQuery("#wplc_transfer_modal_step_two_container").show();
|
152 |
+
jQuery("#wplc_modal_inner_actions_transfer").show();
|
153 |
+
jQuery("#wplc_transfer_modal_step_two_department").show();
|
154 |
+
wplc_to_agent = false;
|
155 |
+
});
|
156 |
+
|
157 |
+
jQuery("body").on("change", "#wplc_transfer_modal_agent_selection", function() {
|
158 |
+
wplc_online_check_complete = false;
|
159 |
+
jQuery("#wplc_modal_confirm_transfer").removeClass("button-primary");
|
160 |
+
jQuery("#wplc_modal_confirm_transfer").addClass("button-disabled");
|
161 |
+
jQuery("#wplc_transfer_to_agent_check").text(wplc_transfer_checking_agent_string);
|
162 |
+
wplc_modal_transfer_check_online_agent(function() {
|
163 |
+
wplc_online_check_complete = true;
|
164 |
+
jQuery("#wplc_modal_confirm_transfer").removeClass("button-disabled");
|
165 |
+
jQuery("#wplc_modal_confirm_transfer").addClass("button-primary");
|
166 |
+
jQuery("#wplc_transfer_to_agent_check").text(wplc_transfer_success_string);
|
167 |
+
}, function() {
|
168 |
+
jQuery("#wplc_transfer_to_agent_check").text(wplc_transfer_error_agent_string);
|
169 |
+
});
|
170 |
+
|
171 |
+
});
|
172 |
+
|
173 |
+
jQuery("body").on("change", "#wplc_transfer_modal_department_selection", function() {
|
174 |
+
wplc_online_check_complete = false;
|
175 |
+
jQuery("#wplc_modal_confirm_transfer").removeClass("button-primary");
|
176 |
+
jQuery("#wplc_modal_confirm_transfer").addClass("button-disabled");
|
177 |
+
jQuery("#wplc_transfer_to_department_check").text(wplc_transfer_checking_department_string);
|
178 |
+
wplc_modal_transfer_check_online_department(function() {
|
179 |
+
wplc_online_check_complete = true;
|
180 |
+
jQuery("#wplc_modal_confirm_transfer").removeClass("button-disabled");
|
181 |
+
jQuery("#wplc_modal_confirm_transfer").addClass("button-primary");
|
182 |
+
jQuery("#wplc_transfer_to_department_check").text(wplc_transfer_success_string);
|
183 |
+
}, function() {
|
184 |
+
jQuery("#wplc_transfer_to_department_check").text(wplc_transfer_error_department_string);
|
185 |
+
});
|
186 |
+
});
|
187 |
+
});
|
188 |
+
|
189 |
+
function wplc_modal_transfer_open_modal() {
|
190 |
+
jQuery("#wplc_transfer_modal_step_one_container").show();
|
191 |
+
jQuery("#wplc_transfer_modal_step_two_container").hide();
|
192 |
+
jQuery("#wplc_modal_inner_actions_transfer").hide();
|
193 |
+
jQuery("#wplc_transfer_modal_step_two_agent").hide();
|
194 |
+
jQuery("#wplc_transfer_modal_step_two_department").hide();
|
195 |
+
jQuery("#wplc_modal_confirm_transfer").removeClass("button-primary");
|
196 |
+
jQuery("#wplc_modal_confirm_transfer").addClass("button-disabled");
|
197 |
+
|
198 |
+
jQuery("#wplc_transfer_to_agent_check").text("");
|
199 |
+
jQuery("#wplc_transfer_to_department_check").text("");
|
200 |
+
|
201 |
+
wplc_to_agent = null;
|
202 |
+
wplc_online_check_complete = false;
|
203 |
+
}
|
204 |
+
|
205 |
+
function wplc_modal_transfer_check_online_agent(check_success_callback, check_fail_callback) {
|
206 |
+
var aid = jQuery("#wplc_transfer_modal_agent_selection").val();
|
207 |
+
|
208 |
+
var data = {
|
209 |
+
action: "wplc_admin_transfer_check_agent_online",
|
210 |
+
agent_id: parseInt(aid)
|
211 |
+
};
|
212 |
+
|
213 |
+
wplc_modal_transfer_ajax(data, function(return_data) {
|
214 |
+
if (return_data == "true") {
|
215 |
+
if (typeof check_success_callback === "function") {
|
216 |
+
check_success_callback();
|
217 |
+
}
|
218 |
+
} else {
|
219 |
+
if (typeof check_fail_callback === "function") {
|
220 |
+
check_fail_callback();
|
221 |
+
}
|
222 |
+
}
|
223 |
+
}, function() {
|
224 |
+
if (typeof check_fail_callback === "function") {
|
225 |
+
check_fail_callback();
|
226 |
+
}
|
227 |
+
});
|
228 |
+
|
229 |
+
|
230 |
+
}
|
231 |
+
|
232 |
+
function wplc_modal_transfer_check_online_department(check_success_callback, check_fail_callback) {
|
233 |
+
var depid = jQuery("#wplc_transfer_modal_department_selection").val();
|
234 |
+
|
235 |
+
var data = {
|
236 |
+
action: "wplc_admin_transfer_check_department_online",
|
237 |
+
dep_id: parseInt(depid)
|
238 |
+
};
|
239 |
+
|
240 |
+
wplc_modal_transfer_ajax(data, function(return_data) {
|
241 |
+
if (return_data == "true") {
|
242 |
+
if (typeof check_success_callback === "function") {
|
243 |
+
check_success_callback();
|
244 |
+
}
|
245 |
+
} else {
|
246 |
+
if (typeof check_fail_callback === "function") {
|
247 |
+
check_fail_callback();
|
248 |
+
}
|
249 |
+
}
|
250 |
+
}, function() {
|
251 |
+
if (typeof check_fail_callback === "function") {
|
252 |
+
check_fail_callback();
|
253 |
+
}
|
254 |
+
});
|
255 |
+
}
|
256 |
|
257 |
function wplc_modal_transfer_ajax(req_data, on_succcess, on_error) {
|
258 |
jQuery.ajax({
|
259 |
+
url: "<?php echo admin_url('admin-ajax.php'); ?>",
|
260 |
+
type: 'POST',
|
261 |
+
data: req_data,
|
262 |
+
success: function(return_data) {
|
263 |
+
if (typeof on_succcess === "function") {
|
264 |
+
on_succcess(return_data);
|
265 |
}
|
266 |
},
|
267 |
+
error: function() {
|
268 |
+
if (typeof on_error === "function") {
|
269 |
+
on_error();
|
270 |
}
|
271 |
}
|
272 |
});
|
273 |
}
|
274 |
|
275 |
function wplc_modal_transfer_confirm() {
|
276 |
+
if (wplc_online_check_complete) {
|
277 |
+
if (wplc_to_agent !== null) {
|
278 |
<?php
|
279 |
$cid = intval($_GET['cid']);
|
280 |
+
?>
|
281 |
+
if (wplc_to_agent == true) {
|
282 |
//Send to agent
|
283 |
var aid = jQuery("#wplc_transfer_modal_agent_selection").val();
|
284 |
var data = {
|
285 |
+
action: "wplc_admin_transfer_to_agent",
|
286 |
+
cid: parseInt("<?php echo $cid; ?>"),
|
287 |
+
agent_id: parseInt(aid)
|
288 |
};
|
289 |
+
|
290 |
+
wplc_modal_transfer_ajax(data, function(return_data) {
|
291 |
+
if (return_data == "true") {
|
292 |
jQuery("#wplc_transfer_to_agent_check").text(wplc_transfer_complete_string);
|
293 |
setTimeout(function() {
|
294 |
window.close();
|
296 |
} else {
|
297 |
jQuery("#wplc_transfer_to_agent_check").text(wplc_transfer_fail_string);
|
298 |
}
|
299 |
+
}, function() {
|
300 |
jQuery("#wplc_transfer_to_agent_check").text(wplc_transfer_fail_string);
|
301 |
});
|
302 |
} else {
|
303 |
//Send to department
|
304 |
var depid = jQuery("#wplc_transfer_modal_department_selection").val();
|
305 |
var data = {
|
306 |
+
action: "wplc_admin_transfer_to_department",
|
307 |
+
cid: parseInt("<?php echo $cid; ?>"),
|
308 |
+
dep_id: parseInt(depid)
|
309 |
};
|
310 |
|
311 |
+
wplc_modal_transfer_ajax(data, function(return_data) {
|
312 |
+
if (return_data == "true") {
|
313 |
jQuery("#wplc_transfer_to_department_check").text(wplc_transfer_complete_string);
|
314 |
setTimeout(function() {
|
315 |
window.close();
|
317 |
} else {
|
318 |
jQuery("#wplc_transfer_to_department_check").text(wplc_transfer_fail_string);
|
319 |
}
|
320 |
+
}, function() {
|
321 |
jQuery("#wplc_transfer_to_department_check").text(wplc_transfer_fail_string);
|
322 |
});
|
323 |
}
|
327 |
}
|
328 |
}
|
329 |
|
330 |
+
function wplc_modal_transfer_cancel() {
|
331 |
+
wplc_to_agent = null;
|
332 |
+
wplc_online_check_complete = false;
|
333 |
+
}
|
334 |
+
</script>
|
335 |
+
<?php
|
336 |
}
|
337 |
|
338 |
/**
|
339 |
* Outputs inline css for Transfer Modal
|
340 |
*
|
341 |
* @return void
|
342 |
+
*/
|
343 |
+
function wplc_mrg_admin_transfer_tools_css()
|
344 |
+
{
|
345 |
+
?>
|
346 |
+
<style>
|
347 |
+
#wplc_transfer_modal_step_one_container,
|
348 |
+
#wplc_transfer_modal_step_two_container {
|
349 |
+
text-align: center;
|
350 |
+
}
|
351 |
+
</style>
|
352 |
+
<?php
|
353 |
}
|
354 |
|
355 |
add_filter("wplc_accept_chat_button_filter", "wplc_mrg_admin_accept_chat_button_text", 10, 2);
|
357 |
* Changes 'Accept Chat' to 'Accept Transfer'
|
358 |
*
|
359 |
* @return string
|
360 |
+
*/
|
361 |
+
function wplc_mrg_admin_accept_chat_button_text($content, $cid)
|
362 |
+
{
|
363 |
+
$chat_data = wplc_get_chat_data($cid, __LINE__);
|
364 |
+
$max_wait_time = 60; //60 Seconds
|
365 |
+
if (isset($chat_data->other)) {
|
366 |
+
$other_data = maybe_unserialize($chat_data->other);
|
367 |
+
if ((isset($other_data['transfer']) && $other_data['transfer'] == true)) {
|
368 |
+
if (isset($chat_data->agent_id) && intval($chat_data->agent_id) !== 0) {
|
369 |
+
//For a specific agent
|
370 |
+
if (isset($other_data['agent_transfer_time'])) {
|
371 |
+
//Check the time difference
|
372 |
+
$seconds = time() - $other_data['agent_transfer_time'];
|
373 |
+
if (intval($seconds) > $max_wait_time) {
|
374 |
+
do_action("wplc_pro_admin_transfer_agent_exceeded_accept_time", $cid, $chat_data->agent_id);
|
375 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
376 |
}
|
377 |
+
|
378 |
+
$agent_info = get_userdata(intval($chat_data->agent_id));
|
379 |
+
|
380 |
+
return __("Transfer for", 'wp-live-chat-support') . " " . $agent_info->display_name;
|
381 |
+
} else {
|
382 |
+
//Department
|
383 |
+
return __("Accept Transfer", 'wp-live-chat-support');
|
384 |
+
}
|
385 |
+
} else if ((isset($other_data['unanswered']) && $other_data['unanswered'] == true)) {
|
386 |
+
// Initial chat request -> Should still check timer
|
387 |
+
if (isset($other_data['agent_transfer_time'])) {
|
388 |
+
//Check the time difference
|
389 |
+
$seconds = time() - $other_data['agent_transfer_time'];
|
390 |
+
if (intval($seconds) > $max_wait_time) {
|
391 |
+
do_action("wplc_pro_admin_transfer_agent_exceeded_accept_time", $cid, -1); //Transfer to the next agent
|
392 |
+
}
|
393 |
+
}
|
394 |
+
return $content;
|
395 |
}
|
396 |
+
}
|
397 |
|
398 |
+
return $content;
|
399 |
}
|
400 |
|
401 |
add_filter("wplc_start_chat_hook_other_data_hook", "wplc_mrg_admin_transfer_add_initial_transfer_time", 10, 1);
|
403 |
* Adds an initial 'agent transfer time' value to the other data of the chat - On Chat Request
|
404 |
*
|
405 |
* @return array
|
406 |
+
*/
|
407 |
+
function wplc_mrg_admin_transfer_add_initial_transfer_time($other_data)
|
408 |
+
{
|
409 |
+
$other_data['agent_transfer_time'] = time();
|
410 |
+
return $other_data;
|
411 |
}
|
412 |
|
413 |
add_action("wplc_pro_admin_transfer_agent_exceeded_accept_time", "wplc_mrg_admin_transfer_to_next_available_agent", 10, 2);
|
415 |
* Transfers chat to the next available agetn
|
416 |
*
|
417 |
* @return void
|
418 |
+
*/
|
419 |
+
function wplc_mrg_admin_transfer_to_next_available_agent($chat_id, $current_agent)
|
420 |
+
{
|
421 |
+
$chat_id = intval($chat_id);
|
422 |
+
$current_agent = intval($current_agent);
|
423 |
+
//Find all online agents
|
424 |
+
$user_array = wplc_get_online_agent_users();
|
425 |
+
$identified_candidate = false;
|
426 |
+
foreach ($user_array as $user) {
|
427 |
+
if ($identified_candidate === false) {
|
428 |
+
if ($current_agent !== $user->ID) {
|
429 |
+
$identified_candidate = $user->ID;
|
430 |
+
}
|
431 |
+
}
|
432 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
433 |
|
434 |
+
if ($identified_candidate !== false) {
|
435 |
+
wplc_mrg_admin_transfer_to_agent($chat_id, $identified_candidate, true);
|
436 |
+
}
|
437 |
}
|
438 |
|
439 |
|
440 |
+
add_action("wplc_hook_chat_notification", "wplc_filter_control_chat_notification_department_transfer_mrg", 10, 3);
|
441 |
/**
|
442 |
* Handles 'Transfer' system notification
|
443 |
*
|
444 |
* @return string
|
445 |
+
*/
|
446 |
+
function wplc_filter_control_chat_notification_department_transfer_mrg($type, $cid, $data)
|
447 |
+
{
|
448 |
if ($type == "transfer") {
|
449 |
global $wpdb;
|
450 |
global $wplc_tblname_msgs;
|
451 |
$user_info = get_userdata(intval($data['aid']));
|
452 |
$agent = "";
|
453 |
+
if ($user_info) {
|
454 |
+
$agent = $user_info->display_name;
|
455 |
+
}
|
456 |
if (isset($data["auto_transfer"]) && $data["auto_transfer"] == true) {
|
457 |
if (intval($data['aid']) === 0) {
|
458 |
//Came from a department originally
|
459 |
+
$msg = __("Department took too long to respond, we are transferring this chat to the next available agent.", 'wp-live-chat-support');
|
460 |
} else {
|
461 |
+
$msg = $agent . " " . __("took too long to respond, we are transferring this chat to the next available agent.", 'wp-live-chat-support');
|
462 |
}
|
463 |
} else {
|
464 |
+
$msg = $agent . " " . __("has transferred the chat.", 'wp-live-chat-support');
|
465 |
}
|
466 |
|
467 |
$wpdb->insert( // for user
|
468 |
+
$wplc_tblname_msgs,
|
469 |
+
array(
|
470 |
+
'chat_sess_id' => $cid,
|
471 |
'timestamp' => current_time('mysql'),
|
472 |
+
'msgfrom' => __('System notification', 'wp-live-chat-support'),
|
473 |
'msg' => $msg,
|
474 |
'status' => 0,
|
475 |
'originates' => 0
|
476 |
+
),
|
477 |
+
array(
|
478 |
+
'%s',
|
479 |
'%s',
|
480 |
'%s',
|
481 |
'%s',
|
482 |
'%d',
|
483 |
'%d'
|
484 |
+
)
|
485 |
);
|
486 |
|
487 |
+
$msg = "*" . __("User received this message", 'wp-live-chat-support') . ":* " . $msg;
|
488 |
$wpdb->insert( // for agent
|
489 |
+
$wplc_tblname_msgs,
|
490 |
+
array(
|
491 |
+
'chat_sess_id' => $cid,
|
492 |
'timestamp' => current_time('mysql'),
|
493 |
+
'msgfrom' => __('System notification', 'wp-live-chat-support'),
|
494 |
'msg' => $msg,
|
495 |
'status' => 0,
|
496 |
'originates' => 3
|
497 |
+
),
|
498 |
+
array(
|
499 |
+
'%s',
|
500 |
'%s',
|
501 |
'%s',
|
502 |
'%s',
|
503 |
'%d',
|
504 |
'%d'
|
505 |
+
)
|
506 |
);
|
507 |
}
|
508 |
}
|
509 |
|
510 |
+
add_action("wplc_hook_chat_notification", "wplc_filter_control_chat_notification_auto_department_transfer_mrg", 10, 3);
|
511 |
/**
|
512 |
* Handles 'Transfer' system notification
|
513 |
*
|
514 |
* @return string
|
515 |
+
*/
|
516 |
+
function wplc_filter_control_chat_notification_auto_department_transfer_mrg($type, $cid, $data)
|
517 |
+
{
|
518 |
+
if ($type == "system_dep_transfer") {
|
519 |
+
global $wpdb;
|
520 |
+
global $wplc_tblname_msgs;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
521 |
|
522 |
+
$from_department = null;
|
523 |
+
$to_department = null;
|
524 |
|
525 |
+
if (isset($data['to_dep_id']) && isset($data['from_dep_id'])) {
|
526 |
+
if (function_exists("wplc_get_department_mrg")) {
|
527 |
+
$from_department = wplc_get_department_mrg(intval($data['from_dep_id']));
|
528 |
+
$to_department = wplc_get_department_mrg(intval($data['to_dep_id']));
|
529 |
+
}
|
530 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
531 |
|
532 |
+
|
533 |
+
$msg = __("No agents available in", 'wp-live-chat-support') . " ";
|
534 |
+
if ($from_department === null) {
|
535 |
+
$msg .= __("selected department", 'wp-live-chat-support');
|
536 |
+
} else {
|
537 |
+
if (!empty($from_department[0]) && !empty($from_department[0]->name)) {
|
538 |
+
$msg .= $from_department[0]->name;
|
539 |
+
}
|
540 |
+
}
|
541 |
+
$msg .= ", " . __("automatically transferring you to", 'wp-live-chat-support') . " ";
|
542 |
+
if ($to_department === null) {
|
543 |
+
$msg .= __("the next available department", 'wp-live-chat-support');
|
544 |
+
} else {
|
545 |
+
if (!empty($to_department[0]) && !empty($to_department[0]->name)) {
|
546 |
+
$msg .= $to_department[0]->name;
|
547 |
+
}
|
548 |
+
}
|
549 |
+
$msg .= ".";
|
550 |
+
|
551 |
+
$wpdb->insert(
|
552 |
+
$wplc_tblname_msgs,
|
553 |
+
array(
|
554 |
+
'chat_sess_id' => $cid,
|
555 |
+
'timestamp' => current_time('mysql'),
|
556 |
+
'msgfrom' => __('System notification', 'wp-live-chat-support'),
|
557 |
+
'msg' => $msg,
|
558 |
+
'status' => 0,
|
559 |
+
'originates' => 0
|
560 |
+
),
|
561 |
+
array(
|
562 |
+
'%s',
|
563 |
+
'%s',
|
564 |
+
'%s',
|
565 |
+
'%s',
|
566 |
+
'%d',
|
567 |
+
'%d'
|
568 |
+
)
|
569 |
+
);
|
570 |
+
|
571 |
+
$msg = __("User has been transferred from", 'wp-live-chat-support') . " ";
|
572 |
+
if ($from_department === null) {
|
573 |
+
$msg .= __("department", 'wp-live-chat-support');
|
574 |
+
} else {
|
575 |
+
if (!empty($from_department[0]) && !empty($from_department[0]->name)) {
|
576 |
+
$msg .= $from_department[0]->name;
|
577 |
+
}
|
578 |
+
}
|
579 |
+
|
580 |
+
if ($to_department !== null) {
|
581 |
+
if (!empty($to_department[0]) && !empty($to_department[0]->name)) {
|
582 |
+
$msg .= ' ' . __("to", 'wp-live-chat-support') . " " . $to_department[0]->name;
|
583 |
+
}
|
584 |
}
|
585 |
+
$msg .= " " . __("as there were no agents online") . ".";
|
586 |
+
|
587 |
+
$wpdb->insert(
|
588 |
+
$wplc_tblname_msgs,
|
589 |
+
array(
|
590 |
+
'chat_sess_id' => $cid,
|
591 |
+
'timestamp' => current_time('mysql'),
|
592 |
+
'msgfrom' => __('System notification', 'wp-live-chat-support'),
|
593 |
+
'msg' => $msg,
|
594 |
+
'status' => 0,
|
595 |
+
'originates' => 3
|
596 |
+
),
|
597 |
+
array(
|
598 |
+
'%s',
|
599 |
+
'%s',
|
600 |
+
'%s',
|
601 |
+
'%s',
|
602 |
+
'%d',
|
603 |
+
'%d'
|
604 |
+
)
|
605 |
+
);
|
606 |
+
}
|
607 |
+
return;
|
608 |
}
|
609 |
|
610 |
+
add_action("wplc_hook_change_status_on_answer", "wplc_mrg_clear_transfer_request_if_set", 10, 2);
|
611 |
/**
|
612 |
* Unsets the transfer request once it is answered
|
613 |
*
|
614 |
* @return int (response code)
|
615 |
+
*/
|
616 |
+
function wplc_mrg_clear_transfer_request_if_set($get_data, $chat_data = false)
|
617 |
+
{
|
618 |
+
global $wpdb;
|
619 |
+
global $wplc_tblname_chats;
|
620 |
+
|
621 |
+
$chat_id = intval($get_data['cid']);
|
622 |
+
if (!$chat_data) {
|
623 |
+
$chat_data = wplc_get_chat_data($chat_id, __LINE__);
|
624 |
+
}
|
625 |
+
|
626 |
+
if (isset($chat_data->other)) {
|
627 |
+
$other_data = maybe_unserialize($chat_data->other);
|
628 |
+
if (isset($other_data['transfer']) && $other_data['transfer'] == true) {
|
629 |
+
unset($other_data['transfer']);
|
630 |
+
unset($other_data['unanswered']);
|
631 |
+
unset($other_data['agent_transfer_time']);
|
632 |
+
|
633 |
+
$new_chat_data = array('other' => maybe_serialize($other_data));
|
634 |
+
|
635 |
+
$wpdb->update($wplc_tblname_chats, $new_chat_data, array('id' => $chat_id), array('%s'), array('%d'));
|
636 |
}
|
637 |
+
}
|
638 |
}
|
639 |
|
640 |
add_filter("wplc_pro_department_update_filter", "wplc_mrg_admin_transfer_department_online_check", 10, 2);
|
642 |
* Unsets the transfer request once it is answered
|
643 |
*
|
644 |
* @return int (response code)
|
645 |
+
*/
|
646 |
+
function wplc_mrg_admin_transfer_department_online_check($department_id, $cid)
|
647 |
+
{
|
648 |
+
$search_department = intval($department_id);
|
649 |
+
$user_array = wplc_get_online_agent_users();
|
650 |
+
$fallback_department = null; //First agent who is online will be responsible for fallback
|
651 |
+
|
652 |
+
$check = false;
|
653 |
+
foreach ($user_array as $user) {
|
654 |
+
$this_user_department = get_user_meta($user->ID, "wplc_user_department", true);
|
655 |
+
if (intval($this_user_department == -1) || $this_user_department === "") {
|
656 |
+
$check = true;
|
657 |
+
} else if (intval($this_user_department) === $search_department) {
|
658 |
+
$check = true;
|
659 |
+
}
|
660 |
+
|
661 |
+
if ($fallback_department === null) {
|
662 |
+
$fallback_department = $this_user_department;
|
663 |
+
}
|
664 |
+
}
|
665 |
+
|
666 |
+
if ($check) {
|
667 |
+
return $department_id; //Someone is online in this department, or a global department
|
668 |
+
} else {
|
669 |
+
if ($fallback_department !== null) {
|
670 |
+
wplc_record_chat_notification("system_dep_transfer", $cid, array("from_dep_id" => $department_id, "to_dep_id" => $fallback_department));
|
671 |
+
return $fallback_department;
|
672 |
+
} else {
|
673 |
+
//Joh.... This is broken
|
674 |
+
return $department_id; //Just return the department ID passed in originally, hope for the best
|
675 |
+
}
|
676 |
+
}
|
|
|
|
|
677 |
}
|
678 |
|
679 |
/**
|
682 |
* @param int $chat_id Chat ID
|
683 |
* @param int $agent_id Agent ID
|
684 |
* @return boolean
|
685 |
+
*/
|
686 |
+
function wplc_mrg_admin_transfer_to_agent($chat_id, $agent_id, $auto_transfer)
|
687 |
+
{
|
688 |
+
global $wpdb;
|
689 |
+
global $wplc_tblname_chats;
|
690 |
+
|
691 |
+
$chat_data = wplc_get_chat_data($chat_id, __LINE__);
|
692 |
+
if (isset($chat_data->other)) {
|
693 |
+
$other_data = maybe_unserialize($chat_data->other);
|
694 |
+
$other_data['unanswered'] = true;
|
695 |
+
$other_data['transfer'] = true;
|
696 |
+
$other_data['agent_transfer_time'] = time();
|
697 |
+
|
698 |
+
$user_department = get_user_meta($agent_id, "wplc_user_department", true);
|
699 |
+
if (!$user_department || $user_department === "") {
|
700 |
+
$user_department = 0;
|
701 |
+
}
|
702 |
|
703 |
+
$new_chat_data = array('status' => 2, 'agent_id' => $agent_id, 'department_id' => $user_department, 'other' => maybe_serialize($other_data));
|
704 |
|
705 |
+
if ($wpdb->update($wplc_tblname_chats, $new_chat_data, array('id' => $chat_id), array('%d', '%d', '%d', '%s'), array('%d'))) {
|
706 |
+
if (function_exists("wplc_record_chat_notification")) {
|
707 |
+
wplc_record_chat_notification("transfer", $chat_id, array("aid" => $chat_data->agent_id, "auto_transfer" => $auto_transfer));
|
708 |
+
}
|
709 |
+
return true;
|
710 |
+
} else {
|
711 |
+
return false;
|
|
|
712 |
}
|
713 |
+
}
|
714 |
+
return false;
|
715 |
}
|
716 |
|
717 |
/**
|
720 |
* @param int $chat_id Chat ID
|
721 |
* @param int $dep_id Department ID
|
722 |
* @return boolean
|
723 |
+
*/
|
724 |
+
function wplc_mrg_admin_transfer_to_department($chat_id, $dep_id)
|
725 |
+
{
|
726 |
+
global $wpdb;
|
727 |
+
global $wplc_tblname_chats;
|
728 |
+
|
729 |
+
$chat_data = wplc_get_chat_data($chat_id, __LINE__);
|
730 |
+
if (isset($chat_data->other)) {
|
731 |
+
$other_data = maybe_unserialize($chat_data->other);
|
732 |
+
$other_data['unanswered'] = true;
|
733 |
+
$other_data['transfer'] = true;
|
734 |
+
|
735 |
+
$new_chat_data = array('status' => 2, 'agent_id' => 0, 'department_id' => $dep_id, 'other' => maybe_serialize($other_data));
|
736 |
+
|
737 |
+
if ($wpdb->update($wplc_tblname_chats, $new_chat_data, array('id' => $chat_id), array('%d', '%d', '%d', '%s'), array('%d'))) {
|
738 |
+
if (function_exists("wplc_record_chat_notification")) {
|
739 |
+
wplc_record_chat_notification("transfer", $chat_id, array("aid" => $chat_data->agent_id));
|
740 |
+
}
|
741 |
+
return true;
|
742 |
+
} else {
|
743 |
+
return false;
|
744 |
}
|
745 |
+
}
|
746 |
|
747 |
+
return false;
|
748 |
}
|
749 |
|
750 |
add_action('wp_ajax_wplc_admin_transfer_check_agent_online', 'wplc_mrg_admin_transfer_ajax');
|
755 |
* Handles the ajax calls for transfers
|
756 |
*
|
757 |
* @return string (response status)
|
758 |
+
*/
|
759 |
+
function wplc_mrg_admin_transfer_ajax() {
|
760 |
+
if (isset($_POST['action'])) {
|
761 |
+
if ($_POST['action'] == "wplc_admin_transfer_check_agent_online") {
|
762 |
+
if (isset($_POST['agent_id'])) {
|
763 |
+
$user_id = intval($_POST['agent_id']);
|
764 |
+
if (wplc_agent_is_online($user_id)) {
|
765 |
+
echo "true";
|
766 |
+
} else {
|
767 |
+
echo "false"; //Agent no longer online
|
768 |
+
}
|
769 |
+
}
|
770 |
+
exit();
|
771 |
+
}
|
772 |
+
|
773 |
+
if ($_POST['action'] == "wplc_admin_transfer_check_department_online") {
|
774 |
+
if (isset($_POST['dep_id'])) {
|
775 |
+
$search_department = intval($_POST['dep_id']);
|
776 |
+
$user_array = wplc_get_online_agent_users();
|
777 |
+
$check = false;
|
778 |
+
foreach ($user_array as $user) {
|
779 |
+
$this_user_department = get_user_meta($user->ID, "wplc_user_department", true);
|
780 |
+
if (intval($this_user_department) === $search_department) {
|
781 |
+
$check = true;
|
782 |
+
}
|
783 |
+
}
|
784 |
+
if ($check) {
|
785 |
+
echo "true";
|
786 |
+
} else {
|
787 |
+
echo "false"; //Agent no longer online
|
788 |
+
}
|
789 |
+
}
|
790 |
+
exit();
|
791 |
+
}
|
792 |
+
|
793 |
+
if ($_POST['action'] == "wplc_admin_transfer_to_agent") {
|
794 |
+
if (isset($_POST['cid']) && isset($_POST['agent_id'])) {
|
795 |
+
$chat_id = intval($_POST['cid']);
|
796 |
+
$agent_id = intval($_POST['agent_id']);
|
797 |
+
if (wplc_mrg_admin_transfer_to_agent($chat_id, $agent_id, false)) {
|
798 |
+
echo "true";
|
799 |
+
} else {
|
800 |
+
echo "false";
|
801 |
+
}
|
802 |
+
}
|
803 |
+
exit();
|
804 |
+
}
|
805 |
+
|
806 |
+
if ($_POST['action'] == "wplc_admin_transfer_to_department") {
|
807 |
+
if (isset($_POST['cid']) && isset($_POST['dep_id'])) {
|
808 |
+
$chat_id = intval($_POST['cid']);
|
809 |
+
$dep_id = intval($_POST['dep_id']);
|
810 |
+
if (wplc_mrg_admin_transfer_to_department($chat_id, $dep_id)) {
|
811 |
+
echo "true";
|
812 |
+
} else {
|
813 |
+
echo "false";
|
814 |
+
}
|
815 |
+
}
|
816 |
+
exit();
|
817 |
+
}
|
818 |
+
}
|
819 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
js/media.js
CHANGED
@@ -92,22 +92,21 @@ jQuery(function($){
|
|
92 |
|
93 |
$("#wplc_btn_remove_pic").click(function() {
|
94 |
$("#wplc_pic_area").empty();
|
95 |
-
$("#wplc_upload_pic").val("");
|
96 |
});
|
97 |
$("#wplc_btn_remove_logo").click(function() {
|
98 |
$("#wplc_logo_area").empty();
|
99 |
-
$("#wplc_upload_logo").val("");
|
100 |
});
|
101 |
-
$("#wplc_btn_remove_icon").click(function() {
|
102 |
-
$("#wplc_icon_area").empty();
|
103 |
-
$("#wplc_upload_icon").val("");
|
104 |
-
});
|
105 |
-
|
106 |
-
|
107 |
$("#wplc_btn_select_default_icon").click(function() {
|
108 |
$("#wplc_default_chat_icons").slideToggle();
|
109 |
});
|
110 |
|
|
|
|
|
|
|
|
|
|
|
111 |
$(".wplc_default_chat_icon_selector").click(function() {
|
112 |
var image_url = $(this).attr("src");
|
113 |
$('#wplc_upload_icon').val(btoa(image_url));
|
92 |
|
93 |
$("#wplc_btn_remove_pic").click(function() {
|
94 |
$("#wplc_pic_area").empty();
|
95 |
+
$("#wplc_upload_pic").val("remove");
|
96 |
});
|
97 |
$("#wplc_btn_remove_logo").click(function() {
|
98 |
$("#wplc_logo_area").empty();
|
99 |
+
$("#wplc_upload_logo").val("remove");
|
100 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
$("#wplc_btn_select_default_icon").click(function() {
|
102 |
$("#wplc_default_chat_icons").slideToggle();
|
103 |
});
|
104 |
|
105 |
+
$("#wplc_btn_select_default_pic").click(function() {
|
106 |
+
$('#wplc_upload_pic').val(btoa($("#wplc_pic_area").attr('default')));
|
107 |
+
$("#wplc_pic_area").html("<img src=\""+$("#wplc_pic_area").attr('default')+"\" width='50px'/>");
|
108 |
+
});
|
109 |
+
|
110 |
$(".wplc_default_chat_icon_selector").click(function() {
|
111 |
var image_url = $(this).attr("src");
|
112 |
$('#wplc_upload_icon').val(btoa(image_url));
|
js/wplc_agent_node.js
CHANGED
@@ -2280,7 +2280,7 @@ function nc_return_location_details(data) {
|
|
2280 |
return "<img src='" + wplc_baseurl + "images/flags/" + location_info.code + ".png' alt='" + country_name + "' title='" + country_name + "' />";
|
2281 |
}
|
2282 |
}
|
2283 |
-
catch {
|
2284 |
// invalid data
|
2285 |
}
|
2286 |
}
|
@@ -2873,14 +2873,12 @@ tcx_delegates = function() {
|
|
2873 |
}
|
2874 |
});
|
2875 |
|
2876 |
-
|
2877 |
socket.on('agent connected', function(data) {
|
2878 |
var t_c_aid = data.aid;
|
2879 |
var t_c_sid = data.socketid;
|
2880 |
jQuery(".online_agent_" + t_c_aid).attr('socket', t_c_sid);
|
2881 |
jQuery(".online_agent_" + t_c_aid + ' .online_offline').removeClass('offline');
|
2882 |
jQuery(".online_agent_" + t_c_aid + ' .online_offline').addClass('online');
|
2883 |
-
|
2884 |
jQuery.event.trigger({ type: "tcx_agent_connected", ndata: data });
|
2885 |
});
|
2886 |
|
@@ -2890,7 +2888,6 @@ tcx_delegates = function() {
|
|
2890 |
jQuery(".online_agent_" + t_c_aid).attr('socket', null);
|
2891 |
jQuery(".online_agent_" + t_c_aid + ' .online_offline').removeClass('online');
|
2892 |
jQuery(".online_agent_" + t_c_aid + ' .online_offline').addClass('offline');
|
2893 |
-
|
2894 |
jQuery.event.trigger({ type: "tcx_agent_disconnected", ndata: data });
|
2895 |
});
|
2896 |
|
2280 |
return "<img src='" + wplc_baseurl + "images/flags/" + location_info.code + ".png' alt='" + country_name + "' title='" + country_name + "' />";
|
2281 |
}
|
2282 |
}
|
2283 |
+
catch (e) {
|
2284 |
// invalid data
|
2285 |
}
|
2286 |
}
|
2873 |
}
|
2874 |
});
|
2875 |
|
|
|
2876 |
socket.on('agent connected', function(data) {
|
2877 |
var t_c_aid = data.aid;
|
2878 |
var t_c_sid = data.socketid;
|
2879 |
jQuery(".online_agent_" + t_c_aid).attr('socket', t_c_sid);
|
2880 |
jQuery(".online_agent_" + t_c_aid + ' .online_offline').removeClass('offline');
|
2881 |
jQuery(".online_agent_" + t_c_aid + ' .online_offline').addClass('online');
|
|
|
2882 |
jQuery.event.trigger({ type: "tcx_agent_connected", ndata: data });
|
2883 |
});
|
2884 |
|
2888 |
jQuery(".online_agent_" + t_c_aid).attr('socket', null);
|
2889 |
jQuery(".online_agent_" + t_c_aid + ' .online_offline').removeClass('online');
|
2890 |
jQuery(".online_agent_" + t_c_aid + ' .online_offline').addClass('offline');
|
|
|
2891 |
jQuery.event.trigger({ type: "tcx_agent_disconnected", ndata: data });
|
2892 |
});
|
2893 |
|
js/wplc_choose.js
CHANGED
@@ -5,23 +5,81 @@ jQuery(function() {
|
|
5 |
wplc_choose_delegate();
|
6 |
});
|
7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
jQuery(document).on("tcx_dom_ready", function(e) {
|
9 |
wplc_choose_delegate();
|
10 |
|
11 |
-
/**
|
12 |
-
* New agent connected
|
13 |
-
*/
|
14 |
-
jQuery(document).on("tcx_agent_connected", function(e) {
|
15 |
-
wplc_ma_update_admin_bar(1, "event one"); //Add one agent
|
16 |
-
});
|
17 |
-
|
18 |
-
/**
|
19 |
-
* New agent disconnected
|
20 |
-
*/
|
21 |
-
jQuery(document).on("tcx_agent_disconnected", function(e) {
|
22 |
-
if(typeof e.ndata.chatid !== 'undefined'){ return; }
|
23 |
-
wplc_ma_update_admin_bar(-1, "event off"); //remove one agent
|
24 |
-
});
|
25 |
});
|
26 |
|
27 |
function wplc_choose_delegate() {
|
@@ -40,19 +98,6 @@ function wplc_choose_delegate() {
|
|
40 |
jQuery("#wplc_agent_status_text").html(wplc_choose_admin_strings.not_accepting_chats);
|
41 |
}
|
42 |
|
43 |
-
//Transient
|
44 |
-
function wplc_ma_update_agent_transient(data) {
|
45 |
-
jQuery.post(ajaxurl, data, function(response) {
|
46 |
-
if (response) {
|
47 |
-
if (!config.wplc_use_node_server) {
|
48 |
-
window.location.reload();
|
49 |
-
} else {
|
50 |
-
jQuery.event.trigger({type: "wplc_switchery_changed",response:response, ndata:data});
|
51 |
-
}
|
52 |
-
}
|
53 |
-
});
|
54 |
-
}
|
55 |
-
|
56 |
/* Make sure switchery has been loaded on this page */
|
57 |
if (typeof Switchery !== 'undefined') {
|
58 |
var wplc_switchery_element = document.querySelector('.wplc_switchery');
|
@@ -67,26 +112,9 @@ function wplc_choose_delegate() {
|
|
67 |
setTimeout(function() {wplc_switchery_init.enable();},3000);
|
68 |
var wplc_accepting_chats = jQuery(this).attr('checked');
|
69 |
if (wplc_accepting_chats === 'checked') {
|
70 |
-
|
71 |
-
jQuery("#wplc_agent_status_text").html(wplc_choose_admin_strings.accepting_status);
|
72 |
-
var data = {
|
73 |
-
action: 'wplc_choose_accepting',
|
74 |
-
security: wplc_admin_strings.nonce,
|
75 |
-
user_id: wplc_admin_strings.user_id
|
76 |
-
};
|
77 |
-
wplc_ma_update_agent_transient(data);
|
78 |
-
wplc_ma_update_admin_bar(1, "click on"); //Add one agent
|
79 |
} else {
|
80 |
-
|
81 |
-
jQuery("#wplc_agent_status_text").html(wplc_choose_admin_strings.not_accepting_status);
|
82 |
-
connection_lost_type = 'offline_status';
|
83 |
-
var data = {
|
84 |
-
action: 'wplc_choose_not_accepting',
|
85 |
-
security: wplc_admin_strings.nonce,
|
86 |
-
user_id: wplc_admin_strings.user_id
|
87 |
-
};
|
88 |
-
wplc_ma_update_agent_transient(data);
|
89 |
-
wplc_ma_update_admin_bar(-1, "click off"); //remove one agent
|
90 |
}
|
91 |
};
|
92 |
|
@@ -94,33 +122,60 @@ function wplc_choose_delegate() {
|
|
94 |
}
|
95 |
}
|
96 |
|
97 |
-
//
|
98 |
-
function
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
|
|
|
|
104 |
}
|
|
|
|
|
105 |
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
}
|
118 |
-
}
|
119 |
|
120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
}
|
122 |
|
123 |
//Get the value currently stored in the admin bar
|
124 |
function wplc_ma_parse_active_count_from_container(){
|
125 |
return parseInt(jQuery("#wplc_ma_online_agents_count").text());
|
126 |
-
}
|
|
|
|
5 |
wplc_choose_delegate();
|
6 |
});
|
7 |
|
8 |
+
function wplc_update_agent_status(isOnline) {
|
9 |
+
if (isOnline) {
|
10 |
+
jQuery('#wplc_online_topbar_switch').removeClass('wplc_online_topbar_switch_offline');
|
11 |
+
jQuery('#wplc_online_topbar_switch').addClass('wplc_online_topbar_switch_online');
|
12 |
+
jQuery('#wplc_ma_online_agent_text').text(wplc_choose_admin_strings.accepting_chats);
|
13 |
+
jQuery('#wplc_online_topbar_switch').attr('checked','true');
|
14 |
+
} else {
|
15 |
+
jQuery('#wplc_online_topbar_switch').removeClass('wplc_online_topbar_switch_online');
|
16 |
+
jQuery('#wplc_online_topbar_switch').addClass('wplc_online_topbar_switch_offline');
|
17 |
+
jQuery('#wplc_ma_online_agent_text').text(wplc_choose_admin_strings.not_accepting_chats);
|
18 |
+
jQuery('#wplc_online_topbar_switch').removeAttr('checked');
|
19 |
+
}
|
20 |
+
}
|
21 |
+
|
22 |
+
jQuery(document).ready(function() {
|
23 |
+
jQuery('#wplc_online_topbar_switch').on('click',function(e) {
|
24 |
+
jQuery('#wplc_online_topbar_switch').attr('disabled', true);
|
25 |
+
setTimeout(function() {jQuery('#wplc_online_topbar_switch').removeAttr('disabled');}, 2000);
|
26 |
+
if (jQuery('#wplc_online_topbar_switch').attr('checked')) {
|
27 |
+
if (jQuery('#wplc_agent_status').length) {
|
28 |
+
jQuery('#wplc_agent_status').click();
|
29 |
+
} else {
|
30 |
+
wplc_set_agent_online();
|
31 |
+
}
|
32 |
+
} else {
|
33 |
+
if (jQuery('#wplc_agent_status').length) {
|
34 |
+
jQuery('#wplc_agent_status').click();
|
35 |
+
} else {
|
36 |
+
wplc_set_agent_offline();
|
37 |
+
}
|
38 |
+
}
|
39 |
+
return true;
|
40 |
+
});
|
41 |
+
|
42 |
+
jQuery(document).on("wplc_agent_online_changed", function(e) {
|
43 |
+
if (typeof e.response !== "undefined") {
|
44 |
+
var reply = JSON.parse(e.response);
|
45 |
+
if (!!reply && reply.agents) {
|
46 |
+
jQuery("#wplc_ma_online_agents_label").text(wplc_choose_admin_strings.agent_online_plural);
|
47 |
+
if (reply.agents.length>0) { // at least one agent online
|
48 |
+
// agent count
|
49 |
+
jQuery("#wplc_ma_online_agents_circle").removeClass("wplc_red_circle");
|
50 |
+
jQuery("#wplc_ma_online_agents_circle").addClass("wplc_green_circle");
|
51 |
+
if (reply.agents.length==1) {
|
52 |
+
jQuery("#wplc_ma_online_agents_label").text(wplc_choose_admin_strings.agent_online_singular);
|
53 |
+
}
|
54 |
+
} else { // no agents online
|
55 |
+
// agent count
|
56 |
+
jQuery("#wplc_ma_online_agents_circle").removeClass("wplc_green_circle");
|
57 |
+
jQuery("#wplc_ma_online_agents_circle").addClass("wplc_red_circle");
|
58 |
+
}
|
59 |
+
jQuery("#wplc_ma_online_agents_count").text(reply.agents.length);
|
60 |
+
}
|
61 |
+
// todo: update dropdown agent list in admin menu
|
62 |
+
}
|
63 |
+
|
64 |
+
});
|
65 |
+
|
66 |
+
jQuery(document).on("wplc_switchery_changed", function(e) {
|
67 |
+
jQuery.event.trigger({type: "wplc_agent_online_changed", response: e.response, ndata:e.ndata});
|
68 |
+
});
|
69 |
+
|
70 |
+
jQuery(document).on("tcx_agent_connected", function(e) {
|
71 |
+
wplc_ma_update_admin_bar();
|
72 |
+
});
|
73 |
+
|
74 |
+
jQuery(document).on("tcx_agent_disconnected", function(e) {
|
75 |
+
wplc_ma_update_admin_bar();
|
76 |
+
});
|
77 |
+
|
78 |
+
});
|
79 |
+
|
80 |
jQuery(document).on("tcx_dom_ready", function(e) {
|
81 |
wplc_choose_delegate();
|
82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
});
|
84 |
|
85 |
function wplc_choose_delegate() {
|
98 |
jQuery("#wplc_agent_status_text").html(wplc_choose_admin_strings.not_accepting_chats);
|
99 |
}
|
100 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
/* Make sure switchery has been loaded on this page */
|
102 |
if (typeof Switchery !== 'undefined') {
|
103 |
var wplc_switchery_element = document.querySelector('.wplc_switchery');
|
112 |
setTimeout(function() {wplc_switchery_init.enable();},3000);
|
113 |
var wplc_accepting_chats = jQuery(this).attr('checked');
|
114 |
if (wplc_accepting_chats === 'checked') {
|
115 |
+
wplc_set_agent_online();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
} else {
|
117 |
+
wplc_set_agent_offline();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
}
|
119 |
};
|
120 |
|
122 |
}
|
123 |
}
|
124 |
|
125 |
+
//Transient
|
126 |
+
function wplc_ma_update_agent_transient(data) {
|
127 |
+
jQuery.post(ajaxurl, data, function(response) {
|
128 |
+
if (response) {
|
129 |
+
if (!config.wplc_use_node_server) {
|
130 |
+
window.location.reload();
|
131 |
+
} else {
|
132 |
+
jQuery.event.trigger({type: "wplc_switchery_changed", response:response, ndata:data});
|
133 |
+
}
|
134 |
}
|
135 |
+
});
|
136 |
+
}
|
137 |
|
138 |
+
function wplc_set_agent_online() {
|
139 |
+
connection_lost_type = '';
|
140 |
+
jQuery("#wplc_agent_status_text").html(wplc_choose_admin_strings.accepting_status);
|
141 |
+
var data = {
|
142 |
+
action: 'wplc_choose_accepting',
|
143 |
+
security: wplc_admin_strings.nonce,
|
144 |
+
user_id: wplc_admin_strings.user_id
|
145 |
+
};
|
146 |
+
wplc_update_agent_status(true);
|
147 |
+
wplc_ma_update_agent_transient(data);
|
148 |
+
}
|
|
|
|
|
149 |
|
150 |
+
function wplc_set_agent_offline() {
|
151 |
+
jQuery.event.trigger({type: "wplc_end_all_open_chats"});
|
152 |
+
jQuery("#wplc_agent_status_text").html(wplc_choose_admin_strings.not_accepting_status);
|
153 |
+
connection_lost_type = 'offline_status';
|
154 |
+
var data = {
|
155 |
+
action: 'wplc_choose_not_accepting',
|
156 |
+
security: wplc_admin_strings.nonce,
|
157 |
+
user_id: wplc_admin_strings.user_id
|
158 |
+
};
|
159 |
+
wplc_update_agent_status(false);
|
160 |
+
wplc_ma_update_agent_transient(data);
|
161 |
+
}
|
162 |
+
|
163 |
+
function wplc_ma_update_admin_bar() {
|
164 |
+
var data = {
|
165 |
+
action: 'wplc_agent_list',
|
166 |
+
security: wplc_admin_strings.nonce,
|
167 |
+
user_id: wplc_admin_strings.user_id
|
168 |
+
};
|
169 |
+
jQuery.post(ajaxurl, data, function(response) {
|
170 |
+
if (response) {
|
171 |
+
jQuery.event.trigger({type: "wplc_agent_online_changed", response: response, ndata:data});
|
172 |
+
}
|
173 |
+
});
|
174 |
}
|
175 |
|
176 |
//Get the value currently stored in the admin bar
|
177 |
function wplc_ma_parse_active_count_from_container(){
|
178 |
return parseInt(jQuery("#wplc_ma_online_agents_count").text());
|
179 |
+
}
|
180 |
+
|
181 |
+
setInterval(function() {wplc_ma_update_admin_bar();}, 30000); // force update agent count - for offline agents
|
js/wplc_gutenberg.js
CHANGED
@@ -164,7 +164,7 @@ jQuery(function($){
|
|
164 |
templates['template_default'] = '<!-- Default Template - Dark -->\n<div class="wplc_block">\n\t<span class="wplc_block_logo">{wplc_logo}</span>\n\t<span class="wplc_block_text">{wplc_text}</span>\n\t<span class="wplc_block_icon">{wplc_icon}</span>\n</div>';
|
165 |
templates['template_default_tooltip'] = '<!-- Default - Tooltip -->\n<!-- Hover over the block to see the tooltip -->\n<div class="wplc_block">\n\t<span class="wplc_block_tooltip">Want to chat?</span>\n\t<span class="wplc_block_logo">{wplc_logo}</span>\n\t<span class="wplc_block_text">{wplc_text}</span>\n\t<span class="wplc_block_icon">{wplc_icon}</span>\n</div>';
|
166 |
templates['template_default_light'] = '<!-- Default - Light Template -->\n<div class="wplc_block light">\n\t<span class="wplc_block_logo">{wplc_logo}</span>\n\t<span class="wplc_block_text">{wplc_text}</span>\n\t<span class="wplc_block_icon">{wplc_icon}</span>\n</div>';
|
167 |
-
templates['template_tooltip'] = '<!--
|
168 |
templates['template_circle'] = '<!-- Circle Template -->\n<div class="wplc_block circle">\n\t<span class="wplc_block_logo">{wplc_logo}</span>\n</div>';
|
169 |
templates['template_chat_bubble'] = '<!-- Chat Bubble Template -->\n<div class="wplc_block chat_bubble">\n\t<span class="wplc_block_logo">{wplc_logo}</span>\n\t<span class="wplc_block_text">{wplc_text}</span>\n</div>';
|
170 |
templates['template_circle_rotate'] = '<!-- Circle - Rotating Template -->\n<!-- Hover over the icon to see it rotate -->\n<div class="wplc_block circle rotate">\n\t<span class="wplc_block_logo">{wplc_logo}</span>\n\t<span class="wplc_block_icon">{wplc_icon}</span>\n</div>';
|
164 |
templates['template_default'] = '<!-- Default Template - Dark -->\n<div class="wplc_block">\n\t<span class="wplc_block_logo">{wplc_logo}</span>\n\t<span class="wplc_block_text">{wplc_text}</span>\n\t<span class="wplc_block_icon">{wplc_icon}</span>\n</div>';
|
165 |
templates['template_default_tooltip'] = '<!-- Default - Tooltip -->\n<!-- Hover over the block to see the tooltip -->\n<div class="wplc_block">\n\t<span class="wplc_block_tooltip">Want to chat?</span>\n\t<span class="wplc_block_logo">{wplc_logo}</span>\n\t<span class="wplc_block_text">{wplc_text}</span>\n\t<span class="wplc_block_icon">{wplc_icon}</span>\n</div>';
|
166 |
templates['template_default_light'] = '<!-- Default - Light Template -->\n<div class="wplc_block light">\n\t<span class="wplc_block_logo">{wplc_logo}</span>\n\t<span class="wplc_block_text">{wplc_text}</span>\n\t<span class="wplc_block_icon">{wplc_icon}</span>\n</div>';
|
167 |
+
templates['template_tooltip'] = '<!-- Circle - Tooltip Template -->\n<!-- Hover over the block to see the tooltip -->\n<div class="wplc_block circle">\n\t<span class="wplc_block_tooltip">Chat with us!</span>\n\t<span class="wplc_block_logo">{wplc_logo}</span>\n</div>';
|
168 |
templates['template_circle'] = '<!-- Circle Template -->\n<div class="wplc_block circle">\n\t<span class="wplc_block_logo">{wplc_logo}</span>\n</div>';
|
169 |
templates['template_chat_bubble'] = '<!-- Chat Bubble Template -->\n<div class="wplc_block chat_bubble">\n\t<span class="wplc_block_logo">{wplc_logo}</span>\n\t<span class="wplc_block_text">{wplc_text}</span>\n</div>';
|
170 |
templates['template_circle_rotate'] = '<!-- Circle - Rotating Template -->\n<!-- Hover over the icon to see it rotate -->\n<div class="wplc_block circle rotate">\n\t<span class="wplc_block_logo">{wplc_logo}</span>\n\t<span class="wplc_block_icon">{wplc_icon}</span>\n</div>';
|
js/wplc_ma_transient.js
CHANGED
@@ -12,6 +12,7 @@
|
|
12 |
user_id: wplc_admin_strings.user_id
|
13 |
};
|
14 |
jQuery.post(ajaxurl, data, function(response) {
|
|
|
15 |
});
|
16 |
}
|
17 |
});
|
12 |
user_id: wplc_admin_strings.user_id
|
13 |
};
|
14 |
jQuery.post(ajaxurl, data, function(response) {
|
15 |
+
jQuery.event.trigger({type: "wplc_agent_online_changed", response: response, ndata:data});
|
16 |
});
|
17 |
}
|
18 |
});
|
js/wplc_server.js
CHANGED
@@ -341,52 +341,6 @@ function wplc_rest_api(type, wplc_send_data, wplc_send_timeout, next) {
|
|
341 |
}
|
342 |
}
|
343 |
|
344 |
-
function wplc_socket_async_storage_handler(wplc_send_url, wplc_send_data, wplc_send_timeout){
|
345 |
-
var wplc_node_ajax_action = "wplc_node_async_storage_ajax";
|
346 |
-
//Send the data to the Async
|
347 |
-
if(!!wplc_restapi_enabled.value && typeof wplc_restapi_endpoint !== "undefined") {
|
348 |
-
//REST API
|
349 |
-
wplc_send_url = wplc_restapi_endpoint + "/async_storage";
|
350 |
-
} else {
|
351 |
-
//Ajax
|
352 |
-
}
|
353 |
-
|
354 |
-
var prepared_data = {
|
355 |
-
action : wplc_node_ajax_action,
|
356 |
-
relay_action : wplc_send_data.action,
|
357 |
-
chat_id : wplc_send_data.cid,
|
358 |
-
security : wplc_send_data.security,
|
359 |
-
messages : JSON.stringify(wplc_node_async_array),
|
360 |
-
wplc_extra_data:document.wplc_extra_data
|
361 |
-
};
|
362 |
-
|
363 |
-
if(typeof tcx_api_key !== "undefined"){
|
364 |
-
prepared_data.server_token = tcx_api_key;
|
365 |
-
}
|
366 |
-
|
367 |
-
/*
|
368 |
-
wplc_node_async_array = new Array(); //Clearing the storage array before the next data can be sent through
|
369 |
-
if(typeof Cookies !== "undefined" && typeof Cookies === "function"){
|
370 |
-
Cookies.remove('wplc_server_async_storage'); //Clear the cookies now so that we don't do this again.
|
371 |
-
}
|
372 |
-
*/
|
373 |
-
jQuery.ajax({
|
374 |
-
url : wplc_send_url,
|
375 |
-
data : prepared_data,
|
376 |
-
type : "POST",
|
377 |
-
timeout : wplc_send_timeout,
|
378 |
-
success : function(response){
|
379 |
-
wplc_server_log("ASYNC STORAGE = SUCCESS");
|
380 |
-
},
|
381 |
-
error : function(error, exception){
|
382 |
-
wplc_server_log("ASYNC STORAGE = FAIL");
|
383 |
-
},
|
384 |
-
complete : function(response){
|
385 |
-
|
386 |
-
}
|
387 |
-
});
|
388 |
-
}
|
389 |
-
|
390 |
function wplc_json_validator(str) {
|
391 |
try {
|
392 |
JSON.parse(str);
|
341 |
}
|
342 |
}
|
343 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
344 |
function wplc_json_validator(str) {
|
345 |
try {
|
346 |
JSON.parse(str);
|
js/wplc_u_admin_events.js
CHANGED
@@ -542,7 +542,7 @@ jQuery(document).on("tcx_dom_ready", function(e) {
|
|
542 |
jQuery(document).on("wplc_switchery_changed", function(e) {
|
543 |
if (typeof e.ndata !== "undefined" && typeof e.ndata.action !== "undefined" && e.ndata.action === "wplc_choose_not_accepting") {
|
544 |
/* drop the connection */
|
545 |
-
if (socket.connected) {
|
546 |
socket.disconnect();
|
547 |
}
|
548 |
} else if (e.ndata.action === "wplc_choose_accepting") {
|
542 |
jQuery(document).on("wplc_switchery_changed", function(e) {
|
543 |
if (typeof e.ndata !== "undefined" && typeof e.ndata.action !== "undefined" && e.ndata.action === "wplc_choose_not_accepting") {
|
544 |
/* drop the connection */
|
545 |
+
if (!!socket && socket.connected) {
|
546 |
socket.disconnect();
|
547 |
}
|
548 |
} else if (e.ndata.action === "wplc_choose_accepting") {
|
js/wplc_u_pro.js
CHANGED
@@ -134,7 +134,7 @@ jQuery(function() {
|
|
134 |
var height = jQuery('#wplc_chatbox')[0].scrollHeight;
|
135 |
jQuery('#wplc_chatbox').scrollTop(height);
|
136 |
if (!!wplc_enable_ding.value) {
|
137 |
-
new Audio(wplc_plugin_url + '
|
138 |
}
|
139 |
|
140 |
}
|
134 |
var height = jQuery('#wplc_chatbox')[0].scrollHeight;
|
135 |
jQuery('#wplc_chatbox').scrollTop(height);
|
136 |
if (!!wplc_enable_ding.value) {
|
137 |
+
new Audio(wplc_plugin_url + 'wp-live-chat-support/includes/sounds/general/ding.mp3').play()
|
138 |
}
|
139 |
|
140 |
}
|
modules/api/agent/wplc-api-functions.php
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
-
<?php
|
2 |
/* Handles all functions related to the WP Live Chat Support API */
|
3 |
|
4 |
-
if (
|
5 |
-
|
6 |
}
|
7 |
|
8 |
|
@@ -13,64 +13,74 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
13 |
* - Chat ID
|
14 |
* - Agent ID
|
15 |
*/
|
16 |
-
function wplc_api_accept_chat(WP_REST_Request $request){
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
}
|
75 |
|
76 |
/*
|
@@ -80,68 +90,78 @@ function wplc_api_accept_chat(WP_REST_Request $request){
|
|
80 |
* - Chat ID
|
81 |
* - Agent ID
|
82 |
*/
|
83 |
-
function wplc_api_agent_end_chat(WP_REST_Request $request){
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
}
|
146 |
|
147 |
|
@@ -153,79 +173,86 @@ function wplc_api_agent_end_chat(WP_REST_Request $request){
|
|
153 |
* - Chat ID
|
154 |
* - Message
|
155 |
*/
|
156 |
-
function wplc_api_agent_send_message(WP_REST_Request $request){
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
229 |
}
|
230 |
|
231 |
|
@@ -239,180 +266,181 @@ function wplc_api_agent_send_message(WP_REST_Request $request){
|
|
239 |
* - Limit (Defaults to 50/Max Limit of 50)
|
240 |
* - Offset (Defaults to 0)
|
241 |
*/
|
242 |
-
function wplc_api_agent_get_messages(WP_REST_Request $request){
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
300 |
}
|
301 |
|
302 |
|
303 |
/*
|
304 |
* Records an admin message via the API
|
305 |
*/
|
306 |
-
function wplc_api_agent_record_admin_message($cid, $msg){
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
}
|
341 |
|
342 |
/*
|
343 |
* Returns messages from server
|
344 |
*/
|
345 |
-
function wplc_api_agent_return_messages($cid, $limit, $offset, $received_via = 'u'){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
346 |
|
347 |
-
|
|
|
|
|
348 |
|
349 |
-
|
350 |
|
351 |
-
|
352 |
-
wplc_mark_as_read_user_chat_messages( $cid );
|
353 |
-
} else {
|
354 |
-
wplc_mark_as_read_agent_chat_messages( $cid, $received_via );
|
355 |
-
}
|
356 |
-
return $messages;
|
357 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
358 |
|
359 |
-
|
|
|
|
|
|
|
|
|
|
|
360 |
|
361 |
|
362 |
-
|
363 |
-
global $wpdb;
|
364 |
-
global $wplc_tblname_chats;
|
365 |
-
|
366 |
-
$results = $wpdb->get_results("SELECT * FROM $wplc_tblname_chats WHERE `status` = 3 OR `status` = 2 OR `status` = 10 OR `status` = 5 or `status` = 8 or `status` = 9 ORDER BY `timestamp` ASC");
|
367 |
-
|
368 |
-
$session_array = array();
|
369 |
-
|
370 |
-
if ($results) {
|
371 |
-
foreach ($results as $result) {
|
372 |
-
$ip_info = maybe_unserialize($result->ip);
|
373 |
-
$user_ip = $ip_info['ip'];
|
374 |
-
if($user_ip == ""){
|
375 |
-
$user_ip = __('IP Address not recorded', 'wp-live-chat-support');
|
376 |
-
}
|
377 |
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
$path = parse_url($result->url, PHP_URL_PATH);
|
403 |
-
|
404 |
-
if (strlen($path) > 20) {
|
405 |
-
$session_array[$result->id]['data']['browsing_nice_url'] = substr($path,0,20).'...';
|
406 |
-
} else {
|
407 |
-
$session_array[$result->id]['data']['browsing_nice_url'] = $path;
|
408 |
-
}
|
409 |
-
|
410 |
-
$session_array[$result->id]['data']['browser'] = WPLC_PLUGIN_URL . "images/$browser_image";
|
411 |
-
$session_array[$result->id]['data']['ip'] = $user_ip;
|
412 |
-
}
|
413 |
}
|
414 |
-
|
415 |
-
|
|
|
416 |
}
|
417 |
|
418 |
|
@@ -425,295 +453,285 @@ function wplc_api_agent_return_sessions() {
|
|
425 |
/*
|
426 |
* Upload end point
|
427 |
*/
|
428 |
-
function wplc_api_remote_upload(WP_REST_Request $request){
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
$return_array = apply_filters("wplc_api_remote_upload_filter", $return_array, $request);
|
434 |
-
|
435 |
-
return $return_array;
|
436 |
}
|
437 |
|
438 |
/*
|
439 |
* Rest Permission check for restricted end points
|
440 |
*/
|
441 |
-
function wplc_api_agent_permission_check(){
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
447 |
}
|
448 |
|
449 |
-
function wplc_agent_validate_agent_check(WP_REST_Request $request){
|
450 |
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
456 |
$return_array['code'] = "200";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
457 |
} else {
|
458 |
-
|
459 |
-
$return_array['code'] = "200";
|
460 |
}
|
461 |
-
|
462 |
-
$return_array['response'] = "No
|
463 |
$return_array['code'] = "401";
|
464 |
-
$return_array['requirements'] = array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
465 |
}
|
466 |
-
|
467 |
-
$return_array['response'] = "
|
468 |
-
$return_array['code'] = "
|
469 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
470 |
}
|
471 |
-
|
472 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
473 |
}
|
474 |
|
475 |
|
476 |
-
# PRO API FUNCTIONS
|
477 |
-
function wplc_api_send_agent_message_mrg(WP_REST_Request $request){
|
478 |
-
|
479 |
-
$return_array = array();
|
480 |
-
if(isset($request)){
|
481 |
-
if(isset($request['server_token'])){
|
482 |
-
$check_token = get_option('wplc_api_secret_token');
|
483 |
-
if($check_token !== false && $request['server_token'] === $check_token){
|
484 |
-
if(isset($request['chat_id'])){
|
485 |
-
if(isset($request['message'])){
|
486 |
-
if(isset($request['relay_action'])){
|
487 |
-
|
488 |
-
$chat_id = sanitize_text_field($request['chat_id']);
|
489 |
-
$message = $request['message'];
|
490 |
-
$action = $request['relay_action'];
|
491 |
-
|
492 |
-
if (!empty($request['msg_id'])) {
|
493 |
-
$other = new stdClass();
|
494 |
-
$other->msgID = $request['msg_id'];
|
495 |
-
} else {
|
496 |
-
$other = false;
|
497 |
-
}
|
498 |
-
|
499 |
-
if ($action == "wplc_admin_send_msg"){
|
500 |
-
$message = sanitize_text_field( $message );
|
501 |
-
$ato = intval( $request['ato'] );
|
502 |
-
if(isset($request['orig_override'])){
|
503 |
-
wplc_api_record_agent_chat_msg_mrg(sanitize_text_field( $request['agent_id'] ), $chat_id, $message, true, $ato, $other, $request['orig_override']);
|
504 |
-
} else {
|
505 |
-
wplc_api_record_agent_chat_msg_mrg(sanitize_text_field( $request['agent_id'] ), $chat_id, $message, true, $ato, $other);
|
506 |
-
}
|
507 |
-
wplc_update_active_timestamp($chat_id);
|
508 |
-
|
509 |
-
$return_array['response'] = "Message sent successfully";
|
510 |
-
$return_array['code'] = "200";
|
511 |
-
$return_array['data'] = array("chat_id" => intval($request['chat_id']),
|
512 |
-
"agent_id" => intval($request['agent_id']));
|
513 |
-
|
514 |
-
do_action("wplc_new_user_message_after_record_hook", $chat_id, $message);
|
515 |
-
}
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
} else {
|
520 |
-
$return_array['request_information'] = __("Action not set", 'wp-live-chat-support');
|
521 |
-
}
|
522 |
-
} else {
|
523 |
-
$return_array['response'] = "No 'message' found";
|
524 |
-
$return_array['code'] = "401";
|
525 |
-
$return_array['requirements'] = array("server_token" => "YOUR_SECRET_TOKEN",
|
526 |
-
"chat_id" => "Chat ID",
|
527 |
-
"message" => "Message");
|
528 |
-
}
|
529 |
-
} else {
|
530 |
-
$return_array['response'] = "No 'chat_id' found";
|
531 |
-
$return_array['code'] = "401";
|
532 |
-
$return_array['requirements'] = array("server_token" => "YOUR_SECRET_TOKEN",
|
533 |
-
"chat_id" => "Chat ID",
|
534 |
-
"message" => "Message");
|
535 |
-
}
|
536 |
-
} else {
|
537 |
-
$return_array['response'] = "Secret server_token is invalid";
|
538 |
-
$return_array['code'] = "401";
|
539 |
-
}
|
540 |
-
}else{
|
541 |
-
$return_array['response'] = "No secret 'server_token' found";
|
542 |
-
$return_array['code'] = "401";
|
543 |
-
$return_array['requirements'] = array("server_token" => "YOUR_SECRET_TOKEN",
|
544 |
-
"chat_id" => "Chat ID",
|
545 |
-
"message" => "Message");
|
546 |
-
}
|
547 |
-
}else{
|
548 |
-
$return_array['response'] = "No request data found";
|
549 |
-
$return_array['code'] = "400";
|
550 |
-
$return_array['requirements'] = array("server_token" => "YOUR_SECRET_TOKEN",
|
551 |
-
"chat_id" => "Chat ID",
|
552 |
-
"message" => "Message");
|
553 |
-
}
|
554 |
-
|
555 |
-
return $return_array;
|
556 |
-
}
|
557 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
558 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
559 |
|
560 |
-
|
561 |
-
|
562 |
-
$return_array = array();
|
563 |
-
if(isset($request)){
|
564 |
-
if(isset($request['token'])){
|
565 |
-
$check_token = get_option('wplc_api_secret_token');
|
566 |
-
if($check_token !== false && $request['token'] === $check_token){
|
567 |
-
|
568 |
-
$current_agent = intval( sanitize_text_field( $request['agent_id'] ) );
|
569 |
-
|
570 |
-
/**
|
571 |
-
* Get all agents
|
572 |
-
* @var [type]
|
573 |
-
*/
|
574 |
-
$user_array = get_users(array(
|
575 |
-
'meta_key' => 'wplc_ma_agent',
|
576 |
-
));
|
577 |
-
|
578 |
-
|
579 |
-
$a_array = array();
|
580 |
-
if ($user_array) {
|
581 |
-
foreach ($user_array as $user) {
|
582 |
-
$unread = wplc_return_unread_agent_messages_mrg( $current_agent, $user->ID );
|
583 |
-
$a_array[$user->ID] = $unread;
|
584 |
-
|
585 |
-
}
|
586 |
-
}
|
587 |
-
$return_array['response'] = "Unread count agents"; /* needs to be exactly this for the JS to fire correctly */
|
588 |
-
$return_array['code'] = "200";
|
589 |
-
$return_array['data'] = $a_array;
|
590 |
-
|
591 |
-
} else {
|
592 |
-
$return_array['response'] = "Secret token is invalid";
|
593 |
-
$return_array['code'] = "401";
|
594 |
-
}
|
595 |
-
}else{
|
596 |
-
$return_array['response'] = "No secret 'token' found";
|
597 |
-
$return_array['code'] = "401";
|
598 |
-
$return_array['requirements'] = array("token" => "YOUR_SECRET_TOKEN");
|
599 |
-
}
|
600 |
-
}else{
|
601 |
-
$return_array['response'] = "No request data found";
|
602 |
-
$return_array['code'] = "400";
|
603 |
-
$return_array['requirements'] = array("token" => "YOUR_SECRET_TOKEN");
|
604 |
-
}
|
605 |
-
|
606 |
-
return $return_array;
|
607 |
}
|
608 |
|
609 |
function wplc_api_initiate_chat_mrg(WP_REST_REQUEST $request) {
|
610 |
$wplc_settings = wplc_get_options();
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
"cid" => "Chat ID",
|
713 |
-
"wplc_extra_data" => "Data array");
|
714 |
-
}
|
715 |
-
|
716 |
-
return $return_array;
|
717 |
}
|
718 |
|
719 |
function wplc_api_agent_email_notification_mrg(WP_REST_Request $request) { // TODO: this function is never referenced
|
@@ -726,7 +744,7 @@ function wplc_api_agent_email_notification_mrg(WP_REST_Request $request) { // TO
|
|
726 |
if (isset($request['wplc_extra_data'])) {
|
727 |
// TODO: this code does nothing useful
|
728 |
$data = $request['wplc_extra_data'];
|
729 |
-
$wplc_settings = wplc_get_options();
|
730 |
$email_address = wplc_determine_admin_email($wplc_settings);
|
731 |
return true;
|
732 |
} else {
|
@@ -735,15 +753,17 @@ function wplc_api_agent_email_notification_mrg(WP_REST_Request $request) { // TO
|
|
735 |
$return_array['requirements'] = array(
|
736 |
"security" => "YOUR_SECRET_TOKEN",
|
737 |
"cid" => "Chat ID",
|
738 |
-
"wplc_extra_data" => "Data array"
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
|
|
|
|
747 |
}
|
748 |
} else {
|
749 |
$return_array['response'] = "Nonce is invalid";
|
@@ -770,218 +790,229 @@ function wplc_api_agent_email_notification_mrg(WP_REST_Request $request) { // TO
|
|
770 |
return $return_array;
|
771 |
}
|
772 |
|
773 |
-
function wplc_api_agent_is_typing_mrg(WP_REST_Request $request){
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
847 |
}
|
848 |
|
849 |
|
850 |
function wplc_api_record_agent_chat_msg_mrg($from, $cid, $msg, $rest_check = false, $ato = false, $other = false, $orig_override = false) {
|
851 |
-
|
852 |
-
|
853 |
|
854 |
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
/**
|
859 |
-
* We need to identify if this CID is a node CID, and if so, return the WP CID from the wplc_chat_msgs table
|
860 |
-
*/
|
861 |
-
$cid = wplc_return_chat_id_by_rel($cid);
|
862 |
-
}
|
863 |
|
864 |
/**
|
865 |
-
*
|
866 |
-
*
|
867 |
-
* If it doesnt exist, it most likely is an agent-to-agent chat that we now need to save.
|
868 |
*/
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
|
|
|
|
|
|
|
|
906 |
|
907 |
-
$msg_id = '';
|
908 |
-
if ($other !== false) {
|
909 |
-
if (!empty($other->msgID)) {
|
910 |
-
$msg_id = $other->msgID;
|
911 |
-
} else {
|
912 |
-
$msg_id = '';
|
913 |
-
}
|
914 |
-
}
|
915 |
|
916 |
-
$
|
917 |
-
|
918 |
-
|
|
|
|
|
|
|
|
|
919 |
} else {
|
920 |
-
|
921 |
-
}
|
922 |
-
$orig = '1';
|
923 |
-
if($orig_override !== false){
|
924 |
-
$orig = sanitize_text_field($orig_override);
|
925 |
}
|
|
|
926 |
|
927 |
-
|
928 |
-
|
929 |
-
$
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
'msgfrom' => $fromname,
|
938 |
-
'msg' => $msg,
|
939 |
-
'status' => 0,
|
940 |
-
'originates' => $orig,
|
941 |
-
'other' => '',
|
942 |
-
'rel' => $msg_id,
|
943 |
-
'ato' => $ato,
|
944 |
-
'afrom' => $from
|
945 |
-
),
|
946 |
-
array(
|
947 |
-
'%s',
|
948 |
-
'%s',
|
949 |
-
'%s',
|
950 |
-
'%s',
|
951 |
-
'%d',
|
952 |
-
'%s',
|
953 |
-
'%s',
|
954 |
-
'%s',
|
955 |
-
'%d',
|
956 |
-
'%d'
|
957 |
-
)
|
958 |
-
);
|
959 |
-
|
960 |
-
$data = array(
|
961 |
-
'cid' => $cid,
|
962 |
-
'from' => $from,
|
963 |
-
'msg' => $orig_msg,
|
964 |
-
'orig' => $orig
|
965 |
-
);
|
966 |
-
//do_action("wplc_hook_message_sent",$data);
|
967 |
-
|
968 |
-
wplc_update_active_timestamp(sanitize_text_field($cid));
|
969 |
-
|
970 |
-
|
971 |
-
return true;
|
972 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
973 |
}
|
974 |
|
975 |
add_filter("wplc_api_remote_upload_filter", "wplc_api_agent_remote_upload_handler_mrg", 10, 2);
|
976 |
/*
|
977 |
* Processes remote uploads, from app or main agent files as an example
|
978 |
*/
|
979 |
-
function wplc_api_agent_remote_upload_handler_mrg($return_array, $request) {
|
980 |
$remote_files = $request->get_file_params();
|
981 |
if (is_array($remote_files)) {
|
982 |
$upload_dir = wp_upload_dir();
|
983 |
$user_dirname = $upload_dir['basedir'];
|
984 |
-
$cid=0;
|
985 |
if (isset($request['cid'])) {
|
986 |
$cid = sanitize_text_field($request['cid']);
|
987 |
if (!filter_var($cid, FILTER_VALIDATE_INT)) {
|
@@ -991,24 +1022,24 @@ function wplc_api_agent_remote_upload_handler_mrg($return_array, $request) {
|
|
991 |
$cid = intval($cid);
|
992 |
}
|
993 |
|
994 |
-
if (!file_exists(
|
995 |
-
@mkdir($user_dirname.'/wp_live_chat/');
|
996 |
-
}
|
997 |
|
998 |
-
if (!realpath($user_dirname."/wp_live_chat/"
|
999 |
-
@mkdir(
|
1000 |
-
}
|
1001 |
|
1002 |
if (isset($remote_files['file'])) {
|
1003 |
-
$file_name = strtolower(sanitize_file_name($remote_files['file']['name'])
|
1004 |
$file_name = basename($file_name); //This prevents traversal
|
1005 |
$file_name = str_replace(" ", "_", $file_name);
|
1006 |
if (wplc_check_file_name_for_safe_extension($file_name)) {
|
1007 |
-
if (realpath($user_dirname . "/wp_live_chat/" . $cid . "/" . $file_name
|
1008 |
$file_name = rand(0, 10) . "-" . $file_name;
|
1009 |
-
}
|
1010 |
-
if (move_uploaded_file($remote_files['file']['tmp_name'], $user_dirname."/wp_live_chat/" . $cid . "/" . $file_name)) {
|
1011 |
-
$response = $upload_dir['baseurl']."/wp_live_chat/" . $cid . "/" . $file_name;
|
1012 |
$return_array['response'] = wp_filter_post_kses(strip_tags($response));
|
1013 |
} else {
|
1014 |
$return_array['response'] = __('Upload error', 'wp-live-chat-support');
|
@@ -1027,16 +1058,16 @@ function wplc_api_agent_remote_upload_handler_mrg($return_array, $request) {
|
|
1027 |
|
1028 |
/**
|
1029 |
* Cleanup all REST Params
|
1030 |
-
*/
|
1031 |
-
function wplc_api_agent_sanitize_request_params(WP_REST_Request $request){
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
|
1041 |
-
|
1042 |
}
|
1 |
+
<?php
|
2 |
/* Handles all functions related to the WP Live Chat Support API */
|
3 |
|
4 |
+
if (!defined('ABSPATH')) {
|
5 |
+
exit;
|
6 |
}
|
7 |
|
8 |
|
13 |
* - Chat ID
|
14 |
* - Agent ID
|
15 |
*/
|
16 |
+
function wplc_api_accept_chat(WP_REST_Request $request) {
|
17 |
+
|
18 |
+
$return_array = array();
|
19 |
+
if (isset($request)) {
|
20 |
+
if (isset($request['token'])) {
|
21 |
+
$check_token = get_option('wplc_api_secret_token');
|
22 |
+
if ($check_token !== false && $request['token'] === $check_token) {
|
23 |
+
if (isset($request['chat_id'])) {
|
24 |
+
if (isset($request['agent_id'])) {
|
25 |
+
|
26 |
+
$cid = wplc_return_chat_id_by_rel($request['chat_id']);
|
27 |
+
if (wplc_change_chat_status($cid, 3, intval($request['agent_id']))) {
|
28 |
+
|
29 |
+
|
30 |
+
do_action("wplc_hook_update_agent_id", sanitize_text_field($request['cid']), intval($request['agent_id']));
|
31 |
+
|
32 |
+
$return_array['response'] = "Chat accepted successfully";
|
33 |
+
$return_array['code'] = "200";
|
34 |
+
$return_array['data'] = array(
|
35 |
+
"chat_id" => intval($request['chat_id']),
|
36 |
+
"agent_id" => intval($request['agent_id'])
|
37 |
+
);
|
38 |
+
} else {
|
39 |
+
$return_array['response'] = "Status could not be changed";
|
40 |
+
$return_array['code'] = "404";
|
41 |
+
}
|
42 |
+
} else {
|
43 |
+
$return_array['response'] = "No 'agent_id' found";
|
44 |
+
$return_array['code'] = "401";
|
45 |
+
$return_array['requirements'] = array(
|
46 |
+
"token" => "YOUR_SECRET_TOKEN",
|
47 |
+
"chat_id" => "Chat ID",
|
48 |
+
"agent_id" => "Agent ID"
|
49 |
+
);
|
50 |
+
}
|
51 |
+
} else {
|
52 |
+
$return_array['response'] = "No 'chat_id' found";
|
53 |
+
$return_array['code'] = "401";
|
54 |
+
$return_array['requirements'] = array(
|
55 |
+
"token" => "YOUR_SECRET_TOKEN",
|
56 |
+
"chat_id" => "Chat ID",
|
57 |
+
"agent_id" => "Agent ID"
|
58 |
+
);
|
59 |
+
}
|
60 |
+
} else {
|
61 |
+
$return_array['response'] = "Secret token is invalid";
|
62 |
+
$return_array['code'] = "401";
|
63 |
+
}
|
64 |
+
} else {
|
65 |
+
$return_array['response'] = "No secret 'token' found";
|
66 |
+
$return_array['code'] = "401";
|
67 |
+
$return_array['requirements'] = array(
|
68 |
+
"token" => "YOUR_SECRET_TOKEN",
|
69 |
+
"chat_id" => "Chat ID",
|
70 |
+
"agent_id" => "Agent ID"
|
71 |
+
);
|
72 |
+
}
|
73 |
+
} else {
|
74 |
+
$return_array['response'] = "No request data found";
|
75 |
+
$return_array['code'] = "400";
|
76 |
+
$return_array['requirements'] = array(
|
77 |
+
"token" => "YOUR_SECRET_TOKEN",
|
78 |
+
"chat_id" => "Chat ID",
|
79 |
+
"agent_id" => "Agent ID"
|
80 |
+
);
|
81 |
+
}
|
82 |
+
|
83 |
+
return $return_array;
|
84 |
}
|
85 |
|
86 |
/*
|
90 |
* - Chat ID
|
91 |
* - Agent ID
|
92 |
*/
|
93 |
+
function wplc_api_agent_end_chat(WP_REST_Request $request) {
|
94 |
+
|
95 |
+
$return_array = array();
|
96 |
+
if (isset($request)) {
|
97 |
+
if (isset($request['token'])) {
|
98 |
+
$check_token = get_option('wplc_api_secret_token');
|
99 |
+
if ($check_token !== false && $request['token'] === $check_token) {
|
100 |
+
if (isset($request['chat_id'])) {
|
101 |
+
if (isset($request['agent_id'])) {
|
102 |
+
|
103 |
+
$cid = $request['chat_id'];
|
104 |
+
if (!filter_var($request['chat_id'], FILTER_VALIDATE_INT)) {
|
105 |
+
/* We need to identify if this CID is a node CID, and if so, return the WP CID */
|
106 |
+
$cid = wplc_return_chat_id_by_rel($cid);
|
107 |
+
}
|
108 |
+
|
109 |
+
if (wplc_change_chat_status($cid, 1, intval($request['agent_id']))) {
|
110 |
+
|
111 |
+
do_action('wplc_send_transcript_hook', $cid);
|
112 |
+
|
113 |
+
$return_array['response'] = "Chat ended successfully";
|
114 |
+
$return_array['code'] = "200";
|
115 |
+
$return_array['data'] = array(
|
116 |
+
"chat_id" => $cid,
|
117 |
+
"agent_id" => intval($request['agent_id'])
|
118 |
+
);
|
119 |
+
} else {
|
120 |
+
$return_array['response'] = "Status could not be changed";
|
121 |
+
$return_array['code'] = "404";
|
122 |
+
}
|
123 |
+
} else {
|
124 |
+
$return_array['response'] = "No 'agent_id' found";
|
125 |
+
$return_array['code'] = "401";
|
126 |
+
$return_array['requirements'] = array(
|
127 |
+
"token" => "YOUR_SECRET_TOKEN",
|
128 |
+
"chat_id" => "Chat ID",
|
129 |
+
"agent_id" => "Agent ID"
|
130 |
+
);
|
131 |
+
}
|
132 |
+
} else {
|
133 |
+
$return_array['response'] = "No 'chat_id' found";
|
134 |
+
$return_array['code'] = "401";
|
135 |
+
$return_array['requirements'] = array(
|
136 |
+
"token" => "YOUR_SECRET_TOKEN",
|
137 |
+
"chat_id" => "Chat ID",
|
138 |
+
"agent_id" => "Agent ID"
|
139 |
+
);
|
140 |
+
}
|
141 |
+
} else {
|
142 |
+
$return_array['response'] = "Secret token is invalid";
|
143 |
+
$return_array['code'] = "401";
|
144 |
+
}
|
145 |
+
} else {
|
146 |
+
$return_array['response'] = "No secret 'token' found";
|
147 |
+
$return_array['code'] = "401";
|
148 |
+
$return_array['requirements'] = array(
|
149 |
+
"token" => "YOUR_SECRET_TOKEN",
|
150 |
+
"chat_id" => "Chat ID",
|
151 |
+
"agent_id" => "Agent ID"
|
152 |
+
);
|
153 |
+
}
|
154 |
+
} else {
|
155 |
+
$return_array['response'] = "No request data found";
|
156 |
+
$return_array['code'] = "400";
|
157 |
+
$return_array['requirements'] = array(
|
158 |
+
"token" => "YOUR_SECRET_TOKEN",
|
159 |
+
"chat_id" => "Chat ID",
|
160 |
+
"agent_id" => "Agent ID"
|
161 |
+
);
|
162 |
+
}
|
163 |
+
|
164 |
+
return $return_array;
|
165 |
}
|
166 |
|
167 |
|
173 |
* - Chat ID
|
174 |
* - Message
|
175 |
*/
|
176 |
+
function wplc_api_agent_send_message(WP_REST_Request $request) {
|
177 |
+
|
178 |
+
$return_array = array();
|
179 |
+
if (isset($request)) {
|
180 |
+
if (isset($request['server_token'])) {
|
181 |
+
$check_token = get_option('wplc_api_secret_token');
|
182 |
+
if ($check_token !== false && $request['server_token'] === $check_token) {
|
183 |
+
if (isset($request['chat_id'])) {
|
184 |
+
if (isset($request['message'])) {
|
185 |
+
if (isset($request['relay_action'])) {
|
186 |
+
|
187 |
+
$chat_id = sanitize_text_field($request['chat_id']);
|
188 |
+
$message = $request['message'];
|
189 |
+
$action = $request['relay_action'];
|
190 |
+
|
191 |
+
if (!empty($request['msg_id'])) {
|
192 |
+
$other = new stdClass();
|
193 |
+
$other->msgID = $request['msg_id'];
|
194 |
+
} else {
|
195 |
+
$other = false;
|
196 |
+
}
|
197 |
+
|
198 |
+
if ($action == "wplc_admin_send_msg") {
|
199 |
+
wplc_record_chat_msg("2", $chat_id, $message, true, sanitize_text_field($request['agent_id']), $other);
|
200 |
+
wplc_update_active_timestamp($chat_id);
|
201 |
+
|
202 |
+
$return_array['response'] = "Message sent successfully";
|
203 |
+
$return_array['code'] = "200";
|
204 |
+
$return_array['data'] = array(
|
205 |
+
"chat_id" => sanitize_text_field($request['chat_id']),
|
206 |
+
"agent_id" => intval($request['agent_id'])
|
207 |
+
);
|
208 |
+
|
209 |
+
do_action("wplc_new_user_message_after_record_hook", $chat_id, $message);
|
210 |
+
}
|
211 |
+
} else {
|
212 |
+
$return_array['request_information'] = __("Action not set", 'wp-live-chat-support');
|
213 |
+
}
|
214 |
+
} else {
|
215 |
+
$return_array['response'] = "No 'message' found";
|
216 |
+
$return_array['code'] = "401";
|
217 |
+
$return_array['requirements'] = array(
|
218 |
+
"server_token" => "YOUR_SECRET_TOKEN",
|
219 |
+
"chat_id" => "Chat ID",
|
220 |
+
"message" => "Message"
|
221 |
+
);
|
222 |
+
}
|
223 |
+
} else {
|
224 |
+
$return_array['response'] = "No 'chat_id' found";
|
225 |
+
$return_array['code'] = "401";
|
226 |
+
$return_array['requirements'] = array(
|
227 |
+
"server_token" => "YOUR_SECRET_TOKEN",
|
228 |
+
"chat_id" => "Chat ID",
|
229 |
+
"message" => "Message"
|
230 |
+
);
|
231 |
+
}
|
232 |
+
} else {
|
233 |
+
$return_array['response'] = "Secret server_token is invalid";
|
234 |
+
$return_array['code'] = "401";
|
235 |
+
}
|
236 |
+
} else {
|
237 |
+
$return_array['response'] = "No secret 'server_token' found";
|
238 |
+
$return_array['code'] = "401";
|
239 |
+
$return_array['requirements'] = array(
|
240 |
+
"server_token" => "YOUR_SECRET_TOKEN",
|
241 |
+
"chat_id" => "Chat ID",
|
242 |
+
"message" => "Message"
|
243 |
+
);
|
244 |
+
}
|
245 |
+
} else {
|
246 |
+
$return_array['response'] = "No request data found";
|
247 |
+
$return_array['code'] = "400";
|
248 |
+
$return_array['requirements'] = array(
|
249 |
+
"server_token" => "YOUR_SECRET_TOKEN",
|
250 |
+
"chat_id" => "Chat ID",
|
251 |
+
"message" => "Message"
|
252 |
+
);
|
253 |
+
}
|
254 |
+
|
255 |
+
return $return_array;
|
256 |
}
|
257 |
|
258 |
|
266 |
* - Limit (Defaults to 50/Max Limit of 50)
|
267 |
* - Offset (Defaults to 0)
|
268 |
*/
|
269 |
+
function wplc_api_agent_get_messages(WP_REST_Request $request) {
|
270 |
+
|
271 |
+
$return_array = array();
|
272 |
+
if (isset($request)) {
|
273 |
+
if (isset($request['token'])) {
|
274 |
+
$check_token = get_option('wplc_api_secret_token');
|
275 |
+
if ($check_token !== false && $request['token'] === $check_token) {
|
276 |
+
if (isset($request['chat_id'])) {
|
277 |
+
$limit = 50;
|
278 |
+
$offset = 0;
|
279 |
+
if (isset($request['limit'])) {
|
280 |
+
$limit = intval($request['limit']);
|
281 |
+
}
|
282 |
+
if (isset($request['offset'])) {
|
283 |
+
$offset = intval($request['offset']);
|
284 |
+
}
|
285 |
+
|
286 |
+
if (isset($request['received_via'])) {
|
287 |
+
$received_via = sanitize_text_field($request['received_via']);
|
288 |
+
} else {
|
289 |
+
$received_via = 'u';
|
290 |
+
}
|
291 |
+
|
292 |
+
$message_data = wplc_api_return_messages($request['chat_id'], $limit, $offset, $received_via);
|
293 |
+
|
294 |
+
if ($message_data) {
|
295 |
+
$return_array['response'] = "Message data returned";
|
296 |
+
$return_array['code'] = "200";
|
297 |
+
$return_array['data'] = array("messages" => $message_data);
|
298 |
+
} else {
|
299 |
+
$return_array['response'] = "Messages not found";
|
300 |
+
$return_array['code'] = "404";
|
301 |
+
$return_array['data'] = array("chat_id" => intval($request['chat_id']));
|
302 |
+
}
|
303 |
+
} else {
|
304 |
+
$return_array['response'] = "No 'chat_id' found";
|
305 |
+
$return_array['code'] = "401";
|
306 |
+
$return_array['requirements'] = array(
|
307 |
+
"token" => "YOUR_SECRET_TOKEN",
|
308 |
+
"chat_id" => "Chat ID"
|
309 |
+
);
|
310 |
+
}
|
311 |
+
} else {
|
312 |
+
$return_array['response'] = "Secret token is invalid";
|
313 |
+
$return_array['code'] = "401";
|
314 |
+
}
|
315 |
+
} else {
|
316 |
+
$return_array['response'] = "No secret 'token' found";
|
317 |
+
$return_array['code'] = "401";
|
318 |
+
$return_array['requirements'] = array(
|
319 |
+
"token" => "YOUR_SECRET_TOKEN",
|
320 |
+
"chat_id" => "Chat ID"
|
321 |
+
);
|
322 |
+
}
|
323 |
+
} else {
|
324 |
+
$return_array['response'] = "No request data found";
|
325 |
+
$return_array['code'] = "400";
|
326 |
+
$return_array['requirements'] = array(
|
327 |
+
"token" => "YOUR_SECRET_TOKEN",
|
328 |
+
"chat_id" => "Chat ID"
|
329 |
+
);
|
330 |
+
}
|
331 |
+
|
332 |
+
return $return_array;
|
333 |
}
|
334 |
|
335 |
|
336 |
/*
|
337 |
* Records an admin message via the API
|
338 |
*/
|
339 |
+
function wplc_api_agent_record_admin_message($cid, $msg) {
|
340 |
+
|
341 |
+
global $wpdb;
|
342 |
+
global $wplc_tblname_msgs;
|
343 |
+
|
344 |
+
$fromname = apply_filters("wplc_filter_admin_name", "Admin");
|
345 |
+
$orig = '1';
|
346 |
+
|
347 |
+
$msg = apply_filters("wplc_filter_message_control", $msg);
|
348 |
+
|
349 |
+
$wpdb->insert(
|
350 |
+
$wplc_tblname_msgs,
|
351 |
+
array(
|
352 |
+
'chat_sess_id' => $cid,
|
353 |
+
'timestamp' => current_time('mysql'),
|
354 |
+
'msgfrom' => $fromname,
|
355 |
+
'msg' => $msg,
|
356 |
+
'status' => 0,
|
357 |
+
'originates' => $orig
|
358 |
+
),
|
359 |
+
array(
|
360 |
+
'%s',
|
361 |
+
'%s',
|
362 |
+
'%s',
|
363 |
+
'%s',
|
364 |
+
'%d',
|
365 |
+
'%s'
|
366 |
+
)
|
367 |
+
);
|
368 |
+
|
369 |
+
wplc_update_active_timestamp(sanitize_text_field($cid));
|
370 |
+
wplc_change_chat_status(sanitize_text_field($cid), 3);
|
371 |
+
|
372 |
+
return true;
|
373 |
}
|
374 |
|
375 |
/*
|
376 |
* Returns messages from server
|
377 |
*/
|
378 |
+
function wplc_api_agent_return_messages($cid, $limit, $offset, $received_via = 'u') {
|
379 |
+
$cid = wplc_return_chat_id_by_rel($cid);
|
380 |
+
$messages = wplc_return_chat_messages($cid, false, true, false, false, 'array', false);
|
381 |
+
if ($received_via === 'u') {
|
382 |
+
wplc_mark_as_read_user_chat_messages($cid);
|
383 |
+
} else {
|
384 |
+
wplc_mark_as_read_agent_chat_messages($cid, $received_via);
|
385 |
+
}
|
386 |
+
return $messages;
|
387 |
+
}
|
388 |
+
|
389 |
|
390 |
+
function wplc_api_agent_return_sessions() {
|
391 |
+
global $wpdb;
|
392 |
+
global $wplc_tblname_chats;
|
393 |
|
394 |
+
$results = $wpdb->get_results("SELECT * FROM $wplc_tblname_chats WHERE `status` = 3 OR `status` = 2 OR `status` = 10 OR `status` = 5 or `status` = 8 or `status` = 9 ORDER BY `timestamp` ASC");
|
395 |
|
396 |
+
$session_array = array();
|
|
|
|
|
|
|
|
|
|
|
397 |
|
398 |
+
if ($results) {
|
399 |
+
foreach ($results as $result) {
|
400 |
+
$ip_info = maybe_unserialize($result->ip);
|
401 |
+
$user_ip = $ip_info['ip'];
|
402 |
+
if ($user_ip == "") {
|
403 |
+
$user_ip = __('IP Address not recorded', 'wp-live-chat-support');
|
404 |
+
}
|
405 |
|
406 |
+
$browser = 'Unknown';
|
407 |
+
$browser_image = '';
|
408 |
+
if (!empty($ip_info['user_agent'])) {
|
409 |
+
$browser = wplc_return_browser_string($ip_info['user_agent']);
|
410 |
+
$browser_image = wplc_return_browser_image($browser, "16");
|
411 |
+
}
|
412 |
|
413 |
|
414 |
+
$session_array[$result->id] = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
415 |
|
416 |
+
$session_array[$result->id]['name'] = $result->name;
|
417 |
+
$session_array[$result->id]['email'] = $result->email;
|
418 |
+
|
419 |
+
$session_array[$result->id]['status'] = $result->status;
|
420 |
+
$session_array[$result->id]['timestamp'] = wplc_time_ago($result->timestamp);
|
421 |
+
|
422 |
+
if ((current_time('timestamp') - strtotime($result->timestamp)) < 3600) {
|
423 |
+
$session_array[$result->id]['type'] = __("New", 'wp-live-chat-support');
|
424 |
+
} else {
|
425 |
+
$session_array[$result->id]['type'] = __("Returning", 'wp-live-chat-support');
|
426 |
+
}
|
427 |
+
|
428 |
+
$session_array[$result->id]['image'] = "//www.gravatar.com/avatar/" . md5($result->email) . "?s=30&d=mm";
|
429 |
+
$session_array[$result->id]['data']['browsing'] = $result->url;
|
430 |
+
$path = parse_url($result->url, PHP_URL_PATH);
|
431 |
+
|
432 |
+
if (strlen($path) > 20) {
|
433 |
+
$session_array[$result->id]['data']['browsing_nice_url'] = substr($path, 0, 20) . '...';
|
434 |
+
} else {
|
435 |
+
$session_array[$result->id]['data']['browsing_nice_url'] = $path;
|
436 |
+
}
|
437 |
+
|
438 |
+
$session_array[$result->id]['data']['browser'] = WPLC_PLUGIN_URL . "images/$browser_image";
|
439 |
+
$session_array[$result->id]['data']['ip'] = $user_ip;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
440 |
}
|
441 |
+
}
|
442 |
+
|
443 |
+
return $session_array;
|
444 |
}
|
445 |
|
446 |
|
453 |
/*
|
454 |
* Upload end point
|
455 |
*/
|
456 |
+
function wplc_api_remote_upload(WP_REST_Request $request) {
|
457 |
+
$return_array = array();
|
458 |
+
$return_array['response'] = 'false';
|
459 |
+
$return_array = apply_filters("wplc_api_remote_upload_filter", $return_array, $request);
|
460 |
+
return $return_array;
|
|
|
|
|
|
|
461 |
}
|
462 |
|
463 |
/*
|
464 |
* Rest Permission check for restricted end points
|
465 |
*/
|
466 |
+
function wplc_api_agent_permission_check() {
|
467 |
+
if (is_user_logged_in() && wplc_user_is_agent()) {
|
468 |
+
return true;
|
469 |
+
} else {
|
470 |
+
return false;
|
471 |
+
}
|
472 |
+
}
|
473 |
+
|
474 |
+
function wplc_agent_validate_agent_check(WP_REST_Request $request) {
|
475 |
+
$return_array = array();
|
476 |
+
if (isset($request)) {
|
477 |
+
if (isset($request['agent_id'])) {
|
478 |
+
if (wplc_user_is_agent(intval($request['agent_id']))) {
|
479 |
+
$return_array['response'] = "true";
|
480 |
+
$return_array['code'] = "200";
|
481 |
+
} else {
|
482 |
+
$return_array['response'] = "false";
|
483 |
+
$return_array['code'] = "200";
|
484 |
+
}
|
485 |
+
} else {
|
486 |
+
$return_array['response'] = "No Agent ID found";
|
487 |
+
$return_array['code'] = "401";
|
488 |
+
$return_array['requirements'] = array("agent_id" => "Agent ID");
|
489 |
+
}
|
490 |
+
} else {
|
491 |
+
$return_array['response'] = "No request data found";
|
492 |
+
$return_array['code'] = "400";
|
493 |
+
$return_array['requirements'] = array("agent_id" => "Agent ID");
|
494 |
+
}
|
495 |
+
|
496 |
+
return $return_array;
|
497 |
}
|
498 |
|
|
|
499 |
|
500 |
+
# PRO API FUNCTIONS
|
501 |
+
function wplc_api_send_agent_message_mrg(WP_REST_Request $request) {
|
502 |
+
$return_array = array();
|
503 |
+
if (isset($request)) {
|
504 |
+
if (isset($request['server_token'])) {
|
505 |
+
$check_token = get_option('wplc_api_secret_token');
|
506 |
+
if ($check_token !== false && $request['server_token'] === $check_token) {
|
507 |
+
if (isset($request['chat_id'])) {
|
508 |
+
if (isset($request['message'])) {
|
509 |
+
if (isset($request['relay_action'])) {
|
510 |
+
|
511 |
+
$chat_id = sanitize_text_field($request['chat_id']);
|
512 |
+
$message = $request['message'];
|
513 |
+
$action = $request['relay_action'];
|
514 |
+
|
515 |
+
if (!empty($request['msg_id'])) {
|
516 |
+
$other = new stdClass();
|
517 |
+
$other->msgID = $request['msg_id'];
|
518 |
+
} else {
|
519 |
+
$other = false;
|
520 |
+
}
|
521 |
+
|
522 |
+
if ($action == "wplc_admin_send_msg") {
|
523 |
+
$message = sanitize_text_field($message);
|
524 |
+
$ato = intval($request['ato']);
|
525 |
+
if (isset($request['orig_override'])) {
|
526 |
+
wplc_api_record_agent_chat_msg_mrg(sanitize_text_field($request['agent_id']), $chat_id, $message, true, $ato, $other, $request['orig_override']);
|
527 |
+
} else {
|
528 |
+
wplc_api_record_agent_chat_msg_mrg(sanitize_text_field($request['agent_id']), $chat_id, $message, true, $ato, $other);
|
529 |
+
}
|
530 |
+
wplc_update_active_timestamp($chat_id);
|
531 |
+
|
532 |
+
$return_array['response'] = "Message sent successfully";
|
533 |
$return_array['code'] = "200";
|
534 |
+
$return_array['data'] = array(
|
535 |
+
"chat_id" => intval($request['chat_id']),
|
536 |
+
"agent_id" => intval($request['agent_id'])
|
537 |
+
);
|
538 |
+
|
539 |
+
do_action("wplc_new_user_message_after_record_hook", $chat_id, $message);
|
540 |
+
}
|
541 |
} else {
|
542 |
+
$return_array['request_information'] = __("Action not set", 'wp-live-chat-support');
|
|
|
543 |
}
|
544 |
+
} else {
|
545 |
+
$return_array['response'] = "No 'message' found";
|
546 |
$return_array['code'] = "401";
|
547 |
+
$return_array['requirements'] = array(
|
548 |
+
"server_token" => "YOUR_SECRET_TOKEN",
|
549 |
+
"chat_id" => "Chat ID",
|
550 |
+
"message" => "Message"
|
551 |
+
);
|
552 |
+
}
|
553 |
+
} else {
|
554 |
+
$return_array['response'] = "No 'chat_id' found";
|
555 |
+
$return_array['code'] = "401";
|
556 |
+
$return_array['requirements'] = array(
|
557 |
+
"server_token" => "YOUR_SECRET_TOKEN",
|
558 |
+
"chat_id" => "Chat ID",
|
559 |
+
"message" => "Message"
|
560 |
+
);
|
561 |
}
|
562 |
+
} else {
|
563 |
+
$return_array['response'] = "Secret server_token is invalid";
|
564 |
+
$return_array['code'] = "401";
|
565 |
+
}
|
566 |
+
} else {
|
567 |
+
$return_array['response'] = "No secret 'server_token' found";
|
568 |
+
$return_array['code'] = "401";
|
569 |
+
$return_array['requirements'] = array(
|
570 |
+
"server_token" => "YOUR_SECRET_TOKEN",
|
571 |
+
"chat_id" => "Chat ID",
|
572 |
+
"message" => "Message"
|
573 |
+
);
|
574 |
}
|
575 |
+
} else {
|
576 |
+
$return_array['response'] = "No request data found";
|
577 |
+
$return_array['code'] = "400";
|
578 |
+
$return_array['requirements'] = array(
|
579 |
+
"server_token" => "YOUR_SECRET_TOKEN",
|
580 |
+
"chat_id" => "Chat ID",
|
581 |
+
"message" => "Message"
|
582 |
+
);
|
583 |
+
}
|
584 |
+
|
585 |
+
return $return_array;
|
586 |
}
|
587 |
|
588 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
589 |
|
590 |
+
function wplc_api_get_agent_unread_message_counts_mrg(WP_REST_Request $request) {
|
591 |
+
$return_array = array();
|
592 |
+
if (isset($request)) {
|
593 |
+
if (isset($request['token'])) {
|
594 |
+
$check_token = get_option('wplc_api_secret_token');
|
595 |
+
if ($check_token !== false && $request['token'] === $check_token) {
|
596 |
+
|
597 |
+
$current_agent = intval(sanitize_text_field($request['agent_id']));
|
598 |
|
599 |
+
/**
|
600 |
+
* Get all agents
|
601 |
+
* @var [type]
|
602 |
+
*/
|
603 |
+
$user_array = wplc_get_agent_users();
|
604 |
+
$a_array = array();
|
605 |
+
if ($user_array) {
|
606 |
+
foreach ($user_array as $user) {
|
607 |
+
$unread = wplc_return_unread_agent_messages_mrg($current_agent, $user->ID);
|
608 |
+
$a_array[$user->ID] = $unread;
|
609 |
+
}
|
610 |
+
}
|
611 |
+
$return_array['response'] = "Unread count agents"; /* needs to be exactly this for the JS to fire correctly */
|
612 |
+
$return_array['code'] = "200";
|
613 |
+
$return_array['data'] = $a_array;
|
614 |
+
} else {
|
615 |
+
$return_array['response'] = "Secret token is invalid";
|
616 |
+
$return_array['code'] = "401";
|
617 |
+
}
|
618 |
+
} else {
|
619 |
+
$return_array['response'] = "No secret 'token' found";
|
620 |
+
$return_array['code'] = "401";
|
621 |
+
$return_array['requirements'] = array("token" => "YOUR_SECRET_TOKEN");
|
622 |
+
}
|
623 |
+
} else {
|
624 |
+
$return_array['response'] = "No request data found";
|
625 |
+
$return_array['code'] = "400";
|
626 |
+
$return_array['requirements'] = array("token" => "YOUR_SECRET_TOKEN");
|
627 |
+
}
|
628 |
|
629 |
+
return $return_array;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
630 |
}
|
631 |
|
632 |
function wplc_api_initiate_chat_mrg(WP_REST_REQUEST $request) {
|
633 |
$wplc_settings = wplc_get_options();
|
634 |
+
$return_array = array();
|
635 |
+
if (isset($request)) {
|
636 |
+
if (isset($request['security'])) {
|
637 |
+
$check_token = get_option('wplc_api_secret_token');
|
638 |
+
if ($check_token !== false && $request['token'] === $check_token) {
|
639 |
+
|
640 |
+
if (isset($request['rel']) || isset($request['cid'])) {
|
641 |
+
|
642 |
+
if (isset($request['aid'])) {
|
643 |
+
|
644 |
+
$aid = intval($request['aid']);
|
645 |
+
|
646 |
+
if (isset($request['rel'])) {
|
647 |
+
$cid = $request['rel'];
|
648 |
+
} else {
|
649 |
+
$cid = $request['cid'];
|
650 |
+
}
|
651 |
+
|
652 |
+
|
653 |
+
global $wplc_tblname_chats;
|
654 |
+
global $wpdb;
|
655 |
+
$results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wplc_tblname_chats WHERE `rel` = %s OR `id` = %s LIMIT 1", $cid, $cid));
|
656 |
+
if (!$results) {
|
657 |
+
/* it doesnt exist, lets put it in the table */
|
658 |
+
|
659 |
+
$wpdb->insert(
|
660 |
+
$wplc_tblname_chats,
|
661 |
+
array(
|
662 |
+
'status' => 3,
|
663 |
+
'timestamp' => current_time('mysql'),
|
664 |
+
'name' => $wplc_settings['wplc_user_default_visitor_name'],
|
665 |
+
'email' => 'none',
|
666 |
+
'session' => '1',
|
667 |
+
'ip' => wplc_get_user_ip(),
|
668 |
+
'url' => '',
|
669 |
+
'last_active_timestamp' => current_time('mysql'),
|
670 |
+
'other' => '',
|
671 |
+
'agent_id' => $aid,
|
672 |
+
'rel' => $cid,
|
673 |
+
),
|
674 |
+
array(
|
675 |
+
'%s',
|
676 |
+
'%s',
|
677 |
+
'%s',
|
678 |
+
'%s',
|
679 |
+
'%s',
|
680 |
+
'%s',
|
681 |
+
'%s',
|
682 |
+
'%s',
|
683 |
+
'%s',
|
684 |
+
'%d',
|
685 |
+
'%s'
|
686 |
+
)
|
687 |
+
);
|
688 |
+
|
689 |
+
|
690 |
+
$cid = $wpdb->insert_id;
|
691 |
+
do_action("wplc_hook_update_agent_id", $cid, $aid);
|
692 |
+
}
|
693 |
+
} else {
|
694 |
+
$return_array['response'] = "No 'AID' found (base64 encoded)";
|
695 |
+
$return_array['code'] = "401";
|
696 |
+
$return_array['requirements'] = array(
|
697 |
+
"security" => "YOUR_SECRET_TOKEN",
|
698 |
+
"cid" => "Chat ID",
|
699 |
+
"aid" => "agent ID"
|
700 |
+
);
|
701 |
+
}
|
702 |
+
} else {
|
703 |
+
$return_array['response'] = "No 'REL' or 'CID' found (base64 encoded)";
|
704 |
+
$return_array['code'] = "401";
|
705 |
+
$return_array['requirements'] = array(
|
706 |
+
"security" => "YOUR_SECRET_TOKEN",
|
707 |
+
"cid" => "Chat ID",
|
708 |
+
"rel/cid" => "related ID or Chat ID"
|
709 |
+
);
|
710 |
+
}
|
711 |
+
} else {
|
712 |
+
$return_array['response'] = "Nonce is invalid";
|
713 |
+
$return_array['code'] = "401";
|
714 |
+
}
|
715 |
+
} else {
|
716 |
+
$return_array['response'] = "No 'security' found";
|
717 |
+
$return_array['code'] = "401";
|
718 |
+
$return_array['requirements'] = array(
|
719 |
+
"security" => "YOUR_SECRET_TOKEN",
|
720 |
+
"cid" => "Chat ID",
|
721 |
+
"wplc_extra_data" => "Data array"
|
722 |
+
);
|
723 |
+
}
|
724 |
+
} else {
|
725 |
+
$return_array['response'] = "No request data found";
|
726 |
+
$return_array['code'] = "400";
|
727 |
+
$return_array['requirements'] = array(
|
728 |
+
"security" => "YOUR_SECRET_TOKEN",
|
729 |
+
"cid" => "Chat ID",
|
730 |
+
"wplc_extra_data" => "Data array"
|
731 |
+
);
|
732 |
+
}
|
733 |
+
|
734 |
+
return $return_array;
|
|
|
|
|
|
|
|
|
|
|
735 |
}
|
736 |
|
737 |
function wplc_api_agent_email_notification_mrg(WP_REST_Request $request) { // TODO: this function is never referenced
|
744 |
if (isset($request['wplc_extra_data'])) {
|
745 |
// TODO: this code does nothing useful
|
746 |
$data = $request['wplc_extra_data'];
|
747 |
+
$wplc_settings = wplc_get_options();
|
748 |
$email_address = wplc_determine_admin_email($wplc_settings);
|
749 |
return true;
|
750 |
} else {
|
753 |
$return_array['requirements'] = array(
|
754 |
"security" => "YOUR_SECRET_TOKEN",
|
755 |
"cid" => "Chat ID",
|
756 |
+
"wplc_extra_data" => "Data array"
|
757 |
+
);
|
758 |
+
}
|
759 |
+
} else {
|
760 |
+
$return_array['response'] = "No 'CID' found";
|
761 |
+
$return_array['code'] = "401";
|
762 |
+
$return_array['requirements'] = array(
|
763 |
+
"security" => "YOUR_SECRET_TOKEN",
|
764 |
+
"cid" => "Chat ID",
|
765 |
+
"wplc_extra_data" => "Data array"
|
766 |
+
);
|
767 |
}
|
768 |
} else {
|
769 |
$return_array['response'] = "Nonce is invalid";
|
790 |
return $return_array;
|
791 |
}
|
792 |
|
793 |
+
function wplc_api_agent_is_typing_mrg(WP_REST_Request $request) {
|
794 |
+
|
795 |
+
$return_array = array();
|
796 |
+
if (isset($request)) {
|
797 |
+
if (isset($request['security'])) {
|
798 |
+
$check_token = get_option('wplc_api_secret_token');
|
799 |
+
if ($check_token !== false && $request['security'] === $check_token) {
|
800 |
+
if (isset($request['cid'])) {
|
801 |
+
if (isset($request['user'])) {
|
802 |
+
if (isset($request['type'])) {
|
803 |
+
if (wplc_typing_mrg($request['user'], sanitize_text_field($request['cid']), sanitize_text_field($request['type']))) {
|
804 |
+
|
805 |
+
$return_array['response'] = "Successful";
|
806 |
+
$return_array['code'] = "200";
|
807 |
+
$return_array['data'] = array(
|
808 |
+
"cid" => intval($request['cid']),
|
809 |
+
"user" => intval($request['user']),
|
810 |
+
"type" => intval($request['type'])
|
811 |
+
);
|
812 |
+
} else {
|
813 |
+
$return_array['response'] = "Failed to send typing indicaator";
|
814 |
+
$return_array['code'] = "401";
|
815 |
+
$return_array['requirements'] = array(
|
816 |
+
"security" => "YOUR_SECRET_TOKEN",
|
817 |
+
"cid" => "Chat ID",
|
818 |
+
"user" => "User type",
|
819 |
+
'type' => "TYPE"
|
820 |
+
);
|
821 |
+
}
|
822 |
+
} else {
|
823 |
+
|
824 |
+
$return_array['response'] = "No 'type' found";
|
825 |
+
$return_array['code'] = "401";
|
826 |
+
$return_array['requirements'] = array(
|
827 |
+
"security" => "YOUR_SECRET_TOKEN",
|
828 |
+
"cid" => "Chat ID",
|
829 |
+
"user" => "User type",
|
830 |
+
'type' => "TYPE"
|
831 |
+
);
|
832 |
+
}
|
833 |
+
} else {
|
834 |
+
$return_array['response'] = "No 'user' found";
|
835 |
+
$return_array['code'] = "401";
|
836 |
+
$return_array['requirements'] = array(
|
837 |
+
"security" => "YOUR_SECRET_TOKEN",
|
838 |
+
"cid" => "Chat ID",
|
839 |
+
"user" => "User type",
|
840 |
+
'type' => "TYPE"
|
841 |
+
);
|
842 |
+
}
|
843 |
+
} else {
|
844 |
+
$return_array['response'] = "No 'cid' found";
|
845 |
+
$return_array['code'] = "401";
|
846 |
+
$return_array['requirements'] = array(
|
847 |
+
"security" => "YOUR_SECRET_TOKEN",
|
848 |
+
"cid" => "Chat ID",
|
849 |
+
"user" => "User type",
|
850 |
+
'type' => "TYPE"
|
851 |
+
);
|
852 |
+
}
|
853 |
+
} else {
|
854 |
+
$return_array['response'] = "Nonce is invalid";
|
855 |
+
$return_array['code'] = "401";
|
856 |
+
}
|
857 |
+
} else {
|
858 |
+
$return_array['response'] = "No 'security' found";
|
859 |
+
$return_array['code'] = "401";
|
860 |
+
$return_array['requirements'] = array(
|
861 |
+
"security" => "YOUR_SECRET_TOKEN",
|
862 |
+
"cid" => "Chat ID",
|
863 |
+
"user" => "User type",
|
864 |
+
'type' => "TYPE"
|
865 |
+
);
|
866 |
+
}
|
867 |
+
} else {
|
868 |
+
$return_array['response'] = "No request data found";
|
869 |
+
$return_array['code'] = "400";
|
870 |
+
$return_array['requirements'] = array(
|
871 |
+
"security" => "YOUR_SECRET_TOKEN",
|
872 |
+
"cid" => "Chat ID",
|
873 |
+
"user" => "User type",
|
874 |
+
'type' => "TYPE"
|
875 |
+
);
|
876 |
+
}
|
877 |
+
|
878 |
+
return $return_array;
|
879 |
}
|
880 |
|
881 |
|
882 |
function wplc_api_record_agent_chat_msg_mrg($from, $cid, $msg, $rest_check = false, $ato = false, $other = false, $orig_override = false) {
|
883 |
+
global $wpdb;
|
884 |
+
global $wplc_tblname_msgs;
|
885 |
|
886 |
|
887 |
+
|
888 |
+
if (!filter_var($cid, FILTER_VALIDATE_INT)) {
|
|
|
|
|
|
|
|
|
|
|
|
|
889 |
|
890 |
/**
|
891 |
+
* We need to identify if this CID is a node CID, and if so, return the WP CID from the wplc_chat_msgs table
|
|
|
|
|
892 |
*/
|
893 |
+
$cid = wplc_return_chat_id_by_rel($cid);
|
894 |
+
}
|
895 |
+
|
896 |
+
/**
|
897 |
+
* check if this CID even exists, if not, create it
|
898 |
+
*
|
899 |
+
* If it doesnt exist, it most likely is an agent-to-agent chat that we now need to save.
|
900 |
+
*/
|
901 |
+
|
902 |
+
global $wplc_tblname_chats;
|
903 |
+
$results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wplc_tblname_chats WHERE `rel` = %s OR `id` = %s LIMIT 1", $cid, $cid));
|
904 |
+
if (!$results) {
|
905 |
+
/* it doesnt exist, lets put it in the table */
|
906 |
+
|
907 |
+
$wpdb->insert(
|
908 |
+
$wplc_tblname_chats,
|
909 |
+
array(
|
910 |
+
'status' => 3,
|
911 |
+
'timestamp' => current_time('mysql'),
|
912 |
+
'name' => 'agent-to-agent chat',
|
913 |
+
'email' => 'none',
|
914 |
+
'session' => '1',
|
915 |
+
'ip' => wplc_get_user_ip(),
|
916 |
+
'url' => '',
|
917 |
+
'last_active_timestamp' => current_time('mysql'),
|
918 |
+
'other' => '',
|
919 |
+
'rel' => $cid,
|
920 |
+
),
|
921 |
+
array(
|
922 |
+
'%s',
|
923 |
+
'%s',
|
924 |
+
'%s',
|
925 |
+
'%s',
|
926 |
+
'%s',
|
927 |
+
'%s',
|
928 |
+
'%s',
|
929 |
+
'%s',
|
930 |
+
'%s',
|
931 |
+
'%s'
|
932 |
+
)
|
933 |
+
);
|
934 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
935 |
|
936 |
+
$cid = $wpdb->insert_id;
|
937 |
+
}
|
938 |
+
|
939 |
+
$msg_id = '';
|
940 |
+
if ($other !== false) {
|
941 |
+
if (!empty($other->msgID)) {
|
942 |
+
$msg_id = $other->msgID;
|
943 |
} else {
|
944 |
+
$msg_id = '';
|
|
|
|
|
|
|
|
|
945 |
}
|
946 |
+
}
|
947 |
|
948 |
+
$user_info = get_userdata($from);
|
949 |
+
if ($user_info) {
|
950 |
+
$fromname = $user_info->display_name;
|
951 |
+
} else {
|
952 |
+
$fromname = 'agent';
|
953 |
+
}
|
954 |
+
$orig = '1';
|
955 |
+
if ($orig_override !== false) {
|
956 |
+
$orig = sanitize_text_field($orig_override);
|
957 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
958 |
|
959 |
+
$orig_msg = $msg;
|
960 |
+
|
961 |
+
$msg = apply_filters("wplc_filter_message_control", $msg);
|
962 |
+
|
963 |
+
|
964 |
+
$wpdb->insert(
|
965 |
+
$wplc_tblname_msgs,
|
966 |
+
array(
|
967 |
+
'chat_sess_id' => $cid,
|
968 |
+
'timestamp' => current_time('mysql'),
|
969 |
+
'msgfrom' => $fromname,
|
970 |
+
'msg' => $msg,
|
971 |
+
'status' => 0,
|
972 |
+
'originates' => $orig,
|
973 |
+
'other' => '',
|
974 |
+
'rel' => $msg_id,
|
975 |
+
'ato' => $ato,
|
976 |
+
'afrom' => $from
|
977 |
+
),
|
978 |
+
array(
|
979 |
+
'%s',
|
980 |
+
'%s',
|
981 |
+
'%s',
|
982 |
+
'%s',
|
983 |
+
'%d',
|
984 |
+
'%s',
|
985 |
+
'%s',
|
986 |
+
'%s',
|
987 |
+
'%d',
|
988 |
+
'%d'
|
989 |
+
)
|
990 |
+
);
|
991 |
+
|
992 |
+
$data = array(
|
993 |
+
'cid' => $cid,
|
994 |
+
'from' => $from,
|
995 |
+
'msg' => $orig_msg,
|
996 |
+
'orig' => $orig
|
997 |
+
);
|
998 |
+
//do_action("wplc_hook_message_sent",$data);
|
999 |
+
|
1000 |
+
wplc_update_active_timestamp(sanitize_text_field($cid));
|
1001 |
+
|
1002 |
+
|
1003 |
+
return true;
|
1004 |
}
|
1005 |
|
1006 |
add_filter("wplc_api_remote_upload_filter", "wplc_api_agent_remote_upload_handler_mrg", 10, 2);
|
1007 |
/*
|
1008 |
* Processes remote uploads, from app or main agent files as an example
|
1009 |
*/
|
1010 |
+
function wplc_api_agent_remote_upload_handler_mrg($return_array, $request) {
|
1011 |
$remote_files = $request->get_file_params();
|
1012 |
if (is_array($remote_files)) {
|
1013 |
$upload_dir = wp_upload_dir();
|
1014 |
$user_dirname = $upload_dir['basedir'];
|
1015 |
+
$cid = 0;
|
1016 |
if (isset($request['cid'])) {
|
1017 |
$cid = sanitize_text_field($request['cid']);
|
1018 |
if (!filter_var($cid, FILTER_VALIDATE_INT)) {
|
1022 |
$cid = intval($cid);
|
1023 |
}
|
1024 |
|
1025 |
+
if (!file_exists($user_dirname . "/wp_live_chat/")) {
|
1026 |
+
@mkdir($user_dirname . '/wp_live_chat/');
|
1027 |
+
}
|
1028 |
|
1029 |
+
if (!realpath($user_dirname . "/wp_live_chat/" . $cid)) {
|
1030 |
+
@mkdir($user_dirname . '/wp_live_chat/' . $cid);
|
1031 |
+
}
|
1032 |
|
1033 |
if (isset($remote_files['file'])) {
|
1034 |
+
$file_name = strtolower(sanitize_file_name($remote_files['file']['name']));
|
1035 |
$file_name = basename($file_name); //This prevents traversal
|
1036 |
$file_name = str_replace(" ", "_", $file_name);
|
1037 |
if (wplc_check_file_name_for_safe_extension($file_name)) {
|
1038 |
+
if (realpath($user_dirname . "/wp_live_chat/" . $cid . "/" . $file_name) == false) {
|
1039 |
$file_name = rand(0, 10) . "-" . $file_name;
|
1040 |
+
}
|
1041 |
+
if (move_uploaded_file($remote_files['file']['tmp_name'], $user_dirname . "/wp_live_chat/" . $cid . "/" . $file_name)) {
|
1042 |
+
$response = $upload_dir['baseurl'] . "/wp_live_chat/" . $cid . "/" . $file_name;
|
1043 |
$return_array['response'] = wp_filter_post_kses(strip_tags($response));
|
1044 |
} else {
|
1045 |
$return_array['response'] = __('Upload error', 'wp-live-chat-support');
|
1058 |
|
1059 |
/**
|
1060 |
* Cleanup all REST Params
|
1061 |
+
*/
|
1062 |
+
function wplc_api_agent_sanitize_request_params(WP_REST_Request $request) {
|
1063 |
+
global $wpdb;
|
1064 |
+
|
1065 |
+
$params = $request->get_params();
|
1066 |
+
foreach ($params as $key => $value) {
|
1067 |
+
if (is_string($value)) {
|
1068 |
+
$request->set_param($key, $wpdb->_real_escape($value));
|
1069 |
+
}
|
1070 |
+
}
|
1071 |
|
1072 |
+
return $request;
|
1073 |
}
|
modules/api/agent/wplc-api.php
CHANGED
@@ -3,8 +3,8 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
3 |
exit;
|
4 |
}
|
5 |
|
6 |
-
if(class_exists("WP_REST_Request")){
|
7 |
-
if(
|
8 |
include_once "wplc-api-routes.php";
|
9 |
include_once "wplc-api-functions.php";
|
10 |
}
|
3 |
exit;
|
4 |
}
|
5 |
|
6 |
+
if (class_exists("WP_REST_Request")) {
|
7 |
+
if (wplc_user_is_agent()) {
|
8 |
include_once "wplc-api-routes.php";
|
9 |
include_once "wplc-api-functions.php";
|
10 |
}
|
modules/gdpr.php
CHANGED
@@ -590,47 +590,6 @@ function wplc_gdpr_footer_mod( $footer_text ) {
|
|
590 |
|
591 |
}
|
592 |
|
593 |
-
add_filter( 'wplc_node_server_us_options_enabled', 'wplc_gdpr_allow_us_servers_check',10 ,2);
|
594 |
-
/**
|
595 |
-
* Checks if GDPR option is enabled so we can force users into the EU
|
596 |
-
*/
|
597 |
-
function wplc_gdpr_allow_us_servers_check($is_allowed, $wplc_settings = false){
|
598 |
-
if($wplc_settings === false){ $wplc_settings = wplc_get_options(); }
|
599 |
-
|
600 |
-
if(isset($wplc_settings['wplc_gdpr_enabled']) && $wplc_settings['wplc_gdpr_enabled'] == '1'){
|
601 |
-
return false;
|
602 |
-
}
|
603 |
-
|
604 |
-
return $is_allowed;
|
605 |
-
}
|
606 |
-
|
607 |
-
|
608 |
-
add_filter( 'wplc_node_server_default_selection_override', 'wplc_gdpr_node_server_eu_default_override',10,2);
|
609 |
-
/**
|
610 |
-
* Checks if GDPR option is enabled so we can force users into the EU
|
611 |
-
*/
|
612 |
-
function wplc_gdpr_node_server_eu_default_override($selected, $wplc_settings = false){
|
613 |
-
if($wplc_settings === false){ $wplc_settings = wplc_get_options(); }
|
614 |
-
if(isset($wplc_settings['wplc_gdpr_enabled']) && $wplc_settings['wplc_gdpr_enabled'] == '1'){
|
615 |
-
if($selected === 'auto' || substr($selected,0,2) == 'us') {
|
616 |
-
//This is not allowed in the GDPR
|
617 |
-
$selected = 'eu'.rand(1,10);
|
618 |
-
}
|
619 |
-
}
|
620 |
-
return $selected;
|
621 |
-
}
|
622 |
-
|
623 |
-
|
624 |
-
add_action('wplc_node_server_selection_notices', 'wplc_gdpr_node_server_override_notice',10,1);
|
625 |
-
/**
|
626 |
-
* Will add a very simple server override if GDPR is enabled
|
627 |
-
*/
|
628 |
-
function wplc_gdpr_node_server_override_notice($wplc_settings = false){
|
629 |
-
if($wplc_settings === false){ $wplc_settings = wplc_get_options(); }
|
630 |
-
if(isset($wplc_settings['wplc_gdpr_enabled']) && $wplc_settings['wplc_gdpr_enabled'] == '1'){
|
631 |
-
echo "<small><strong><em>" . __("GDPR Compliance Enabled - Server Selection Limited to EU", 'wp-live-chat-support') . "</em></strong></small>";
|
632 |
-
}
|
633 |
-
}
|
634 |
|
635 |
add_filter('wplc_update_settings_between_versions_hook', 'wplc_gdpr_update_settings_between_versions',10,1);
|
636 |
/**
|
590 |
|
591 |
}
|
592 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
593 |
|
594 |
add_filter('wplc_update_settings_between_versions_hook', 'wplc_gdpr_update_settings_between_versions',10,1);
|
595 |
/**
|
modules/node_server.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Node Code
|
4 |
*/
|
5 |
|
6 |
-
if (
|
7 |
exit;
|
8 |
}
|
9 |
|
@@ -18,14 +18,14 @@ add_action("wplc_update_hook", "wplc_node_server_token_get", 10);
|
|
18 |
* If not create one for use in the API
|
19 |
*
|
20 |
* @return void
|
21 |
-
*/
|
22 |
-
function wplc_node_server_token_get($reset=false) {
|
23 |
-
$tk='';
|
24 |
if (!$reset) {
|
25 |
$tk = get_option("wplc_node_server_secret_token");
|
26 |
}
|
27 |
-
|
28 |
-
|
29 |
update_option("wplc_node_server_secret_token", $tk);
|
30 |
}
|
31 |
return $tk;
|
@@ -35,69 +35,72 @@ add_action("wplc_admin_dashboard_render", "wplc_admin_dashboard");
|
|
35 |
function wplc_admin_dashboard() {
|
36 |
$wplc_node_token = wplc_node_server_token_get();
|
37 |
$variables = array("node_token" => $wplc_node_token, "action" => "wordpress");
|
38 |
-
$variables = apply_filters("wplc_admin_dashboard_layout_node_request_variable_filter", $variables);
|
39 |
$wplc_settings = wplc_get_options();
|
40 |
-
|
41 |
-
|
42 |
-
<div class=
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
<i id="toolbar-item-fullscreen-wp" class="fa fa-clone fa-fw" title="<?php _e('Toggle WordPress Menu for a full screen experience','wp-live-chat-support');?>."></i>
|
47 |
-
</div>
|
48 |
-
<div id="page-wrapper" style='position:relative;'>
|
49 |
-
<div class='nifty_bg_holder'>
|
50 |
-
<div class='nifty_bg_holder_text'><img src='<?php echo WPLC_PLUGIN_URL;?>images/wplc_loading.png' width='50' /><br /><br /><div id='nifty_bg_holder_text_inner'>Connecting...</div></div>
|
51 |
-
<div class='tcx_tips_hints'></div>
|
52 |
</div>
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
<div class="nifty_admin_overlay" style="display:none">
|
55 |
|
56 |
</div>
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
</div>
|
66 |
|
67 |
<div id='nifty_wrapper'>
|
68 |
<input type="checkbox" id="user_list_mobile_control" name="user_list_mobile_control" checked="checked">
|
69 |
<div id='user_list' class='col-md-3'>
|
70 |
-
|
71 |
<div id='choose_online'>
|
72 |
-
|
73 |
-
|
74 |
-
</div>
|
75 |
-
<?php } ?>
|
76 |
-
<div id='user_count'>
|
77 |
-
<span id='active_count'>... </span>
|
78 |
-
<span id='active_count_string'><?php _e('Active visitors','wp-live-chat-support');?></span>
|
79 |
-
</div>
|
80 |
-
<div class='exp_cols'>
|
81 |
-
<div class='col1'><?php _e('Name','wp-live-chat-support');?></div>
|
82 |
-
<div class='col3'><?php _e('Agent','wp-live-chat-support');?></div>
|
83 |
-
</div>
|
84 |
-
<div class='userListBox_Wrapper'>
|
85 |
-
<div class='userListBox'></div>
|
86 |
-
</div>
|
87 |
-
<div id='agent_list'>
|
88 |
-
<h4 id='nifty_agent_heading'><?php _e('Agents','wp-live-chat-support');?></h4>
|
89 |
-
<ul class='online_agent_list'>
|
90 |
-
</ul>
|
91 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
</div>
|
93 |
|
94 |
<div id='chat_area' class='col-md-9'>
|
95 |
-
<?php if ($variables['include_media_sharing']){ ?>
|
96 |
-
|
|
|
|
|
97 |
<?php } ?>
|
98 |
<div class="chatArea" style='display:none;'>
|
99 |
<div class="chatInfoArea">
|
100 |
-
|
101 |
<div class="dropdown pull-right"></div>
|
102 |
|
103 |
<div class="btn-group inchat-menu pull-right">
|
@@ -107,13 +110,13 @@ function wplc_admin_dashboard() {
|
|
107 |
</button>
|
108 |
<div class="dropdown-menu" aria-labelledby='inchat_drop_down'>
|
109 |
<?php if ($variables['include_transfers']) { ?>
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
<?php } ?>
|
114 |
-
<a href="javascript:void(0);" class='dropdown-item chatTranscript' id='chatTranscriptTitle' style='display:none;'><?php _e('Transcript','wp-live-chat-support')
|
115 |
-
<a href="javascript:void(0);" class='dropdown-item chatClose' id='chatCloseTitle' style="display:none;"><?php _e('Leave chat','wp-live-chat-support')
|
116 |
-
<a href="javascript:void(0);" class='dropdown-item endChat' id='chatEndTitle'><?php _e('End chat','wp-live-chat-support')
|
117 |
</div>
|
118 |
</div>
|
119 |
|
@@ -122,168 +125,168 @@ function wplc_admin_dashboard() {
|
|
122 |
<div class='user_gravatar'></div>
|
123 |
</div>
|
124 |
<div class='user_header_wrapper_info'>
|
125 |
-
<h3><span class='chatInfoArea-Name'><?php _e('Name','wp-live-chat-support')
|
126 |
-
<h4><span class='chatInfoArea-Email'><?php _e('Email','wp-live-chat-support')
|
127 |
-
<p><span class='chatInfoArea-Info1'><?php _e('Something','wp-live-chat-support')
|
128 |
</div>
|
129 |
-
|
130 |
</div>
|
131 |
|
132 |
<ul class="messages" id="messages"></ul>
|
133 |
-
|
134 |
-
<?php if ($variables['include_quick_responses']){ ?>
|
135 |
-
|
136 |
<?php } ?>
|
137 |
<div class='typing_preview_wplc' style='display:none;'></div>
|
138 |
-
<div class='tcx_join_chat_div'><button class='tcx_join_chat_btn btn btn-success' id='nifty_join_chat_button'><?php _e('Join chat','wp-live-chat-support')
|
139 |
-
<input class="inputMessage wdt-emoji-bundle-enabled" id="inputMessage" placeholder="<?php _e('Type here...','wp-live-chat-support')
|
140 |
-
<span class="editing_hints"><strong>*<?php _e('bold','wp-live-chat-support')
|
141 |
-
<img id="wplc_send_msg" class='nifty_send_arrow' style="display:none;" src='<?php echo WPLC_PLUGIN_URL
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
|
157 |
</div>
|
158 |
<div class="infoArea">
|
159 |
<div class="dropdown filter-menu pull-right">
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
</div>
|
175 |
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
|
|
|
|
182 |
|
183 |
-
<h2 id='nifty_active_chats_heading'><?php _e('Active visitors','wp-live-chat-support');?></h2>
|
184 |
-
|
185 |
<div class='visitorListBoxHeader'>
|
186 |
-
<div class='vcol visCol' id='nifty_vis_col_heading'><?php _e('Visitor','wp-live-chat-support')
|
187 |
-
<div class='vcol visStatusCol' id='nifty_vis_info_heading'><?php _e('Info','wp-live-chat-support')
|
188 |
-
<div class='vcol visPageCol' id='nifty_vis_page_heading'><?php _e('Page','wp-live-chat-support')
|
189 |
-
<div class='vcol visChatStatusCol' id='nifty_vis_status_heading'><?php _e('Chat Status','wp-live-chat-support')
|
190 |
-
<?php if ($variables['include_departments']){ ?>
|
191 |
-
|
192 |
<?php } ?>
|
193 |
<div class='vcol visActionCol'></div>
|
194 |
</div>
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
</div>
|
202 |
</div>
|
203 |
-
</div>
|
204 |
-
<div class="wdt-emoji-popup">
|
205 |
-
<a href="#" class="wdt-emoji-popup-mobile-closer"> × </a>
|
206 |
-
<div class="wdt-emoji-menu-content">
|
207 |
-
<div id="wdt-emoji-menu-header">
|
208 |
-
<a class="wdt-emoji-tab" data-group-name="People"></a>
|
209 |
-
<a class="wdt-emoji-tab" data-group-name="Nature"></a>
|
210 |
-
<a class="wdt-emoji-tab" data-group-name="Foods"></a>
|
211 |
-
<a class="wdt-emoji-tab" data-group-name="Activity"></a>
|
212 |
-
<a class="wdt-emoji-tab" data-group-name="Places"></a>
|
213 |
-
<a class="wdt-emoji-tab" data-group-name="Objects"></a>
|
214 |
-
<a class="wdt-emoji-tab" data-group-name="Symbols"></a>
|
215 |
-
<a class="wdt-emoji-tab" data-group-name="Flags"></a>
|
216 |
-
</div>
|
217 |
-
<div class="wdt-emoji-scroll-wrapper">
|
218 |
-
<div id="wdt-emoji-menu-items">
|
219 |
-
<input id="wdt-emoji-search" type="text" placeholder="<?php _e('Search','wp-live-chat-support');?>">
|
220 |
-
<h3 id="wdt-emoji-search-result-title"><?php _e('Search Results','wp-live-chat-support');?></h3>
|
221 |
-
<div class="wdt-emoji-sections"></div>
|
222 |
-
<div id="wdt-emoji-no-result"><?php _e('No emoji found','wp-live-chat-support');?></div>
|
223 |
-
</div>
|
224 |
</div>
|
225 |
-
<div
|
226 |
-
<
|
227 |
-
|
228 |
-
<div id="wdt-emoji-
|
229 |
-
<
|
230 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
</div>
|
232 |
</div>
|
233 |
-
<div id="wdt-emoji-preview-bundle">
|
234 |
-
<span></span>
|
235 |
-
</div>
|
236 |
-
<span class="wdt-credit">WDT Emoji Bundle</span>
|
237 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
238 |
</div>
|
239 |
</div>
|
|
|
|
|
240 |
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
|
|
251 |
|
252 |
-
/**
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
$token = md5($the_code . $the_time);
|
261 |
-
return $token;
|
262 |
-
}
|
263 |
-
|
264 |
-
/**
|
265 |
-
* Post to the NODE server -
|
266 |
-
*
|
267 |
-
* @param string $route Route you would like to use for the node server
|
268 |
-
* @param string $form_data data to send
|
269 |
-
* @return string (or false on fail)
|
270 |
-
*/
|
271 |
-
function wplc_node_server_post($route, $form_data){
|
272 |
|
273 |
$url = trailingslashit(WPLC_CHAT_SERVER) . trailingslashit(tcx_NODE_END_POINTS_ROUTE) . $route;
|
274 |
|
275 |
-
if(!isset($form_data['token'])){
|
276 |
-
|
277 |
}
|
278 |
|
279 |
-
|
280 |
-
|
281 |
}
|
282 |
|
283 |
-
if(!isset($form_data['origin_url'])){
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
}
|
288 |
|
289 |
// $options = array();
|
@@ -291,441 +294,283 @@ function wplc_node_server_post($route, $form_data){
|
|
291 |
// $result = @file_get_contents($url . "?" . http_build_query($form_data), false, $context);
|
292 |
|
293 |
$result = wp_remote_get($url . "?" . http_build_query($form_data));
|
294 |
-
if (
|
295 |
$result = $result['body']; // use the content
|
296 |
}
|
297 |
|
298 |
if ($result === FALSE) {
|
299 |
-
|
300 |
} else {
|
301 |
-
|
302 |
-
}
|
303 |
-
}
|
304 |
-
|
305 |
-
add_action("wplc_api_route_hook", "wplc_api_node_routes");
|
306 |
-
/**
|
307 |
-
* Add a REST API routes for the node server
|
308 |
-
*
|
309 |
-
* @return void
|
310 |
-
*/
|
311 |
-
function wplc_api_node_routes(){
|
312 |
-
register_rest_route('wp_live_chat_support/v1','/async_storage', array(
|
313 |
-
'methods' => 'POST',
|
314 |
-
'callback' => 'wplc_node_async_storage_rest'
|
315 |
-
));
|
316 |
-
}
|
317 |
-
|
318 |
-
/**
|
319 |
-
* Handles Async storage REST -> Params are processed within the request
|
320 |
-
* Required POST variables:
|
321 |
-
* - Chat ID
|
322 |
-
* - Security Key
|
323 |
-
* - Message (JSON encoded array)
|
324 |
-
* - Action
|
325 |
-
*
|
326 |
-
* @param WP_REST_Request $request Request Data
|
327 |
-
* @return void
|
328 |
-
*/
|
329 |
-
function wplc_node_async_storage_rest(WP_REST_Request $request){
|
330 |
-
|
331 |
-
$return_array = array();
|
332 |
-
$return_array['request_status'] = false; //Default to be returned if something goes wrong
|
333 |
-
if(isset($request)){
|
334 |
-
if(isset($request['security'])){
|
335 |
-
$stored_token = wplc_node_server_token_get();
|
336 |
-
$check = $_POST['server_token'] == $stored_token ? true : false;
|
337 |
-
if ($check) {
|
338 |
-
if(isset($request['chat_id'])){
|
339 |
-
if(isset($request['messages'])){
|
340 |
-
if(isset($request['relay_action'])){
|
341 |
-
$chat_id = sanitize_text_field($request['chat_id']);
|
342 |
-
$message_data = json_decode($request['messages']);
|
343 |
-
$chat_session = wplc_return_chat_session_variable($chat_id);
|
344 |
-
$action = $request['relay_action'];
|
345 |
-
if($message_data !== NULL){
|
346 |
-
if($action == "wplc_user_send_msg"){
|
347 |
-
foreach ($message_data as $message) {
|
348 |
-
wplc_record_chat_msg("1", $chat_id, $message);
|
349 |
-
wplc_update_active_timestamp($chat_id);
|
350 |
-
}
|
351 |
-
|
352 |
-
$return_array['request_status'] = true;
|
353 |
-
$return_array['request_information'] = __("Success", 'wp-live-chat-support');
|
354 |
-
} else if ($action == "wplc_admin_send_msg"){
|
355 |
-
foreach ($message_data as $message) {
|
356 |
-
wplc_record_chat_msg("2", $chat_id, $message, true);
|
357 |
-
wplc_update_active_timestamp($chat_id);
|
358 |
-
}
|
359 |
-
|
360 |
-
$return_array['request_status'] = true;
|
361 |
-
$return_array['request_information'] = __("Success", 'wp-live-chat-support');
|
362 |
-
}
|
363 |
-
} else {
|
364 |
-
$return_array['request_information'] = __("Message data is corrupt", 'wp-live-chat-support');
|
365 |
-
}
|
366 |
-
} else {
|
367 |
-
$return_array['request_information'] = __("Action not set", 'wp-live-chat-support');
|
368 |
-
}
|
369 |
-
} else {
|
370 |
-
$return_array['request_information'] = __("Message data array not set", 'wp-live-chat-support');
|
371 |
-
}
|
372 |
-
} else {
|
373 |
-
$return_array['request_information'] = __("Chat ID is not set", 'wp-live-chat-support');
|
374 |
-
}
|
375 |
-
}
|
376 |
-
} else {
|
377 |
-
$return_array['request_information'] = __("No security nonce found", 'wp-live-chat-support');
|
378 |
-
}
|
379 |
-
}
|
380 |
-
|
381 |
-
return $return_array;
|
382 |
-
|
383 |
-
}
|
384 |
-
|
385 |
-
add_action("wp_ajax_wplc_node_async_storage_ajax", "wplc_node_async_storage_ajax");
|
386 |
-
add_action("wp_ajax_nopriv_wplc_node_async_storage_ajax", "wplc_node_async_storage_ajax");
|
387 |
-
/**
|
388 |
-
* Handles Async storage AJAX (Fallback for if REST is not present) -> Params are processed within the request
|
389 |
-
* Required POST variables:
|
390 |
-
* - Chat ID
|
391 |
-
* - Security Key
|
392 |
-
* - Message (JSON encoded array)
|
393 |
-
* - Action
|
394 |
-
*
|
395 |
-
* @return void
|
396 |
-
*/
|
397 |
-
function wplc_node_async_storage_ajax(){
|
398 |
-
$return_array = array();
|
399 |
-
$return_array['request_status'] = false; //Default to be returned if something goes wrong
|
400 |
-
if(isset($_POST)){
|
401 |
-
if(isset($_POST['server_token'])){
|
402 |
-
$stored_token = wplc_node_server_token_get();
|
403 |
-
$check = $_POST['server_token'] == $stored_token ? true : false;
|
404 |
-
if ($check) {
|
405 |
-
if(isset($_POST['chat_id'])){
|
406 |
-
if(isset($_POST['messages'])){
|
407 |
-
if(isset($_POST['relay_action'])){
|
408 |
-
$chat_id = sanitize_text_field($_POST['chat_id']);
|
409 |
-
$message_data = json_decode($_POST['messages']);
|
410 |
-
$chat_session = wplc_return_chat_session_variable($chat_id);
|
411 |
-
$action = sanitize_text_field($_POST['relay_action']);
|
412 |
-
if($message_data !== NULL){
|
413 |
-
if($action == "wplc_user_send_msg"){
|
414 |
-
foreach ($message_data as $message) {
|
415 |
-
wplc_record_chat_msg("1", $chat_id, $message);
|
416 |
-
wplc_update_active_timestamp($chat_id);
|
417 |
-
|
418 |
-
}
|
419 |
-
|
420 |
-
$return_array['request_status'] = true;
|
421 |
-
$return_array['request_information'] = __("Success", 'wp-live-chat-support');
|
422 |
-
} else if ($action == "wplc_admin_send_msg"){
|
423 |
-
foreach ($message_data as $message) {
|
424 |
-
wplc_record_chat_msg("2", $chat_id, $message);
|
425 |
-
wplc_update_active_timestamp($chat_id);
|
426 |
-
}
|
427 |
-
|
428 |
-
$return_array['request_status'] = true;
|
429 |
-
$return_array['request_information'] = __("Success", 'wp-live-chat-support');
|
430 |
-
}
|
431 |
-
} else {
|
432 |
-
$return_array['request_information'] = __("Message data is corrupt", 'wp-live-chat-support');
|
433 |
-
}
|
434 |
-
} else {
|
435 |
-
$return_array['request_information'] = __("Action not set", 'wp-live-chat-support');
|
436 |
-
}
|
437 |
-
} else {
|
438 |
-
$return_array['request_information'] = __("Message data array not set", 'wp-live-chat-support');
|
439 |
-
}
|
440 |
-
} else {
|
441 |
-
$return_array['request_information'] = __("Chat ID is not set", 'wp-live-chat-support');
|
442 |
-
}
|
443 |
-
}
|
444 |
-
} else {
|
445 |
-
$return_array['request_information'] = __("No security nonce found", 'wp-live-chat-support');
|
446 |
-
}
|
447 |
-
}
|
448 |
-
|
449 |
-
return $return_array;
|
450 |
-
|
451 |
-
}
|
452 |
-
|
453 |
-
/**
|
454 |
-
* Loads remote dashboard
|
455 |
-
*
|
456 |
-
* @return void
|
457 |
-
*/
|
458 |
-
function wplc_admin_dashboard_layout_node( $location = 'dashboard' ) {
|
459 |
-
if ($location == 'dashboard') {
|
460 |
-
if (!get_user_meta(get_current_user_id(), 'wplc_ma_agent', true)) {
|
461 |
-
echo "<div class='error below-h1'><h2>".__("Error", 'wp-live-chat-support')."</h2><p>".__("Only chat agents can access this page.", 'wp-live-chat-support')."</p></div>";
|
462 |
-
return;
|
463 |
}
|
464 |
}
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
|
|
|
|
|
|
|
|
473 |
}
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
|
|
|
|
|
|
480 |
} else {
|
481 |
-
$
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
489 |
}
|
490 |
}
|
491 |
}
|
492 |
}
|
493 |
}
|
494 |
-
}
|
495 |
|
496 |
-
add_action('admin_enqueue_scripts', 'wplc_enqueue_dashboard_popup_scripts');
|
497 |
-
/**
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
function wplc_enqueue_dashboard_popup_scripts() {
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
wp_button_pointers_load_scripts('toplevel_page_wplivechat-menu');
|
506 |
-
}
|
507 |
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
|
|
|
|
|
|
529 |
}
|
530 |
}
|
531 |
}
|
532 |
-
}
|
533 |
|
534 |
-
/**
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
*/
|
539 |
-
function wplc_admin_remote_dashboard_scripts($wplc_settings){
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
$a_array[$user->ID]['name'] = $user->display_name;
|
554 |
-
$a_array[$user->ID]['display_name'] = $user->display_name;
|
555 |
-
$a_array[$user->ID]['md5'] = md5( $user->user_email );
|
556 |
-
$a_array[$user->ID]['email'] = md5( $user->user_email );
|
557 |
}
|
558 |
-
}
|
559 |
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
<p>" . __("Connection Error", 'wp-live-chat-support') . "<br /></p>
|
614 |
<p>" . __("We are having some trouble contacting the server. Please try again later.", 'wp-live-chat-support') . "</p>
|
615 |
</div>";
|
616 |
-
|
617 |
|
618 |
|
619 |
-
wp_localize_script('wplc-admin-js-agent', 'tcx_enable_visitor_sound', array('value'
|
620 |
|
621 |
-
|
622 |
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
|
627 |
-
|
628 |
-
|
629 |
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
$wplc_chat_detail = array(
|
638 |
-
'name' => $wplc_settings['wplc_show_name'],
|
639 |
-
'avatar' => $wplc_settings['wplc_show_avatar'],
|
640 |
-
'date' => $wplc_settings['wplc_show_date'],
|
641 |
-
'time' => $wplc_settings['wplc_show_time'],
|
642 |
-
);
|
643 |
-
wp_localize_script( 'wplc-admin-js-agent', 'wplc_show_chat_detail', $wplc_chat_detail);
|
644 |
-
wp_localize_script('wplc-admin-chat-server', 'wplc_show_chat_detail', $wplc_chat_detail);
|
645 |
|
646 |
-
|
647 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
648 |
|
649 |
-
|
|
|
650 |
|
651 |
-
|
652 |
-
|
653 |
-
$
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
|
|
|
|
659 |
|
660 |
-
|
661 |
-
|
662 |
-
wp_localize_script('wplc-admin-js-agent', 'wplc_restapi_enabled', array('value'=>true));
|
663 |
wp_localize_script('wplc-admin-js-agent', 'wplc_restapi_token', get_option('wplc_api_secret_token'));
|
664 |
wp_localize_script('wplc-admin-js-agent', 'wplc_restapi_endpoint', rest_url('wp_live_chat_support/v1'));
|
665 |
wp_localize_script('wplc-admin-js-agent', 'tcx_override_upload_url', rest_url('wp_live_chat_support/v1/remote_upload'));
|
666 |
-
wp_localize_script('wplc-admin-js-agent', 'wplc_restapi_nonce', wp_create_nonce(
|
667 |
-
|
668 |
-
|
669 |
-
wp_localize_script('wplc-admin-js-agent', 'wplc_restapi_enabled', array('value'=>false));
|
670 |
wp_localize_script('wplc-admin-js-agent', 'wplc_restapi_nonce', '');
|
671 |
-
|
672 |
|
673 |
-
|
674 |
-
$agent_tagline = get_user_meta(
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
|
681 |
-
|
682 |
|
683 |
-
|
684 |
|
685 |
-
|
686 |
-
|
687 |
|
688 |
-
|
689 |
-
|
690 |
|
691 |
-
|
692 |
|
693 |
-
|
694 |
|
695 |
-
|
696 |
-
|
697 |
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
wp_register_script('wplc-admin-chat-events', WPLC_PLUGIN_URL.'/js/wplc_u_admin_events.js', array("wplc-admin-js-agent", "wplc-admin-js-sockets", "wplc-admin-chat-server"), WPLC_PLUGIN_VERSION, false); //Added this for async storage calls
|
704 |
-
wp_enqueue_script('wplc-admin-chat-events');
|
705 |
|
706 |
-
|
707 |
-
|
|
|
|
|
708 |
|
709 |
|
710 |
-
/**
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
*/
|
715 |
-
function wplc_admin_remote_dashboard_styles(){
|
716 |
$wplc_settings = wplc_get_options();
|
717 |
|
718 |
-
wp_register_style(
|
719 |
-
wp_enqueue_style(
|
720 |
|
721 |
-
if (!isset($wplc_settings['wplc_show_avatar']) || (isset($wplc_settings['wplc_show_avatar']) && intval($wplc_settings['wplc_show_avatar']) == 0)
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
"
|
729 |
.wplc-admin-message-avatar, .wplc-user-message-avatar {
|
730 |
max-width:28px !important;
|
731 |
max-height:28px !important;
|
@@ -751,121 +596,121 @@ function wplc_admin_remote_dashboard_styles(){
|
|
751 |
}
|
752 |
";
|
753 |
|
754 |
-
|
755 |
}
|
756 |
|
757 |
-
wp_register_style(
|
758 |
-
wp_enqueue_style(
|
759 |
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
do_action("wplc_admin_remote_dashboard_styles_hook");
|
766 |
-
}
|
767 |
|
768 |
-
|
|
|
|
|
|
|
769 |
* Add action for notice checks
|
770 |
*/
|
771 |
-
if (
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
}
|
776 |
|
777 |
-
add_action("admin_notices", "wplc_node_v8_plus_notice_dismissable");
|
778 |
-
/*
|
779 |
* Displays an admin notice (which can be dismissed), to notify any V8+ users of the node option (if not already checked)
|
780 |
*/
|
781 |
-
function wplc_node_v8_plus_notice_dismissable() {
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
}
|
786 |
-
if (!empty($page) && strpos($page, 'wplivechat') === 0) { // only if it begins with wplivechat
|
787 |
-
if (isset($_GET['wplc_dismiss_notice_v8']) && $_GET['wplc_dismiss_notice_v8'] === "true") {
|
788 |
-
update_option("wplc_node_v8_plus_notice_dismissed", 'true');
|
789 |
}
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
$
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
|
|
|
|
|
|
|
|
|
|
808 |
}
|
809 |
}
|
810 |
}
|
811 |
-
}
|
812 |
|
813 |
-
add_filter(
|
814 |
-
/**
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
function wplc_node_rest_url_ssl_fix($url){
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
}
|
825 |
|
826 |
-
/**
|
827 |
-
|
828 |
-
*/
|
829 |
-
function wplc_node_pages_posts_array(){
|
830 |
$r = array(
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
);
|
841 |
|
842 |
-
|
843 |
-
|
844 |
|
845 |
-
|
846 |
|
847 |
-
|
848 |
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
|
853 |
-
|
854 |
-
|
855 |
|
856 |
-
|
857 |
-
|
858 |
|
859 |
|
860 |
|
861 |
-
add_action("wplc_admin_remoter_dashboard_scripts_localizer", "wplc_admin_remote_dashboard_dynamic_translation_handler");
|
862 |
-
/*
|
863 |
* Localizes an array of strings and ids in the dashboard which need to be replaced
|
864 |
* Loads the custom JS file responsible for replacing the content dynamically.
|
865 |
*/
|
866 |
-
function wplc_admin_remote_dashboard_dynamic_translation_handler(){
|
867 |
|
868 |
-
wp_register_script('wplc-admin-dynamic-translation', WPLC_PLUGIN_URL.'
|
869 |
|
870 |
$wplc_dynamic_translation_array = array(
|
871 |
'nifty_bg_holder_text_inner' => __('Connecting...', 'wp-live-chat-support'),
|
@@ -905,164 +750,164 @@ function wplc_admin_remote_dashboard_dynamic_translation_handler(){
|
|
905 |
|
906 |
wp_localize_script('wplc-admin-dynamic-translation', 'wplc_dynamic_translation_array', $wplc_dynamic_translation_array);
|
907 |
wp_enqueue_script('wplc-admin-dynamic-translation');
|
908 |
-
|
909 |
-
}
|
910 |
|
911 |
|
912 |
|
913 |
|
914 |
-
add_action("wplc_admin_remoter_dashboard_scripts_localizer", "wplc_admin_remote_dashboard_localize_variables");
|
915 |
-
/*
|
916 |
* Localizes all the admin variables
|
917 |
*/
|
918 |
-
function wplc_admin_remote_dashboard_localize_variables(){
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
|
|
927 |
}
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
|
|
|
|
936 |
} else {
|
937 |
-
wp_localize_script(
|
938 |
}
|
939 |
-
} else {
|
940 |
-
wp_localize_script( 'wplc-admin-js-agent', 'tcx_default_department_tag', 'any' );
|
941 |
-
}
|
942 |
|
943 |
-
|
944 |
-
|
|
|
|
|
|
|
|
|
|
|
945 |
}
|
946 |
-
wp_register_script('wplc-admin-chat-events-pro', WPLC_PLUGIN_URL . 'js/wplc_admin_pro_events.js', array("wplc-admin-js-agent", "wplc-admin-chat-events", "wplc-admin-chat-server"), WPLC_PLUGIN_VERSION, false); //Added this for async storage calls
|
947 |
-
wp_enqueue_script('wplc-admin-chat-events-pro');
|
948 |
-
wp_register_script('wplc-admin-tcx-event-tracking-pro', WPLC_PLUGIN_URL . 'js/wplc_tcx_admin_events.js', array("wplc-admin-js-agent", "wplc-admin-chat-events", "wplc-admin-chat-server"), WPLC_PLUGIN_VERSION, false); //Added this for async storage calls
|
949 |
-
wp_enqueue_script('wplc-admin-tcx-event-tracking-pro');
|
950 |
-
}
|
951 |
|
952 |
-
add_filter("wplc_admin_dashboard_layout_node_request_variable_filter", "wplc_admin_dashboard_layout_node_request_add_mrg_variables", 10, 1);
|
953 |
-
/*
|
954 |
* Adds the Pro request variables to our node request
|
955 |
*/
|
956 |
-
function wplc_admin_dashboard_layout_node_request_add_mrg_variables($variables) {
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
}
|
968 |
|
969 |
-
add_filter("wplc_admin_remote_dashboard_localize_tips_array", "wplc_admin_remote_dashboard_localize_tips_array_mrg_handler", 1, 1);
|
970 |
-
/*
|
971 |
* Overrides the tip array in the Pro add-on
|
972 |
*/
|
973 |
-
function wplc_admin_remote_dashboard_localize_tips_array_mrg_handler($tip_array) {
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
}
|
981 |
|
982 |
|
983 |
-
/**
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
function wplc_return_unread_agent_messages_mrg(
|
991 |
global $wpdb;
|
992 |
global $wplc_tblname_msgs;
|
993 |
-
$count = $wpdb->get_var(
|
994 |
return $count;
|
995 |
-
}
|
996 |
|
997 |
-
add_action("wplc_admin_remote_dashboard_above", "wplc_admin_remote_dashboard_quick_responses_container_mrg");
|
998 |
-
/*
|
999 |
* Adds the quick response container
|
1000 |
*/
|
1001 |
-
function wplc_admin_remote_dashboard_quick_responses_container_mrg(){
|
1002 |
|
1003 |
$wplc_settings = wplc_get_options();
|
1004 |
-
$wplc_quick_response_order_by = isset(
|
1005 |
-
$wplc_quick_response_order = isset(
|
1006 |
$args = array(
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
|
|
1021 |
$posts_array = get_posts($args);
|
1022 |
echo '<div id="quick_response_drawer_container" style="display:none;">';
|
1023 |
-
echo '<h5>'.__("Quick Responses", 'wp-live-chat-support').'</h5>';
|
1024 |
-
echo '<hr>';
|
1025 |
-
|
1026 |
-
if($posts_array){
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
} else {
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
}
|
1035 |
echo '</div>';
|
1036 |
-
}
|
1037 |
|
1038 |
|
1039 |
-
add_filter("wplc_agent_display_name_filter", "wplc_agent_display_name_filter_control_mrg", 10, 1);
|
1040 |
-
/*
|
1041 |
* Filters the agent display name
|
1042 |
*/
|
1043 |
-
function wplc_agent_display_name_filter_control_mrg($wplc_display_name) {
|
1044 |
-
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
|
|
1050 |
}
|
|
|
1051 |
}
|
1052 |
-
return $wplc_display_name;
|
1053 |
-
}
|
1054 |
|
1055 |
-
add_action("wplc_admin_remote_dashboard_styles_hook", "wplc_admin_remote_dashboard_styles_mrg");
|
1056 |
-
/**
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
*/
|
1061 |
-
function wplc_admin_remote_dashboard_styles_mrg(){
|
1062 |
-
|
1063 |
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
}
|
3 |
* Node Code
|
4 |
*/
|
5 |
|
6 |
+
if (!defined('ABSPATH')) {
|
7 |
exit;
|
8 |
}
|
9 |
|
18 |
* If not create one for use in the API
|
19 |
*
|
20 |
* @return void
|
21 |
+
*/
|
22 |
+
function wplc_node_server_token_get($reset = false) {
|
23 |
+
$tk = '';
|
24 |
if (!$reset) {
|
25 |
$tk = get_option("wplc_node_server_secret_token");
|
26 |
}
|
27 |
+
if (empty($tk)) {
|
28 |
+
$tk = wplc_node_server_token_create();
|
29 |
update_option("wplc_node_server_secret_token", $tk);
|
30 |
}
|
31 |
return $tk;
|
35 |
function wplc_admin_dashboard() {
|
36 |
$wplc_node_token = wplc_node_server_token_get();
|
37 |
$variables = array("node_token" => $wplc_node_token, "action" => "wordpress");
|
38 |
+
$variables = apply_filters("wplc_admin_dashboard_layout_node_request_variable_filter", $variables);
|
39 |
$wplc_settings = wplc_get_options();
|
40 |
+
?>
|
41 |
+
<div class='nifty_top_wrapper'>
|
42 |
+
<div class="wrap">
|
43 |
+
<div class='floating-right-toolbar'>
|
44 |
+
<label for="user_list_mobile_control" style="margin-bottom: 0;"><i id="toolbar-item-user_list" class="fa fa-bars fa-fw" title="<?php _e('Toggle user list', 'wp-live-chat-support'); ?>"></i></label>
|
45 |
+
<i id="toolbar-item-fullscreen-wp" class="fa fa-clone fa-fw" title="<?php _e('Toggle WordPress Menu for a full screen experience', 'wp-live-chat-support'); ?>."></i>
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
</div>
|
47 |
+
<div id="page-wrapper" style='position:relative;'>
|
48 |
+
<div class='nifty_bg_holder'>
|
49 |
+
<div class='nifty_bg_holder_text'><img src='<?php echo WPLC_PLUGIN_URL; ?>images/wplc_loading.png' width='50' /><br /><br />
|
50 |
+
<div id='nifty_bg_holder_text_inner'>Connecting...</div>
|
51 |
+
</div>
|
52 |
+
<div class='tcx_tips_hints'></div>
|
53 |
+
</div>
|
54 |
+
|
55 |
<div class="nifty_admin_overlay" style="display:none">
|
56 |
|
57 |
</div>
|
58 |
+
|
59 |
+
<div class="nifty_admin_chat_prompt" style="display:none">
|
60 |
+
<div class="nifty_admin_chat_prompt_title" id='nifty_admin_chat_prompt_title'><?php _e('Please Confirm', 'wp-live-chat-support'); ?></div>
|
61 |
+
<div class="nifty_admin_chat_prompt_message"></div>
|
62 |
+
<div class="nifty_admin_chat_prompt_actions">
|
63 |
+
<button class="btn btn-info" id="nifty_admin_chat_prompt_confirm"><?php _e('Confirm', 'wp-live-chat-support'); ?></button>
|
64 |
+
<button class="btn btn-secondary" id="nifty_admin_chat_prompt_cancel"><?php _e('Cancel', 'wp-live-chat-support'); ?></button>
|
65 |
+
</div>
|
66 |
</div>
|
67 |
|
68 |
<div id='nifty_wrapper'>
|
69 |
<input type="checkbox" id="user_list_mobile_control" name="user_list_mobile_control" checked="checked">
|
70 |
<div id='user_list' class='col-md-3'>
|
71 |
+
<?php if ($wplc_settings['wplc_allow_agents_set_status'] && !empty($variables['aid'])) { ?>
|
72 |
<div id='choose_online'>
|
73 |
+
<div id="wplc_agent_status_text" style="display: inline-block; padding-left: 10px;"></div>
|
74 |
+
<input type="checkbox" class="wplc_switchery" name="wplc_agent_status" id="wplc_agent_status" <?php echo (wplc_get_agent_accepting(get_current_user_id()) ? ' checked' : ''); ?> />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
</div>
|
76 |
+
<?php } ?>
|
77 |
+
<div id='user_count'>
|
78 |
+
<span id='active_count'>... </span>
|
79 |
+
<span id='active_count_string'><?php _e('Active visitors', 'wp-live-chat-support'); ?></span>
|
80 |
+
</div>
|
81 |
+
<div class='exp_cols'>
|
82 |
+
<div class='col1'><?php _e('Name', 'wp-live-chat-support'); ?></div>
|
83 |
+
<div class='col3'><?php _e('Agent', 'wp-live-chat-support'); ?></div>
|
84 |
+
</div>
|
85 |
+
<div class='userListBox_Wrapper'>
|
86 |
+
<div class='userListBox'></div>
|
87 |
+
</div>
|
88 |
+
<div id='agent_list'>
|
89 |
+
<h4 id='nifty_agent_heading'><?php _e('Agents', 'wp-live-chat-support'); ?></h4>
|
90 |
+
<ul class='online_agent_list'>
|
91 |
+
</ul>
|
92 |
+
</div>
|
93 |
</div>
|
94 |
|
95 |
<div id='chat_area' class='col-md-9'>
|
96 |
+
<?php if ($variables['include_media_sharing']) { ?>
|
97 |
+
<div id="chat_drag_zone" style="display:none;">
|
98 |
+
<div id="chat_drag_zone_inner"><span id='drag_zone_inner_text'><?php _e('Drag Files Here', 'wp-live-chat-support'); ?></span></div>
|
99 |
+
</div>
|
100 |
<?php } ?>
|
101 |
<div class="chatArea" style='display:none;'>
|
102 |
<div class="chatInfoArea">
|
103 |
+
<span class="minChat btn" id="tcx_min_chat" title="<?php _e('Minimize Chat', 'wp-live-chat-support'); ?>"><i class="fas fa-window-close"></i></span>
|
104 |
<div class="dropdown pull-right"></div>
|
105 |
|
106 |
<div class="btn-group inchat-menu pull-right">
|
110 |
</button>
|
111 |
<div class="dropdown-menu" aria-labelledby='inchat_drop_down'>
|
112 |
<?php if ($variables['include_transfers']) { ?>
|
113 |
+
<a href="javascript:void(0);" class='dropdown-item chatTransfer' id='chatTransferLink'><?php _e('Invite Agent', 'wp-live-chat-support'); ?></a>
|
114 |
+
<a href="javascript:void(0);" class='dropdown-item chatTransferDepartment' id='chatTransferDepLink'><?php _e('Invite Department', 'wp-live-chat-support'); ?></a>
|
115 |
+
<a href="javascript:void(0);" class='dropdown-item chatDirectUserToPagePrompt' id='chatDirectUserToPageLink'><?php _e('Direct User To Page', 'wp-live-chat-support'); ?></a>
|
116 |
<?php } ?>
|
117 |
+
<a href="javascript:void(0);" class='dropdown-item chatTranscript' id='chatTranscriptTitle' style='display:none;'><?php _e('Transcript', 'wp-live-chat-support'); ?></a>
|
118 |
+
<a href="javascript:void(0);" class='dropdown-item chatClose' id='chatCloseTitle' style="display:none;"><?php _e('Leave chat', 'wp-live-chat-support'); ?></a>
|
119 |
+
<a href="javascript:void(0);" class='dropdown-item endChat' id='chatEndTitle'><?php _e('End chat', 'wp-live-chat-support'); ?></a>
|
120 |
</div>
|
121 |
</div>
|
122 |
|
125 |
<div class='user_gravatar'></div>
|
126 |
</div>
|
127 |
<div class='user_header_wrapper_info'>
|
128 |
+
<h3><span class='chatInfoArea-Name'><?php _e('Name', 'wp-live-chat-support'); ?></span></h3>
|
129 |
+
<h4><span class='chatInfoArea-Email'><?php _e('Email', 'wp-live-chat-support'); ?></span></h4>
|
130 |
+
<p><span class='chatInfoArea-Info1'><?php _e('Something', 'wp-live-chat-support'); ?></span></p>
|
131 |
</div>
|
132 |
+
|
133 |
</div>
|
134 |
|
135 |
<ul class="messages" id="messages"></ul>
|
136 |
+
|
137 |
+
<?php if ($variables['include_quick_responses']) { ?>
|
138 |
+
<div id="quick_response_drawer_handle"><i class="fa fa-bolt" title="<?php _e('Quick Responses', 'wp-live-chat-support'); ?>"></i></div>
|
139 |
<?php } ?>
|
140 |
<div class='typing_preview_wplc' style='display:none;'></div>
|
141 |
+
<div class='tcx_join_chat_div'><button class='tcx_join_chat_btn btn btn-success' id='nifty_join_chat_button'><?php _e('Join chat', 'wp-live-chat-support'); ?></button></div>
|
142 |
+
<input class="inputMessage wdt-emoji-bundle-enabled" id="inputMessage" placeholder="<?php _e('Type here...', 'wp-live-chat-support'); ?>" />
|
143 |
+
<span class="editing_hints"><strong>*<?php _e('bold', 'wp-live-chat-support'); ?>*</strong> <em>_<?php _e('italics', 'wp-live-chat-support'); ?>_</em> <code>`<?php _e('code', 'wp-live-chat-support'); ?>`</code> <code>```<?php _e('preformatted', 'wp-live-chat-support'); ?>```</code></span>
|
144 |
+
<img id="wplc_send_msg" class='nifty_send_arrow' style="display:none;" src='<?php echo WPLC_PLUGIN_URL; ?>images/arrow.png' />
|
145 |
+
|
146 |
+
<?php if ($variables['include_media_sharing']) { ?>
|
147 |
+
<label for="nifty_file_input" class='nifty_add_media_button'>
|
148 |
+
<i class="nifty_tedit_icon fa fa-paperclip" id="nifty_attach"></i>
|
149 |
+
<i class="nifty_attach_icon far fa-circle-notch fa-spin" id="nifty_attach_uploading_icon" style="display:none;"></i>
|
150 |
+
<i class="nifty_attach_icon fa fa-check-circle" id="nifty_attach_success_icon" style="display:none;"></i>
|
151 |
+
<i class="nifty_attach_icon fa fa-minus-circle" id="nifty_attach_fail_icon" style="display:none;"></i>
|
152 |
+
</label>
|
153 |
+
|
154 |
+
<input type="file" id="nifty_file_input" name="nifty_file_input" style="display:none">
|
155 |
+
<?php } else { ?>
|
156 |
+
<label for='nifty_add_media' class="nifty_add_media_button"><i class="fa fa-plus"></i></label>
|
157 |
+
<input type="checkbox" id="nifty_add_media" />
|
158 |
+
<?php } ?>
|
159 |
|
160 |
</div>
|
161 |
<div class="infoArea">
|
162 |
<div class="dropdown filter-menu pull-right">
|
163 |
+
<button class="btn dropdown-toggle" type="button" data-toggle="dropdown" style='margin-right:25px;' title="<?php _e('Filter the user list based on activity.', 'wp-live-chat-support'); ?>" id='nifty_filter_button'>
|
164 |
+
Filters
|
165 |
+
<span class="caret"></span>
|
166 |
+
</button>
|
167 |
+
<div class="dropdown-menu">
|
168 |
+
<a href="javascript:void(0);" class='dropdown-item filter-new-visitors' id='nifty_new_visitor_item'><?php _e('New Visitors (3 Min)', 'wp-live-chat-support'); ?></a>
|
169 |
+
<a href="javascript:void(0);" class='dropdown-item filter-active-chats' id='nifty_active_chats_item'><?php _e('Active Chats', 'wp-live-chat-support'); ?></a>
|
170 |
+
<a href="javascript:void(0);" class="dropdown-item filter-referer" id="nifty_referer_item"><?php _e('Page URL', 'wp-live-chat-support'); ?></a>
|
171 |
+
<a href="javascript:void(0);" class='dropdown-item filter-clear' id='nifty_clear_filters_item'><?php _e('Clear Filters', 'wp-live-chat-support'); ?></a>
|
172 |
+
</div>
|
173 |
+
<div class='filter-active-tag-container' style='display:none;'>
|
174 |
+
<i class='fa fa-times-circle filter-clear' style="cursor:pointer;"></i>
|
175 |
+
<span class='filter-active-tag-inner'></span>
|
176 |
+
</div>
|
177 |
</div>
|
178 |
|
179 |
+
<div id="nifty_referer_options" style="display:none;float:right;margin-right:10px;">
|
180 |
+
<input placeholder="Page URL" type="text" id="nifty_referer_url" style="width:100%;float:right;">
|
181 |
+
<label style="font-weight:normal;">
|
182 |
+
<input type="checkbox" id="nifty_referer_contains" style="margin:0;"> <?php _e('Contains', 'wp-live-chat-support'); ?>
|
183 |
+
</label>
|
184 |
+
</div>
|
185 |
+
|
186 |
+
<h2 id='nifty_active_chats_heading'><?php _e('Active visitors', 'wp-live-chat-support'); ?></h2>
|
187 |
|
|
|
|
|
188 |
<div class='visitorListBoxHeader'>
|
189 |
+
<div class='vcol visCol' id='nifty_vis_col_heading'><?php _e('Visitor', 'wp-live-chat-support'); ?></div>
|
190 |
+
<div class='vcol visStatusCol' id='nifty_vis_info_heading'><?php _e('Info', 'wp-live-chat-support'); ?></div>
|
191 |
+
<div class='vcol visPageCol' id='nifty_vis_page_heading'><?php _e('Page', 'wp-live-chat-support'); ?></div>
|
192 |
+
<div class='vcol visChatStatusCol' id='nifty_vis_status_heading'><?php _e('Chat Status', 'wp-live-chat-support'); ?></div>
|
193 |
+
<?php if ($variables['include_departments']) { ?>
|
194 |
+
<div class='vcol visChatDepCol' id='nifty_vis_dep_heading'><?php _e('Department', 'wp-live-chat-support'); ?></div>
|
195 |
<?php } ?>
|
196 |
<div class='vcol visActionCol'></div>
|
197 |
</div>
|
198 |
+
<?php if ($wplc_settings["wplc_settings_enabled"] == 1) { ?>
|
199 |
+
<div class='visitorListBox'>
|
200 |
+
|
201 |
+
</div>
|
202 |
+
<?php } ?>
|
203 |
+
|
204 |
</div>
|
205 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
206 |
</div>
|
207 |
+
<div class="wdt-emoji-popup">
|
208 |
+
<a href="#" class="wdt-emoji-popup-mobile-closer"> × </a>
|
209 |
+
<div class="wdt-emoji-menu-content">
|
210 |
+
<div id="wdt-emoji-menu-header">
|
211 |
+
<a class="wdt-emoji-tab" data-group-name="People"></a>
|
212 |
+
<a class="wdt-emoji-tab" data-group-name="Nature"></a>
|
213 |
+
<a class="wdt-emoji-tab" data-group-name="Foods"></a>
|
214 |
+
<a class="wdt-emoji-tab" data-group-name="Activity"></a>
|
215 |
+
<a class="wdt-emoji-tab" data-group-name="Places"></a>
|
216 |
+
<a class="wdt-emoji-tab" data-group-name="Objects"></a>
|
217 |
+
<a class="wdt-emoji-tab" data-group-name="Symbols"></a>
|
218 |
+
<a class="wdt-emoji-tab" data-group-name="Flags"></a>
|
219 |
+
</div>
|
220 |
+
<div class="wdt-emoji-scroll-wrapper">
|
221 |
+
<div id="wdt-emoji-menu-items">
|
222 |
+
<input id="wdt-emoji-search" type="text" placeholder="<?php _e('Search', 'wp-live-chat-support'); ?>">
|
223 |
+
<h3 id="wdt-emoji-search-result-title"><?php _e('Search Results', 'wp-live-chat-support'); ?></h3>
|
224 |
+
<div class="wdt-emoji-sections"></div>
|
225 |
+
<div id="wdt-emoji-no-result"><?php _e('No emoji found', 'wp-live-chat-support'); ?></div>
|
226 |
+
</div>
|
227 |
+
</div>
|
228 |
+
<div id="wdt-emoji-footer">
|
229 |
+
<div id="wdt-emoji-preview">
|
230 |
+
<span id="wdt-emoji-preview-img"></span>
|
231 |
+
<div id="wdt-emoji-preview-text">
|
232 |
+
<span id="wdt-emoji-preview-name"></span><br>
|
233 |
+
<span id="wdt-emoji-preview-aliases"></span>
|
234 |
+
</div>
|
235 |
+
</div>
|
236 |
+
<div id="wdt-emoji-preview-bundle">
|
237 |
+
<span></span>
|
238 |
+
</div>
|
239 |
+
<span class="wdt-credit">WDT Emoji Bundle</span>
|
240 |
</div>
|
241 |
</div>
|
|
|
|
|
|
|
|
|
242 |
</div>
|
243 |
+
|
244 |
+
<script>
|
245 |
+
jQuery(document).ready(function() {
|
246 |
+
jQuery("#wplc_footer_loading_icon").hide();
|
247 |
+
jQuery("#wplc_footer_message").fadeIn();
|
248 |
+
});
|
249 |
+
</script>
|
250 |
</div>
|
251 |
</div>
|
252 |
+
<?php
|
253 |
+
}
|
254 |
|
255 |
+
/**
|
256 |
+
* Generates a new Secret Token
|
257 |
+
*
|
258 |
+
* @return string
|
259 |
+
*/
|
260 |
+
function wplc_node_server_token_create() {
|
261 |
+
$the_code = rand(0, 1000) . rand(0, 1000) . rand(0, 1000) . rand(0, 1000) . rand(0, 1000);
|
262 |
+
$the_time = time();
|
263 |
+
$token = md5($the_code . $the_time);
|
264 |
+
return $token;
|
265 |
+
}
|
266 |
|
267 |
+
/**
|
268 |
+
* Post to the NODE server -
|
269 |
+
*
|
270 |
+
* @param string $route Route you would like to use for the node server
|
271 |
+
* @param string $form_data data to send
|
272 |
+
* @return string (or false on fail)
|
273 |
+
*/
|
274 |
+
function wplc_node_server_post($route, $form_data) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
275 |
|
276 |
$url = trailingslashit(WPLC_CHAT_SERVER) . trailingslashit(tcx_NODE_END_POINTS_ROUTE) . $route;
|
277 |
|
278 |
+
if (!isset($form_data['token'])) {
|
279 |
+
$form_data['token'] = tcx_NODE_END_POINT_TOKEN; //Add the security token
|
280 |
}
|
281 |
|
282 |
+
if (!isset($form_data['api_key'])) {
|
283 |
+
$form_data['api_key'] = wplc_node_server_token_get(); //Add the security token
|
284 |
}
|
285 |
|
286 |
+
if (!isset($form_data['origin_url'])) {
|
287 |
+
$ajax_url = admin_url('admin-ajax.php');
|
288 |
+
$origin_url = str_replace("/wp-admin/admin-ajax.php", "", $ajax_url);
|
289 |
+
$form_data['origin_url'] = $origin_url; //Add the security token
|
290 |
}
|
291 |
|
292 |
// $options = array();
|
294 |
// $result = @file_get_contents($url . "?" . http_build_query($form_data), false, $context);
|
295 |
|
296 |
$result = wp_remote_get($url . "?" . http_build_query($form_data));
|
297 |
+
if (is_array($result)) {
|
298 |
$result = $result['body']; // use the content
|
299 |
}
|
300 |
|
301 |
if ($result === FALSE) {
|
302 |
+
return false;
|
303 |
} else {
|
304 |
+
return $result;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
305 |
}
|
306 |
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* Loads remote dashboard
|
310 |
+
*
|
311 |
+
* @return void
|
312 |
+
*/
|
313 |
+
function wplc_admin_dashboard_layout_node($location = 'dashboard') {
|
314 |
+
if ($location == 'dashboard') {
|
315 |
+
if (!wplc_user_is_agent()) {
|
316 |
+
echo "<div class='error below-h1'><h2>" . __("Error", 'wp-live-chat-support') . "</h2><p>" . __("Only chat agents can access this page.", 'wp-live-chat-support') . "</p></div>";
|
317 |
+
return;
|
318 |
+
}
|
319 |
}
|
320 |
+
do_action("wplc_admin_remote_dashboard_above");
|
321 |
+
echo "<div id='tcx_content_wrapper'></div>";
|
322 |
+
if ($location == 'dashboard') {
|
323 |
+
if (!isset($_GET['action']) || 'history' !== $_GET['action']) {
|
324 |
+
echo "<div class='wplc_remote_dash_below_contianer'>";
|
325 |
+
do_action("wplc_admin_dashboard_render");
|
326 |
+
do_action("wplc_admin_remote_dashboard_below");
|
327 |
+
echo "</div>";
|
328 |
+
}
|
329 |
} else {
|
330 |
+
if (!empty($_GET['page']) && 'wplivechat-menu' === $_GET['page']) { // This div is also hidden by js under the same conditions
|
331 |
+
echo "<div class='wplc_remote_dash_below_contianer'>";
|
332 |
+
do_action("wplc_admin_remote_dashboard_below");
|
333 |
+
do_action("wplc_admin_dashboard_render");
|
334 |
+
echo "</div>";
|
335 |
+
} else {
|
336 |
+
$wplc_settings = wplc_get_options();
|
337 |
+
if ($wplc_settings['wplc_use_node_server']) {
|
338 |
+
if (isset($_GET['page']) && $_GET['page'] === 'wplivechat-menu') { } else {
|
339 |
+
if ($wplc_settings['wplc_enable_all_admin_pages']) {
|
340 |
+
echo "<div class='wplc_remote_dash_below_contianer'>";
|
341 |
+
do_action("wplc_admin_dashboard_render");
|
342 |
+
echo "</div>";
|
343 |
+
}
|
344 |
}
|
345 |
}
|
346 |
}
|
347 |
}
|
348 |
}
|
|
|
349 |
|
350 |
+
add_action('admin_enqueue_scripts', 'wplc_enqueue_dashboard_popup_scripts');
|
351 |
+
/**
|
352 |
+
* Enqueues the scripts for the admin dashboard popup icon and chat box
|
353 |
+
* @return void
|
354 |
+
*/
|
355 |
+
function wplc_enqueue_dashboard_popup_scripts() {
|
356 |
+
wp_enqueue_script('jquery-ui-draggable');
|
357 |
+
wp_enqueue_script('wplc-admin-popup', WPLC_PLUGIN_URL . 'js/wplc_admin_popup.js', array('jquery-ui-draggable'), WPLC_PLUGIN_VERSION);
|
|
|
|
|
|
|
358 |
|
359 |
+
wp_button_pointers_load_scripts('toplevel_page_wplivechat-menu');
|
360 |
+
}
|
361 |
+
|
362 |
+
add_action("admin_footer", "wplc_dashboard_display_decide");
|
363 |
+
/**
|
364 |
+
* Decide whether or not to display the dashboard layout on an admin page
|
365 |
+
* @return void
|
366 |
+
*/
|
367 |
+
function wplc_dashboard_display_decide() {
|
368 |
+
$wplc_settings = wplc_get_options();
|
369 |
+
if ($wplc_settings['wplc_use_node_server']) {
|
370 |
+
//Node in use, load remote dashboard
|
371 |
+
if (isset($_GET['page']) && $_GET['page'] === 'wplivechat-menu') { } else {
|
372 |
+
/**
|
373 |
+
* Check to see if we have enabled "Enable chat dashboard and notifications on all admin pages"
|
374 |
+
*/
|
375 |
+
|
376 |
+
if ($wplc_settings['wplc_enable_all_admin_pages']) {
|
377 |
+
wplc_admin_dashboard_layout_node('other');
|
378 |
+
echo '<div class="floating-right-toolbar">';
|
379 |
+
echo '<label for="user_list_tcx_control" style="margin-bottom: 0; display:none;"></label>';
|
380 |
+
echo '<i id="toolbar-item-open-tcx" class="fa fa-fw" style="background:url(\'' . plugins_url('../images/tcx48px.png', __FILE__) . '\') no-repeat; background-size: cover;"></i>';
|
381 |
+
echo '</div>';
|
382 |
+
}
|
383 |
}
|
384 |
}
|
385 |
}
|
|
|
386 |
|
387 |
+
/**
|
388 |
+
* Loads remote dashboard scripts and styles
|
389 |
+
*
|
390 |
+
* @return void
|
391 |
+
*/
|
392 |
+
function wplc_admin_remote_dashboard_scripts($wplc_settings) {
|
393 |
+
$wplc_current_user = get_current_user_id();
|
394 |
+
if (wplc_user_is_agent($wplc_current_user)) {
|
395 |
+
$user_info = get_userdata($wplc_current_user);
|
396 |
+
$user_array = wplc_get_agent_users();
|
397 |
+
$a_array = array();
|
398 |
+
if ($user_array) {
|
399 |
+
foreach ($user_array as $user) {
|
400 |
+
$a_array[$user->ID] = array();
|
401 |
+
$a_array[$user->ID]['name'] = $user->display_name;
|
402 |
+
$a_array[$user->ID]['display_name'] = $user->display_name;
|
403 |
+
$a_array[$user->ID]['md5'] = md5($user->user_email);
|
404 |
+
$a_array[$user->ID]['email'] = md5($user->user_email);
|
405 |
+
}
|
|
|
|
|
|
|
|
|
406 |
}
|
|
|
407 |
|
408 |
+
wp_register_script('wplc-admin-js-sockets', WPLC_PLUGIN_URL . "js/vendor/sockets.io/socket.io.slim.js", false, WPLC_PLUGIN_VERSION, false);
|
409 |
+
wp_enqueue_script('wplc-admin-js-sockets');
|
410 |
+
|
411 |
+
wp_register_script('wplc-admin-js-bootstrap', WPLC_PLUGIN_URL . "js/vendor/bootstrap/dist/js/bootstrap.js", array("wplc-admin-js-sockets"), WPLC_PLUGIN_VERSION, false);
|
412 |
+
wp_enqueue_script('wplc-admin-js-bootstrap');
|
413 |
+
|
414 |
+
wplc_register_common_node();
|
415 |
+
|
416 |
+
// NB: This causes Failed to initVars ReferenceError: wplc_show_date is not defined when uncommented and enabled
|
417 |
+
if (!$wplc_settings['wplc_disable_emojis']) {
|
418 |
+
wp_register_script('wplc-admin-js-emoji', WPLC_PLUGIN_URL . "js/vendor/wdt-emoji/emoji.min.js", array("wplc-admin-js-sockets"), WPLC_PLUGIN_VERSION, false);
|
419 |
+
wp_enqueue_script('wplc-admin-js-emoji');
|
420 |
+
wp_register_script('wplc-admin-js-emoji-bundle', WPLC_PLUGIN_URL . "js/vendor/wdt-emoji/wdt-emoji-bundle.min.js", array("wplc-admin-js-emoji"), WPLC_PLUGIN_VERSION, false);
|
421 |
+
wp_enqueue_script('wplc-admin-js-emoji-bundle');
|
422 |
+
}
|
423 |
+
|
424 |
+
wp_register_script('md5', WPLC_PLUGIN_URL . 'js/md5.js', array("wplc-admin-js-sockets"), false, false);
|
425 |
+
wp_enqueue_script('md5');
|
426 |
+
|
427 |
+
$dependencies = array();
|
428 |
+
if (!$wplc_settings['wplc_disable_emojis']) {
|
429 |
+
$dependencies[] = "wplc-admin-js-emoji-bundle";
|
430 |
+
}
|
431 |
+
wp_register_script('wplc-admin-js-agent', WPLC_PLUGIN_URL . 'js/wplc_agent_node.js', $dependencies, WPLC_PLUGIN_VERSION, false);
|
432 |
+
wp_localize_script('wplc-admin-js-agent', "tcx_ping_sound_notification_enabled", array('value' => boolval($wplc_settings['wplc_enable_msg_sound'])));
|
433 |
+
|
434 |
+
wp_register_script('my-wplc-admin-chatbox-ui-events', WPLC_PLUGIN_URL . 'js/wplc_u_admin_chatbox_ui_events.js', array('jquery'), WPLC_PLUGIN_VERSION, true);
|
435 |
+
wp_enqueue_script('my-wplc-admin-chatbox-ui-events');
|
436 |
+
|
437 |
+
|
438 |
+
|
439 |
+
$wplc_et_ajax_nonce = wp_create_nonce("wplc_et_nonce");
|
440 |
+
wp_register_script('wplc_transcript_admin', WPLC_PLUGIN_URL . 'js/wplc_transcript.js', null, '', true);
|
441 |
+
$wplc_transcript_localizations = array(
|
442 |
+
'ajax_nonce' => $wplc_et_ajax_nonce,
|
443 |
+
'string_loading' => __("Sending transcript...", 'wp-live-chat-support'),
|
444 |
+
'string_title' => __("Chat Transcript", 'wp-live-chat-support'),
|
445 |
+
'string_close' => __("Close", 'wp-live-chat-support'),
|
446 |
+
'string_chat_emailed' => __("The chat transcript has been emailed.", 'wp-live-chat-support'),
|
447 |
+
'string_error1' => __("There was a problem emailing the chat.", 'wp-live-chat-support')
|
448 |
+
);
|
449 |
+
wp_localize_script('wplc_transcript_admin', 'wplc_transcript_nonce', $wplc_transcript_localizations);
|
450 |
+
wp_enqueue_script('wplc_transcript_admin');
|
451 |
+
|
452 |
+
$wplc_node_token = wplc_node_server_token_get();
|
453 |
+
|
454 |
+
if (isset($_GET['page']) && $_GET['page'] === 'wplivechat-menu') {
|
455 |
+
wp_localize_script('wplc-admin-js-agent', 'tcx_in_dashboard', array('value' => true));
|
456 |
+
} else {
|
457 |
+
wp_localize_script('wplc-admin-js-agent', 'tcx_in_dashboard', array('value' => false));
|
458 |
+
}
|
459 |
+
|
460 |
+
$inline_error_message = "<div class='error below-h1' style='display:none;' id='tcx_inline_connection_error'>
|
461 |
<p>" . __("Connection Error", 'wp-live-chat-support') . "<br /></p>
|
462 |
<p>" . __("We are having some trouble contacting the server. Please try again later.", 'wp-live-chat-support') . "</p>
|
463 |
</div>";
|
464 |
+
wp_localize_script('wplc-admin-js-agent', 'tcx_remote_form_error', $inline_error_message);
|
465 |
|
466 |
|
467 |
+
wp_localize_script('wplc-admin-js-agent', 'tcx_enable_visitor_sound', array('value' => $wplc_settings['wplc_enable_visitor_sound']));
|
468 |
|
469 |
+
$agent_display_name = $user_info->display_name;
|
470 |
|
471 |
+
wp_localize_script('wplc-admin-js-agent', 'agent_id', "" . $wplc_current_user);
|
472 |
+
wp_localize_script('wplc-admin-js-agent', 'tcx_agent_name', apply_filters("wplc_agent_display_name_filter", $agent_display_name));
|
473 |
+
wp_localize_script('wplc-admin-js-agent', 'nifty_api_key', wplc_node_server_token_get());
|
474 |
|
475 |
+
//For node verification
|
476 |
+
wplc_check_guid();
|
477 |
|
478 |
+
wp_localize_script('wplc-admin-js-agent', 'wplc_guid', get_option('WPLC_GUID', ''));
|
479 |
+
wp_localize_script('wplc-admin-js-agent', 'tcx_agent_verification_end_point', rest_url('wp_live_chat_support/v1/validate_agent'));
|
480 |
+
wp_localize_script('wplc-admin-js-agent', 'tcx_disable_add_message', array('value' => true));
|
481 |
+
wp_localize_script('wplc-admin-js-agent', 'wplc_nonce', wp_create_nonce("wplc"));
|
482 |
+
wp_localize_script('wplc-admin-js-agent', 'wplc_cid', null);
|
483 |
+
wp_localize_script('wplc-admin-js-agent', 'wplc_chat_name', null);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
484 |
|
485 |
+
$wplc_chat_detail = array(
|
486 |
+
'name' => $wplc_settings['wplc_show_name'],
|
487 |
+
'avatar' => $wplc_settings['wplc_show_avatar'],
|
488 |
+
'date' => $wplc_settings['wplc_show_date'],
|
489 |
+
'time' => $wplc_settings['wplc_show_time'],
|
490 |
+
);
|
491 |
+
wp_localize_script('wplc-admin-js-agent', 'wplc_show_chat_detail', $wplc_chat_detail);
|
492 |
+
wp_localize_script('wplc-admin-chat-server', 'wplc_show_chat_detail', $wplc_chat_detail);
|
493 |
|
494 |
+
wp_localize_script('wplc-admin-js-agent', 'wplc_agent_data', $a_array);
|
495 |
+
wp_localize_script('wplc-admin-js-agent', 'all_agents', $a_array);
|
496 |
|
497 |
+
wp_localize_script('wplc-admin-js-agent', 'wplc_url', plugins_url('', dirname(__FILE__)));
|
498 |
+
|
499 |
+
if (isset($wplc_settings['wplc_settings_enabled']) && intval($wplc_settings["wplc_settings_enabled"]) == 2) {
|
500 |
+
$wplc_disabled_html = __("Chat is disabled in settings area, re-enable", 'wp-live-chat-support');
|
501 |
+
$wplc_disabled_html .= " <a href='?page=wplivechat-menu-settings'>" . __("here", 'wp-live-chat-support') . "</a>";
|
502 |
+
wp_localize_script('wplc-admin-js-agent', 'wplc_disabled', array('value' => true));
|
503 |
+
wp_localize_script('wplc-admin-js-agent', 'wplc_disabled_html', $wplc_disabled_html);
|
504 |
+
} else {
|
505 |
+
wp_localize_script('wplc-admin-js-agent', 'wplc_disabled', array('value' => false));
|
506 |
+
}
|
507 |
|
508 |
+
//Added rest nonces
|
509 |
+
if (class_exists("WP_REST_Request")) {
|
510 |
+
wp_localize_script('wplc-admin-js-agent', 'wplc_restapi_enabled', array('value' => true));
|
511 |
wp_localize_script('wplc-admin-js-agent', 'wplc_restapi_token', get_option('wplc_api_secret_token'));
|
512 |
wp_localize_script('wplc-admin-js-agent', 'wplc_restapi_endpoint', rest_url('wp_live_chat_support/v1'));
|
513 |
wp_localize_script('wplc-admin-js-agent', 'tcx_override_upload_url', rest_url('wp_live_chat_support/v1/remote_upload'));
|
514 |
+
wp_localize_script('wplc-admin-js-agent', 'wplc_restapi_nonce', wp_create_nonce('wp_rest'));
|
515 |
+
} else {
|
516 |
+
wp_localize_script('wplc-admin-js-agent', 'wplc_restapi_enabled', array('value' => false));
|
|
|
517 |
wp_localize_script('wplc-admin-js-agent', 'wplc_restapi_nonce', '');
|
518 |
+
}
|
519 |
|
520 |
+
// $agent_tagline = apply_filters( "wplc_filter_simple_agent_data_agent_tagline", '', get_current_user_id() );
|
521 |
+
$agent_tagline = get_user_meta(intval(get_current_user_id()), 'wplc_user_tagline', true);
|
522 |
+
$head_data = array(
|
523 |
+
'tagline' => $agent_tagline
|
524 |
+
);
|
525 |
+
wp_localize_script('wplc-admin-js-agent', 'wplc_head_data', $head_data);
|
526 |
+
wp_localize_script('wplc-admin-js-agent', 'wplc_user_chat_notification_prefix', __("User received notification:", 'wp-live-chat-support'));
|
527 |
|
528 |
+
wp_localize_script('wplc-admin-js-agent', 'tcx_valid_direct_to_page_array', wplc_node_pages_posts_array());
|
529 |
|
530 |
+
wp_localize_script('wplc-admin-js-agent', 'tcx_ringer_count', array('value' => intval($wplc_settings['wplc_new_chat_ringer_count'])));
|
531 |
|
532 |
+
wp_localize_script('wplc-admin-js-agent', 'tcx_new_chat_notification_title', __('New chat received', 'wp-live-chat-support'));
|
533 |
+
wp_localize_script('wplc-admin-js-agent', 'tcx_new_chat_notification_text', __("A new chat has been received. Please go the 'Live Chat' page to accept the chat", 'wp-live-chat-support'));
|
534 |
|
535 |
+
$wplc_notification_icon = plugin_dir_url(dirname(__FILE__)) . 'images/wplc_notification_icon.png';
|
536 |
+
wp_localize_script('wplc-admin-js-agent', 'tcx_new_chat_notification_icon', $wplc_notification_icon);
|
537 |
|
538 |
+
do_action("wplc_admin_remoter_dashboard_scripts_localizer"); //For pro localization of agents list, and departments
|
539 |
|
540 |
+
wp_enqueue_script('wplc-admin-js-agent');
|
541 |
|
542 |
+
wp_register_script('wplc-admin-chat-server', WPLC_PLUGIN_URL . 'js/wplc_server.js', array("wplc-admin-js-agent", "wplc-admin-js-sockets"), WPLC_PLUGIN_VERSION, false); //Added this for async storage calls
|
543 |
+
wp_enqueue_script('wplc-admin-chat-server');
|
544 |
|
545 |
+
wp_localize_script('wplc-admin-chat-server', 'wplc_datetime_format', array(
|
546 |
+
'date_format' => get_option('date_format'),
|
547 |
+
'time_format' => get_option('time_format'),
|
548 |
+
));
|
|
|
|
|
|
|
549 |
|
550 |
+
wp_register_script('wplc-admin-chat-events', WPLC_PLUGIN_URL . 'js/wplc_u_admin_events.js', array("wplc-admin-js-agent", "wplc-admin-js-sockets", "wplc-admin-chat-server"), WPLC_PLUGIN_VERSION, false); //Added this for async storage calls
|
551 |
+
wp_enqueue_script('wplc-admin-chat-events');
|
552 |
+
}
|
553 |
+
}
|
554 |
|
555 |
|
556 |
+
/**
|
557 |
+
* Loads remote dashboard styles
|
558 |
+
*
|
559 |
+
* @return void
|
560 |
+
*/
|
561 |
+
function wplc_admin_remote_dashboard_styles() {
|
562 |
$wplc_settings = wplc_get_options();
|
563 |
|
564 |
+
wp_register_style('wplc-admin-style', WPLC_PLUGIN_URL . "css/chat_dashboard/admin_style.css", false, WPLC_PLUGIN_VERSION);
|
565 |
+
wp_enqueue_style('wplc-admin-style');
|
566 |
|
567 |
+
if (!isset($wplc_settings['wplc_show_avatar']) || (isset($wplc_settings['wplc_show_avatar']) && intval($wplc_settings['wplc_show_avatar']) == 0)) {
|
568 |
+
wp_add_inline_style('wplc-admin-style', ".wplc-user-message, .wplc-admin-message { padding-left: 0 !important; }");
|
569 |
+
} else if (!isset($wplc_settings['wplc_show_name']) || (isset($wplc_settings['wplc_show_name']) && intval($wplc_settings['wplc_show_name']) == 0)) {
|
570 |
+
//User has enabled the gravatar, but has chosen to hide the user name.
|
571 |
+
//This causes some issues with admin display so let's just add some different styling to get around this
|
572 |
+
$inline_identity_css =
|
573 |
+
"
|
|
|
574 |
.wplc-admin-message-avatar, .wplc-user-message-avatar {
|
575 |
max-width:28px !important;
|
576 |
max-height:28px !important;
|
596 |
}
|
597 |
";
|
598 |
|
599 |
+
wp_add_inline_style('wplc-admin-style', $inline_identity_css);
|
600 |
}
|
601 |
|
602 |
+
wp_register_style('wplc-admin-style-bootstrap', WPLC_PLUGIN_URL . "css/bootstrap.css", false, WPLC_PLUGIN_VERSION);
|
603 |
+
wp_enqueue_style('wplc-admin-style-bootstrap');
|
604 |
|
605 |
+
if (!$wplc_settings['wplc_disable_emojis']) {
|
606 |
+
wp_register_style('wplc-admin-style-emoji', WPLC_PLUGIN_URL . "js/vendor/wdt-emoji/wdt-emoji-bundle.css", false, WPLC_PLUGIN_VERSION);
|
607 |
+
wp_enqueue_style('wplc-admin-style-emoji');
|
608 |
+
}
|
|
|
|
|
|
|
609 |
|
610 |
+
do_action("wplc_admin_remote_dashboard_styles_hook");
|
611 |
+
}
|
612 |
+
|
613 |
+
/*
|
614 |
* Add action for notice checks
|
615 |
*/
|
616 |
+
if (!function_exists("wplc_active_chat_box_notices")) {
|
617 |
+
if (isset($_GET['page']) && $_GET['page'] === "wplivechat-menu") {
|
618 |
+
add_action("wplc_admin_remote_dashboard_above", "wplc_active_chat_box_notices");
|
619 |
+
}
|
620 |
+
}
|
621 |
|
622 |
+
add_action("admin_notices", "wplc_node_v8_plus_notice_dismissable");
|
623 |
+
/*
|
624 |
* Displays an admin notice (which can be dismissed), to notify any V8+ users of the node option (if not already checked)
|
625 |
*/
|
626 |
+
function wplc_node_v8_plus_notice_dismissable() {
|
627 |
+
$page = '';
|
628 |
+
if (isset($_GET['page'])) {
|
629 |
+
$page = preg_replace('/[^a-z0-9-]/', '', sanitize_text_field($_GET['page']));
|
|
|
|
|
|
|
|
|
630 |
}
|
631 |
+
if (!empty($page) && strpos($page, 'wplivechat') === 0) { // only if it begins with wplivechat
|
632 |
+
if (isset($_GET['wplc_dismiss_notice_v8']) && $_GET['wplc_dismiss_notice_v8'] === "true") {
|
633 |
+
update_option("wplc_node_v8_plus_notice_dismissed", 'true');
|
634 |
+
}
|
635 |
+
|
636 |
+
$wplc_settings = wplc_get_options();
|
637 |
+
if (!$wplc_settings['wplc_use_node_server']) {
|
638 |
+
//User is not on node, let's check if they have seen this notice before, if not, let's show a notice
|
639 |
+
$wplc_has_notice_been_dismissed = get_option("wplc_node_v8_plus_notice_dismissed", false);
|
640 |
+
if ($wplc_has_notice_been_dismissed === false) {
|
641 |
+
//Has not been dismissed
|
642 |
+
$output = "<div class='notice notice-warning' style='border-color: #0180bc;'>";
|
643 |
+
$output .= "<p><strong>" . __('Welcome to V8 of WP Live Chat by 3CX', 'wp-live-chat-support') . "</strong></p>";
|
644 |
+
$output .= "<p>" . __('Did you know, this version features high speed message delivery, agent to agent chat, and a single window layout?', 'wp-live-chat-support') . "</p>";
|
645 |
+
$output .= "<p>" . __('To activate this functionality please navigate to Live Chat -> Settings -> Advanced Features -> And enable 3CX High Performance Chat Cloud Servers.', 'wp-live-chat-support') . "</p>";
|
646 |
+
|
647 |
+
$output .= "<p>";
|
648 |
+
$output .= "<a href='?page=wplivechat-menu-settings#tabs-beta' class='button button-primary'>" . __("Show me!", 'wp-live-chat-support') . "</a> ";
|
649 |
+
$output .= "<a href='?page=" . $page . "&wplc_dismiss_notice_v8=true' id='wplc_v8_dismiss_node_notice' class='button'>" . __("Don't Show This Again", 'wp-live-chat-support') . "</a>";
|
650 |
+
$output .= "</p>";
|
651 |
+
$output .= "</div>";
|
652 |
+
echo $output;
|
653 |
+
}
|
654 |
}
|
655 |
}
|
656 |
}
|
|
|
657 |
|
658 |
+
add_filter('rest_url', 'wplc_node_rest_url_ssl_fix');
|
659 |
+
/**
|
660 |
+
* Changes the REST URL to include the SSL version if we are using SSL
|
661 |
+
* See https://core.trac.wordpress.org/ticket/36451
|
662 |
+
*/
|
663 |
+
function wplc_node_rest_url_ssl_fix($url) {
|
664 |
+
if (is_ssl()) {
|
665 |
+
$url = set_url_scheme($url, 'https');
|
666 |
+
return $url;
|
667 |
+
}
|
668 |
+
return $url;
|
669 |
+
}
|
670 |
|
671 |
+
/**
|
672 |
+
* Returns an array of pages/posts available on the site
|
673 |
+
*/
|
674 |
+
function wplc_node_pages_posts_array() {
|
675 |
$r = array(
|
676 |
+
'depth' => 0,
|
677 |
+
'child_of' => 0,
|
678 |
+
'echo' => false,
|
679 |
+
'id' => '',
|
680 |
+
'class' => '',
|
681 |
+
'show_option_none' => '',
|
682 |
+
'show_option_no_change' => '',
|
683 |
+
'option_none_value' => '',
|
684 |
+
'value_field' => 'ID',
|
685 |
);
|
686 |
|
687 |
+
$pages = get_pages($r);
|
688 |
+
$posts = get_posts(array('posts_per_page' => -1));
|
689 |
|
690 |
+
$posts_pages = array_merge($pages, $posts);
|
691 |
|
692 |
+
$return_array = array();
|
693 |
|
694 |
+
foreach ($posts_pages as $key => $value) {
|
695 |
+
$post_page_id = $value->ID;
|
696 |
+
$post_page_title = $value->post_title;
|
697 |
|
698 |
+
$return_array[get_permalink($post_page_id)] = $post_page_title;
|
699 |
+
}
|
700 |
|
701 |
+
return $return_array;
|
702 |
+
}
|
703 |
|
704 |
|
705 |
|
706 |
+
add_action("wplc_admin_remoter_dashboard_scripts_localizer", "wplc_admin_remote_dashboard_dynamic_translation_handler");
|
707 |
+
/*
|
708 |
* Localizes an array of strings and ids in the dashboard which need to be replaced
|
709 |
* Loads the custom JS file responsible for replacing the content dynamically.
|
710 |
*/
|
711 |
+
function wplc_admin_remote_dashboard_dynamic_translation_handler() {
|
712 |
|
713 |
+
wp_register_script('wplc-admin-dynamic-translation', WPLC_PLUGIN_URL . 'js/wplc_admin_dynamic_translations.js', array("wplc-admin-js-agent", "wplc-admin-js-sockets", "jquery"), WPLC_PLUGIN_VERSION, false); //Added this for async storage calls
|
714 |
|
715 |
$wplc_dynamic_translation_array = array(
|
716 |
'nifty_bg_holder_text_inner' => __('Connecting...', 'wp-live-chat-support'),
|
750 |
|
751 |
wp_localize_script('wplc-admin-dynamic-translation', 'wplc_dynamic_translation_array', $wplc_dynamic_translation_array);
|
752 |
wp_enqueue_script('wplc-admin-dynamic-translation');
|
753 |
+
}
|
|
|
754 |
|
755 |
|
756 |
|
757 |
|
758 |
+
add_action("wplc_admin_remoter_dashboard_scripts_localizer", "wplc_admin_remote_dashboard_localize_variables");
|
759 |
+
/*
|
760 |
* Localizes all the admin variables
|
761 |
*/
|
762 |
+
function wplc_admin_remote_dashboard_localize_variables() {
|
763 |
+
$wplc_settings = wplc_get_options();
|
764 |
+
$user_id = get_current_user_id();
|
765 |
+
$user_department = get_user_meta($user_id, "wplc_user_department", true);
|
766 |
+
$department_array = array();
|
767 |
+
$departments = wplc_get_all_deparments_mrg();
|
768 |
+
if ($departments) {
|
769 |
+
foreach ($departments as $dep) {
|
770 |
+
$department_array[$dep->id] = $dep->name;
|
771 |
+
}
|
772 |
}
|
773 |
+
$departments['any'] = __("None", 'wp-live-chat-support');
|
774 |
+
$default_department = $wplc_settings['wplc_default_department'];
|
775 |
+
wp_localize_script('wplc-admin-js-agent', 'tcx_departments', $department_array);
|
776 |
+
|
777 |
+
if ($wplc_settings['wplc_allow_department_selection'] && !empty($department_array)) {
|
778 |
+
if (intval($default_department) >= 0) {
|
779 |
+
wp_localize_script('wplc-admin-js-agent', 'tcx_default_department_tag', $department_array[$default_department]);
|
780 |
+
} else {
|
781 |
+
wp_localize_script('wplc-admin-js-agent', 'tcx_default_department_tag', $departments['any']);
|
782 |
+
}
|
783 |
} else {
|
784 |
+
wp_localize_script('wplc-admin-js-agent', 'tcx_default_department_tag', 'any');
|
785 |
}
|
|
|
|
|
|
|
786 |
|
787 |
+
if (!empty($user_department)) {
|
788 |
+
wp_localize_script('wplc-admin-js-agent', 'tcx_agent_department', $user_department);
|
789 |
+
}
|
790 |
+
wp_register_script('wplc-admin-chat-events-pro', WPLC_PLUGIN_URL . 'js/wplc_admin_pro_events.js', array("wplc-admin-js-agent", "wplc-admin-chat-events", "wplc-admin-chat-server"), WPLC_PLUGIN_VERSION, false); //Added this for async storage calls
|
791 |
+
wp_enqueue_script('wplc-admin-chat-events-pro');
|
792 |
+
wp_register_script('wplc-admin-tcx-event-tracking-pro', WPLC_PLUGIN_URL . 'js/wplc_tcx_admin_events.js', array("wplc-admin-js-agent", "wplc-admin-chat-events", "wplc-admin-chat-server"), WPLC_PLUGIN_VERSION, false); //Added this for async storage calls
|
793 |
+
wp_enqueue_script('wplc-admin-tcx-event-tracking-pro');
|
794 |
}
|
|
|
|
|
|
|
|
|
|
|
795 |
|
796 |
+
add_filter("wplc_admin_dashboard_layout_node_request_variable_filter", "wplc_admin_dashboard_layout_node_request_add_mrg_variables", 10, 1);
|
797 |
+
/*
|
798 |
* Adds the Pro request variables to our node request
|
799 |
*/
|
800 |
+
function wplc_admin_dashboard_layout_node_request_add_mrg_variables($variables) {
|
801 |
+
if (is_array($variables)) {
|
802 |
+
$variables['include_filters'] = true;
|
803 |
+
$variables['include_transfers'] = true;
|
804 |
+
$variables['include_media_sharing'] = true;
|
805 |
+
$variables['include_quick_responses'] = true;
|
806 |
+
$variables['include_departments'] = true;
|
807 |
+
$variables['aid'] = get_current_user_id();
|
808 |
+
$variables['agent_count'] = wplc_get_online_agent_users_count();
|
809 |
+
}
|
810 |
+
return $variables;
|
811 |
+
}
|
812 |
|
813 |
+
add_filter("wplc_admin_remote_dashboard_localize_tips_array", "wplc_admin_remote_dashboard_localize_tips_array_mrg_handler", 1, 1);
|
814 |
+
/*
|
815 |
* Overrides the tip array in the Pro add-on
|
816 |
*/
|
817 |
+
function wplc_admin_remote_dashboard_localize_tips_array_mrg_handler($tip_array) {
|
818 |
+
$tip_array = array(
|
819 |
+
"0" => "<p>" . __("You can transfer chats from within a chat by clicking on the in chat menu, and selecting Transfer Chat or Transfer Department", 'wp-live-chat-support') . "</p>",
|
820 |
+
"1" => "<p>" . __("You can share files quickly when in a chat, by simply dragging a file into the chat window!", 'wp-live-chat-support') . "</p>",
|
821 |
+
"2" => "<p>" . __("You can now move between chats without ending/closing an open chat", 'wp-live-chat-support') . "</p>"
|
822 |
+
);
|
823 |
+
return $tip_array;
|
824 |
+
}
|
825 |
|
826 |
|
827 |
+
/**
|
828 |
+
* Return a count of unread messages for a specific agent from a specific agent
|
829 |
+
*
|
830 |
+
* @param [intval] $ato Agent ID
|
831 |
+
* @param [intval] $afrom Agent ID
|
832 |
+
* @return [intval] Count
|
833 |
+
*/
|
834 |
+
function wplc_return_unread_agent_messages_mrg($ato = 0, $afrom = 0) {
|
835 |
global $wpdb;
|
836 |
global $wplc_tblname_msgs;
|
837 |
+
$count = $wpdb->get_var($wpdb->prepare("SELECT count(id) FROM $wplc_tblname_msgs WHERE ato = %d AND afrom = %d AND status = 0", $ato, $afrom));
|
838 |
return $count;
|
839 |
+
}
|
840 |
|
841 |
+
add_action("wplc_admin_remote_dashboard_above", "wplc_admin_remote_dashboard_quick_responses_container_mrg");
|
842 |
+
/*
|
843 |
* Adds the quick response container
|
844 |
*/
|
845 |
+
function wplc_admin_remote_dashboard_quick_responses_container_mrg() {
|
846 |
|
847 |
$wplc_settings = wplc_get_options();
|
848 |
+
$wplc_quick_response_order_by = isset($wplc_settings['wplc_quick_response_orderby']) ? sanitize_text_field($wplc_settings['wplc_quick_response_orderby']) : 'title';
|
849 |
+
$wplc_quick_response_order = isset($wplc_settings['wplc_quick_response_order']) ? sanitize_text_field($wplc_settings['wplc_quick_response_order']) : 'DESC';
|
850 |
$args = array(
|
851 |
+
'posts_per_page' => -1,
|
852 |
+
'offset' => 0,
|
853 |
+
'category' => '',
|
854 |
+
'order' => $wplc_quick_response_order,
|
855 |
+
'orderby' => $wplc_quick_response_order_by != 'number' ? $wplc_quick_response_order_by : 'meta_value_num',
|
856 |
+
'include' => '',
|
857 |
+
'exclude' => '',
|
858 |
+
'meta_key' => $wplc_quick_response_order_by != 'number' ? '' : 'wplc_quick_response_number',
|
859 |
+
'meta_value' => '',
|
860 |
+
'post_type' => 'wplc_quick_response',
|
861 |
+
'post_mime_type' => '',
|
862 |
+
'post_parent' => '',
|
863 |
+
'post_status' => 'publish',
|
864 |
+
'suppress_filters' => true
|
865 |
+
);
|
866 |
$posts_array = get_posts($args);
|
867 |
echo '<div id="quick_response_drawer_container" style="display:none;">';
|
868 |
+
echo '<h5>' . __("Quick Responses", 'wp-live-chat-support') . '</h5>';
|
869 |
+
echo '<hr>';
|
870 |
+
//Add quick responses
|
871 |
+
if ($posts_array) {
|
872 |
+
foreach ($posts_array as $post) {
|
873 |
+
echo '<div class="quick_response_item">' . $post->post_content . '</div>';
|
874 |
+
}
|
875 |
} else {
|
876 |
+
echo "<div style='position: absolute; top: 23px; bottom: 0; left: 10px; right: 0; margin: auto; height: 20px;'>";
|
877 |
+
echo __("No quick responses found", 'wp-live-chat-support') . " - <a target='_blank' href='" . admin_url('post-new.php?post_type=wplc_quick_response') . "'>" . __("Add New Quick Response", 'wp-live-chat-support') . "</a>";
|
878 |
+
echo "</div>";
|
879 |
}
|
880 |
echo '</div>';
|
881 |
+
}
|
882 |
|
883 |
|
884 |
+
add_filter("wplc_agent_display_name_filter", "wplc_agent_display_name_filter_control_mrg", 10, 1);
|
885 |
+
/*
|
886 |
* Filters the agent display name
|
887 |
*/
|
888 |
+
function wplc_agent_display_name_filter_control_mrg($wplc_display_name) {
|
889 |
+
$wplc_settings = wplc_get_options();
|
890 |
+
if (!empty($wplc_settings['wplc_use_wp_name'])) {
|
891 |
+
return $wplc_display_name;
|
892 |
+
} else {
|
893 |
+
if (!empty($wplc_settings['wplc_chat_name'])) {
|
894 |
+
$wplc_display_name = $wplc_settings['wplc_chat_name'];
|
895 |
+
}
|
896 |
}
|
897 |
+
return $wplc_display_name;
|
898 |
}
|
|
|
|
|
899 |
|
900 |
+
add_action("wplc_admin_remote_dashboard_styles_hook", "wplc_admin_remote_dashboard_styles_mrg");
|
901 |
+
/**
|
902 |
+
* Loads remote dashboard styles
|
903 |
+
*
|
904 |
+
* @return void
|
905 |
+
*/
|
906 |
+
function wplc_admin_remote_dashboard_styles_mrg() {
|
907 |
+
$wplc_settings = wplc_get_options();
|
908 |
|
909 |
+
if (!$wplc_settings['wplc_use_node_server'] || !$wplc_settings['wplc_enable_initiate_chat']) {
|
910 |
+
$initiate_chat_inline_styles = ".init_chat {display:none !important;}";
|
911 |
+
wp_add_inline_style('wplc-admin-style', $initiate_chat_inline_styles);
|
912 |
+
}
|
913 |
+
}
|
modules/webhooks_manager.php
CHANGED
@@ -1,30 +1,30 @@
|
|
1 |
-
<?php
|
2 |
|
3 |
-
if (
|
4 |
-
|
5 |
}
|
6 |
|
7 |
global $wplc_webhook_table, $wplc_webhook_events;
|
8 |
$wplc_webhook_table = $wpdb->prefix . "wplc_webhooks";
|
9 |
|
10 |
//Use these when sending a payload
|
11 |
-
$wplc_webhook_events = array
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
);
|
18 |
|
19 |
add_action("wplc_activate_hook", "wplc_webhook_db_setup", 10);
|
20 |
add_action("wplc_update_hook", "wplc_webhook_db_setup", 10);
|
21 |
/*
|
22 |
* Updates/Creates the required tables in order to use devices on node
|
23 |
*/
|
24 |
-
function wplc_webhook_db_setup(){
|
25 |
-
|
26 |
|
27 |
-
|
28 |
CREATE TABLE " . $wplc_webhook_table . " (
|
29 |
id int(11) NOT NULL AUTO_INCREMENT,
|
30 |
url varchar(700) NULL,
|
@@ -34,244 +34,244 @@ function wplc_webhook_db_setup(){
|
|
34 |
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
|
35 |
";
|
36 |
|
37 |
-
|
38 |
}
|
39 |
|
40 |
-
add_action("wplc_hook_menu_mid","wplc_webhooks_manager_menu",11,1);
|
41 |
/*
|
42 |
* Adds a Webhooks menu item to admin menu
|
43 |
*/
|
44 |
function wplc_webhooks_manager_menu($cap) {
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
}
|
51 |
}
|
|
|
52 |
}
|
53 |
|
54 |
/*
|
55 |
* Draws the webhooks page
|
56 |
*/
|
57 |
-
function wplc_webhooks_page(){
|
58 |
-
|
59 |
|
60 |
-
|
61 |
|
62 |
-
|
63 |
-
|
64 |
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
|
78 |
-
|
|
|
79 |
}
|
80 |
|
81 |
-
function wplc_webhook_header_check(){
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
}
|
89 |
}
|
|
|
90 |
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
}
|
98 |
}
|
|
|
99 |
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
}
|
113 |
}
|
|
|
114 |
}
|
115 |
|
116 |
-
function wplc_webhook_add_webhook(){
|
117 |
-
|
118 |
-
|
119 |
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
|
|
|
|
|
|
|
|
124 |
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
$sql = $wpdb->prepare($sql, $action_url, $event, $method);
|
131 |
-
$wpdb->query($sql);
|
132 |
-
if ($wpdb->last_error) {
|
133 |
-
return false;
|
134 |
-
} else {
|
135 |
-
return true;
|
136 |
-
}
|
137 |
} else {
|
138 |
-
|
139 |
}
|
|
|
|
|
|
|
140 |
}
|
141 |
|
142 |
-
function wplc_webhook_edit_webhook(){
|
143 |
-
|
144 |
-
|
145 |
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
} else {
|
162 |
-
return true;
|
163 |
-
}
|
164 |
} else {
|
165 |
-
|
166 |
}
|
|
|
|
|
|
|
167 |
}
|
168 |
|
169 |
-
function wplc_webhook_delete_webhook($webhook_id = false){
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
} else {
|
180 |
-
return true;
|
181 |
-
}
|
182 |
} else {
|
183 |
-
|
184 |
}
|
|
|
|
|
|
|
185 |
}
|
186 |
|
187 |
/*
|
188 |
* Return all webhooks from database
|
189 |
*/
|
190 |
-
function wplc_webhooks_get_all_db($where = false, $id = false){
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
}
|
210 |
|
211 |
/*
|
212 |
* Return specific webhook data
|
213 |
*/
|
214 |
-
function wplc_webhook_get_data($webhook_id){
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
}
|
222 |
|
223 |
/*
|
224 |
* Return all matched webhook
|
225 |
*/
|
226 |
-
function wplc_webhook_get_matched_hooks($event_code){
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
}
|
234 |
|
235 |
/*
|
236 |
* Renders webhooks table
|
237 |
*/
|
238 |
function wplc_webhooks_table() {
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
}
|
267 |
-
|
268 |
-
$content .= "</tbody>";
|
269 |
-
$content .= "</table>";
|
270 |
-
} else {
|
271 |
-
$content .= "<p class='notice notice-error' style='max-width:300px'>" . __("No Webhooks", 'wp-live-chat-support') . "</p>";
|
272 |
}
|
273 |
|
274 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
275 |
}
|
276 |
|
277 |
|
@@ -279,58 +279,58 @@ function wplc_webhooks_table() {
|
|
279 |
* Renders webhooks add webhook form
|
280 |
*/
|
281 |
function wplc_webhooks_add_form($force_edit = false, $webhook_id = false) {
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
$wplc_webhook_nonce = wp_create_nonce('wplc_webhook_nonce');
|
287 |
-
|
288 |
-
if($force_edit && $webhook_id !== false){
|
289 |
-
$webhook_id = intval($webhook_id);
|
290 |
-
$webhook_data = wplc_webhook_get_data($webhook_id);
|
291 |
-
if($webhook_data !== false){
|
292 |
-
$event_value = $webhook_data->action;
|
293 |
-
$url_value = $webhook_data->url;
|
294 |
-
$method_value = $webhook_data->method;
|
295 |
-
}
|
296 |
-
}
|
297 |
-
|
298 |
-
$content = "<form method='POST' action='?page=wplivechat-menu-webhooks-page'>";
|
299 |
-
$content .= "<table class='wp-list-table wplc_list_table widefat striped'>";
|
300 |
-
$content .= "<tr>";
|
301 |
-
$content .= "<td>" . __("Event", 'wp-live-chat-support') . "</td>";
|
302 |
-
$content .= "<td>" . wplc_webhook_render_event_selection_dropdown("add_webhook_event", $event_value, 'width:200px') . "</td>";
|
303 |
-
$content .= "</tr>";
|
304 |
-
|
305 |
-
$content .= "<tr>";
|
306 |
-
$content .= "<td>" . __("Target URL", 'wp-live-chat-support') . "</td>";
|
307 |
-
$content .= "<td><input placeholder='http://example.com/webhook_handler' name='add_webhook_domain' value='".$url_value."' type='text' style='width:200px'></td>";
|
308 |
-
$content .= "</tr>";
|
309 |
|
310 |
-
|
311 |
-
$content .= "<td>" . __("Method", 'wp-live-chat-support') . "</td>";
|
312 |
-
$content .= "<td>";
|
313 |
-
$content .= "<select id='add_webhook_method' name='add_webhook_method' style='width:200px' value='".$method_value."'>";
|
314 |
-
$content .= "<option value='GET' ".($method_value === "GET" ? "selected" : "").">" . __("GET", 'wp-live-chat-support') . "</option>";
|
315 |
-
$content .= "<option value='POST' ".($method_value === "POST" ? "selected" : "").">" . __("POST", 'wp-live-chat-support') . "</option>";
|
316 |
-
$content .= "</select>";
|
317 |
-
$content .= "</td>";
|
318 |
-
$content .= "</tr>";
|
319 |
-
|
320 |
-
$content .= "<tr>";
|
321 |
-
$content .= "<td><input type='submit' name='".($force_edit ? "edit_webhook" : "add_webhook")."' value='" . ($force_edit ? __("Save Changes", 'wp-live-chat-support') : __("Add New", 'wp-live-chat-support') ) . "' class='button button-primary'></td>";
|
322 |
-
$content .= "<td>" . ($force_edit ? "<input type='hidden' name='edit_webhook_id' value='" . $webhook_id . "' >" : "") . "</td>";
|
323 |
-
$content .= "</tr>";
|
324 |
|
325 |
-
|
326 |
-
$
|
327 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
328 |
|
329 |
-
|
330 |
}
|
331 |
|
332 |
function wplc_webhooks_confirm_delete_prompt() {
|
333 |
-
$id=intval($_GET['id']);
|
334 |
$wplc_webhook_nonce = wp_create_nonce('wplc_webhook_nonce');
|
335 |
$content = "<table class='wp-list-table wplc_list_table widefat striped' style='max-width:350px'>";
|
336 |
$content .= "<tr>";
|
@@ -338,7 +338,7 @@ function wplc_webhooks_confirm_delete_prompt() {
|
|
338 |
$content .= "</tr>";
|
339 |
$content .= "<tr>";
|
340 |
$content .= "<td>";
|
341 |
-
$content .= "<a href='?page=wplivechat-menu-webhooks-page&wplc_action=delete_webhook_confirmed&id="
|
342 |
$content .= "<a href='?page=wplivechat-menu-webhooks-page' title='" . __("Cancel", 'wp-live-chat-support') . "' class='button button-secondary'>" . __("Cancel", 'wp-live-chat-support') . "</a> ";
|
343 |
$content .= "</td>";
|
344 |
$content .= "</tr>";
|
@@ -346,126 +346,127 @@ function wplc_webhooks_confirm_delete_prompt() {
|
|
346 |
return $content;
|
347 |
}
|
348 |
|
349 |
-
function wplc_webhook_render_event_selection_dropdown($name, $selected = 0, $styles = ''){
|
350 |
-
|
351 |
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
|
358 |
-
|
359 |
}
|
360 |
|
361 |
add_action("wplc_fire_webhook", "wplc_webhook_send", 10, 2);
|
362 |
/*
|
363 |
* Sends the payload to any matched events - Magic
|
364 |
*/
|
365 |
-
function wplc_webhook_send($event_code, $payload){
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
}
|
424 |
}
|
|
|
425 |
}
|
|
|
426 |
}
|
|
|
427 |
}
|
428 |
|
429 |
add_action("wplc_change_chat_status_hook", "wplc_webhook_status_change_monitor", 10, 2);
|
430 |
/*
|
431 |
-
* Special delegate function for status changes
|
432 |
-
*/
|
433 |
-
function wplc_webhook_status_change_monitor($cid, $status){
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
}
|
445 |
|
446 |
add_action("wplc_log_user_on_page_after_hook", "wplc_webhook_new_visitor_monitor", 10, 2);
|
447 |
/*
|
448 |
* Special Delegate function for new visitor (log user on page)
|
449 |
*/
|
450 |
-
function wplc_webhook_new_visitor_monitor($dbid, $wplc_session_data){
|
451 |
-
|
452 |
}
|
453 |
|
454 |
add_action("wp_login", "wplc_webhook_login_monitor", 10, 2);
|
455 |
/*
|
456 |
* Watches all login activity to track when an agent logs in
|
457 |
*/
|
458 |
-
function wplc_webhook_login_monitor($user_login, $user){
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
}
|
463 |
}
|
464 |
|
465 |
add_action("wplc_hook_admin_settings_save", "wplc_webhook_save_settings_monitor");
|
466 |
/*
|
467 |
* Checks when settings are saved
|
468 |
*/
|
469 |
-
function wplc_webhook_save_settings_monitor(){
|
470 |
-
|
471 |
}
|
1 |
+
<?php
|
2 |
|
3 |
+
if (!defined('ABSPATH')) {
|
4 |
+
exit;
|
5 |
}
|
6 |
|
7 |
global $wplc_webhook_table, $wplc_webhook_events;
|
8 |
$wplc_webhook_table = $wpdb->prefix . "wplc_webhooks";
|
9 |
|
10 |
//Use these when sending a payload
|
11 |
+
$wplc_webhook_events = array(
|
12 |
+
0 => __("Agent Login", 'wp-live-chat-support'),
|
13 |
+
3 => __("New Visitor", 'wp-live-chat-support'),
|
14 |
+
4 => __("Chat Request", 'wp-live-chat-support'),
|
15 |
+
5 => __("Agent Accept", 'wp-live-chat-support'),
|
16 |
+
6 => __("Settings Changed", 'wp-live-chat-support')
|
17 |
+
);
|
18 |
|
19 |
add_action("wplc_activate_hook", "wplc_webhook_db_setup", 10);
|
20 |
add_action("wplc_update_hook", "wplc_webhook_db_setup", 10);
|
21 |
/*
|
22 |
* Updates/Creates the required tables in order to use devices on node
|
23 |
*/
|
24 |
+
function wplc_webhook_db_setup() {
|
25 |
+
global $wplc_webhook_table;
|
26 |
|
27 |
+
$wplc_webhooks_sql = "
|
28 |
CREATE TABLE " . $wplc_webhook_table . " (
|
29 |
id int(11) NOT NULL AUTO_INCREMENT,
|
30 |
url varchar(700) NULL,
|
34 |
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
|
35 |
";
|
36 |
|
37 |
+
dbDelta($wplc_webhooks_sql);
|
38 |
}
|
39 |
|
40 |
+
add_action("wplc_hook_menu_mid", "wplc_webhooks_manager_menu", 11, 1);
|
41 |
/*
|
42 |
* Adds a Webhooks menu item to admin menu
|
43 |
*/
|
44 |
function wplc_webhooks_manager_menu($cap) {
|
45 |
+
$wplc_settings = wplc_get_options();
|
46 |
+
if ($wplc_settings['wplc_use_node_server']) {
|
47 |
+
//Only add this menu item if user is using node.
|
48 |
+
if (current_user_can("manage_options")) {
|
49 |
+
add_submenu_page('wplivechat-menu', __('Webhooks', 'wp-live-chat-support'), __('Webhooks', 'edit_posts'), $cap[0], 'wplivechat-menu-webhooks-page', 'wplc_webhooks_page');
|
|
|
50 |
}
|
51 |
+
}
|
52 |
}
|
53 |
|
54 |
/*
|
55 |
* Draws the webhooks page
|
56 |
*/
|
57 |
+
function wplc_webhooks_page() {
|
58 |
+
wplc_webhook_header_check();
|
59 |
|
60 |
+
$add_webhook_btn = isset($_GET["wplc_action"]) && $_GET["wplc_action"] !== "delete_webhook_confirmed" ? "" : "<a href='?page=wplivechat-menu-webhooks-page&wplc_action=add_webhook' class='button button-secondary'>" . __("Add New", 'wp-livechat') . "</a>";
|
61 |
|
62 |
+
$content = "<div class='wrap wplc_wrap'>";
|
63 |
+
$content .= "<h2>" . __('Web Hooks', 'wp-live-chat-support') . " " . $add_webhook_btn . "</h2>";
|
64 |
|
65 |
+
if (isset($_GET['wplc_action']) && $_GET['wplc_action'] === 'add_webhook') {
|
66 |
+
$content .= wplc_webhooks_add_form();
|
67 |
+
} else if (isset($_GET['wplc_action']) && $_GET['wplc_action'] === 'edit_webhook') {
|
68 |
+
$content .= wplc_webhooks_add_form(true, $_GET['id']);
|
69 |
+
} else if (isset($_GET['wplc_action']) && $_GET['wplc_action'] === 'delete_webhook') {
|
70 |
+
$content .= wplc_webhooks_confirm_delete_prompt();
|
71 |
+
} else {
|
72 |
+
$content .= wplc_webhooks_table();
|
73 |
+
}
|
74 |
+
|
75 |
+
$content .= "</div>"; //Close Wrap
|
|
|
76 |
|
77 |
+
|
78 |
+
echo $content;
|
79 |
}
|
80 |
|
81 |
+
function wplc_webhook_header_check() {
|
82 |
+
if (isset($_POST['add_webhook'])) {
|
83 |
+
//User is trying to add a webhook
|
84 |
+
if (wplc_webhook_add_webhook()) {
|
85 |
+
echo "<p class='notice notice-success' style='max-width:300px'>" . __("Webhook created", 'wp-live-chat-support') . "</p>";
|
86 |
+
} else {
|
87 |
+
echo "<p class='notice notice-error' style='max-width:300px'>" . __("Webhook could not be created", 'wp-live-chat-support') . "</p>";
|
|
|
88 |
}
|
89 |
+
}
|
90 |
|
91 |
+
if (isset($_POST['edit_webhook'])) {
|
92 |
+
//User is trying to edit a webhook
|
93 |
+
if (wplc_webhook_edit_webhook()) {
|
94 |
+
echo "<p class='notice notice-success' style='max-width:300px'>" . __("Webhook edited", 'wp-live-chat-support') . "</p>";
|
95 |
+
} else {
|
96 |
+
echo "<p class='notice notice-error' style='max-width:300px'>" . __("Webhook could not be edited", 'wp-live-chat-support') . "</p>";
|
|
|
97 |
}
|
98 |
+
}
|
99 |
|
100 |
+
if (isset($_GET['wplc_action']) && $_GET['wplc_action'] === 'delete_webhook_confirmed') {
|
101 |
+
if (!isset($_GET['wplc_webhook_nonce']) || !wp_verify_nonce($_GET['wplc_webhook_nonce'], 'wplc_webhook_nonce')) {
|
102 |
+
wp_die(__("You do not have permission do perform this action", 'wp-live-chat-support'));
|
103 |
+
}
|
104 |
|
105 |
+
$webhook_id = isset($_GET['id']) ? intval($_GET['id']) : false;
|
106 |
+
if ($webhook_id !== false) {
|
107 |
+
if (wplc_webhook_delete_webhook($webhook_id)) {
|
108 |
+
echo "<p class='notice notice-success' style='max-width:300px'>" . __("Webhook deleted", 'wp-live-chat-support') . "</p>";
|
109 |
+
} else {
|
110 |
+
echo "<p class='notice notice-error' style='max-width:300px'>" . __("Webhook could not be delete", 'wp-live-chat-support') . "</p>";
|
111 |
+
}
|
|
|
112 |
}
|
113 |
+
}
|
114 |
}
|
115 |
|
116 |
+
function wplc_webhook_add_webhook() {
|
117 |
+
global $wpdb;
|
118 |
+
global $wplc_webhook_table;
|
119 |
|
120 |
+
if (isset($_POST['add_webhook_event'])) {
|
121 |
+
if (!isset($_POST['wplc_webhook_nonce']) || !wp_verify_nonce($_POST['wplc_webhook_nonce'], 'wplc_webhook_nonce')) {
|
122 |
+
wp_die(__("You do not have permission do perform this action", 'wp-live-chat-support'));
|
123 |
+
}
|
124 |
+
|
125 |
+
$event = intval($_POST['add_webhook_event']);
|
126 |
+
$action_url = sanitize_text_field($_POST['add_webhook_domain']);
|
127 |
+
$method = isset($_POST['add_webhook_method']) ? sanitize_text_field($_POST['add_webhook_method']) : "GET";
|
128 |
|
129 |
+
$sql = "INSERT INTO $wplc_webhook_table SET `url` = '%s', `action` = '%s', `method` = '%s' ";
|
130 |
+
$sql = $wpdb->prepare($sql, $action_url, $event, $method);
|
131 |
+
$wpdb->query($sql);
|
132 |
+
if ($wpdb->last_error) {
|
133 |
+
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
} else {
|
135 |
+
return true;
|
136 |
}
|
137 |
+
} else {
|
138 |
+
return false;
|
139 |
+
}
|
140 |
}
|
141 |
|
142 |
+
function wplc_webhook_edit_webhook() {
|
143 |
+
global $wpdb;
|
144 |
+
global $wplc_webhook_table;
|
145 |
|
146 |
+
$webhook_id = isset($_POST['edit_webhook_id']) ? intval($_POST['edit_webhook_id']) : false;
|
147 |
+
if (isset($_POST['add_webhook_event']) && $webhook_id !== false) {
|
148 |
+
if (!isset($_POST['wplc_webhook_nonce']) || !wp_verify_nonce($_POST['wplc_webhook_nonce'], 'wplc_webhook_nonce')) {
|
149 |
+
wp_die(__("You do not have permission do perform this action", 'wp-live-chat-support'));
|
150 |
+
}
|
151 |
|
152 |
+
$event = intval($_POST['add_webhook_event']);
|
153 |
+
$action_url = sanitize_text_field($_POST['add_webhook_domain']);
|
154 |
+
$method = isset($_POST['add_webhook_method']) ? sanitize_text_field($_POST['add_webhook_method']) : "GET";
|
155 |
+
|
156 |
+
$sql = "UPDATE $wplc_webhook_table SET `url` = '%s', `action` = '%s', `method` = '%s' WHERE `id` = '%d' LIMIT 1";
|
157 |
+
$sql = $wpdb->prepare($sql, $action_url, $event, $method, $webhook_id);
|
158 |
+
$wpdb->query($sql);
|
159 |
+
if ($wpdb->last_error) {
|
160 |
+
return false;
|
|
|
|
|
|
|
161 |
} else {
|
162 |
+
return true;
|
163 |
}
|
164 |
+
} else {
|
165 |
+
return false;
|
166 |
+
}
|
167 |
}
|
168 |
|
169 |
+
function wplc_webhook_delete_webhook($webhook_id = false) {
|
170 |
+
global $wpdb;
|
171 |
+
global $wplc_webhook_table;
|
172 |
+
|
173 |
+
if ($webhook_id !== false) {
|
174 |
+
$sql = "DELETE FROM $wplc_webhook_table WHERE `id` = '%d' LIMIT 1";
|
175 |
+
$sql = $wpdb->prepare($sql, $webhook_id);
|
176 |
+
$wpdb->query($sql);
|
177 |
+
if ($wpdb->last_error) {
|
178 |
+
return false;
|
|
|
|
|
|
|
179 |
} else {
|
180 |
+
return true;
|
181 |
}
|
182 |
+
} else {
|
183 |
+
return false;
|
184 |
+
}
|
185 |
}
|
186 |
|
187 |
/*
|
188 |
* Return all webhooks from database
|
189 |
*/
|
190 |
+
function wplc_webhooks_get_all_db($where = false, $id = false) {
|
191 |
+
global $wpdb;
|
192 |
+
global $wplc_webhook_table;
|
193 |
+
|
194 |
+
$where = ($where === false) ? "" : $where;
|
195 |
+
|
196 |
+
$sql = "SELECT * FROM $wplc_webhook_table ";
|
197 |
+
|
198 |
+
if ($where !== "") {
|
199 |
+
$results = $wpdb->get_results($wpdb->prepare($sql . $where, intval($id)));
|
200 |
+
} else {
|
201 |
+
$results = $wpdb->get_results($sql);
|
202 |
+
}
|
203 |
+
|
204 |
+
if ($wpdb->num_rows) {
|
205 |
+
return $results;
|
206 |
+
} else {
|
207 |
+
return false;
|
208 |
+
}
|
209 |
}
|
210 |
|
211 |
/*
|
212 |
* Return specific webhook data
|
213 |
*/
|
214 |
+
function wplc_webhook_get_data($webhook_id) {
|
215 |
+
$results = wplc_webhooks_get_all_db("WHERE `id` = %d", $webhook_id);
|
216 |
+
if ($results !== false) {
|
217 |
+
return $results[0];
|
218 |
+
} else {
|
219 |
+
return false;
|
220 |
+
}
|
221 |
}
|
222 |
|
223 |
/*
|
224 |
* Return all matched webhook
|
225 |
*/
|
226 |
+
function wplc_webhook_get_matched_hooks($event_code) {
|
227 |
+
$results = wplc_webhooks_get_all_db("WHERE `action` = %d", $event_code);
|
228 |
+
if ($results !== false) {
|
229 |
+
return $results;
|
230 |
+
} else {
|
231 |
+
return false;
|
232 |
+
}
|
233 |
}
|
234 |
|
235 |
/*
|
236 |
* Renders webhooks table
|
237 |
*/
|
238 |
function wplc_webhooks_table() {
|
239 |
+
global $wpdb, $wplc_webhook_table, $wplc_webhook_events;
|
240 |
+
$webhooks = wplc_webhooks_get_all_db();
|
241 |
+
|
242 |
+
$content = "";
|
243 |
+
if ($webhooks !== false) {
|
244 |
+
|
245 |
+
$content .= "<table id='webhooks' class='wp-list-table wplc_list_table widefat' cellspacing='0' width='100%'>";
|
246 |
+
$content .= "<thead>";
|
247 |
+
$content .= "<tr>";
|
248 |
+
$content .= "<th scope='col' id='event' style='width:30%;'><span>" . __("Event", 'wp-live-chat-support') . "</span></th>";
|
249 |
+
$content .= "<th scope='col' id='target' style='width:30%;'><span>" . __("Target URL", 'wp-live-chat-support') . "</span></th>";
|
250 |
+
$content .= "<th scope='col' id='method' style='width:10%;'><span>" . __("Method", 'wp-live-chat-support') . "</span></th>";
|
251 |
+
$content .= "<th scope='col' id='action'><span>" . __("Action", 'wp-live-chat-support') . "</span></th>";
|
252 |
+
$content .= "</tr>";
|
253 |
+
$content .= "</thead>";
|
254 |
+
$content .= "<tbody>";
|
255 |
+
|
256 |
+
foreach ($webhooks as $key => $webhook) {
|
257 |
+
$content .= "<tr>";
|
258 |
+
$content .= "<td>" . $wplc_webhook_events[$webhook->action] . "</td>";
|
259 |
+
$content .= "<td>" . $webhook->url . "</td>";
|
260 |
+
$content .= "<td>" . $webhook->method . "</td>";
|
261 |
+
$content .= "<td>";
|
262 |
+
$content .= "<a href='?page=wplivechat-menu-webhooks-page&wplc_action=edit_webhook&id=" . $webhook->id . "' title='" . __("Edit", 'wp-live-chat-support') . "' class='button button-secondary'>" . __("Edit", 'wp-live-chat-support') . "</a> ";
|
263 |
+
$content .= "<a href='?page=wplivechat-menu-webhooks-page&wplc_action=delete_webhook&id=" . $webhook->id . "' title='" . __("Delete", 'wp-live-chat-support') . "' class='button button-secondary'>" . __("Delete", 'wp-live-chat-support') . "</a>";
|
264 |
+
$content .= "</td>";
|
265 |
+
$content .= "</tr>";
|
|
|
|
|
|
|
|
|
|
|
|
|
266 |
}
|
267 |
|
268 |
+
$content .= "</tbody>";
|
269 |
+
$content .= "</table>";
|
270 |
+
} else {
|
271 |
+
$content .= "<p class='notice notice-error' style='max-width:300px'>" . __("No Webhooks", 'wp-live-chat-support') . "</p>";
|
272 |
+
}
|
273 |
+
|
274 |
+
return $content;
|
275 |
}
|
276 |
|
277 |
|
279 |
* Renders webhooks add webhook form
|
280 |
*/
|
281 |
function wplc_webhooks_add_form($force_edit = false, $webhook_id = false) {
|
282 |
+
$event_value = 0;
|
283 |
+
$url_value = "";
|
284 |
+
$method_value = "GET";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
285 |
|
286 |
+
$wplc_webhook_nonce = wp_create_nonce('wplc_webhook_nonce');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
287 |
|
288 |
+
if ($force_edit && $webhook_id !== false) {
|
289 |
+
$webhook_id = intval($webhook_id);
|
290 |
+
$webhook_data = wplc_webhook_get_data($webhook_id);
|
291 |
+
if ($webhook_data !== false) {
|
292 |
+
$event_value = $webhook_data->action;
|
293 |
+
$url_value = $webhook_data->url;
|
294 |
+
$method_value = $webhook_data->method;
|
295 |
+
}
|
296 |
+
}
|
297 |
+
|
298 |
+
$content = "<form method='POST' action='?page=wplivechat-menu-webhooks-page'>";
|
299 |
+
$content .= "<table class='wp-list-table wplc_list_table widefat striped'>";
|
300 |
+
$content .= "<tr>";
|
301 |
+
$content .= "<td>" . __("Event", 'wp-live-chat-support') . "</td>";
|
302 |
+
$content .= "<td>" . wplc_webhook_render_event_selection_dropdown("add_webhook_event", $event_value, 'width:200px') . "</td>";
|
303 |
+
$content .= "</tr>";
|
304 |
+
|
305 |
+
$content .= "<tr>";
|
306 |
+
$content .= "<td>" . __("Target URL", 'wp-live-chat-support') . "</td>";
|
307 |
+
$content .= "<td><input placeholder='http://example.com/webhook_handler' name='add_webhook_domain' value='" . $url_value . "' type='text' style='width:200px'></td>";
|
308 |
+
$content .= "</tr>";
|
309 |
+
|
310 |
+
$content .= "<tr>";
|
311 |
+
$content .= "<td>" . __("Method", 'wp-live-chat-support') . "</td>";
|
312 |
+
$content .= "<td>";
|
313 |
+
$content .= "<select id='add_webhook_method' name='add_webhook_method' style='width:200px' value='" . $method_value . "'>";
|
314 |
+
$content .= "<option value='GET' " . ($method_value === "GET" ? "selected" : "") . ">" . __("GET", 'wp-live-chat-support') . "</option>";
|
315 |
+
$content .= "<option value='POST' " . ($method_value === "POST" ? "selected" : "") . ">" . __("POST", 'wp-live-chat-support') . "</option>";
|
316 |
+
$content .= "</select>";
|
317 |
+
$content .= "</td>";
|
318 |
+
$content .= "</tr>";
|
319 |
+
|
320 |
+
$content .= "<tr>";
|
321 |
+
$content .= "<td><input type='submit' name='" . ($force_edit ? "edit_webhook" : "add_webhook") . "' value='" . ($force_edit ? __("Save Changes", 'wp-live-chat-support') : __("Add New", 'wp-live-chat-support')) . "' class='button button-primary'></td>";
|
322 |
+
$content .= "<td>" . ($force_edit ? "<input type='hidden' name='edit_webhook_id' value='" . $webhook_id . "' >" : "") . "</td>";
|
323 |
+
$content .= "</tr>";
|
324 |
+
|
325 |
+
$content .= "</table>";
|
326 |
+
$content .= "<input name='wplc_webhook_nonce' type='hidden' value='" . $wplc_webhook_nonce . "' >";
|
327 |
+
$content .= "</form>";
|
328 |
|
329 |
+
return $content;
|
330 |
}
|
331 |
|
332 |
function wplc_webhooks_confirm_delete_prompt() {
|
333 |
+
$id = intval($_GET['id']);
|
334 |
$wplc_webhook_nonce = wp_create_nonce('wplc_webhook_nonce');
|
335 |
$content = "<table class='wp-list-table wplc_list_table widefat striped' style='max-width:350px'>";
|
336 |
$content .= "<tr>";
|
338 |
$content .= "</tr>";
|
339 |
$content .= "<tr>";
|
340 |
$content .= "<td>";
|
341 |
+
$content .= "<a href='?page=wplivechat-menu-webhooks-page&wplc_action=delete_webhook_confirmed&id=" . $id . "&wplc_webhook_nonce=" . $wplc_webhook_nonce . "' title='" . __("Confirm", 'wp-live-chat-support') . "' class='button button-primary'>" . __("Confirm", 'wp-live-chat-support') . "</a> ";
|
342 |
$content .= "<a href='?page=wplivechat-menu-webhooks-page' title='" . __("Cancel", 'wp-live-chat-support') . "' class='button button-secondary'>" . __("Cancel", 'wp-live-chat-support') . "</a> ";
|
343 |
$content .= "</td>";
|
344 |
$content .= "</tr>";
|
346 |
return $content;
|
347 |
}
|
348 |
|
349 |
+
function wplc_webhook_render_event_selection_dropdown($name, $selected = 0, $styles = '') {
|
350 |
+
global $wplc_webhook_events;
|
351 |
|
352 |
+
$content = "<select id='$name' name='$name' style='$styles'>";
|
353 |
+
foreach ($wplc_webhook_events as $key => $value) {
|
354 |
+
$content .= "<option value='$key' " . (intval($key) === intval($selected) ? "selected " : "") . ">" . $value . "</option>";
|
355 |
+
}
|
356 |
+
$content .= "</select>";
|
357 |
|
358 |
+
return $content;
|
359 |
}
|
360 |
|
361 |
add_action("wplc_fire_webhook", "wplc_webhook_send", 10, 2);
|
362 |
/*
|
363 |
* Sends the payload to any matched events - Magic
|
364 |
*/
|
365 |
+
function wplc_webhook_send($event_code, $payload) {
|
366 |
+
global $wplc_webhook_events;
|
367 |
+
if (isset($event_code) && isset($payload)) {
|
368 |
+
$event_code = intval($event_code);
|
369 |
+
if (array_key_exists($event_code, $wplc_webhook_events)) {
|
370 |
+
$matches = wplc_webhook_get_matched_hooks(intval($event_code));
|
371 |
+
if ($matches !== false) {
|
372 |
+
//fire off the hooks
|
373 |
+
$error_found = false;
|
374 |
+
foreach ($matches as $webhook) {
|
375 |
+
$target_url = isset($webhook->url) ? $webhook->url : false;
|
376 |
+
$method = isset($webhook->method) && $webhook->method === "GET" ? "GET" : "POST";
|
377 |
+
|
378 |
+
if (!is_array($payload)) {
|
379 |
+
//Not an array, no worries we will fix that
|
380 |
+
$payload = array("other" => $payload);
|
381 |
+
}
|
382 |
+
|
383 |
+
$payload = array(
|
384 |
+
"event" => $wplc_webhook_events[intval($event_code)],
|
385 |
+
"data" => json_encode($payload),
|
386 |
+
"time_sent" => time()
|
387 |
+
);
|
388 |
+
|
389 |
+
if ($target_url !== false && $target_url !== "") {
|
390 |
+
$result = "";
|
391 |
+
if ($method === "POST") {
|
392 |
+
/** Replaced with WP HTTP API Calls */
|
393 |
+
|
394 |
+
$response = wp_remote_post(
|
395 |
+
$target_url,
|
396 |
+
array(
|
397 |
+
'method' => 'POST',
|
398 |
+
'timeout' => 45,
|
399 |
+
'redirection' => 5,
|
400 |
+
'httpversion' => '1.0',
|
401 |
+
'blocking' => true,
|
402 |
+
'headers' => array(),
|
403 |
+
'body' => $payload,
|
404 |
+
'cookies' => array()
|
405 |
+
)
|
406 |
+
);
|
407 |
+
|
408 |
+
if (is_wp_error($response)) {
|
409 |
+
//This has failed
|
410 |
+
$error_found = true;
|
411 |
+
$result = "Failed! No Response.";
|
412 |
+
}
|
413 |
+
} else {
|
414 |
+
/** Replaced with WP HTTP API Calls */
|
415 |
+
|
416 |
+
$get_data = http_build_query($payload);
|
417 |
+
$response = wp_remote_get($target_url . "?" . $get_data);
|
418 |
+
if (is_wp_error($response)) {
|
419 |
+
//This has failed
|
420 |
+
$error_found = true;
|
421 |
+
$result = "Failed! No Response.";
|
422 |
+
}
|
|
|
423 |
}
|
424 |
+
}
|
425 |
}
|
426 |
+
}
|
427 |
}
|
428 |
+
}
|
429 |
}
|
430 |
|
431 |
add_action("wplc_change_chat_status_hook", "wplc_webhook_status_change_monitor", 10, 2);
|
432 |
/*
|
433 |
+
* Special delegate function for status changes
|
434 |
+
*/
|
435 |
+
function wplc_webhook_status_change_monitor($cid, $status) {
|
436 |
+
switch (intval($status)) {
|
437 |
+
case 2:
|
438 |
+
//Chat Request
|
439 |
+
do_action("wplc_fire_webhook", 4, array("chat_id" => $cid));
|
440 |
+
break;
|
441 |
+
case 3:
|
442 |
+
//Agent Accept
|
443 |
+
do_action("wplc_fire_webhook", 5, array("chat_id" => $cid));
|
444 |
+
break;
|
445 |
+
}
|
446 |
}
|
447 |
|
448 |
add_action("wplc_log_user_on_page_after_hook", "wplc_webhook_new_visitor_monitor", 10, 2);
|
449 |
/*
|
450 |
* Special Delegate function for new visitor (log user on page)
|
451 |
*/
|
452 |
+
function wplc_webhook_new_visitor_monitor($dbid, $wplc_session_data) {
|
453 |
+
do_action("wplc_fire_webhook", 3, array("chat_id" => $dbid));
|
454 |
}
|
455 |
|
456 |
add_action("wp_login", "wplc_webhook_login_monitor", 10, 2);
|
457 |
/*
|
458 |
* Watches all login activity to track when an agent logs in
|
459 |
*/
|
460 |
+
function wplc_webhook_login_monitor($user_login, $user) {
|
461 |
+
if (wplc_user_is_agent($user->ID)) {
|
462 |
+
do_action("wplc_fire_webhook", 0, array("agent_id" => $user->ID));
|
463 |
+
}
|
|
|
464 |
}
|
465 |
|
466 |
add_action("wplc_hook_admin_settings_save", "wplc_webhook_save_settings_monitor");
|
467 |
/*
|
468 |
* Checks when settings are saved
|
469 |
*/
|
470 |
+
function wplc_webhook_save_settings_monitor() {
|
471 |
+
do_action("wplc_fire_webhook", 6, array("user_id" => get_current_user_id()));
|
472 |
}
|
readme.txt
CHANGED
@@ -1,11 +1,13 @@
|
|
1 |
=== WP-Live Chat by 3CX ===
|
2 |
-
Contributors: WP-LiveChat, wordpress3cx
|
3 |
Tags: live chat, live support, chat plugin, live help, wordpress live chat, chat, live chat plugin, live support plugin, live chat support plugin, chat plugin, support plugin, live help
|
4 |
-
Requires at least: 4.
|
5 |
Tested up to: 5.2.4
|
6 |
Requires PHP: 5.3
|
7 |
-
Stable tag: 8.1.
|
8 |
License: GPLv2
|
|
|
|
|
9 |
|
10 |
Chat with your website visitors in real-time for free! Engage with your customers and increase sales.
|
11 |
|
@@ -56,7 +58,6 @@ Connect with your website visitors for free with the WP-Live Chat plugin by 3CX.
|
|
56 |
* Include/exclude the live chat from appearing on certain pages
|
57 |
* Choose when to accept chats
|
58 |
|
59 |
-
|
60 |
Get [WP-Live Chat by 3CX](https://www.3cx.com/wp-live-chat/) for free!
|
61 |
|
62 |
= 30 second live chat installation =
|
@@ -185,6 +186,19 @@ Huge update with over 300 changes that include: Bugfixes, Vulnerability Fixes &
|
|
185 |
|
186 |
== Changelog ==
|
187 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
= 8.1.2 - 2019-10-24
|
189 |
* New feature: improved auto pop-up feature, now 3 options to choose from
|
190 |
* New feature: Pop-up only when agents are online
|
1 |
=== WP-Live Chat by 3CX ===
|
2 |
+
Contributors: WP-LiveChat, wordpress3cx, wp3cx
|
3 |
Tags: live chat, live support, chat plugin, live help, wordpress live chat, chat, live chat plugin, live support plugin, live chat support plugin, chat plugin, support plugin, live help
|
4 |
+
Requires at least: 4.6
|
5 |
Tested up to: 5.2.4
|
6 |
Requires PHP: 5.3
|
7 |
+
Stable tag: 8.1.3
|
8 |
License: GPLv2
|
9 |
+
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
10 |
+
Text Domain: wp-live-chat-support
|
11 |
|
12 |
Chat with your website visitors in real-time for free! Engage with your customers and increase sales.
|
13 |
|
58 |
* Include/exclude the live chat from appearing on certain pages
|
59 |
* Choose when to accept chats
|
60 |
|
|
|
61 |
Get [WP-Live Chat by 3CX](https://www.3cx.com/wp-live-chat/) for free!
|
62 |
|
63 |
= 30 second live chat installation =
|
186 |
|
187 |
== Changelog ==
|
188 |
|
189 |
+
= 8.1.3 - 2019-10-31
|
190 |
+
* Bugfix: Admin detected as an agent - doesn't show offline messages form
|
191 |
+
* Bugfix: Remove picture from chat box doesn't work properly
|
192 |
+
* Bugfix: Edge JS compatibility issue in dashboard has been fixed
|
193 |
+
* Bugfix: The page will no longer refresh upon ending a chat with an agent.
|
194 |
+
* New feature: Agent online/offline switch in Wordpress admin bar
|
195 |
+
* New feature: Adjustable chatbox height 30% - 80% of page size
|
196 |
+
* Improvement: Cleaned up async_storage functions
|
197 |
+
* Improvement: Better alignment for chat popup with no picture
|
198 |
+
* Improvement: Reworked agent online/offline functions
|
199 |
+
* Improvement: Default business hours are now 9:00 - 18:00 instead of 00:00 - 00:00
|
200 |
+
* Improvement: The 'Use Logged In User Details' feature has been moved to the 'Chat Box' settings page
|
201 |
+
|
202 |
= 8.1.2 - 2019-10-24
|
203 |
* New feature: improved auto pop-up feature, now 3 options to choose from
|
204 |
* New feature: Pop-up only when agents are online
|
wp-live-chat-support.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: WP-Live Chat by 3CX
|
4 |
Plugin URI: https://www.3cx.com/wp-live-chat/
|
5 |
Description: The easiest to use website live chat plugin. Let your visitors chat with you and increase sales conversion rates with WP-Live Chat by 3CX.
|
6 |
-
Version: 8.1.
|
7 |
Author: 3CX
|
8 |
Author URI: https://www.3cx.com/wp-live-chat/
|
9 |
Domain Path: /languages
|
@@ -12,6 +12,19 @@
|
|
12 |
*/
|
13 |
|
14 |
/*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
= 8.1.2 - 2019-10-24
|
16 |
* New feature: improved auto pop-up feature, now 3 options to choose from
|
17 |
* New feature: Pop-up only when agents are online
|
@@ -377,15 +390,16 @@ function wplc_set_defaults() {
|
|
377 |
'wplc_avatar_source' => '',
|
378 |
'wplc_bh_enable' => false,
|
379 |
'wplc_bh_interval' => 0,
|
380 |
-
'wplc_bh_hours_start' =>
|
381 |
'wplc_bh_minutes_start' => 0,
|
382 |
-
'wplc_bh_hours_end' =>
|
383 |
'wplc_bh_minutes_end' => 0,
|
384 |
'wplc_chat_delay' => 2,
|
385 |
'wplc_chat_icon' => plugins_url( '/', __FILE__ ).'images/chaticon.png',
|
386 |
'wplc_chat_logo' => '',
|
387 |
'wplc_chat_name' => __( 'Admin', 'wp-live-chat-support'),
|
388 |
'wplc_chat_pic' => plugins_url( '/', __FILE__ ).'images/picture-for-chat-box.jpg',
|
|
|
389 |
'wplc_close_btn_text' => __("close", 'wp-live-chat-support'),
|
390 |
'wplc_default_department' => -1,
|
391 |
'wplc_delay_between_loops' => 500,
|
@@ -611,6 +625,7 @@ add_action('wp_ajax_wplc_a2a_dismiss', 'wplc_action_callback');
|
|
611 |
add_action('activated_plugin', 'wplc_redirect_on_activate');
|
612 |
add_action('wp_ajax_wplc_choose_accepting','wplc_action_callback');
|
613 |
add_action('wp_ajax_wplc_choose_not_accepting','wplc_action_callback');
|
|
|
614 |
add_action('wplc_hook_action_callback','wplc_choose_hook_control_action_callback');
|
615 |
add_action('wplc_hook_admin_menu_layout_display_top','wplc_ma_hook_control_admin_meny_layout_display_top');
|
616 |
add_action('edit_user_profile_update', 'wplc_maa_set_user_as_agent');
|
@@ -686,19 +701,16 @@ function wplc_uninstall() {
|
|
686 |
$admins->remove_cap('wplc_ma_agent');
|
687 |
}
|
688 |
|
689 |
-
$users =
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
}
|
700 |
-
}
|
701 |
-
|
702 |
}
|
703 |
}
|
704 |
|
@@ -789,7 +801,7 @@ function wplc_version_control() {
|
|
789 |
|
790 |
$uid = get_current_user_id();
|
791 |
update_user_meta($uid, 'wplc_ma_agent', 1);
|
792 |
-
|
793 |
|
794 |
/* add caps to admin */
|
795 |
if (current_user_can('manage_options')) {
|
@@ -916,8 +928,10 @@ function wplc_action_callback() {
|
|
916 |
));
|
917 |
} else if ($_POST['action'] == "wplc_admin_set_transient") {
|
918 |
do_action("wplc_hook_set_transient");
|
|
|
919 |
} else if ($_POST['action'] == "wplc_admin_remove_transient") {
|
920 |
do_action("wplc_hook_remove_transient");
|
|
|
921 |
} else if ($_POST['action'] == 'wplc_hide_ftt') {
|
922 |
update_option("WPLC_FIRST_TIME_TUTORIAL",true);
|
923 |
}
|
@@ -990,34 +1004,23 @@ function wplc_metric_dashboard_redirect(){
|
|
990 |
}
|
991 |
|
992 |
function wplc_admin_menu() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
993 |
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
}
|
1004 |
-
|
1005 |
-
|
1006 |
-
/* only if user is both an agent and an admin that has the cap assigned, can they access these pages */
|
1007 |
-
if( get_user_meta( $wplc_current_user, 'wplc_ma_agent', true ) && current_user_can("wplc_ma_agent")){
|
1008 |
-
|
1009 |
-
add_submenu_page('wplivechat-menu', __('History', 'wp-live-chat-support'), __('History', 'wp-live-chat-support'), $cap[2], 'wplivechat-menu-history', 'wplc_admin_history_layout');
|
1010 |
-
add_submenu_page('wplivechat-menu', __('Missed Chats', 'wp-live-chat-support'), __('Missed Chats', 'wp-live-chat-support'), $cap[3], 'wplivechat-menu-missed-chats', 'wplc_admin_missed_chats');
|
1011 |
-
|
1012 |
-
|
1013 |
-
add_submenu_page('wplivechat-menu', __('Offline Messages', 'wp-live-chat-support'), __('Offline Messages', 'wp-live-chat-support'), $cap[4], 'wplivechat-menu-offline-messages', 'wplc_admin_offline_messages');
|
1014 |
-
|
1015 |
-
do_action("wplc_hook_menu_mid",$cap);
|
1016 |
-
|
1017 |
-
|
1018 |
-
add_submenu_page('wplivechat-menu', __('Support', 'wp-live-chat-support'), __('Support', 'wp-live-chat-support'), 'manage_options', 'wplivechat-menu-support-page', 'wplc_support_menu');
|
1019 |
-
}
|
1020 |
-
do_action("wplc_hook_menu");
|
1021 |
}
|
1022 |
|
1023 |
|
@@ -1108,7 +1111,7 @@ function wplc_push_js_to_front() {
|
|
1108 |
|
1109 |
if ($wplc_settings['wplc_use_node_server']) {
|
1110 |
wp_localize_script('wplc-server-script', 'tcx_api_key', wplc_node_server_token_get());
|
1111 |
-
wp_register_script('wplc-node-server-script', WPLC_PLUGIN_URL."
|
1112 |
wp_enqueue_script('wplc-node-server-script');
|
1113 |
wp_register_script('wplc-user-events-script', plugins_url('/js/wplc_u_node_events.js', __FILE__),array('jquery', 'wplc-server-script'),WPLC_PLUGIN_VERSION);
|
1114 |
/* Not used in front-end
|
@@ -1120,9 +1123,9 @@ function wplc_push_js_to_front() {
|
|
1120 |
|
1121 |
//Emoji Libs
|
1122 |
if (!$wplc_settings['wplc_disable_emojis']) {
|
1123 |
-
wp_register_script('wplc-user-js-emoji-concat', WPLC_PLUGIN_URL."
|
1124 |
wp_enqueue_script('wplc-user-js-emoji-concat');
|
1125 |
-
wp_register_style( 'wplc-admin-style-emoji', WPLC_PLUGIN_URL."
|
1126 |
wp_enqueue_style( 'wplc-admin-style-emoji' );
|
1127 |
}
|
1128 |
wp_register_script('wplc-user-node-node-primary', plugins_url('/js/wplc_node.js', __FILE__),array('jquery', 'wplc-server-script', 'wplc-user-script'), WPLC_PLUGIN_VERSION);
|
@@ -1201,18 +1204,13 @@ function wplc_push_js_to_front() {
|
|
1201 |
/**
|
1202 |
* Create a JS object for all Agent ID's and Gravatar MD5's
|
1203 |
*/
|
1204 |
-
$user_array =
|
1205 |
-
'meta_key' => 'wplc_ma_agent',
|
1206 |
-
));
|
1207 |
-
|
1208 |
$a_array = array();
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
$a_array[$user->ID]['tagline'] = get_user_meta($user->ID, 'wplc_user_tagline', true);
|
1215 |
-
}
|
1216 |
}
|
1217 |
wp_localize_script('wplc-user-script', 'wplc_agent_data', $a_array);
|
1218 |
|
@@ -1520,7 +1518,12 @@ function wplc_filter_control_live_chat_box_html_main_div_top($wplc_settings,$log
|
|
1520 |
|
1521 |
default:
|
1522 |
$wplc_theme_type = "modern";
|
1523 |
-
$hovercard_content = "
|
|
|
|
|
|
|
|
|
|
|
1524 |
$hovercard_content = apply_filters("wplc_filter_hovercard_content", $hovercard_content);
|
1525 |
$ret_msg .= "<div id='wplc_hovercard' style='display:none' class='".$wplc_theme_type."'>";
|
1526 |
$ret_msg .= "<div id='wplc_hovercard_content'>".apply_filters("wplc_filter_live_chat_box_pre_layer1","").$hovercard_content."</div>";
|
@@ -1546,8 +1549,6 @@ function wplc_filter_control_live_chat_box_html_main_div_top($wplc_settings,$log
|
|
1546 |
|
1547 |
add_filter("wplc_filter_modern_theme_hovercard_content_left","wplc_filter_control_modern_theme_hovercard_content_left",10,1);
|
1548 |
function wplc_filter_control_modern_theme_hovercard_content_left($msg) {
|
1549 |
-
|
1550 |
-
$msg .= "<div class='wplc_left_logo' style='background:url(".plugins_url('images/iconmicro.png', __FILE__).") no-repeat; background-size: cover;'></div>";
|
1551 |
$msg = apply_filters("wplc_filter_microicon",$msg);
|
1552 |
return $msg;
|
1553 |
}
|
@@ -1792,11 +1793,7 @@ function wplc_filter_control_live_chat_box_html_2nd_layer($wplc_settings,$logged
|
|
1792 |
}
|
1793 |
|
1794 |
/* admin not logged in, show offline messages */
|
1795 |
-
$wplc_offline = $wplc_default_settings_array['wplc_pro_offline1'];
|
1796 |
-
$text = ($wplc_using_locale ? $wplc_offline : stripslashes($wplc_settings['wplc_pro_offline1']));
|
1797 |
-
|
1798 |
$ret_msg = "<div id=\"wp-live-chat-2-info\" class=\"wplc-color-bg-1 wplc-color-2\">";
|
1799 |
-
$ret_msg .= $text;
|
1800 |
$ret_msg .= "</div>";
|
1801 |
$ret_msg .= "<div id=\"wplc_message_div\">";
|
1802 |
$ret_msg .= "<input type=\"text\" name=\"wplc_name\" id=\"wplc_name\" value=\"$wplc_loggedin_user_name\" placeholder=\"".__("Name", 'wp-live-chat-support')."\" />";
|
@@ -1949,27 +1946,23 @@ function wplc_filter_control_live_chat_box_html_4th_layer($wplc_settings, $wplc_
|
|
1949 |
* @return string
|
1950 |
* @since 6.0.00
|
1951 |
*/
|
1952 |
-
function wplc_filter_control_live_chat_box_html_1st_layer($wplc_settings
|
1953 |
global $wplc_default_settings_array;
|
1954 |
$ret_msg = "<div id='wplc_first_message'>";
|
1955 |
if ($logged_in) {
|
1956 |
-
$wplc_fst_1 = __('Questions?', 'wp-live-chat-support');
|
1957 |
-
$wplc_fst_2 = __('Chat with us', 'wp-live-chat-support');
|
1958 |
if ($wplc_settings['wplc_newtheme'] == "theme-2") {
|
1959 |
$coltheme = "wplc-color-4";
|
1960 |
} else {
|
1961 |
$coltheme = "wplc-color-2";
|
1962 |
}
|
1963 |
-
|
1964 |
-
if ($class_override){
|
1965 |
//Override color class
|
1966 |
$coltheme = $class_override;
|
1967 |
}
|
1968 |
-
$wplc_tl_msg = "<div class='$coltheme'><strong>" . ($wplc_using_locale ? $
|
1969 |
$ret_msg .= $wplc_tl_msg;
|
1970 |
} else {
|
1971 |
-
$
|
1972 |
-
$wplc_tl_msg = "<span class='wplc_offline'>" . ($wplc_using_locale ? $wplc_na : stripslashes($wplc_settings['wplc_pro_na'])) . "</span>";
|
1973 |
$ret_msg .= $wplc_tl_msg;
|
1974 |
}
|
1975 |
$ret_msg .= "</div>";
|
@@ -1979,7 +1972,6 @@ function wplc_filter_control_live_chat_box_html_1st_layer($wplc_settings,$logged
|
|
1979 |
add_filter("wplc_loggedin_filter","wplc_filter_control_loggedin",10,1);
|
1980 |
function wplc_filter_control_loggedin($logged_in) {
|
1981 |
$wplc_is_admin_logged_in = get_transient("wplc_is_admin_logged_in");
|
1982 |
-
|
1983 |
if ($wplc_is_admin_logged_in != 1) {
|
1984 |
$logged_in = false;
|
1985 |
} else {
|
@@ -1996,7 +1988,6 @@ function wplc_filter_control_loggedin($logged_in) {
|
|
1996 |
if (isset($logged_in_checks['app']) && $logged_in_checks['app'] == true) { $logged_in_via_app = true; }
|
1997 |
|
1998 |
$logged_in = apply_filters("wplc_final_loggedin_control",$logged_in,$logged_in_via_app);
|
1999 |
-
|
2000 |
/* admin is using the basic version and is logged in */
|
2001 |
if ($wplc_is_admin_logged_in) { $logged_in = true; }
|
2002 |
|
@@ -2261,8 +2252,7 @@ function wplc_admin_javascript() {
|
|
2261 |
*/
|
2262 |
function wplc_admin_output_js() {
|
2263 |
$ajax_nonce = wp_create_nonce("wplc");
|
2264 |
-
|
2265 |
-
if (get_user_meta($wplc_current_user, 'wplc_ma_agent', true)) {
|
2266 |
$wplc_settings = wplc_get_options();
|
2267 |
wp_register_script('wplc-admin-js', plugins_url('js/wplc_u_admin.js', __FILE__), false, WPLC_PLUGIN_VERSION, false);
|
2268 |
wp_enqueue_script('wplc-admin-js');
|
@@ -2272,7 +2262,7 @@ function wplc_admin_output_js() {
|
|
2272 |
wp_localize_script('wplc-admin-js', 'wplc_wav_file', $wplc_wav_file);
|
2273 |
wp_localize_script('wplc-admin-js', 'wplc_ajax_nonce', $ajax_nonce);
|
2274 |
wp_localize_script('wplc-admin-js', 'wplc_notification_icon', $not_icon);
|
2275 |
-
wp_localize_script('wplc-admin-js', 'tcx_favico_noti', WPLC_PLUGIN_URL . 'images/
|
2276 |
wp_localize_script('wplc-admin-js', 'tcx_favico', WPLC_PLUGIN_URL . 'images/tcx48px.png');
|
2277 |
$extra_data = apply_filters("wplc_filter_admin_javascript",array());
|
2278 |
wp_localize_script('wplc-admin-js', 'wplc_extra_data', $extra_data);
|
@@ -2341,106 +2331,77 @@ function wplc_filter_control_chat_dashboard_visitors_online_bottom($text) {
|
|
2341 |
}
|
2342 |
|
2343 |
function wplc_admin_menu_layout_display() {
|
2344 |
-
|
2345 |
-
|
2346 |
-
|
2347 |
-
if
|
2348 |
-
|
2349 |
-
|
2350 |
-
|
2351 |
-
|
2352 |
-
|
2353 |
-
|
2354 |
-
|
2355 |
-
|
2356 |
-
|
2357 |
-
|
2358 |
-
|
2359 |
-
|
2360 |
-
|
2361 |
-
|
2362 |
-
|
2363 |
-
|
2364 |
-
|
2365 |
-
|
2366 |
-
|
2367 |
-
|
2368 |
-
|
2369 |
-
|
2370 |
-
|
2371 |
-
|
2372 |
-
|
2373 |
-
|
2374 |
-
|
2375 |
-
|
2376 |
-
|
2377 |
-
|
2378 |
-
|
2379 |
-
|
2380 |
-
|
2381 |
-
|
2382 |
-
|
2383 |
-
|
2384 |
-
|
2385 |
-
|
2386 |
-
|
2387 |
-
|
2388 |
-
|
2389 |
-
|
2390 |
-
|
2391 |
-
|
2392 |
-
|
2393 |
-
<div id="wplc_admin_chat_area_new">
|
2394 |
-
<div style="display:block;">
|
2395 |
-
<div class='wplc_chat_on_premise_header'>
|
2396 |
-
<div class='wplc_header_vh wplc_header_v'><?php _e("Visitor",'wp-live-chat-support'); ?></div>
|
2397 |
-
<div class='wplc_header_vh wplc_header_t'><?php _e("Time",'wp-live-chat-support'); ?></div>
|
2398 |
-
<div class='wplc_header_vh wplc_header_nr'><?php _e("Type",'wp-live-chat-support'); ?></div>
|
2399 |
-
<div class='wplc_header_vh wplc_header_dev'><?php _e("Device",'wp-live-chat-support'); ?></div>
|
2400 |
-
<div class='wplc_header_vh wplc_header_d'><?php _e("Data",'wp-live-chat-support'); ?></div>
|
2401 |
-
<div class='wplc_header_vh wplc_header_s'><?php _e("Status",'wp-live-chat-support'); ?></div>
|
2402 |
-
<div class='wplc_header_vh wplc_header_a'><?php _e("Action",'wp-live-chat-support'); ?></div>
|
2403 |
-
</div>
|
2404 |
-
<div id='wplc_chat_ul'></div>
|
2405 |
-
|
2406 |
-
<?php //do_action("wplc_hook_chat_dashboard_bottom"); ?>
|
2407 |
-
|
2408 |
-
</div>
|
2409 |
-
|
2410 |
-
</div>
|
2411 |
-
</div>
|
2412 |
-
|
2413 |
-
|
2414 |
-
|
2415 |
-
|
2416 |
-
|
2417 |
-
<?php
|
2418 |
-
} else {
|
2419 |
-
if (isset($_GET['aid'])) { $aid = intval($_GET['aid']); } else { $aid = null; }
|
2420 |
-
|
2421 |
-
if (!is_null($aid)) {
|
2422 |
-
do_action("wplc_hook_update_agent_id", intval($_GET['cid']), $aid);
|
2423 |
-
}
|
2424 |
-
|
2425 |
-
if ($_GET['action'] == 'ac') {
|
2426 |
-
do_action('wplc_hook_accept_chat',$_GET, $aid);
|
2427 |
-
}
|
2428 |
-
do_action("wplc_hook_admin_menu_layout_display", $_GET['action'], intval($_GET['cid']), $aid);
|
2429 |
-
}
|
2430 |
} else {
|
2431 |
-
|
2432 |
-
|
2433 |
-
|
2434 |
-
|
2435 |
-
|
2436 |
-
|
2437 |
-
|
2438 |
-
|
2439 |
-
</p>
|
2440 |
-
</div>
|
2441 |
-
</div>
|
2442 |
-
<?php
|
2443 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2444 |
}
|
2445 |
|
2446 |
add_action("wplc_hook_change_status_on_answer","wplc_hook_control_change_status_on_answer",10,2);
|
@@ -2714,17 +2675,12 @@ function wplc_return_admin_chat_javascript($cid) {
|
|
2714 |
/**
|
2715 |
* Create a JS object for all Agent ID's and Gravatar MD5's
|
2716 |
*/
|
2717 |
-
$user_array =
|
2718 |
-
'meta_key' => 'wplc_ma_agent'
|
2719 |
-
));
|
2720 |
-
|
2721 |
$a_array = array();
|
2722 |
-
|
2723 |
-
|
2724 |
-
|
2725 |
-
|
2726 |
-
$a_array[$user->ID]['md5'] = md5( $user->user_email );
|
2727 |
-
}
|
2728 |
}
|
2729 |
wp_localize_script('wplc-admin-chat-server', 'wplc_agent_data', $a_array);
|
2730 |
|
@@ -2864,9 +2820,9 @@ function wplc_activate() {
|
|
2864 |
$wplc_settings = wplc_cleanup_old_options($wplc_settings);
|
2865 |
update_option('WPLC_SETTINGS', $wplc_settings);
|
2866 |
$uid = get_current_user_id();
|
2867 |
-
|
2868 |
update_user_meta($uid, 'wplc_ma_agent', 1);
|
2869 |
-
|
2870 |
|
2871 |
$admins = get_role('administrator');
|
2872 |
if( $admins !== null ) { $admins->add_cap('wplc_ma_agent'); }
|
@@ -2883,7 +2839,7 @@ function wplc_activate() {
|
|
2883 |
if (!function_exists("wplc_choose_activate")) {
|
2884 |
register_activation_hook(__FILE__, 'wplc_choose_activate');
|
2885 |
function wplc_choose_activate( $networkwide ) {
|
2886 |
-
|
2887 |
wplc_mrg_update_db( $networkwide ); //Run update db
|
2888 |
}
|
2889 |
}
|
@@ -2896,7 +2852,7 @@ if (!function_exists("wplc_choose_activate")) {
|
|
2896 |
if (!function_exists("wplc_choose_deactivate")) {
|
2897 |
register_deactivation_hook(__FILE__, 'wplc_choose_deactivate');
|
2898 |
function wplc_choose_deactivate() {
|
2899 |
-
|
2900 |
}
|
2901 |
}
|
2902 |
|
@@ -3007,6 +2963,7 @@ function wplc_add_user_stylesheet() {
|
|
3007 |
$close_icon = plugins_url('images/iconCloseRetina.png', __FILE__);
|
3008 |
|
3009 |
$bg='';
|
|
|
3010 |
if (!empty($wplc_settings['wplc_settings_bg'])) {
|
3011 |
$bg = sanitize_text_field($wplc_settings['wplc_settings_bg']);
|
3012 |
}
|
@@ -3016,6 +2973,9 @@ function wplc_add_user_stylesheet() {
|
|
3016 |
} else {
|
3017 |
$bg_string = "#wp-live-chat-4 { background-color: #fff; }";
|
3018 |
}
|
|
|
|
|
|
|
3019 |
|
3020 |
if (isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] ){ $icon = preg_replace('/^http:\/\//', 'https:\/\/', $icon); }
|
3021 |
if (isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] ){ $close_icon = preg_replace('/^http:\/\//', 'https:\/\/', $close_icon); }
|
@@ -3096,15 +3056,14 @@ add_action( 'init', 'wplc_online_check_script', 10 );
|
|
3096 |
* @return void
|
3097 |
*/
|
3098 |
function wplc_online_check_script() {
|
3099 |
-
|
3100 |
-
|
3101 |
-
|
3102 |
-
|
3103 |
-
|
3104 |
-
|
3105 |
-
|
3106 |
-
|
3107 |
-
}
|
3108 |
}
|
3109 |
|
3110 |
/**
|
@@ -3114,13 +3073,13 @@ function wplc_online_check_script() {
|
|
3114 |
add_filter( 'heartbeat_received', 'wplc_heartbeat_receive', 10, 2 );
|
3115 |
add_filter( 'heartbeat_nopriv_received', 'wplc_heartbeat_receive', 10, 2 );
|
3116 |
function wplc_heartbeat_receive( $response, $data ) {
|
3117 |
-
|
3118 |
-
|
3119 |
-
|
3120 |
-
|
3121 |
-
|
3122 |
-
|
3123 |
-
|
3124 |
}
|
3125 |
|
3126 |
/**
|
@@ -3606,7 +3565,7 @@ function wplc_filter_control_chat_header_extra_attr($wplc_extra_attr) {
|
|
3606 |
$do_popup=false;
|
3607 |
if ($wplc_settings['wplc_auto_pop_up']>0) {
|
3608 |
if ($wplc_settings['wplc_auto_pop_up_online']) {
|
3609 |
-
$do_popup=
|
3610 |
} else {
|
3611 |
$do_popup=true;
|
3612 |
}
|
@@ -3721,6 +3680,13 @@ function wplc_head() {
|
|
3721 |
$wplc_data['wplc_redirect_to_thank_you_page'] = stripslashes(sanitize_text_field(wplc_force_string($_POST, 'wplc_redirect_to_thank_you_page', $wplc_settings)));
|
3722 |
$wplc_data['wplc_redirect_thank_you_url'] = esc_url(wplc_force_url($_POST, 'wplc_redirect_thank_you_url', $wplc_settings));
|
3723 |
$wplc_data['wplc_disable_emojis'] = wplc_force_bool($_POST, 'wplc_disable_emojis');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3724 |
$wplc_data['wplc_record_ip_address'] = "0";
|
3725 |
$wplc_data['wplc_enable_msg_sound'] = wplc_force_bool($_POST, 'wplc_enable_msg_sound');
|
3726 |
$wplc_data['wplc_enable_visitor_sound'] = wplc_force_bool($_POST, 'wplc_enable_visitor_sound');
|
@@ -3807,13 +3773,26 @@ function wplc_head() {
|
|
3807 |
$wplc_upload_icon = wplc_force_string($_POST, 'wplc_upload_icon', '');
|
3808 |
|
3809 |
if (!empty($wplc_upload_pic)) {
|
3810 |
-
|
|
|
|
|
|
|
|
|
3811 |
}
|
3812 |
if (!empty($wplc_upload_logo)) {
|
3813 |
-
|
|
|
|
|
|
|
|
|
3814 |
}
|
3815 |
if (!empty($wplc_upload_icon)) {
|
3816 |
-
|
|
|
|
|
|
|
|
|
|
|
3817 |
}
|
3818 |
|
3819 |
$wplc_data['wplc_chat_delay'] = wplc_force_int($_POST, 'wplc_chat_delay');
|
@@ -3858,24 +3837,20 @@ function wplc_head() {
|
|
3858 |
if ($wplc_data['wplc_delay_between_loops'] > 1000000) { $wplc_data['wplc_delay_between_loops'] = 1000000; }
|
3859 |
|
3860 |
if (isset($_POST['wplc_agent_select']) && $_POST['wplc_agent_select'] != "") {
|
3861 |
-
$user_array =
|
3862 |
-
|
3863 |
-
|
3864 |
-
|
3865 |
-
|
3866 |
-
|
3867 |
-
|
3868 |
-
$wplc_ma_user->remove_cap( 'wplc_ma_agent' );
|
3869 |
-
delete_user_meta($uid, "wplc_ma_agent");
|
3870 |
-
delete_user_meta($uid, "wplc_chat_agent_online");
|
3871 |
-
}
|
3872 |
}
|
3873 |
|
3874 |
$uid = intval($_POST['wplc_agent_select']);
|
3875 |
$wplc_ma_user = new WP_User( $uid );
|
3876 |
$wplc_ma_user->add_cap( 'wplc_ma_agent' );
|
3877 |
update_user_meta($uid, "wplc_ma_agent", 1);
|
3878 |
-
|
3879 |
}
|
3880 |
|
3881 |
if (isset($_POST['wplc_ban_users_ip'])) {
|
@@ -3917,8 +3892,6 @@ function wplc_logout() {
|
|
3917 |
delete_transient('wplc_is_admin_logged_in');
|
3918 |
}
|
3919 |
|
3920 |
-
|
3921 |
-
|
3922 |
/**
|
3923 |
* Error checks used to ensure the user's resources meet the plugin's requirements
|
3924 |
*/
|
@@ -4202,8 +4175,8 @@ add_action('admin_init', 'wplc_admin_download_chat_history');
|
|
4202 |
* @return file
|
4203 |
*/
|
4204 |
function wplc_admin_download_chat_history(){
|
4205 |
-
if(!is_user_logged_in() || !
|
4206 |
-
|
4207 |
}
|
4208 |
|
4209 |
if (isset($_GET['action']) && $_GET['action'] == "download_history") {
|
@@ -4280,8 +4253,8 @@ function wplc_admin_download_chat_history(){
|
|
4280 |
* @return void
|
4281 |
*/
|
4282 |
function wplc_admin_download_history($type, $cid){
|
4283 |
-
|
4284 |
-
|
4285 |
}
|
4286 |
|
4287 |
global $wpdb;
|
@@ -4511,10 +4484,10 @@ function wplc_custom_scripts_scripts(){
|
|
4511 |
|
4512 |
if ( isset( $_GET['page'] ) ) {
|
4513 |
if ( $_GET['page'] == 'wplivechat-menu-settings' ) {
|
4514 |
-
wp_enqueue_script( "wplc-custom-script-tab-ace", WPLC_PLUGIN_URL.'
|
4515 |
} else if ( $_GET['page'] === 'wplivechat-menu-dashboard' || $_GET['page'] === 'wplivechat-menu' ) {
|
4516 |
wplc_register_common_node();
|
4517 |
-
wp_enqueue_script( 'wplc-custom-script-dashboard', WPLC_PLUGIN_URL.'
|
4518 |
wp_localize_script('wplc-custom-script-dashboard', 'nifty_api_key', wplc_node_server_token_get());
|
4519 |
}
|
4520 |
|
3 |
Plugin Name: WP-Live Chat by 3CX
|
4 |
Plugin URI: https://www.3cx.com/wp-live-chat/
|
5 |
Description: The easiest to use website live chat plugin. Let your visitors chat with you and increase sales conversion rates with WP-Live Chat by 3CX.
|
6 |
+
Version: 8.1.3
|
7 |
Author: 3CX
|
8 |
Author URI: https://www.3cx.com/wp-live-chat/
|
9 |
Domain Path: /languages
|
12 |
*/
|
13 |
|
14 |
/*
|
15 |
+
= 8.1.3 - 2019-10-31
|
16 |
+
* Bugfix: Admin detected as an agent - doesn't show offline messages form
|
17 |
+
* Bugfix: Remove picture from chat box doesn't work properly
|
18 |
+
* Bugfix: Edge JS compatibility issue in dashboard has been fixed
|
19 |
+
* Bugfix: The page will no longer refresh upon ending a chat with an agent.
|
20 |
+
* New feature: Agent online/offline switch in Wordpress admin bar
|
21 |
+
* New feature: Adjustable chatbox height 30% - 80% of page size
|
22 |
+
* Improvement: Cleaned up async_storage functions
|
23 |
+
* Improvement: Better alignment for chat popup with no picture
|
24 |
+
* Improvement: Reworked agent online/offline functions
|
25 |
+
* Improvement: Default business hours are now 9:00 - 18:00 instead of 00:00 - 00:00
|
26 |
+
* Improvement: The 'Use Logged In User Details' feature has been moved to the 'Chat Box' settings page.
|
27 |
+
|
28 |
= 8.1.2 - 2019-10-24
|
29 |
* New feature: improved auto pop-up feature, now 3 options to choose from
|
30 |
* New feature: Pop-up only when agents are online
|
390 |
'wplc_avatar_source' => '',
|
391 |
'wplc_bh_enable' => false,
|
392 |
'wplc_bh_interval' => 0,
|
393 |
+
'wplc_bh_hours_start' => 9,
|
394 |
'wplc_bh_minutes_start' => 0,
|
395 |
+
'wplc_bh_hours_end' => 18,
|
396 |
'wplc_bh_minutes_end' => 0,
|
397 |
'wplc_chat_delay' => 2,
|
398 |
'wplc_chat_icon' => plugins_url( '/', __FILE__ ).'images/chaticon.png',
|
399 |
'wplc_chat_logo' => '',
|
400 |
'wplc_chat_name' => __( 'Admin', 'wp-live-chat-support'),
|
401 |
'wplc_chat_pic' => plugins_url( '/', __FILE__ ).'images/picture-for-chat-box.jpg',
|
402 |
+
'wplc_chatbox_height' => 70,
|
403 |
'wplc_close_btn_text' => __("close", 'wp-live-chat-support'),
|
404 |
'wplc_default_department' => -1,
|
405 |
'wplc_delay_between_loops' => 500,
|
625 |
add_action('activated_plugin', 'wplc_redirect_on_activate');
|
626 |
add_action('wp_ajax_wplc_choose_accepting','wplc_action_callback');
|
627 |
add_action('wp_ajax_wplc_choose_not_accepting','wplc_action_callback');
|
628 |
+
add_action('wp_ajax_wplc_agent_list','wplc_action_callback');
|
629 |
add_action('wplc_hook_action_callback','wplc_choose_hook_control_action_callback');
|
630 |
add_action('wplc_hook_admin_menu_layout_display_top','wplc_ma_hook_control_admin_meny_layout_display_top');
|
631 |
add_action('edit_user_profile_update', 'wplc_maa_set_user_as_agent');
|
701 |
$admins->remove_cap('wplc_ma_agent');
|
702 |
}
|
703 |
|
704 |
+
$users = wplc_get_agent_users();
|
705 |
+
foreach($users as $user) {
|
706 |
+
delete_user_meta( $user->ID, 'wplc_user_department' );
|
707 |
+
delete_user_meta( $user->ID, 'wplc_ma_agent' );
|
708 |
+
delete_user_meta( $user->ID, 'wplc_user_bio' );
|
709 |
+
delete_user_meta( $user->ID, 'wplc_user_facebook' );
|
710 |
+
delete_user_meta( $user->ID, 'wplc_user_linkedin' );
|
711 |
+
delete_user_meta( $user->ID, 'wplc_user_tagline' );
|
712 |
+
delete_user_meta( $user->ID, 'wplc_user_twitter' );
|
713 |
+
}
|
|
|
|
|
|
|
714 |
}
|
715 |
}
|
716 |
|
801 |
|
802 |
$uid = get_current_user_id();
|
803 |
update_user_meta($uid, 'wplc_ma_agent', 1);
|
804 |
+
wplc_update_agent_time($uid);
|
805 |
|
806 |
/* add caps to admin */
|
807 |
if (current_user_can('manage_options')) {
|
928 |
));
|
929 |
} else if ($_POST['action'] == "wplc_admin_set_transient") {
|
930 |
do_action("wplc_hook_set_transient");
|
931 |
+
echo wplc_return_online_agents_array();
|
932 |
} else if ($_POST['action'] == "wplc_admin_remove_transient") {
|
933 |
do_action("wplc_hook_remove_transient");
|
934 |
+
echo wplc_return_online_agents_array();
|
935 |
} else if ($_POST['action'] == 'wplc_hide_ftt') {
|
936 |
update_option("WPLC_FIRST_TIME_TUTORIAL",true);
|
937 |
}
|
1004 |
}
|
1005 |
|
1006 |
function wplc_admin_menu() {
|
1007 |
+
$cap = apply_filters("wplc_ma_filter_menu_control",array());
|
1008 |
+
/* If user is either an agent or an admin, access the page. */
|
1009 |
+
if(wplc_user_is_agent() || current_user_can("wplc_ma_agent")) {
|
1010 |
+
add_menu_page('WP Live Chat', __('Live Chat', 'wp-live-chat-support'), $cap[0], 'wplivechat-menu', 'wplc_admin_menu_layout', 'dashicons-format-chat');
|
1011 |
+
add_submenu_page('wplivechat-menu', __('Dashboard', 'wp-live-chat-support'), __('Dashboard', 'wp-live-chat-support'), $cap[1], 'wplivechat-menu-dashboard', 'wplc_admin_dashboard_layout');
|
1012 |
+
add_submenu_page('wplivechat-menu', __('Settings', 'wp-live-chat-support'), __('Settings', 'wp-live-chat-support'), $cap[1], 'wplivechat-menu-settings', 'wplc_admin_settings_layout');
|
1013 |
+
}
|
1014 |
|
1015 |
+
/* only if user is both an agent and an admin that has the cap assigned, can they access these pages */
|
1016 |
+
if(wplc_user_is_agent() && current_user_can("wplc_ma_agent")) {
|
1017 |
+
add_submenu_page('wplivechat-menu', __('History', 'wp-live-chat-support'), __('History', 'wp-live-chat-support'), $cap[2], 'wplivechat-menu-history', 'wplc_admin_history_layout');
|
1018 |
+
add_submenu_page('wplivechat-menu', __('Missed Chats', 'wp-live-chat-support'), __('Missed Chats', 'wp-live-chat-support'), $cap[3], 'wplivechat-menu-missed-chats', 'wplc_admin_missed_chats');
|
1019 |
+
add_submenu_page('wplivechat-menu', __('Offline Messages', 'wp-live-chat-support'), __('Offline Messages', 'wp-live-chat-support'), $cap[4], 'wplivechat-menu-offline-messages', 'wplc_admin_offline_messages');
|
1020 |
+
do_action("wplc_hook_menu_mid",$cap);
|
1021 |
+
add_submenu_page('wplivechat-menu', __('Support', 'wp-live-chat-support'), __('Support', 'wp-live-chat-support'), 'manage_options', 'wplivechat-menu-support-page', 'wplc_support_menu');
|
1022 |
+
}
|
1023 |
+
do_action("wplc_hook_menu");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1024 |
}
|
1025 |
|
1026 |
|
1111 |
|
1112 |
if ($wplc_settings['wplc_use_node_server']) {
|
1113 |
wp_localize_script('wplc-server-script', 'tcx_api_key', wplc_node_server_token_get());
|
1114 |
+
wp_register_script('wplc-node-server-script', WPLC_PLUGIN_URL."js/vendor/sockets.io/socket.io.slim.js", array('jquery'), WPLC_PLUGIN_VERSION);
|
1115 |
wp_enqueue_script('wplc-node-server-script');
|
1116 |
wp_register_script('wplc-user-events-script', plugins_url('/js/wplc_u_node_events.js', __FILE__),array('jquery', 'wplc-server-script'),WPLC_PLUGIN_VERSION);
|
1117 |
/* Not used in front-end
|
1123 |
|
1124 |
//Emoji Libs
|
1125 |
if (!$wplc_settings['wplc_disable_emojis']) {
|
1126 |
+
wp_register_script('wplc-user-js-emoji-concat', WPLC_PLUGIN_URL."js/vendor/wdt-emoji/wdt-emoji-concat.min.js", array("wplc-server-script", "wplc-server-script"), WPLC_PLUGIN_VERSION, false);
|
1127 |
wp_enqueue_script('wplc-user-js-emoji-concat');
|
1128 |
+
wp_register_style( 'wplc-admin-style-emoji', WPLC_PLUGIN_URL."js/vendor/wdt-emoji/wdt-emoji-bundle.css", false, WPLC_PLUGIN_VERSION );
|
1129 |
wp_enqueue_style( 'wplc-admin-style-emoji' );
|
1130 |
}
|
1131 |
wp_register_script('wplc-user-node-node-primary', plugins_url('/js/wplc_node.js', __FILE__),array('jquery', 'wplc-server-script', 'wplc-user-script'), WPLC_PLUGIN_VERSION);
|
1204 |
/**
|
1205 |
* Create a JS object for all Agent ID's and Gravatar MD5's
|
1206 |
*/
|
1207 |
+
$user_array = wplc_get_agent_users();
|
|
|
|
|
|
|
1208 |
$a_array = array();
|
1209 |
+
foreach ($user_array as $user) {
|
1210 |
+
$a_array[$user->ID] = array();
|
1211 |
+
$a_array[$user->ID]['name'] = apply_filters( "wplc_decide_agents_name", sanitize_text_field($user->display_name), $wplc_settings );
|
1212 |
+
$a_array[$user->ID]['md5'] = md5( $user->user_email );
|
1213 |
+
$a_array[$user->ID]['tagline'] = get_user_meta($user->ID, 'wplc_user_tagline', true);
|
|
|
|
|
1214 |
}
|
1215 |
wp_localize_script('wplc-user-script', 'wplc_agent_data', $a_array);
|
1216 |
|
1518 |
|
1519 |
default:
|
1520 |
$wplc_theme_type = "modern";
|
1521 |
+
$hovercard_content = "";
|
1522 |
+
$msg_left = apply_filters("wplc_filter_modern_theme_hovercard_content_left","");
|
1523 |
+
if (!empty($msg_left)) {
|
1524 |
+
$hovercard_content.= "<div class='wplc_hovercard_content_left'>".$msg_left."</div>";
|
1525 |
+
}
|
1526 |
+
$hovercard_content.= "<div class='wplc_hovercard_content_right'>".apply_filters("wplc_filter_live_chat_box_html_1st_layer",wplc_filter_control_live_chat_box_html_1st_layer($wplc_settings,$logged_in,$wplc_using_locale,'wplc-color-4'))."</div>";
|
1527 |
$hovercard_content = apply_filters("wplc_filter_hovercard_content", $hovercard_content);
|
1528 |
$ret_msg .= "<div id='wplc_hovercard' style='display:none' class='".$wplc_theme_type."'>";
|
1529 |
$ret_msg .= "<div id='wplc_hovercard_content'>".apply_filters("wplc_filter_live_chat_box_pre_layer1","").$hovercard_content."</div>";
|
1549 |
|
1550 |
add_filter("wplc_filter_modern_theme_hovercard_content_left","wplc_filter_control_modern_theme_hovercard_content_left",10,1);
|
1551 |
function wplc_filter_control_modern_theme_hovercard_content_left($msg) {
|
|
|
|
|
1552 |
$msg = apply_filters("wplc_filter_microicon",$msg);
|
1553 |
return $msg;
|
1554 |
}
|
1793 |
}
|
1794 |
|
1795 |
/* admin not logged in, show offline messages */
|
|
|
|
|
|
|
1796 |
$ret_msg = "<div id=\"wp-live-chat-2-info\" class=\"wplc-color-bg-1 wplc-color-2\">";
|
|
|
1797 |
$ret_msg .= "</div>";
|
1798 |
$ret_msg .= "<div id=\"wplc_message_div\">";
|
1799 |
$ret_msg .= "<input type=\"text\" name=\"wplc_name\" id=\"wplc_name\" value=\"$wplc_loggedin_user_name\" placeholder=\"".__("Name", 'wp-live-chat-support')."\" />";
|
1946 |
* @return string
|
1947 |
* @since 6.0.00
|
1948 |
*/
|
1949 |
+
function wplc_filter_control_live_chat_box_html_1st_layer($wplc_settings, $logged_in, $wplc_using_locale, $class_override = false) {
|
1950 |
global $wplc_default_settings_array;
|
1951 |
$ret_msg = "<div id='wplc_first_message'>";
|
1952 |
if ($logged_in) {
|
|
|
|
|
1953 |
if ($wplc_settings['wplc_newtheme'] == "theme-2") {
|
1954 |
$coltheme = "wplc-color-4";
|
1955 |
} else {
|
1956 |
$coltheme = "wplc-color-2";
|
1957 |
}
|
1958 |
+
if ($class_override) {
|
|
|
1959 |
//Override color class
|
1960 |
$coltheme = $class_override;
|
1961 |
}
|
1962 |
+
$wplc_tl_msg = "<div class='$coltheme'><strong>" . ($wplc_using_locale ? $wplc_default_settings_array['wplc_pro_fst1']: stripslashes($wplc_settings['wplc_pro_fst1'])) . "</strong> " . ( $wplc_using_locale ? $wplc_default_settings_array['wplc_pro_fst2'] : stripslashes($wplc_settings['wplc_pro_fst2'])) ."</div>";
|
1963 |
$ret_msg .= $wplc_tl_msg;
|
1964 |
} else {
|
1965 |
+
$wplc_tl_msg = "<div class='wplc_offline'><strong>" . ($wplc_using_locale ? $wplc_default_settings_array['wplc_pro_na'] : stripslashes($wplc_settings['wplc_pro_na'])) . "</strong> " . ( $wplc_using_locale ? $wplc_default_settings_array['wplc_pro_offline1'] : stripslashes($wplc_settings['wplc_pro_offline1'])) ."</div>";
|
|
|
1966 |
$ret_msg .= $wplc_tl_msg;
|
1967 |
}
|
1968 |
$ret_msg .= "</div>";
|
1972 |
add_filter("wplc_loggedin_filter","wplc_filter_control_loggedin",10,1);
|
1973 |
function wplc_filter_control_loggedin($logged_in) {
|
1974 |
$wplc_is_admin_logged_in = get_transient("wplc_is_admin_logged_in");
|
|
|
1975 |
if ($wplc_is_admin_logged_in != 1) {
|
1976 |
$logged_in = false;
|
1977 |
} else {
|
1988 |
if (isset($logged_in_checks['app']) && $logged_in_checks['app'] == true) { $logged_in_via_app = true; }
|
1989 |
|
1990 |
$logged_in = apply_filters("wplc_final_loggedin_control",$logged_in,$logged_in_via_app);
|
|
|
1991 |
/* admin is using the basic version and is logged in */
|
1992 |
if ($wplc_is_admin_logged_in) { $logged_in = true; }
|
1993 |
|
2252 |
*/
|
2253 |
function wplc_admin_output_js() {
|
2254 |
$ajax_nonce = wp_create_nonce("wplc");
|
2255 |
+
if (wplc_user_is_agent()) {
|
|
|
2256 |
$wplc_settings = wplc_get_options();
|
2257 |
wp_register_script('wplc-admin-js', plugins_url('js/wplc_u_admin.js', __FILE__), false, WPLC_PLUGIN_VERSION, false);
|
2258 |
wp_enqueue_script('wplc-admin-js');
|
2262 |
wp_localize_script('wplc-admin-js', 'wplc_wav_file', $wplc_wav_file);
|
2263 |
wp_localize_script('wplc-admin-js', 'wplc_ajax_nonce', $ajax_nonce);
|
2264 |
wp_localize_script('wplc-admin-js', 'wplc_notification_icon', $not_icon);
|
2265 |
+
wp_localize_script('wplc-admin-js', 'tcx_favico_noti', WPLC_PLUGIN_URL . 'images/tcx48_n.png');
|
2266 |
wp_localize_script('wplc-admin-js', 'tcx_favico', WPLC_PLUGIN_URL . 'images/tcx48px.png');
|
2267 |
$extra_data = apply_filters("wplc_filter_admin_javascript",array());
|
2268 |
wp_localize_script('wplc-admin-js', 'wplc_extra_data', $extra_data);
|
2331 |
}
|
2332 |
|
2333 |
function wplc_admin_menu_layout_display() {
|
2334 |
+
if (wplc_user_is_agent()) {
|
2335 |
+
do_action("wplc_hook_admin_menu_layout_display_top");
|
2336 |
+
wplc_stats("chat_dashboard");
|
2337 |
+
if (!isset($_GET['action'])) {
|
2338 |
+
?>
|
2339 |
+
<div class='wplc_network_issue' style='display:none;'></div>
|
2340 |
+
<div class='wplc_page_title'>
|
2341 |
+
<?php wplc_first_time_tutorial(); ?>
|
2342 |
+
</div>
|
2343 |
+
<div id="wplc_sound"></div>
|
2344 |
+
<div id="wplc_admin_chat_holder">
|
2345 |
+
<div class="wplc_admin_chat_on_premise_header">
|
2346 |
+
<div class="wplc_admin_chat_on_premise_header_left">
|
2347 |
+
<img src="data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAABkAAD/4QMvaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzE0MiA3OS4xNjA5MjQsIDIwMTcvMDcvMTMtMDE6MDY6MzkgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE4IChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpERkVFRTcwRUFENDkxMUU5QjUzM0I0QThEMzhGNzc5MyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpERkVFRTcwRkFENDkxMUU5QjUzM0I0QThEMzhGNzc5MyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkRGRUVFNzBDQUQ0OTExRTlCNTMzQjRBOEQzOEY3NzkzIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkRGRUVFNzBEQUQ0OTExRTlCNTMzQjRBOEQzOEY3NzkzIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+/+4AJkFkb2JlAGTAAAAAAQMAFQQDBgoNAAAH7QAADocAABIG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" align="middle"> <h2>WP Live Chat by 3CX</h2>
|
2348 |
+
<?php do_action("wplc_hook_chat_dashboard_above"); ?>
|
2349 |
+
</div>
|
2350 |
+
<div id="wplc_admin_chat_info_new" class="wplc_admin_chat_on_premise_header_right">
|
2351 |
+
<div class="wplc_admin_chat_on_premise_switchery_label">
|
2352 |
+
<b><?php _e("Keep this window open to get notified of new chats.",'wp-live-chat-support'); ?></b>
|
2353 |
+
</div>
|
2354 |
+
<div class='wplc_chat_vis_count_box'>
|
2355 |
+
<?php do_action("wplc_hook_chat_dahsboard_visitors_online_top"); ?>
|
2356 |
+
<div class="wplc_chat_dashboard_on_premise_stats">
|
2357 |
+
<span class='wplc_vis_online'>0</span> <?php _e("Visitor(s) online",'wp-live-chat-support'); ?>
|
2358 |
+
</div>
|
2359 |
+
<div class="wplc_chat_dashboard_on_premise_stats">
|
2360 |
+
<?php echo apply_filters("wplc_filter_chat_dahsboard_visitors_online_bottom",""); ?>
|
2361 |
+
</div>
|
2362 |
+
<?php do_action("wplc_after_chat_visitor_count_hook"); ?>
|
2363 |
+
</div>
|
2364 |
+
</div>
|
2365 |
+
</div>
|
2366 |
+
<div id="wplc_admin_chat_area_new">
|
2367 |
+
<div style="display:block;">
|
2368 |
+
<div class='wplc_chat_on_premise_header'>
|
2369 |
+
<div class='wplc_header_vh wplc_header_v'><?php _e("Visitor",'wp-live-chat-support'); ?></div>
|
2370 |
+
<div class='wplc_header_vh wplc_header_t'><?php _e("Time",'wp-live-chat-support'); ?></div>
|
2371 |
+
<div class='wplc_header_vh wplc_header_nr'><?php _e("Type",'wp-live-chat-support'); ?></div>
|
2372 |
+
<div class='wplc_header_vh wplc_header_dev'><?php _e("Device",'wp-live-chat-support'); ?></div>
|
2373 |
+
<div class='wplc_header_vh wplc_header_d'><?php _e("Data",'wp-live-chat-support'); ?></div>
|
2374 |
+
<div class='wplc_header_vh wplc_header_s'><?php _e("Status",'wp-live-chat-support'); ?></div>
|
2375 |
+
<div class='wplc_header_vh wplc_header_a'><?php _e("Action",'wp-live-chat-support'); ?></div>
|
2376 |
+
</div>
|
2377 |
+
<div id='wplc_chat_ul'></div>
|
2378 |
+
</div>
|
2379 |
+
</div>
|
2380 |
+
</div>
|
2381 |
+
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2382 |
} else {
|
2383 |
+
if (isset($_GET['aid'])) { $aid = intval($_GET['aid']); } else { $aid = null; }
|
2384 |
+
if (!is_null($aid)) {
|
2385 |
+
do_action("wplc_hook_update_agent_id", intval($_GET['cid']), $aid);
|
2386 |
+
}
|
2387 |
+
if ($_GET['action'] == 'ac') {
|
2388 |
+
do_action('wplc_hook_accept_chat',$_GET, $aid);
|
2389 |
+
}
|
2390 |
+
do_action("wplc_hook_admin_menu_layout_display", $_GET['action'], intval($_GET['cid']), $aid);
|
|
|
|
|
|
|
|
|
2391 |
}
|
2392 |
+
} else {
|
2393 |
+
?>
|
2394 |
+
<h1><?php _e("Chat Dashboard",'wp-live-chat-support'); ?></h1>
|
2395 |
+
<div id="welcome-panel" class="welcome-panel">
|
2396 |
+
<div class="welcome-panel-content">
|
2397 |
+
<h2><?php _e("Oh no!",'wp-live-chat-support'); ?></h2>
|
2398 |
+
<p class="about-description">
|
2399 |
+
<?php echo sprintf(__("You do not have access to this page as %s.",'wp-live-chat-support'),'<strong>'.__('you are not a chat agent','wp-live-chat-support').'</strong>'); ?>
|
2400 |
+
</p>
|
2401 |
+
</div>
|
2402 |
+
</div>
|
2403 |
+
<?php
|
2404 |
+
}
|
2405 |
}
|
2406 |
|
2407 |
add_action("wplc_hook_change_status_on_answer","wplc_hook_control_change_status_on_answer",10,2);
|
2675 |
/**
|
2676 |
* Create a JS object for all Agent ID's and Gravatar MD5's
|
2677 |
*/
|
2678 |
+
$user_array = wplc_get_agent_users();
|
|
|
|
|
|
|
2679 |
$a_array = array();
|
2680 |
+
foreach ($user_array as $user) {
|
2681 |
+
$a_array[$user->ID] = array();
|
2682 |
+
$a_array[$user->ID]['name'] = sanitize_text_field($user->display_name);
|
2683 |
+
$a_array[$user->ID]['md5'] = md5( $user->user_email );
|
|
|
|
|
2684 |
}
|
2685 |
wp_localize_script('wplc-admin-chat-server', 'wplc_agent_data', $a_array);
|
2686 |
|
2820 |
$wplc_settings = wplc_cleanup_old_options($wplc_settings);
|
2821 |
update_option('WPLC_SETTINGS', $wplc_settings);
|
2822 |
$uid = get_current_user_id();
|
2823 |
+
wplc_set_agent_accepting($uid, true);
|
2824 |
update_user_meta($uid, 'wplc_ma_agent', 1);
|
2825 |
+
wplc_update_agent_time($uid);
|
2826 |
|
2827 |
$admins = get_role('administrator');
|
2828 |
if( $admins !== null ) { $admins->add_cap('wplc_ma_agent'); }
|
2839 |
if (!function_exists("wplc_choose_activate")) {
|
2840 |
register_activation_hook(__FILE__, 'wplc_choose_activate');
|
2841 |
function wplc_choose_activate( $networkwide ) {
|
2842 |
+
wplc_set_agent_accepting(get_current_user_id(),true);
|
2843 |
wplc_mrg_update_db( $networkwide ); //Run update db
|
2844 |
}
|
2845 |
}
|
2852 |
if (!function_exists("wplc_choose_deactivate")) {
|
2853 |
register_deactivation_hook(__FILE__, 'wplc_choose_deactivate');
|
2854 |
function wplc_choose_deactivate() {
|
2855 |
+
wplc_set_agent_accepting(get_current_user_id(),false);
|
2856 |
}
|
2857 |
}
|
2858 |
|
2963 |
$close_icon = plugins_url('images/iconCloseRetina.png', __FILE__);
|
2964 |
|
2965 |
$bg='';
|
2966 |
+
$bg_string = '';
|
2967 |
if (!empty($wplc_settings['wplc_settings_bg'])) {
|
2968 |
$bg = sanitize_text_field($wplc_settings['wplc_settings_bg']);
|
2969 |
}
|
2973 |
} else {
|
2974 |
$bg_string = "#wp-live-chat-4 { background-color: #fff; }";
|
2975 |
}
|
2976 |
+
if ($wplc_settings['wplc_chatbox_height']!=70) {
|
2977 |
+
$bg_string.= "#wp-live-chat-4 { height: ".$wplc_settings['wplc_chatbox_height']."% !important; }";
|
2978 |
+
}
|
2979 |
|
2980 |
if (isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] ){ $icon = preg_replace('/^http:\/\//', 'https:\/\/', $icon); }
|
2981 |
if (isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] ){ $close_icon = preg_replace('/^http:\/\//', 'https:\/\/', $close_icon); }
|
3056 |
* @return void
|
3057 |
*/
|
3058 |
function wplc_online_check_script() {
|
3059 |
+
if (wplc_user_is_agent()) {
|
3060 |
+
$ajax_nonce = wp_create_nonce("wplc");
|
3061 |
+
wp_register_script( 'wplc-heartbeat', plugins_url( 'js/wplc_heartbeat.js', __FILE__ ), array( 'jquery' ), WPLC_PLUGIN_VERSION, true );
|
3062 |
+
wp_enqueue_script( 'wplc-heartbeat' );
|
3063 |
+
wp_localize_script( 'wplc-heartbeat', 'wplc_transient_nonce', $ajax_nonce );
|
3064 |
+
$wplc_ajax_url = apply_filters("wplc_filter_ajax_url", admin_url('admin-ajax.php'));
|
3065 |
+
wp_localize_script('wplc-heartbeat', 'wplc_ajaxurl', $wplc_ajax_url);
|
3066 |
+
}
|
|
|
3067 |
}
|
3068 |
|
3069 |
/**
|
3073 |
add_filter( 'heartbeat_received', 'wplc_heartbeat_receive', 10, 2 );
|
3074 |
add_filter( 'heartbeat_nopriv_received', 'wplc_heartbeat_receive', 10, 2 );
|
3075 |
function wplc_heartbeat_receive( $response, $data ) {
|
3076 |
+
if ( array_key_exists('client',$data) && $data['client'] == 'wplc_heartbeat' ) {
|
3077 |
+
if (wplc_user_is_agent()) {
|
3078 |
+
wplc_update_agent_time();
|
3079 |
+
wplc_hook_control_set_transient();
|
3080 |
+
}
|
3081 |
+
}
|
3082 |
+
return $response;
|
3083 |
}
|
3084 |
|
3085 |
/**
|
3565 |
$do_popup=false;
|
3566 |
if ($wplc_settings['wplc_auto_pop_up']>0) {
|
3567 |
if ($wplc_settings['wplc_auto_pop_up_online']) {
|
3568 |
+
$do_popup=wplc_one_agent_is_online();
|
3569 |
} else {
|
3570 |
$do_popup=true;
|
3571 |
}
|
3680 |
$wplc_data['wplc_redirect_to_thank_you_page'] = stripslashes(sanitize_text_field(wplc_force_string($_POST, 'wplc_redirect_to_thank_you_page', $wplc_settings)));
|
3681 |
$wplc_data['wplc_redirect_thank_you_url'] = esc_url(wplc_force_url($_POST, 'wplc_redirect_thank_you_url', $wplc_settings));
|
3682 |
$wplc_data['wplc_disable_emojis'] = wplc_force_bool($_POST, 'wplc_disable_emojis');
|
3683 |
+
$wplc_data['wplc_chatbox_height'] = wplc_force_int($_POST, 'wplc_chatbox_height');
|
3684 |
+
if ($wplc_data['wplc_chatbox_height']<30) {
|
3685 |
+
$wplc_data['wplc_chatbox_height']=30;
|
3686 |
+
}
|
3687 |
+
if ($wplc_data['wplc_chatbox_height']>80) {
|
3688 |
+
$wplc_data['wplc_chatbox_height']=80;
|
3689 |
+
}
|
3690 |
$wplc_data['wplc_record_ip_address'] = "0";
|
3691 |
$wplc_data['wplc_enable_msg_sound'] = wplc_force_bool($_POST, 'wplc_enable_msg_sound');
|
3692 |
$wplc_data['wplc_enable_visitor_sound'] = wplc_force_bool($_POST, 'wplc_enable_visitor_sound');
|
3773 |
$wplc_upload_icon = wplc_force_string($_POST, 'wplc_upload_icon', '');
|
3774 |
|
3775 |
if (!empty($wplc_upload_pic)) {
|
3776 |
+
if ($wplc_upload_pic=='remove') {
|
3777 |
+
$wplc_data['wplc_chat_pic'] = ''; //$wplc_default_settings_array['wplc_chat_pic']; // cannot be empty, set to default
|
3778 |
+
} else {
|
3779 |
+
$wplc_data['wplc_chat_pic'] = esc_url(base64_decode($wplc_upload_pic));
|
3780 |
+
}
|
3781 |
}
|
3782 |
if (!empty($wplc_upload_logo)) {
|
3783 |
+
if ($wplc_upload_logo=='remove') {
|
3784 |
+
$wplc_data['wplc_chat_logo'] = '';
|
3785 |
+
} else {
|
3786 |
+
$wplc_data['wplc_chat_logo'] = esc_url(base64_decode($wplc_upload_logo));
|
3787 |
+
}
|
3788 |
}
|
3789 |
if (!empty($wplc_upload_icon)) {
|
3790 |
+
if ($wplc_upload_icon=='remove') {
|
3791 |
+
$wplc_data['wplc_chat_icon'] = '';
|
3792 |
+
} else {
|
3793 |
+
$wplc_data['wplc_chat_icon'] = esc_url(base64_decode($wplc_upload_icon));
|
3794 |
+
}
|
3795 |
+
|
3796 |
}
|
3797 |
|
3798 |
$wplc_data['wplc_chat_delay'] = wplc_force_int($_POST, 'wplc_chat_delay');
|
3837 |
if ($wplc_data['wplc_delay_between_loops'] > 1000000) { $wplc_data['wplc_delay_between_loops'] = 1000000; }
|
3838 |
|
3839 |
if (isset($_POST['wplc_agent_select']) && $_POST['wplc_agent_select'] != "") {
|
3840 |
+
$user_array = wplc_get_agent_users();
|
3841 |
+
foreach ($user_array as $user) {
|
3842 |
+
$uid = $user->ID;
|
3843 |
+
$wplc_ma_user = new WP_User( $uid );
|
3844 |
+
$wplc_ma_user->remove_cap( 'wplc_ma_agent' );
|
3845 |
+
delete_user_meta($uid, "wplc_ma_agent");
|
3846 |
+
delete_user_meta($uid, "wplc_chat_agent_online");
|
|
|
|
|
|
|
|
|
3847 |
}
|
3848 |
|
3849 |
$uid = intval($_POST['wplc_agent_select']);
|
3850 |
$wplc_ma_user = new WP_User( $uid );
|
3851 |
$wplc_ma_user->add_cap( 'wplc_ma_agent' );
|
3852 |
update_user_meta($uid, "wplc_ma_agent", 1);
|
3853 |
+
wplc_update_agent_time($uid);
|
3854 |
}
|
3855 |
|
3856 |
if (isset($_POST['wplc_ban_users_ip'])) {
|
3892 |
delete_transient('wplc_is_admin_logged_in');
|
3893 |
}
|
3894 |
|
|
|
|
|
3895 |
/**
|
3896 |
* Error checks used to ensure the user's resources meet the plugin's requirements
|
3897 |
*/
|
4175 |
* @return file
|
4176 |
*/
|
4177 |
function wplc_admin_download_chat_history(){
|
4178 |
+
if (!is_user_logged_in() || !wplc_user_is_agent()) {
|
4179 |
+
return;
|
4180 |
}
|
4181 |
|
4182 |
if (isset($_GET['action']) && $_GET['action'] == "download_history") {
|
4253 |
* @return void
|
4254 |
*/
|
4255 |
function wplc_admin_download_history($type, $cid){
|
4256 |
+
if (!is_user_logged_in() || !wplc_user_is_agent(get_current_user_id())) {
|
4257 |
+
return;
|
4258 |
}
|
4259 |
|
4260 |
global $wpdb;
|
4484 |
|
4485 |
if ( isset( $_GET['page'] ) ) {
|
4486 |
if ( $_GET['page'] == 'wplivechat-menu-settings' ) {
|
4487 |
+
wp_enqueue_script( "wplc-custom-script-tab-ace", WPLC_PLUGIN_URL.'js/vendor/ace/ace.js', array('jquery'),WPLC_PLUGIN_VERSION );
|
4488 |
} else if ( $_GET['page'] === 'wplivechat-menu-dashboard' || $_GET['page'] === 'wplivechat-menu' ) {
|
4489 |
wplc_register_common_node();
|
4490 |
+
wp_enqueue_script( 'wplc-custom-script-dashboard', WPLC_PLUGIN_URL.'js/wplc_dashboard.js', array('jquery'), WPLC_PLUGIN_VERSION, true );
|
4491 |
wp_localize_script('wplc-custom-script-dashboard', 'nifty_api_key', wplc_node_server_token_get());
|
4492 |
}
|
4493 |
|