├── .gitignore ├── LICENSE ├── README.md ├── carousel ├── app.json ├── readme.md └── src │ ├── CarouselControl.controladdin.al │ ├── CustomerListExt.PageExt.al │ └── startup.js ├── content-editor ├── README.md ├── app │ ├── .gitignore │ ├── app.json │ └── src │ │ ├── ContentEditor │ │ ├── ContentEditor.ControlAddin.al │ │ ├── css │ │ │ └── content-editor.css │ │ └── js │ │ │ ├── content-editor-events.js │ │ │ └── content-editor.js │ │ ├── CustomerCardExt.PageExt.al │ │ └── CustomerDetail.TableExt.al ├── media │ └── content-editor.gif └── react-app │ ├── .gitignore │ ├── README.md │ ├── gulpfile.js │ ├── package-lock.json │ ├── package.json │ ├── public │ └── index.html │ ├── src │ ├── ContentEditor.css │ ├── ContentEditor.js │ └── index.js │ ├── webpack.config.js │ └── yarn.lock ├── docs └── readme.md └── media └── carousel.gif /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .alpackages 3 | *.app -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 MSN Raju 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Microsoft Dynamics 365 Business Central - Control Add-in Samples 2 | 3 | ## Overview 4 | This repository is for Business Control `Control Add-in` samples. 5 | 6 | Sample `Control Add-ins`: 7 | * [Carousel](https://github.com/msnraju/control-add-in-samples/tree/master/carousel) 8 | * [Content-Editor](https://github.com/msnraju/control-add-in-samples/tree/master/content-editor) 9 | 10 | :) I will try to add more `User Controls` when I get time. 11 | 12 | 13 | ## Download 14 | 15 | Run this command to clone this repository into your machine: 16 | 17 | ``` 18 | git clone https://github.com/msnraju/control-add-in-samples.git 19 | ``` 20 | 21 | If you do not have [node.js](https://nodejs.org/en/download/) installed, you can directly download from [here](https://github.com/msnraju/control-add-in-samples/archive/master.zip). 22 | 23 | ## References 24 | [Control Add-In Object](https://docs.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/devenv-control-addin-object) 25 | 26 | [How to Create Control Add-in in Microsoft Dynamics 365 Business Central](https://www.msnjournals.com/post/how-to-create-control-add-in-in-microsoft-dynamics-365-business-central) 27 | 28 | -------------------------------------------------------------------------------- /carousel/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "b891013b-f926-4873-9681-81af47f7a2f4", 3 | "name": "carousel", 4 | "publisher": "msnraju", 5 | "version": "1.0.0.0", 6 | "brief": "", 7 | "description": "Carousel Control", 8 | "privacyStatement": "", 9 | "EULA": "", 10 | "help": "", 11 | "url": "", 12 | "logo": "", 13 | "dependencies": [ 14 | { 15 | "id": "63ca2fa4-4f03-4f2b-a480-172fef340d3f", 16 | "publisher": "Microsoft", 17 | "name": "System Application", 18 | "version": "16.0.0.0" 19 | }, 20 | { 21 | "id": "437dbf0e-84ff-417a-965d-ed2bb9650972", 22 | "publisher": "Microsoft", 23 | "name": "Base Application", 24 | "version": "16.0.0.0" 25 | } 26 | ], 27 | "screenshots": [], 28 | "platform": "16.0.0.0", 29 | "idRanges": [ 30 | { 31 | "from": 50100, 32 | "to": 50149 33 | } 34 | ], 35 | "contextSensitiveHelpUrl": "https://carousel.com/help/", 36 | "showMyCode": true, 37 | "runtime": "5.0" 38 | } -------------------------------------------------------------------------------- /carousel/readme.md: -------------------------------------------------------------------------------- 1 | # Carousel Control - Microsoft Dynamics 365 Business Central Control Add-in 2 | 3 | This AL Project contains an implementation of `Carousel Control` using from [Bootstrap](https://getbootstrap.com/) framework. 4 | 5 | ## Output 6 | ![Carousel Control](../media/carousel.gif) 7 | -------------------------------------------------------------------------------- /carousel/src/CarouselControl.controladdin.al: -------------------------------------------------------------------------------- 1 | controladdin "Carousel Control" 2 | { 3 | HorizontalStretch = true; 4 | RequestedHeight = 200; 5 | 6 | // JS files required for Bootstrap 7 | Scripts = 'https://code.jquery.com/jquery-3.5.1.slim.min.js', 8 | 'https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js', 9 | 'https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js'; 10 | 11 | StartupScript = 'src/startup.js'; 12 | 13 | // Bootstrap css 14 | StyleSheets = 'https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css'; 15 | 16 | procedure SetCarouselData(Data: JsonObject); 17 | event OnStartup(); 18 | } -------------------------------------------------------------------------------- /carousel/src/CustomerListExt.PageExt.al: -------------------------------------------------------------------------------- 1 | pageextension 50100 CustomerListExt extends "Customer List" 2 | { 3 | layout 4 | { 5 | addbefore(Control1) 6 | { 7 | usercontrol(Carousel; "Carousel Control") 8 | { 9 | trigger OnStartup() 10 | var 11 | JObject: JsonObject; 12 | Slides: JsonArray; 13 | begin 14 | Slides.Add(AddSlide('Keep your promises', 'check before you make a promise', '//unsplash.it/1024/200')); 15 | Slides.Add(AddSlide('Never forget', 'always register your conversations to ensure you follow-up promptly', '//unsplash.it/1025/200')); 16 | Slides.Add(AddSlide('Qualify', 'be picky about which opportunities to spend time on', '//unsplash.it/1024/201')); 17 | JObject.Add('slides', Slides); 18 | CurrPage.Carousel.SetCarouselData(JObject); 19 | end; 20 | } 21 | } 22 | } 23 | 24 | local procedure AddSlide(Title: Text; Description: Text; Image: Text): JsonObject 25 | var 26 | Slide: JsonObject; 27 | begin 28 | Slide.Add('title', Title); 29 | Slide.Add('description', Description); 30 | Slide.Add('image', Image); 31 | exit(Slide); 32 | end; 33 | } -------------------------------------------------------------------------------- /carousel/src/startup.js: -------------------------------------------------------------------------------- 1 | Microsoft.Dynamics.NAV.InvokeExtensibilityMethod('OnStartup') 2 | 3 | function carouselIndicators(slides) { 4 | var indicators = []; 5 | for (var i = 0; i < slides.length; i++) { 6 | var cssClass = i === 0 ? 'class="active"' : ''; 7 | indicators.push(`
  • `); 8 | } 9 | 10 | return ``; 11 | } 12 | 13 | function carouselItems(slides) { 14 | var carouselItems = []; 15 | for (var i = 0; i < slides.length; i++) { 16 | var slide = slides[i]; 17 | var cssClass = i === 0 ? 'active' : ''; 18 | 19 | carouselItems.push(` 20 | 27 | `); 28 | } 29 | 30 | return ``; 31 | } 32 | 33 | function carouselMarkup(data) { 34 | return ` 35 | `; 47 | } 48 | 49 | window.SetCarouselData = function (data) { 50 | try { 51 | var markup = carouselMarkup(data); 52 | document.getElementById('controlAddIn').innerHTML = markup; 53 | $('#carouselExampleCaptions').carousel(); 54 | console.log(markup); 55 | } catch (err) { 56 | console.log(err); 57 | } 58 | } -------------------------------------------------------------------------------- /content-editor/README.md: -------------------------------------------------------------------------------- 1 | # Sample Project on How to use ReactJS in Control Add-ins 2 | It has the following projects 3 | 4 | ## Projects 5 | * app - AL Project which contains Control Add-in 6 | * react-app - React Application with contains Rich Content Editor React Component 7 | 8 | ## Code in Action 9 | ![content-editor](./media/content-editor.gif) 10 | 11 | ## Learn more 12 | You can find details at [msnJournals.com](https://msnJournals.com). 13 | -------------------------------------------------------------------------------- /content-editor/app/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | *.app -------------------------------------------------------------------------------- /content-editor/app/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "58d8b4ed-24fb-4715-bb56-3e153dbc8460", 3 | "name": "app", 4 | "publisher": "Default publisher", 5 | "version": "1.0.0.0", 6 | "brief": "", 7 | "description": "", 8 | "privacyStatement": "", 9 | "EULA": "", 10 | "help": "", 11 | "url": "", 12 | "logo": "", 13 | "dependencies": [ 14 | { 15 | "id": "63ca2fa4-4f03-4f2b-a480-172fef340d3f", 16 | "publisher": "Microsoft", 17 | "name": "System Application", 18 | "version": "16.0.0.0" 19 | }, 20 | { 21 | "id": "437dbf0e-84ff-417a-965d-ed2bb9650972", 22 | "publisher": "Microsoft", 23 | "name": "Base Application", 24 | "version": "16.0.0.0" 25 | } 26 | ], 27 | "screenshots": [], 28 | "platform": "16.0.0.0", 29 | "idRanges": [ 30 | { 31 | "from": 50100, 32 | "to": 50149 33 | } 34 | ], 35 | "contextSensitiveHelpUrl": "https://app.com/help/", 36 | "showMyCode": true, 37 | "runtime": "5.0" 38 | } -------------------------------------------------------------------------------- /content-editor/app/src/ContentEditor/ContentEditor.ControlAddin.al: -------------------------------------------------------------------------------- 1 | controladdin ContentEditor 2 | { 3 | RequestedHeight = 300; 4 | VerticalStretch = true; 5 | VerticalShrink = true; 6 | HorizontalStretch = true; 7 | HorizontalShrink = true; 8 | Scripts = 9 | './src/ContentEditor/js/content-editor-events.js', 10 | './src/ContentEditor/js/content-editor.js'; 11 | StyleSheets = './src/ContentEditor/css/content-editor.css'; 12 | 13 | event OnContentChange(content: JsonObject) 14 | procedure LoadContent(content: JsonObject) 15 | } -------------------------------------------------------------------------------- /content-editor/app/src/ContentEditor/css/content-editor.css: -------------------------------------------------------------------------------- 1 | ._2S1LT{position:relative;display:flex}._2S1LT:hover,._3J3cS{color:#333}._3J3cS{font-weight:300;font-size:12px;line-height:16px;width:100%;height:40px}[dir] ._3J3cS{border:1px solid rgba(0,0,0,.6);border-radius:unset}[dir=ltr] ._3J3cS{padding-left:37px}[dir=rtl] ._3J3cS{padding-right:37px}._3J3cS::-webkit-input-placeholder{color:rgba(0,0,0,.4)}._3J3cS:-ms-input-placeholder{color:rgba(0,0,0,.4)}._3J3cS::-ms-input-placeholder{color:rgba(0,0,0,.4)}._3J3cS::placeholder{color:rgba(0,0,0,.4)}[dir] ._3J3cS:focus,[dir] ._3J3cS:hover{border-color:#333}._3EJqW,._3Luoz{position:absolute;bottom:0;top:0;width:24px}[dir] ._3EJqW,[dir] ._3Luoz{margin:auto}[dir=ltr] ._3EJqW{left:7px}[dir=rtl] ._3EJqW{right:7px}[dir=ltr] ._3Luoz{right:11px}[dir=rtl] ._3Luoz{left:11px}[dir] ._1diZr{padding:80px 120px}[dir] ._1diZr.fAyNz{padding:24px}@media only screen and (max-width:640px){[dir] ._1diZr{padding:160px 33px!important}}._1TAbz{position:absolute;top:20px;color:#000}[dir] ._1TAbz{cursor:pointer}[dir=ltr] ._1TAbz{right:20px}[dir=rtl] ._1TAbz{left:20px}._1TAbz.fAyNz{top:24px}[dir=ltr] ._1TAbz.fAyNz{right:24px}[dir=rtl] ._1TAbz.fAyNz{left:24px}@media only screen and (max-width:640px){._1TAbz{top:50px}[dir=ltr] ._1TAbz{right:30px}[dir=rtl] ._1TAbz{left:30px}}._26c9d{display:grid;align-items:center;color:#333}._26c9d.fAyNz{align-items:start;height:48px}[dir] ._26c9d.fAyNz{border-bottom:1px solid rgba(0,0,0,.2)}._30lHE{line-height:28px;font-size:20px;width:100%}[dir] ._30lHE{text-align:center}[dir=ltr] ._30lHE.fAyNz{text-align:left}[dir=rtl] ._30lHE.fAyNz{text-align:right}._36dBB{font-size:16px;line-height:24px;color:rgba(0,0,0,.6)}[dir] ._36dBB{padding-top:32px}[dir] ._1y-qK{margin-top:36px;margin-bottom:42px}[dir] ._1y-qK.fAyNz{margin-top:28px}@media only screen and (max-width:640px){[dir] ._1y-qK{margin-top:32px;margin-bottom:33px}}._3-2Tj{font-size:12px;line-height:16px}[dir] ._3-2Tj{border:1px solid rgba(0,0,0,.6)}._3-2Tj::-webkit-input-placeholder{color:rgba(0,0,0,.4)}._3-2Tj:-ms-input-placeholder{color:rgba(0,0,0,.4)}._3-2Tj::-ms-input-placeholder{color:rgba(0,0,0,.4)}._3-2Tj::placeholder{color:rgba(0,0,0,.4)}[dir] ._3-2Tj:focus,[dir] ._3-2Tj:hover{border-color:#000}[dir] .tDFzx,[dir] .tDFzx:focus,[dir] .tDFzx:hover{border-color:#ee5951}.ZdmXT,._3_5xp{font-size:14px}[dir] .ZdmXT,[dir] ._3_5xp{cursor:pointer}._3_5xp{color:#fff}[dir] ._3_5xp{background-color:#0261ff}[dir] ._3_5xp:hover:not([disabled]){background-color:rgba(2,97,255,.8)}._3_5xp:disabled{color:hsla(0,0%,100%,.6)}[dir] ._3_5xp:disabled{cursor:auto;background-color:rgba(0,0,0,.4)}.ZdmXT{color:#0261ff}[dir] .ZdmXT{border:1px solid #0261ff;background:#fff}[dir] .ZdmXT:active,[dir] .ZdmXT:hover{border-color:rgba(2,97,255,.6)}.ZdmXT:disabled{color:rgba(0,0,0,.4)}[dir] .ZdmXT:disabled{background-color:rgba(0,0,0,.4)}.FvE1u,.ReactModalPortal,._1GII1,._1eLVw,._2WgPx,.glob_fontElementMap{font-family:Helvetica}.qv-GZ{display:flex}._215Z4{display:absolute;top:0}[dir=ltr] ._215Z4{left:0}[dir=rtl] ._215Z4{right:0}._1Qael{width:.1px;height:.1px;overflow:hidden;position:absolute;opacity:0;z-index:-1}[dir] .cT8Vv{cursor:default;box-shadow:0 0 0 3px #0261ff}._2y2AG{display:block;width:100%;height:100%;position:absolute;top:0}[dir] ._2y2AG{cursor:move}[dir=ltr] ._2y2AG{left:0}[dir=rtl] ._2y2AG{right:0}._3Dn3P{display:none}._1GII1,._1eLVw{position:relative}[dir] ._1GII1:hover{cursor:default;box-shadow:0 0 0 3px #0261ff}._3xCoF{max-width:100%}._2WgPx{position:absolute;display:flex;color:#757575}[dir] ._2WgPx{padding:12px 24px;background:#fff;border:1px solid #ddd;border-radius:6px}[dir=ltr] ._2WgPx{box-shadow:1px 1px 3px 1px #dcdcdc}[dir=rtl] ._2WgPx{box-shadow:-1px 1px 3px 1px #dcdcdc}._1Ghoa{text-decoration:none;color:#333}._2UcyY{display:block}._1nga8{vertical-align:text-bottom;height:17px}[dir] ._1nga8{padding-top:2px}._1nga8:hover{color:#0161ff}._2iHAv{display:flex}[dir] ._2iHAv{cursor:pointer}._2cpdi{position:absolute;opacity:0}[dir] ._2cpdi{cursor:pointer}._3SFGZ{display:flex}[dir] ._3SFGZ{cursor:pointer;margin-bottom:12px}.EGp4h{display:flex}[dir] ._3PpSF:hover ._3uGfl{background-color:rgba(2,97,255,.2)}._4GWru{width:16px;height:16px;display:inline-block;vertical-align:text-bottom;color:#fff;box-sizing:border-box}[dir] ._4GWru{padding:3px 2px;border-radius:3px;background-color:#fff;border:1px solid #0261ff}._2m_-H{vertical-align:text-bottom;height:19px}[dir] ._2m_-H{padding-top:2px}._2m_-H:hover{color:#0161ff}[dir] .n4-Fn{background-color:#0261ff}.Qxhlg{width:10px;height:8px;display:block}[dir=ltr] .yx-pO{margin-left:12px}[dir=rtl] .yx-pO{margin-right:12px}._2NCtV{color:#333}._3AuFz{height:100%;width:100%;pointer-events:auto;display:flex;flex-direction:column;align-items:center;justify-content:center}[dir] ._3AuFz{background:0 0;border:0;cursor:pointer}._3AuFz._1EEXX{color:#757575}._3AuFz._1EEXX:focus:not([disabled]) ._1qOTu,._3AuFz._1EEXX:hover:not([disabled]) ._1qOTu{color:#0261ff}[dir] ._3AuFz._1EEXX:focus:not([disabled]) ._1qOTu,[dir] ._3AuFz._1EEXX:hover:not([disabled]) ._1qOTu{cursor:pointer}._3AuFz._1EEXX:focus:not([disabled]) ._1qOTu svg,._3AuFz._1EEXX:hover:not([disabled]) ._1qOTu svg{fill:currentColor}._3AuFz:disabled>*{opacity:.4}[dir] ._3AuFz:disabled>*{cursor:default}._1qOTu{width:20px;height:20px}._1qOTu svg{width:100%;height:100%;fill:currentColor}._1iU4F{font-size:12px}[dir] ._1iU4F{margin:8px 0 0}._1BVBi._2qWKP{height:100%}._1BVBi ._3AuFz{width:100%;height:100%;box-sizing:border-box}[dir] ._1BVBi ._3AuFz{padding:22px 0}._1BVBi ._3AuFz:focus:not([disabled]) ._1qOTu{color:#0261ff}[dir] ._1BVBi ._3AuFz:focus:not([disabled]) ._1qOTu{cursor:pointer}._1BVBi ._3AuFz:focus:not([disabled]) ._1qOTu svg{fill:currentColor}._1BVBi ._1qOTu{display:block;width:25px;height:25px}[dir] ._1BVBi ._1qOTu{margin:0 auto}._1BVBi ._1iU4F{display:block;font-size:13px;line-height:21px}[dir] ._1BVBi ._1iU4F{margin:6px 0 0}.w3ICK{position:relative}[dir] .w3ICK{background-position:50%;background-repeat:no-repeat}._1zXfO{display:block;max-width:100%;height:100%;visibility:hidden}._1RC0l{display:block;font-size:14px}[dir] ._1RC0l{margin-bottom:9px}.c6u02{display:block;font-size:14px}[dir] .c6u02{margin:9px}._9dcgR{width:100%;height:42px;box-sizing:border-box;font-size:14px;line-height:1.5;font-weight:300}[dir] ._9dcgR{padding:0 17px;border:1px solid #ededed;border-radius:0;box-shadow:none}._9dcgR::-webkit-input-placeholder{opacity:.4}._9dcgR:-ms-input-placeholder{opacity:.4}._9dcgR::-ms-input-placeholder{opacity:.4}._9dcgR::placeholder{opacity:.4}._3xSEz{height:101px;resize:none}[dir] ._3xSEz{padding:9px 17px}._2hJ8Z{height:100%}._2EU3H{vertical-align:text-bottom;height:17px}._2EU3H:hover{color:#0161ff}._3mklt{font-size:14px;line-height:1.5}[dir] ._3mklt{cursor:pointer}[dir] ._3mklt:hover .UPxWU{border-color:#000}.UPxWU{width:16px;height:16px;box-sizing:border-box;display:inline-block}[dir] .UPxWU{border-radius:50%;border:1px solid rgba(0,0,0,.6);background:#fff}[dir=ltr] .UPxWU{margin-right:12px}[dir=rtl] .UPxWU{margin-left:12px}.UPxWU:after{content:"";width:10px;height:10px;position:relative;top:2px;display:block}[dir] .UPxWU:after{border-radius:50%}[dir=ltr] .UPxWU:after{left:2px}[dir=rtl] .UPxWU:after{right:2px}._1Gl-z{display:none}[dir] ._1Gl-z:checked+.UPxWU{border-color:rgba(0,0,0,.6)}[dir] ._1Gl-z:checked+.UPxWU:after{background-color:#0261ff}._3-Q-q{display:flex;width:-webkit-max-content;width:-moz-max-content;width:max-content}[dir] ._3-Q-q{padding:10px 0}[dir=ltr] ._3-Q-q{margin-right:10px}[dir=rtl] ._3-Q-q{margin-left:10px}[dir=ltr] ._3-Q-q:last-child{margin-right:0}[dir=rtl] ._3-Q-q:last-child{margin-left:0}._1FJxh{color:#333;line-height:normal}[dir] ._1FJxh{background:0 0;padding:5px;border:0;cursor:pointer}._1FJxh:focus,._1FJxh:hover{outline:0;color:#0261ff}._1FJxh:disabled{opacity:.4}[dir] ._1FJxh:disabled{cursor:default}._11tDX{width:20px;height:20px;vertical-align:middle}._11tDX svg{width:100%;height:100%;fill:currentColor}._11tDX:hover,._1RDmX{color:#0261ff}._11tDX:hover svg,._1RDmX svg{fill:currentColor}._31Zhn{width:-webkit-max-content!important;width:-moz-max-content!important;width:max-content!important;display:flex;font-size:14px;font-family:Helvetica;font-weight:500}[dir] ._31Zhn{margin:0 10px!important}._3UW5c{position:relative;top:1px}[dir=ltr] ._3UW5c{left:7px}[dir=rtl] ._3UW5c{right:7px}._3UW5c svg{width:16px;height:16px}._1Hzfu{top:-2px}[dir=ltr] ._1Hzfu{transform:rotate(180deg)}[dir=rtl] ._1Hzfu{transform:rotate(-180deg)}.Q1kOa{display:block}[dir] .Q1kOa{margin-bottom:9px}.a_KIx{display:flex;align-items:center}.a_KIx label{display:inline-flex;align-items:center}.a_KIx span{vertical-align:text-bottom}._3sL4Z label{width:50%}[dir=ltr] ._2zHMK label+label{margin-left:36px}[dir=rtl] ._2zHMK label+label{margin-right:36px}.e1KAA{opacity:.5;pointer-events:none}@supports (display:grid){._11V27{display:grid}}._11V27,._3W-Ve{width:100%}._3W-Ve{font-size:14px;height:85px;display:inline-flex;flex-direction:column;justify-content:center;align-items:center}[dir] ._3W-Ve{text-align:center;cursor:pointer;margin:0}[dir] ._3W-Ve:hover{background-color:rgba(2,97,255,.05)}._1BawR{color:#0261ff}[dir] ._1BawR,[dir] ._1BawR._3W-Ve{background-color:rgba(2,97,255,.1)}.kLQTo{position:relative;display:inline-block;width:45px;height:23px;opacity:.6}._2_euz,.kLQTo:hover{opacity:1}._2_euz:hover{opacity:.6}.BAT9-{display:flex;-webkit-touch-callout:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}[dir=ltr] .BAT9-{margin-left:auto}[dir=rtl] .BAT9-{margin-right:auto}._2WdZZ{display:flex}[dir] ._2WdZZ * p{margin:0}[dir] ._2WdZZ{padding-top:30px}@media only screen and (max-width:640px){[dir] ._2WdZZ{padding-top:0}}@media only screen and (max-width:640px){[dir] ._2WdZZ+._2WdZZ{padding-top:36px}}._2CoLQ{width:100%;height:100%}[dir] ._2CoLQ{margin:0}._2f7tb{position:absolute;top:0;display:flex;align-items:center;width:100%;height:100%;pointer-events:none}[dir=ltr] ._2f7tb{left:0}[dir=rtl] ._2f7tb{right:0}._27Qc0{display:flex;flex-direction:column;justify-content:center}._1MYW9{font-size:14px}._1kaMt{flex:1 1;height:100%}[dir] ._1kaMt{border-radius:12px;background-color:#aaa}[dir] ._2BUb3{background-color:#0261ff}._1Uusj{position:absolute;width:22px;height:21px;transition:transform .3s}[dir] ._1Uusj{background-color:#fff;border-radius:50%}[dir=ltr] ._19ANv{transform:translateX(22px)}[dir=rtl] ._19ANv{transform:translateX(-22px)}[dir=ltr] ._24aZj{transform:translateX(1px)}[dir=rtl] ._24aZj{transform:translateX(-1px)}._2Iyi5{display:inline-block;width:19px;height:19px;vertical-align:middle;color:inherit}[dir=ltr] ._2Iyi5{margin:-4px 12px 0 0}[dir=rtl] ._2Iyi5{margin:-4px 0 0 12px}._1dJV-{display:inline-block;color:inherit}._1dJV-,._3mx4z{font-size:14px}._1p2rK,._3mx4z{position:relative;color:#333}._1p2rK{overflow:hidden;transition:all .2s ease;white-space:nowrap}[dir] ._1p2rK{border:none;background-color:#fff;cursor:pointer}[dir=ltr] ._1p2rK{padding:10px 62px 10px 0}[dir=rtl] ._1p2rK{padding:10px 0 10px 62px}._1p2rK:hover{color:#0261ff}._9IlUC{display:block;position:absolute;top:10px;width:19px;height:19px}[dir=ltr] ._9IlUC{right:6px}[dir=rtl] ._9IlUC{left:6px}[dir=ltr] ._150iF{transform:rotate(180deg)}[dir=rtl] ._150iF{transform:rotate(-180deg)}._1ZUlH{max-height:250px;overflow-y:auto;position:fixed;top:100%;width:auto;z-index:1000;-webkit-overflow-scrolling:touch}[dir] ._1ZUlH{background-color:#fff;margin-top:-2px;border:1px solid #ededed;border-radius:8px;padding:8px 0}[dir=ltr] ._1ZUlH{margin-left:-10px}[dir=rtl] ._1ZUlH{margin-right:-10px}._2GWM2{color:#333;font-weight:700;text-transform:capitalize}[dir] ._2GWM2{padding:8px 10px}._37DkN{color:#333;display:block;white-space:nowrap}[dir] ._37DkN{border:none;background-color:transparent;cursor:pointer;padding:0 12px}[dir=ltr] ._37DkN:last-child,[dir=rtl] ._37DkN:last-child{border-bottom-right-radius:2px;border-bottom-left-radius:2px}._37DkN:hover,._3a8H2{color:rgba(17,34,51,.27)}._3ruU9{color:#333;display:block}[dir] ._3ruU9{cursor:default;padding:8px 10px}[dir] ._1g5Nv{border:none}._1o0mZ{display:block}[dir] ._1o0mZ{margin-bottom:6px}._1O-b7{opacity:.5;pointer-events:none}._3EaBv{display:flex;flex-basis:auto;justify-content:space-between;align-items:center}._1TiZY{flex:1 1 auto}.cdFoO{flex:0 0 50px;height:30px;box-sizing:border-box;font-family:inherit;font-size:14px;max-width:55px}[dir] .cdFoO{padding:.1em;border:1px solid #ededed;border-radius:3px;text-align:center}[dir=ltr] .cdFoO{margin-left:24px}[dir=rtl] .cdFoO{margin-right:24px}._1DBY5,._3LD4v{-webkit-appearance:none}._1DBY5{width:100%}[dir] ._1DBY5{margin:8px 0}[dir] ._1DBY5:focus::-webkit-slider-runnable-track{background:#0261ff}[dir] ._1DBY5:focus::-ms-fill-lower,[dir] ._1DBY5:focus::-ms-fill-upper{background:#0261ff}._1DBY5::-webkit-slider-runnable-track{height:6px;-webkit-transition:all .2s ease;transition:all .2s ease;width:100%}[dir] ._1DBY5::-webkit-slider-runnable-track{cursor:pointer;box-shadow:0 0 0 rgba(0,0,0,.2),0 0 0 rgba(13,13,13,.2);background:#0261ff;border:0 solid #cfd8dc;border-radius:3px}._1DBY5::-webkit-slider-thumb{height:16px;width:16px;-webkit-appearance:none}[dir] ._1DBY5::-webkit-slider-thumb{background:#0261ff;border:4px solid #fff;border-radius:8px;cursor:pointer;margin-top:-5px}[dir=ltr] ._1DBY5::-webkit-slider-thumb{box-shadow:1px 1px 1px rgba(0,0,0,.2),0 0 1px rgba(13,13,13,.2)}[dir=rtl] ._1DBY5::-webkit-slider-thumb{box-shadow:-1px 1px 1px rgba(0,0,0,.2),0 0 1px rgba(13,13,13,.2)}._1DBY5::-moz-range-track{height:6px;-moz-transition:all .2s ease;transition:all .2s ease;width:100%}[dir] ._1DBY5::-moz-range-track{cursor:pointer;box-shadow:0 0 0 rgba(0,0,0,.2),0 0 0 rgba(13,13,13,.2);background:#0261ff;border:0 solid #cfd8dc;border-radius:3px}._1DBY5::-moz-range-thumb{height:16px;width:16px;box-sizing:border-box}[dir] ._1DBY5::-moz-range-thumb{background:#0261ff;border:4px solid #fff;border-radius:8px;cursor:pointer}[dir=ltr] ._1DBY5::-moz-range-thumb{box-shadow:1px 1px 1px rgba(0,0,0,.2),0 0 1px rgba(13,13,13,.2)}[dir=rtl] ._1DBY5::-moz-range-thumb{box-shadow:-1px 1px 1px rgba(0,0,0,.2),0 0 1px rgba(13,13,13,.2)}._1DBY5::-ms-track{height:6px;-ms-transition:all .2s ease;transition:all .2s ease;width:100%;color:transparent}[dir] ._1DBY5::-ms-track{cursor:pointer;background:0 0;border-color:transparent;border-width:8px 0}[dir] ._1DBY5::-ms-fill-lower,[dir] ._1DBY5::-ms-fill-upper{box-shadow:0 0 0 rgba(0,0,0,.2),0 0 0 rgba(13,13,13,.2);background:#0261ff;border:0 solid #cfd8dc;border-radius:6px}._1DBY5::-ms-thumb{height:16px;width:16px}[dir] ._1DBY5::-ms-thumb{background:#0261ff;border:4px solid #fff;border-radius:8px;cursor:pointer;margin-top:0}[dir=ltr] ._1DBY5::-ms-thumb{box-shadow:1px 1px 1px rgba(0,0,0,.2),0 0 1px rgba(13,13,13,.2)}[dir=rtl] ._1DBY5::-ms-thumb{box-shadow:-1px 1px 1px rgba(0,0,0,.2),0 0 1px rgba(13,13,13,.2)}._3YlGz{width:100%}._37UND{display:flex;justify-content:space-evenly;height:50px;font-size:16px;line-height:1.5}[dir] ._37UND{border-bottom:1px solid #ededed;cursor:pointer}._2jMBI{width:100%;font-size:16px;font-weight:300}[dir] ._2jMBI{text-align:center;cursor:pointer;border:none;border-bottom:3px solid transparent;background-color:transparent}._2jMBI:hover:not(._1qgY8) .fvI-8{color:rgba(0,0,0,.4)}[dir] ._1qgY8{border-bottom:3px solid #0261ff}[dir=ltr] ._2jMBI+._2jMBI{border-left:1px solid #ededed}[dir=rtl] ._2jMBI+._2jMBI{border-right:1px solid #ededed}[dir] ._2GTij{padding:24px 30px 30px}[dir] .fvI-8{cursor:pointer}._1ALwM{position:relative}._1yXWP{font-weight:300;font-size:14px;line-height:1.5;color:#333;width:100%;height:42px;box-sizing:border-box}[dir] ._1yXWP{border:1px solid rgba(51,51,51,.1)}[dir=ltr] ._1yXWP{padding-left:18px}[dir=rtl] ._1yXWP{padding-right:18px}._1yXWP::-webkit-input-placeholder{opacity:.4}._1yXWP:-ms-input-placeholder{opacity:.4}._1yXWP::-ms-input-placeholder{opacity:.4}._1yXWP::placeholder{opacity:.4}[dir] .sZSyZ{border-color:red}[dir=ltr] .sZSyZ{padding-right:39px}[dir=rtl] .sZSyZ{padding-left:39px}._2j8qo{position:absolute;bottom:0;top:0;width:13px;color:#ee5951}[dir] ._2j8qo{margin:auto}[dir=ltr] ._2j8qo{right:13px}[dir=rtl] ._2j8qo{left:13px}._24Btg{flex:0 0 1px;height:100%}[dir] ._24Btg{background:#ededed}[dir=ltr] ._24Btg{margin:0 19px 0 9px}[dir=rtl] ._24Btg{margin:0 9px 0 19px}.xfup8{display:block;width:auto;height:1px}[dir] .xfup8{background:#ededed}[dir=ltr] .xfup8{margin:0 -10px 0 -19px}[dir=rtl] .xfup8{margin:0 -19px 0 -10px}.UAQSY{display:inline-flex;align-items:center;flex-direction:row;justify-content:flex-end;width:100%;max-width:419px;height:88px;box-sizing:border-box;font-size:14px}[dir] .UAQSY{padding:24px;border-top:1px solid #ededed;background:#fff}.UAQSY._16puw{justify-content:center;height:-webkit-max-content;height:-moz-max-content;height:max-content}[dir] .UAQSY._16puw{border-top:none;padding:0}@media only screen and (max-width:640px){.UAQSY._16puw{display:grid;grid-template-areas:"save" "cancel";grid-row-gap:9px;grid-auto-columns:100%}}.UAQSY.crSDJ{justify-content:flex-end;max-width:100%}._3USSJ{position:fixed;bottom:0;z-index:5;display:inline-flex;align-items:center;flex-direction:row}._3csFr._16puw,.t0aiQ._16puw{min-width:132px;height:40px}@media only screen and (max-width:640px){._3csFr._16puw,.t0aiQ._16puw{max-width:none;font-size:16px;width:100%;height:46px}[dir=ltr] ._3csFr._16puw,[dir=ltr] .t0aiQ._16puw{margin-left:0!important}[dir=rtl] ._3csFr._16puw,[dir=rtl] .t0aiQ._16puw{margin-right:0!important}}._3csFr,.t0aiQ{min-width:109px;max-width:115px;height:36px;display:flex;flex-direction:column;justify-content:center;align-items:center}[dir] ._3csFr,[dir] .t0aiQ{padding:8.5px 24px;border-style:none}[dir=ltr] ._3csFr._16puw{margin-left:12px!important}[dir=rtl] ._3csFr._16puw{margin-right:12px!important}@media only screen and (max-width:640px){._3csFr._16puw{grid-area:save}[dir=ltr] ._3csFr._16puw{margin-left:0!important}[dir=rtl] ._3csFr._16puw{margin-right:0!important}}._3csFr.crSDJ{height:36px}[dir=ltr] .t0aiQ+._3csFr{margin-left:24px}[dir=rtl] .t0aiQ+._3csFr{margin-right:24px}[dir] .t0aiQ{border-style:solid}@media only screen and (max-width:640px){.t0aiQ._16puw{grid-area:cancel}[dir] .t0aiQ._16puw{border:none;padding-top:9px}}.t0aiQ.crSDJ{height:36px}.t0aiQ:hover{color:#4990e2}[dir] .t0aiQ:hover{background:#fff}._3d-zD{height:100%;width:100%;position:absolute;top:0;color:#fff;display:flex;justify-content:center;align-items:center}[dir] ._3d-zD{text-align:center;background:rgba(0,0,0,.5)}._1qm_l{width:20px;height:20px}[dir] ._3if3F{margin-bottom:80px}.ylIuf{position:absolute;font-size:16px;line-height:24px}._1lrjt{display:flex;align-items:center;justify-content:center;position:fixed;top:0;bottom:0;z-index:5}[dir] ._1lrjt{background-color:rgba(0,0,0,.5)}[dir=ltr] ._1lrjt,[dir=rtl] ._1lrjt{left:0;right:0}._1kSgV{position:relative;min-width:360px;font-size:14px;font-weight:300;font-stretch:normal;font-style:normal}[dir] ._1kSgV{margin-top:18px}._3Dc95{min-width:0}[dir] ._8j3Yy{padding:0 23px}.gnBxn{font-size:14px;font-weight:300;font-style:normal;font-stretch:normal;line-height:1.5;letter-spacing:normal}[dir] .gnBxn{margin:0 1px;padding-bottom:6px}[dir=ltr] .gnBxn{text-align:left}[dir=rtl] .gnBxn{text-align:right}._1kj8Z{position:relative}[dir] ._1kj8Z{margin:5px 0 13px}[dir=ltr] ._1_T30{margin-left:0}[dir=rtl] ._1_T30{margin-right:0}._3W7bW,._3e5aF{color:#333;width:100%;font-size:14px}[dir] ._3W7bW,[dir] ._3e5aF{border:1px solid rgba(51,51,51,.2)}[dir] ._3W7bW:focus,[dir] ._3W7bW:focus+._3e5aF,[dir] ._3e5aF:focus,[dir] ._3e5aF:focus+._3e5aF{border:1px solid rgba(51,51,51,.5)}._3W7bW{height:42px;box-sizing:border-box}[dir] ._3W7bW{padding:0 18px}[dir=ltr] ._3W7bW{text-align:left}[dir=rtl] ._3W7bW{text-align:right}._3W7bW::-webkit-input-placeholder{opacity:.4}._3W7bW:-ms-input-placeholder{opacity:.4}._3W7bW::-ms-input-placeholder{opacity:.4}._3W7bW::placeholder{opacity:.4}._3e5aF{position:absolute}[dir] ._3e5aF{border-top:none}[dir] ._2dP_f{border:1px solid red!important}.dXiJB{width:100%;height:42px;color:#333}[dir] .dXiJB{padding:0 17px;border:1px solid #ededed}.bDr5F{position:absolute;bottom:0;top:0;width:13px}[dir] .bDr5F{margin:auto}[dir=ltr] .bDr5F{right:12px}[dir=rtl] .bDr5F{left:12px}[dir] ._236K7{margin:0 4px;border-bottom:1px solid rgba(51,51,51,.1)}._2b05D{display:flex}[dir] ._2b05D{padding:12px 22px 20px}._1EBTt{width:19px;height:19px}[dir=ltr] ._1EBTt{margin-right:11px}[dir=rtl] ._1EBTt{margin-left:11px}._20YAE{font-size:16px}[dir] ._20YAE{margin:0}/*! rtl:begin:ignore */._3SC9O{position:relative;width:100%;height:100%;background:rgba(0,0,0,.5)}._26uJz{position:absolute;left:0;right:0;top:0;bottom:0;font-size:60px;color:#fbfbfb;width:1em;height:1em;border-radius:50%;margin:auto;-webkit-animation:_1kAQA 1.7s ease infinite,c7O-P 1.7s ease infinite;animation:_1kAQA 1.7s ease infinite,c7O-P 1.7s ease infinite}._26uJz._3uP7K{font-size:40px}._26uJz.Voc_N{font-size:20px}._1kcNE{position:absolute;left:0;right:0;top:0;bottom:0;color:#fbfbfb;height:1.5em;width:3em;border-radius:50%;margin:auto;font-size:60px;text-align:center}._1kcNE._3uP7K{font-size:16px}._1kcNE._1PJ2b{font-size:10px}.HWVQU{width:100%;height:100%}@-webkit-keyframes c7O-P{0%{transform:rotate(0)}to{transform:rotate(1turn)}}@keyframes c7O-P{0%{transform:rotate(0)}to{transform:rotate(1turn)}}@-webkit-keyframes _1kAQA{0%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}5%,95%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}10%,59%{box-shadow:0 -.83em 0 -.4em,-.087em -.825em 0 -.42em,-.173em -.812em 0 -.44em,-.256em -.789em 0 -.46em,-.297em -.775em 0 -.477em}20%{box-shadow:0 -.83em 0 -.4em,-.338em -.758em 0 -.42em,-.555em -.617em 0 -.44em,-.671em -.488em 0 -.46em,-.749em -.34em 0 -.477em}38%{box-shadow:0 -.83em 0 -.4em,-.377em -.74em 0 -.42em,-.645em -.522em 0 -.44em,-.775em -.297em 0 -.46em,-.82em -.09em 0 -.477em}to{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}}@keyframes _1kAQA{0%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}5%,95%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}10%,59%{box-shadow:0 -.83em 0 -.4em,-.087em -.825em 0 -.42em,-.173em -.812em 0 -.44em,-.256em -.789em 0 -.46em,-.297em -.775em 0 -.477em}20%{box-shadow:0 -.83em 0 -.4em,-.338em -.758em 0 -.42em,-.555em -.617em 0 -.44em,-.671em -.488em 0 -.46em,-.749em -.34em 0 -.477em}38%{box-shadow:0 -.83em 0 -.4em,-.377em -.74em 0 -.42em,-.645em -.522em 0 -.44em,-.775em -.297em 0 -.46em,-.82em -.09em 0 -.477em}to{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}}/*! rtl:end:ignore */._23GpA{width:0;height:0}[dir] ._23GpA{border-bottom:6px solid #fff}[dir=ltr] ._23GpA,[dir=rtl] ._23GpA{border-left:8px solid transparent;border-right:8px solid transparent}@media only screen and (max-width:640px){._23GpA{position:relative;top:-6px}}._3Ngo_{width:1px;height:6px}[dir] ._3Ngo_{background-color:#fff}[dir=ltr] ._3Ngo_{margin-left:8px}[dir=rtl] ._3Ngo_{margin-right:8px}@media only screen and (max-width:640px){._3Ngo_{width:2px;height:12px}[dir=ltr] ._3Ngo_{margin-left:7px}[dir=rtl] ._3Ngo_{margin-right:7px}}._1u5e1{width:13px;height:13px}[dir] ._1u5e1{border:1px solid #fff;border-radius:13px}._1Xape{position:relative}[dir=ltr] ._1Xape{transform:translateX(-8px) translateY(-8px)}[dir=rtl] ._1Xape{transform:translateX(8px) translateY(-8px)}._3Eiv5{position:absolute;top:0;width:1px;height:3px}[dir] ._3Eiv5{background:#fff}[dir=ltr] ._3Eiv5{left:7px}[dir=rtl] ._3Eiv5{right:7px}._3SF8y{position:absolute;bottom:0;width:1px;height:3px}[dir] ._3SF8y{background:#fff}[dir=ltr] ._3SF8y{left:7px}[dir=rtl] ._3SF8y{right:7px}._3kzJb{position:absolute;bottom:7px;width:3px;height:1px}[dir] ._3kzJb{background:#fff}[dir=ltr] ._3kzJb{left:0}[dir=rtl] ._3kzJb{right:0}._9Oyjo{position:absolute;bottom:7px;width:3px;height:1px}[dir] ._9Oyjo{background:#fff}[dir=ltr] ._9Oyjo{right:0}[dir=rtl] ._9Oyjo{left:0}._3Gbps{width:312px;height:136px}@media only screen and (max-width:640px){._3Gbps{width:100%}}.-njDt{width:100%;height:76px}.-njDt,._3bzhu{position:relative}._3bzhu{height:12px}[dir] ._3bzhu{margin-top:6px}[dir] ._2lVMt{padding-top:0}@media only screen and (max-width:640px){[dir] ._2lVMt{padding-top:9px;padding-bottom:17px}}._3RtWS{font-size:14px;color:#333;width:auto;display:inline-block}[dir=ltr] ._3RtWS{margin-right:5px}[dir=rtl] ._3RtWS{margin-left:5px}._28c3E{font-size:14px;color:#333;width:64px;display:inline-block}[dir] ._28c3E:hover{border-bottom:1px solid #b5d1ff}[dir] ._28c3E:focus-within{border-bottom:1px solid #0261ff}._1OP8m{z-index:1}._1OP8m:not(._38iML){float:left;margin-right:40px;margin-left:0}@media only screen and (max-width:640px){._1OP8m:not(._38iML){margin-right:0}}._1aaGk{z-index:1}._1aaGk:not(._38iML){float:right;margin-left:40px;margin-right:0}@media only screen and (max-width:640px){._1aaGk:not(._38iML){margin-left:0}}._1O2_H{display:block}._1O2_H:not(._38iML):not(._22Rvh){margin-left:auto;margin-right:auto;max-width:100%}._22Rvh,._38iML{width:100%}._3MfUJ:not(._38iML){max-width:100%;margin-left:auto;margin-right:auto}._1YxDs:not(._38iML){width:350px}._3JRXG:not(._38iML){width:350px;margin-left:auto;margin-right:auto}._2cI4x{display:flex}._3p4q0{position:relative}[dir] ._3p4q0{margin:0}[dir] .iptKO.g6GEm:after{border-color:#000}._3v3Y5{height:1px;width:auto}[dir] ._3v3Y5{border:none;background:rgba(51,51,51,.1);margin:0 12px 10px}@media only screen and (max-width:640px){[dir] ._3v3Y5{margin:22px 0 0}}._3e3Bs,.amIGO,.iptKO{position:relative;flex:none;width:18px;height:18px;outline:0}[dir] ._3e3Bs,[dir] .amIGO,[dir] .iptKO{margin-top:12px;cursor:pointer;padding:0}[dir=ltr] ._3e3Bs,[dir=ltr] .amIGO,[dir=ltr] .iptKO{margin-left:12px}[dir=rtl] ._3e3Bs,[dir=rtl] .amIGO,[dir=rtl] .iptKO{margin-right:12px}@media only screen and (max-width:640px){[dir] ._3e3Bs,[dir] .amIGO,[dir] .iptKO{margin-top:22px}[dir=ltr] ._3e3Bs,[dir=ltr] .amIGO,[dir=ltr] .iptKO{margin-left:calc((100% - 108px)/ 5)}[dir=rtl] ._3e3Bs,[dir=rtl] .amIGO,[dir=rtl] .iptKO{margin-right:calc((100% - 108px)/ 5)}[dir=ltr] ._3e3Bs:nth-child(6n+1),[dir=ltr] .amIGO:nth-child(6n+1),[dir=ltr] .iptKO:nth-child(6n+1){margin-left:0}[dir=rtl] ._3e3Bs:nth-child(6n+1),[dir=rtl] .amIGO:nth-child(6n+1),[dir=rtl] .iptKO:nth-child(6n+1){margin-right:0}}[dir] .iptKO{border-radius:50%;border:1px solid #ccc}.iptKO:after{content:" ";width:22px;height:22px;display:block;position:absolute;top:-4px;outline:0}[dir] .iptKO:after{border-radius:50%;background:0 0;border:1px solid transparent}[dir=ltr] .iptKO:after{left:-4px}[dir=rtl] .iptKO:after{right:-4px}.iptKO:active,.iptKO:focus,.iptKO:hover{outline:0}[dir] .iptKO:not(.g6GEm):focus:after{border-color:#ccc}._3cZAA{width:auto}[dir] ._3cZAA{margin:12px}@media only screen and (max-width:640px){[dir] ._3cZAA{margin:0 18px 24px}}._3e3Bs{display:inline-block;vertical-align:top;top:-2px}[dir] ._3e3Bs{margin-top:5px}[dir=ltr] ._3e3Bs{left:65%}[dir=rtl] ._3e3Bs{right:65%}@media only screen and (max-width:640px){[dir=ltr] ._3e3Bs{left:75%}[dir=rtl] ._3e3Bs{right:75%}}._2Q2Vw{width:18px;height:18px;color:#0261ff;position:relative}[dir] ._2Q2Vw{cursor:pointer}._3cnCX{flex-direction:row;display:flex;flex-wrap:wrap;width:180px}[dir] ._3cnCX{margin-bottom:18px}@media only screen and (max-width:640px){._3cnCX{width:100%}}._26YpN{position:absolute;opacity:0;width:.1px;height:.1px;overflow:hidden;z-index:-1}.amIGO{display:inline-block;vertical-align:top}[dir] .amIGO{margin-top:5px}._1f4K9{font-size:14px;font-stretch:normal;font-style:normal;font-weight:300;line-height:1.5;letter-spacing:normal;color:#0261ff;position:fixed}[dir] ._1f4K9{cursor:pointer}.sUglZ{font-family:HelveticaNeue;color:#000;position:relative;width:502px;min-width:360px;height:372px;font-size:14px;font-weight:300;font-stretch:normal;font-style:normal}[dir] .sUglZ{margin-top:18px}.wX2-G{font-family:HelveticaNeue;color:#000;font-size:14px;font-weight:300;font-stretch:normal;font-style:normal;position:absolute;top:0;bottom:0;min-width:0;width:auto;height:auto}[dir] .wX2-G{margin:0}[dir=ltr] .wX2-G,[dir=rtl] .wX2-G{right:0;left:0}._2FDZ5{display:flex;height:279px}._1uaGX{display:flex;height:calc(100% - 217px)}[dir] ._1uaGX{padding:0 18px}._2N9bw{width:100%}[dir=ltr] ._2N9bw{margin:14px 0 0 20px}[dir=rtl] ._2N9bw{margin:14px 20px 0 0}._1InRm{width:100%}[dir] ._1InRm{margin:8px 0 0}[dir] ._3rVb8{margin:0 -19px;border-bottom:1px solid rgba(51,51,51,.1)}._10GFo{display:flex;justify-content:space-between}[dir] ._10GFo{padding:12px 23px 14px}[dir] ._10GFo._2B0un{padding:12px 0 16px}[dir] ._10GFo._3hthY{padding:12px 18px 14px}[dir] ._10GFo._3hthY._2B0un{background-color:#0060ff;padding:10px}._1b--s,._2Ss-9,.eL-lj{display:flex}.eL-lj{line-height:1.5;font-size:14px;align-items:center}[dir] .eL-lj{border:none;background-color:transparent;cursor:pointer}.eL-lj._3AEIW._17Bs6{color:#fff}._2PU9L{height:auto}[dir=ltr] ._2PU9L{margin:0 0 0 20px;border-right:1px solid rgba(51,51,51,.1)}[dir=rtl] ._2PU9L{margin:0 20px 0 0;border-left:1px solid rgba(51,51,51,.1)}[dir] ._2PU9L.k-J0p{margin:0 13px}[dir] ._2PU9L._3LvPC{margin:0 20px}[dir=ltr] ._2PU9L._3LvPC._1i3bU{border-right:1px solid #fff}[dir=rtl] ._2PU9L._3LvPC._1i3bU{border-left:1px solid #fff}.qyfdD{opacity:.4}[dir] .qyfdD{cursor:default}._3TDkh{color:#0261ff}.HIQ2R{font-size:16px;line-height:1.5}[dir] .HIQ2R{margin-top:2px;margin-bottom:16px}.vdJUk{font-size:16px;line-height:1.5;display:flex;align-items:center;justify-content:center}[dir] .vdJUk{margin-top:28px;margin-bottom:24px;text-align:center}._1Dhbv{width:19px;height:19px}[dir=ltr] ._1Dhbv{margin-right:11px}[dir=rtl] ._1Dhbv{margin-left:11px}._33KtJ{display:flex;flex-direction:column;height:-webkit-fit-content;height:-moz-fit-content;height:fit-content}[dir] ._33KtJ{margin-top:20px}._33KtJ label{font-size:16px;line-height:1.5;width:-webkit-max-content;width:-moz-max-content;width:max-content;display:inline-flex;align-items:center}[dir] ._33KtJ label{margin-bottom:14px}._33KtJ span{vertical-align:text-bottom}._3zLA3{display:flex}[dir] ._3zLA3{border-bottom:1px solid #dcdcdc;margin-bottom:12px}._3zLA3 ._18Xyq{display:flex;height:30px;width:100%;justify-content:center;align-items:center}[dir] ._3zLA3 ._18Xyq{padding-bottom:8px}[dir] ._3zLA3 ._18Xyq:hover{cursor:pointer}._3zLA3 ._1mMrL{color:#0261ff}[dir] ._3zLA3 ._1mMrL{border-bottom:2px solid #0261ff}.ZXLEP{min-height:50px;top:var(--offset-top);position:absolute;z-index:4;max-width:100%;transition:transform .15s cubic-bezier(.3,1.2,.2,1)}[dir] .ZXLEP{transform:scale(0);border:1px solid #ddd;background:#fff;border-radius:6px}[dir=ltr] .ZXLEP{left:var(--offset-left);direction:ltr}[dir=rtl] .ZXLEP{right:var(--offset-left);direction:rtl}.bB8Oi{display:flex;height:48px}[dir] .bB8Oi{padding:0 19px}.bB8Oi::-webkit-scrollbar{display:none;width:0!important}.OZk0e{display:flex;justify-content:center}[dir] .OZk0e{margin-top:-8px}[dir] .EWMok{padding:0 24px;border-top:1px solid hsla(0,0%,45.9%,.2)}._3RXzS{height:auto}[dir] ._3RXzS{padding:0}._3AATV{display:none;flex:0 0 24px}._2OJH9{flex:0 0 40px;height:100%}[dir] ._2OJH9{background:0 0;cursor:pointer;border:none}[dir=ltr] ._2OJH9{margin-right:-19px;border-left:1px solid #ededed}[dir=rtl] ._2OJH9{margin-left:-19px;border-right:1px solid #ededed}._2OJH9>i{display:inline-block;width:6px;height:6px}[dir] ._2OJH9>i{border:1px solid #333}[dir=ltr] ._2OJH9>i{border-width:0 0 1px 1px}[dir=rtl] ._2OJH9>i{border-width:0 1px 1px 0}[dir=ltr] ._1S8-r{right:0;border-left:1px solid #ededed;border-radius:0 6px 6px 0}[dir=rtl] ._1S8-r{left:0;border-right:1px solid #ededed;border-radius:6px 0 0 6px}[dir=ltr] ._1p7AC{margin-right:3px;transform:rotate(45deg)}[dir=rtl] ._1p7AC{margin-left:3px;transform:rotate(-45deg)}[dir=ltr] ._29bKz{right:0;border-left:1px solid #ededed;border-radius:0 6px 6px 0}[dir=rtl] ._29bKz{left:0;border-right:1px solid #ededed;border-radius:6px 0 0 6px}[dir=ltr] ._29UpS{margin-right:3px;transform:rotate(225deg)}[dir=rtl] ._29UpS{margin-left:3px;transform:rotate(-225deg)}@media only screen and (max-width:640px){.bB8Oi{display:flex;width:auto;max-width:100%;overflow-x:scroll;scroll-behavior:smooth;-webkit-overflow-scrolling:auto}.bB8Oi ._2OJH9,.bB8Oi ._3AATV{display:block}}.lm8wE{display:flex;align-items:center;height:auto;overflow:hidden;width:100%;pointer-events:none;scroll-behavior:smooth;-webkit-overflow-scrolling:auto}[dir] .lm8wE{padding:90px 0;margin:-90px 0}.lm8wE>*{pointer-events:auto}.lm8wE::-webkit-scrollbar{display:none;width:0!important}._2IZRz{width:270px}._1os_f{width:auto}[dir] ._1os_f{margin:24px 24px 15px}@media only screen and (max-width:640px){[dir] ._1os_f{margin:27px 18px 15px}}.lRdrZ{outline:0;line-height:1.5;font-size:14px;font-weight:300;flex:none}[dir] .lRdrZ{border:none;background:0 0;cursor:pointer;padding:0}._22niK{color:#0261ff}._2l1Z4{display:flex;justify-content:space-between}._2ubBe{height:1px;width:100%}[dir] ._2ubBe{border:none;background:rgba(51,51,51,.1)}._3Sz7Z{width:100%;font-size:14px;font-weight:300;font-style:normal;font-stretch:normal;line-height:1.5;letter-spacing:normal}[dir] ._3Sz7Z{margin:14px 1px 0}[dir=ltr] ._3Sz7Z{text-align:left}[dir=rtl] ._3Sz7Z{text-align:right}._1s_6K{display:flex}[dir=ltr] ._1s_6K{padding:4px 4px 4px 20px}[dir=rtl] ._1s_6K{padding:4px 20px 4px 4px}[dir] ._1s_6K:hover{cursor:pointer;background-color:rgba(0,0,0,.05)}[dir] ._1s_6K.brSEV{background-color:rgba(0,0,0,.1)}._1s_6K .LlctV{width:50px;height:50px;display:flex;justify-content:center;align-items:center}[dir] ._1s_6K .LlctV{background-color:#fff;border:1px solid #d3d3d3}._1s_6K ._dAhM{width:inherit;height:inherit;object-fit:cover;display:none}._1s_6K ._1L9EG{display:flex;flex-direction:column;justify-content:center}[dir=ltr] ._1s_6K ._1L9EG{margin-left:8px}[dir=rtl] ._1s_6K ._1L9EG{margin-right:8px}._1s_6K ._1L9EG .aVqFB{opacity:.4;font-size:12px;line-height:1.33}._1s_6K ._1L9EG ._1oxFO{font-size:14px;line-height:1.43;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:210px}._2w3HD{display:flex;justify-content:space-between;align-items:baseline}[dir=ltr] ._2w3HD{margin-left:20px}[dir=rtl] ._2w3HD{margin-right:20px}._2w3HD ._1wHqu{font-size:16px;line-height:1.5;opacity:.4}._2w3HD .D5xO6{font-size:14px;box-sizing:border-box;display:flex;align-items:center;height:38px}[dir=ltr] ._2w3HD .D5xO6{padding:0 30px 0 0!important}[dir=rtl] ._2w3HD .D5xO6{padding:0 0 0 30px!important}._2w3HD ._3yf0a{top:auto!important;position:absolute;max-height:204px}[dir=ltr] ._2w3HD ._3yf0a{right:-20px}[dir=rtl] ._2w3HD ._3yf0a{left:-20px}.E2Rzg{max-height:227px;overflow:auto}._3zdXj{font-size:14px}[dir] ._3zdXj{margin:6px}._2Y-Mj{display:flex;flex-flow:column;justify-content:center}[dir] ._2Y-Mj{margin:0 60px}._2Y-Mj ._1__B8{font-size:16px;line-height:1.5;align-self:center}[dir] ._2Y-Mj ._1__B8{text-align:center}._2Y-Mj ._2HCS2{opacity:.4;font-size:16px;line-height:1.5;align-self:center}[dir] ._2Y-Mj ._2HCS2{text-align:center}@media only screen and (max-width:640px){[dir] ._1s_6K{padding:4px}[dir] ._3Sz7Z{margin:10px 1px 0}[dir] ._2w3HD{margin-bottom:7px}[dir=ltr] ._2w3HD{margin-left:0}[dir=rtl] ._2w3HD{margin-right:0}._2Y-Mj{align-self:flex-start}[dir] ._2Y-Mj{margin:80px 35px 0}._2Y-Mj ._1__B8,._2Y-Mj ._2HCS2{font-size:14px}.E2Rzg{max-height:100%}}.aaTFO{display:inline-block}[dir] .aaTFO{padding:10px 0}[dir=ltr] .aaTFO{margin-right:10px}[dir=rtl] .aaTFO{margin-left:10px}[dir=ltr] .aaTFO:last-child{margin-right:0}[dir=rtl] .aaTFO:last-child{margin-left:0}.zXglG{display:inline-block;color:#333;line-height:normal;white-space:nowrap}[dir] .zXglG{background:0 0;padding:5px;border:none;cursor:pointer;margin:0}.zXglG .c5XOl{width:20px;height:20px;line-height:0}.zXglG .c5XOl svg{width:100%;height:100%;fill:currentColor}.zXglG:not(._2DPe5)._3_XwH,.zXglG:not(._2DPe5):focus,.zXglG:not(._2DPe5):hover{color:#0261ff}.zXglG:not(._2DPe5)._3_XwH svg,.zXglG:not(._2DPe5):focus svg,.zXglG:not(._2DPe5):hover svg{fill:currentColor}.zXglG._2DPe5{opacity:.4}[dir] .zXglG._2DPe5{cursor:default}.HLEuq{display:inline-block;position:relative}._1l5fY{display:flex;flex-direction:column;position:absolute;top:0;z-index:10}._Yk_L{display:flex;overflow:auto;justify-items:center;justify-content:center;height:-webkit-max-content;height:-moz-max-content;height:max-content;max-height:400px}[dir] ._Yk_L{padding:0 12px}[dir] ._Yk_L._3zcLi{padding:6px}._Yk_L ._19nme{width:100%}._Yk_L ._3cYau{position:absolute;width:100%;align-self:start;z-index:3}[dir] ._Yk_L ._3cYau{background-color:#fff;padding:12px}@media only screen and (max-width:640px){[dir] ._Yk_L ._3cYau{padding:0}}._Yk_L ._1Y7TI,._Yk_L ._3emvm{color:#000}._Yk_L ._1Y7TI{font-size:14px;white-space:pre;letter-spacing:1px;display:flex;height:100%;justify-content:center;align-items:center}[dir] ._Yk_L ._1Y7TI{text-align:center}[dir] ._Yk_L ._5VaM-{padding-top:52px}._Yk_L ._3emvm{height:28px;align-items:center;display:flex;justify-content:center;font-size:14px;line-height:20px}[dir] ._Yk_L ._3emvm{background-color:rgba(0,0,0,.06)}._Yk_L ._238fN{display:grid;grid-row-gap:12px}[dir] ._Yk_L ._238fN{padding-top:12px}[dir] ._Yk_L ._238fN._3zcLi{padding-top:0}._Yk_L ._9iWn5{display:grid;justify-items:center;grid-row-gap:12px;grid-auto-rows:72px;grid-template-columns:98px 98px 98px;align-items:center}._Yk_L ._9iWn5._3zcLi{display:flex}@media only screen and (max-width:640px){._Yk_L ._9iWn5{grid-row-gap:8px;width:100%;grid-template-columns:repeat(3,1fr)}[dir] ._Yk_L ._9iWn5{margin-top:0}}._Yk_L ._9iWn5 ._1cmF8{display:flex;width:100%;height:100%;justify-content:center}[dir] ._Yk_L ._9iWn5 ._1cmF8{text-align:center;cursor:pointer}._Yk_L ._9iWn5 ._1cmF8._3zcLi{height:38px}._Yk_L ._9iWn5 ._1cmF8 ._1Q9IW{font-size:12px;line-height:16px;color:#000}[dir] ._Yk_L ._9iWn5 ._1cmF8:hover{background-color:rgba(0,0,0,.06)}._1idAv{/*!rtl:begin:ignore*//*!rtl:end:ignore*/}._1idAv,._1idAv>*{text-align:left!important}._21OX4{/*!rtl:begin:ignore*//*!rtl:end:ignore*/}._21OX4,._21OX4>*{text-align:center!important}._3n_Yy{/*!rtl:begin:ignore*//*!rtl:end:ignore*/}._3n_Yy,._3n_Yy>*{text-align:right!important}.public-DraftStyleDefault-ltr{/*!rtl:begin:ignore*/direction:ltr/*!rtl:end:ignore*/}.public-DraftStyleDefault-rtl{/*!rtl:begin:ignore*/direction:rtl/*!rtl:end:ignore*/}.public-DraftStyleDefault-block-depth1.public-DraftStyleDefault-text-ltr{/*!rtl:begin:ignore*/margin-left:1.5em!important/*!rtl:end:ignore*/}.public-DraftStyleDefault-block-depth1.public-DraftStyleDefault-text-rtl{/*!rtl:begin:ignore*/margin-right:1.5em!important/*!rtl:end:ignore*/}.public-DraftStyleDefault-block-depth2.public-DraftStyleDefault-text-ltr{/*!rtl:begin:ignore*/margin-left:3em!important/*!rtl:end:ignore*/}.public-DraftStyleDefault-block-depth2.public-DraftStyleDefault-text-rtl{/*!rtl:begin:ignore*/margin-right:3em!important/*!rtl:end:ignore*/}.public-DraftStyleDefault-block-depth3.public-DraftStyleDefault-text-ltr{/*!rtl:begin:ignore*/margin-left:4.5em!important/*!rtl:end:ignore*/}.public-DraftStyleDefault-block-depth3.public-DraftStyleDefault-text-rtl{/*!rtl:begin:ignore*/margin-right:4.5em!important/*!rtl:end:ignore*/}.public-DraftStyleDefault-block-depth4.public-DraftStyleDefault-text-ltr{/*!rtl:begin:ignore*/margin-left:6em!important/*!rtl:end:ignore*/}.public-DraftStyleDefault-block-depth4.public-DraftStyleDefault-text-rtl{/*!rtl:begin:ignore*/margin-right:6em!important/*!rtl:end:ignore*/}.public-DraftStyleDefault-list-ltr{/*!rtl:begin:ignore*/direction:ltr;text-align:left/*!rtl:end:ignore*/}.public-DraftStyleDefault-list-rtl{/*!rtl:begin:ignore*/direction:rtl;text-align:right/*!rtl:end:ignore*/}.public-DraftStyleDefault-depth0.public-DraftStyleDefault-list-ltr{/*!rtl:begin:ignore*/margin-left:3em/*!rtl:end:ignore*/}.public-DraftStyleDefault-depth0.public-DraftStyleDefault-list-rtl{/*!rtl:begin:ignore*/margin-right:3em/*!rtl:end:ignore*/}.public-DraftStyleDefault-depth1.public-DraftStyleDefault-list-ltr{/*!rtl:begin:ignore*/margin-left:4.5em/*!rtl:end:ignore*/}.public-DraftStyleDefault-depth1.public-DraftStyleDefault-list-rtl{/*!rtl:begin:ignore*/margin-right:4.5em/*!rtl:end:ignore*/}.public-DraftStyleDefault-depth2.public-DraftStyleDefault-list-ltr{/*!rtl:begin:ignore*/margin-left:6em/*!rtl:end:ignore*/}.public-DraftStyleDefault-depth2.public-DraftStyleDefault-list-rtl{/*!rtl:begin:ignore*/margin-right:6em/*!rtl:end:ignore*/}.public-DraftStyleDefault-depth3.public-DraftStyleDefault-list-ltr{/*!rtl:begin:ignore*/margin-left:7.5em/*!rtl:end:ignore*/}.public-DraftStyleDefault-depth3.public-DraftStyleDefault-list-rtl{/*!rtl:begin:ignore*/margin-right:7.5em/*!rtl:end:ignore*/}.public-DraftStyleDefault-depth4.public-DraftStyleDefault-list-ltr{/*!rtl:begin:ignore*/margin-left:9em/*!rtl:end:ignore*/}.public-DraftStyleDefault-depth4.public-DraftStyleDefault-list-rtl{/*!rtl:begin:ignore*/margin-right:9em/*!rtl:end:ignore*/}.public-DraftStyleDefault-unorderedListItem{/*!rtl:begin:ignore*/list-style-type:square;position:relative/*!rtl:end:ignore*/}.public-DraftStyleDefault-unorderedListItem.public-DraftStyleDefault-depth0{/*!rtl:begin:ignore*/list-style-type:disc/*!rtl:end:ignore*/}.public-DraftStyleDefault-unorderedListItem.public-DraftStyleDefault-depth1{/*!rtl:begin:ignore*/list-style-type:circle/*!rtl:end:ignore*/}.public-DraftStyleDefault-orderedListItem{/*!rtl:begin:ignore*/list-style-type:none;position:relative/*!rtl:end:ignore*/}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-list-ltr:before{/*!rtl:begin:ignore*/position:absolute;margin-left:-1.5em/*!rtl:end:ignore*/}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-list-rtl:before{/*!rtl:begin:ignore*/position:absolute;margin-right:-1.5em/*!rtl:end:ignore*/}.public-DraftStyleDefault-orderedListItem:before{/*!rtl:begin:ignore*/content:counter(ol0) ". ";counter-increment:ol0/*!rtl:end:ignore*/}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-depth1:before{/*!rtl:begin:ignore*/content:counter(ol1,lower-alpha) ". ";counter-increment:ol1/*!rtl:end:ignore*/}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-depth2:before{/*!rtl:begin:ignore*/content:counter(ol2,lower-roman) ". ";counter-increment:ol2/*!rtl:end:ignore*/}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-depth3:before{/*!rtl:begin:ignore*/content:counter(ol3) ". ";counter-increment:ol3/*!rtl:end:ignore*/}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-depth4:before{/*!rtl:begin:ignore*/content:counter(ol4,lower-alpha) ". ";counter-increment:ol4/*!rtl:end:ignore*/}.public-DraftStyleDefault-depth0.public-DraftStyleDefault-reset{/*!rtl:begin:ignore*/counter-reset:ol0/*!rtl:end:ignore*/}.public-DraftStyleDefault-depth1.public-DraftStyleDefault-reset{/*!rtl:begin:ignore*/counter-reset:ol1/*!rtl:end:ignore*/}.public-DraftStyleDefault-depth2.public-DraftStyleDefault-reset{/*!rtl:begin:ignore*/counter-reset:ol2/*!rtl:end:ignore*/}.public-DraftStyleDefault-depth3.public-DraftStyleDefault-reset{/*!rtl:begin:ignore*/counter-reset:ol3/*!rtl:end:ignore*/}.public-DraftStyleDefault-depth4.public-DraftStyleDefault-reset{/*!rtl:begin:ignore*/counter-reset:ol4/*!rtl:end:ignore*/}.public-DraftStyleDefault-ol,.public-DraftStyleDefault-ul{/*!rtl:begin:ignore*/margin:0;padding:0;outline:0/*!rtl:end:ignore*/}._2PdJ9[data-focus=true]:after,._3PaWO[data-focus=true]:before{content:"";border-radius:50%;width:14px;height:14px;z-index:1;background:#fff;border:2px solid #3899ec;position:absolute;top:calc(50% - 7px)}/*!rtl:ignore*/[data-focus=true]._3PaWO:before{right:-8px}/*!rtl:ignore*/[data-focus=true]._2PdJ9:after{left:-8px}._2p1n_{position:relative}[dir] ._2p1n_{padding:10px 0}[dir=ltr] ._2p1n_{margin-right:10px}[dir=rtl] ._2p1n_{margin-left:10px}._2bRDr{position:absolute;top:10px}[dir] ._2bRDr{padding:0 3px;background:#fff;box-shadow:0 4px 8px 0 rgba(0,0,0,.1),0 0 4px 0 rgba(0,0,0,.1)}[dir=ltr] ._2bRDr{left:-3px}[dir=rtl] ._2bRDr{right:-3px}[dir] .MytZM{padding:0!important}[dir=ltr] .MytZM{margin-right:0!important}[dir=rtl] .MytZM{margin-left:0!important}._216Ce,._3qjP5{outline:0}[dir].QiJxn .DraftEditor-editorContainer,[dir].QiJxn .DraftEditor-root,[dir].QiJxn .public-DraftEditor-content{height:inherit;text-align:left;text-align:initial}[dir].QiJxn .public-DraftEditorPlaceholder-root{color:#9197a3;position:absolute;direction:ltr}[dir].QiJxn .public-DraftEditor-content[contenteditable=true]{-webkit-user-modify:read-write-plaintext-only}[dir].QiJxn .DraftEditor-root{position:relative}[dir].QiJxn .DraftEditor-alignLeft .public-DraftStyleDefault-block{/*!rtl:begin:ignore*/text-align:left/*!rtl:end:ignore*/}[dir].QiJxn .DraftEditor-alignLeft .public-DraftEditorPlaceholder-root{/*!rtl:begin:ignore*/left:0;text-align:left/*!rtl:end:ignore*/}[dir].QiJxn .DraftEditor-alignCenter .public-DraftStyleDefault-block{text-align:center}[dir].QiJxn .DraftEditor-alignCenter .public-DraftEditorPlaceholder-root{margin:0 auto;text-align:center;width:100%}[dir].QiJxn .DraftEditor-alignRight .public-DraftStyleDefault-block{/*!rtl:begin:ignore*/text-align:right/*!rtl:end:ignore*/}[dir].QiJxn .DraftEditor-alignRight .public-DraftEditorPlaceholder-root{/*!rtl:begin:ignore*/right:0;text-align:right/*!rtl:end:ignore*/}[dir].QiJxn .public-DraftStyleDefault-block{position:relative;white-space:pre-wrap}@media only screen and (max-width:640px){[dir].QiJxn .public-DraftStyleDefault-block{margin-right:10px}}._3gq3m{width:100%;z-index:2;position:relative}[dir] ._3gq3m{background:#fff;border-top:1px solid #ddd;border-bottom:1px solid #ddd;border-radius:2px}[dir=ltr] ._3gq3m{margin-right:auto;margin-left:auto;direction:ltr}[dir=rtl] ._3gq3m{margin-left:auto;margin-right:auto;direction:rtl}._1R64m{display:flex;align-items:center;height:100%;overflow:hidden;scroll-behavior:smooth}[dir] ._1R64m{padding:90px 9px}._1R64m.Ynekp{overflow-x:scroll;-webkit-overflow-scrolling:touch;width:100%}[dir] ._1R64m.Ynekp{padding:0 9px;transform:translateZ(0)}._1R64m::-webkit-scrollbar{display:none;width:0!important}._3v2NX{display:flex;height:50px;max-width:100%;align-items:center}._1O9k1{flex:0 0 40px;height:100%}[dir] ._1O9k1{margin:auto;background:0 0;cursor:pointer;border:none}[dir=ltr] ._1O9k1{border-left:1px solid #ededed;border-right:none}[dir=rtl] ._1O9k1{border-right:1px solid #ededed;border-left:none}._1O9k1>i{display:inline-block;width:6px;height:6px}[dir] ._1O9k1>i{border:1px solid #333}[dir=ltr] ._1O9k1>i{border-width:0 0 1px 1px}[dir=rtl] ._1O9k1>i{border-width:0 1px 1px 0}[dir=ltr] ._1CiRG{margin-right:-3px;transform:rotate(45deg)}[dir=rtl] ._1CiRG{margin-left:-3px;transform:rotate(-45deg)}[dir=ltr] ._3KVM5{margin-right:3px;transform:rotate(225deg)}[dir=rtl] ._3KVM5{margin-left:3px;transform:rotate(-225deg)}._3wCla{outline:0}._1RMoq{position:-webkit-sticky;position:sticky;top:0;z-index:2}.J-smu{height:100%}._30_nC{position:relative}[dir] ._30_nC{border:1px solid #ddd}.Bvr-H{width:100%;pointer-events:none}[dir] .Bvr-H{padding:90px 0;margin:-90px 0}[dir=ltr] .Bvr-H{margin-left:15px}[dir=rtl] .Bvr-H{margin-right:15px}.Bvr-H>*{pointer-events:auto}._2jHVo{position:relative}[dir] ._2jHVo{border-bottom:1px solid hsla(0,0%,45.9%,.2)}[dir] ._35q1X{margin:0 9px}.h9v9v{flex:0 0 12vw}[dir] .h9v9v{text-align:center;padding:0!important}[dir=ltr] .h9v9v{margin-right:0!important}[dir=rtl] .h9v9v{margin-left:0!important}._1CJem{width:100%;height:100%}[dir] ._1CJem{padding:5px 0}[dir] ._3sFFK{padding-top:5px}[dir] ._3Xm-h{margin:0 auto}.Uw7ze{position:absolute;z-index:3;pointer-events:none}.tfFfS{height:52px}[dir] .tfFfS{margin-top:60px}._2E527{height:100%;overflow:visible;overflow:initial;width:-webkit-max-content;width:-moz-max-content;width:max-content}[dir] ._2E527{padding:0}._18O3S{width:100%;pointer-events:none}[dir] ._18O3S{margin:-90px 0}._18O3S>*{pointer-events:auto}[dir=ltr] ._18O3S>div{margin-right:5px}[dir=rtl] ._18O3S>div{margin-left:5px}._1guAn{position:relative;pointer-events:none}._210ya{height:25px;width:25px;line-height:normal;color:#757575;pointer-events:auto}[dir] ._210ya{border:none;background-color:transparent;padding:0;cursor:pointer;text-align:center}._210ya:hover{color:#0261ff}._20iMo{position:absolute;white-space:nowrap;width:320px;max-height:400px;display:grid;pointer-events:auto;overflow:hidden}[dir] ._20iMo{border:1px solid #ededed;background:#fff;border-radius:2px;box-shadow:0 4px 8px 0 rgba(123,99,99,.1),0 0 4px 0 rgba(0,0,0,.1)}[dir=ltr] ._20iMo{transform:translate(-50%)}[dir=rtl] ._20iMo{transform:translate(50%)}.QGwpa{display:flex;width:-webkit-max-content;width:-moz-max-content;width:max-content}[dir] .QGwpa{padding:10px 0}[dir=ltr] .QGwpa{margin-right:10px}[dir=rtl] .QGwpa{margin-left:10px}[dir=ltr] .QGwpa:last-child{margin-right:0}[dir=rtl] .QGwpa:last-child{margin-left:0}._3zx08{color:#333;line-height:normal}[dir] ._3zx08{background:0 0;padding:5px;border:0;cursor:pointer}._3zx08:focus,._3zx08:hover{outline:0;color:#0261ff}._3zx08:disabled{opacity:.4}[dir] ._3zx08:disabled{cursor:default}._2Dg1H{width:20px;height:20px;vertical-align:middle}._2Dg1H svg{width:100%;height:100%;fill:currentColor}._2Dg1H:hover,._2SD0p{color:#0261ff}._2Dg1H:hover svg,._2SD0p svg{fill:currentColor}._1rhR-{width:-webkit-max-content!important;width:-moz-max-content!important;width:max-content!important;display:flex;font-size:14px;font-family:Helvetica;font-weight:500}[dir] ._1rhR-{margin:0 10px!important}._2UFYx{position:relative;top:1px}[dir=ltr] ._2UFYx{left:7px}[dir=rtl] ._2UFYx{right:7px}._2UFYx svg{width:16px;height:16px}.IFNRg{top:-2px}[dir=ltr] .IFNRg{transform:rotate(180deg)}[dir=rtl] .IFNRg{transform:rotate(-180deg)}._3gNw0{min-height:50px;left:var(--offset-left);top:var(--offset-top);transform:scale(0);position:absolute;border:1px solid #ededed;background:#fff;border-radius:6px;z-index:4;max-width:100%;transition:transform .15s cubic-bezier(.3,1.2,.2,1);direction:ltr;box-shadow:0 4px 8px 0 rgba(123,99,99,.1),0 0 4px 0 rgba(0,0,0,.1)}.XRwO7{display:flex;height:50px}._2FzZ3{height:auto;padding:0}.kNBS9{display:flex;align-items:center;overflow:hidden;width:100%;padding:90px 19px;margin:-90px 0;pointer-events:none;scroll-behavior:smooth}.kNBS9._1rx-k,.kNBS9>*{pointer-events:auto}.kNBS9._1rx-k{padding:0 10px;margin:0;transform:translateZ(0);overflow-x:scroll;-webkit-overflow-scrolling:touch}.kNBS9::-webkit-scrollbar{display:none;width:0!important}.IkLgS{border-top:1px solid #ededed}@media only screen and (max-width:640px){.XRwO7{display:flex;width:auto;max-width:100%}.XRwO7 .vPypx{display:block}.XRwO7 ._1T4Oc{display:block;height:49px}}._1b9WG{display:flex}._3r7BO{display:absolute;top:0}[dir=ltr] ._3r7BO{left:0}[dir=rtl] ._3r7BO{right:0}._3_54f{width:.1px;height:.1px;overflow:hidden;position:absolute;opacity:0;z-index:-1}[dir] ._9yezB{cursor:default;box-shadow:0 0 0 3px #0261ff}._3lmrY{display:block;width:100%;height:100%;position:absolute;top:0}[dir] ._3lmrY{cursor:move}[dir=ltr] ._3lmrY{left:0}[dir=rtl] ._3lmrY{right:0}._1I01k{display:none}._1HLi3,._3NnBy{position:relative}[dir] ._3NnBy:hover{cursor:default;box-shadow:0 0 0 3px #0261ff}._2WM_0{max-width:100%}._1E2rR{position:absolute;display:flex;color:#757575}[dir] ._1E2rR{padding:12px 24px;background:#fff;border:1px solid #ddd;border-radius:6px}[dir=ltr] ._1E2rR{box-shadow:1px 1px 3px 1px #dcdcdc}[dir=rtl] ._1E2rR{box-shadow:-1px 1px 3px 1px #dcdcdc}.ReactModal__Body--open{overflow-y:hidden}.ReactModal__Content{font-weight:300}[dir=ltr] .ReactModal__Content{direction:ltr}[dir=rtl] .ReactModal__Content{direction:rtl}.sao9C{text-decoration:none;color:#333}.p2mZq{display:block}._3EZUP{vertical-align:text-bottom;height:17px}[dir] ._3EZUP{padding-top:2px}._3EZUP:hover{color:#0161ff}.mwBaK{display:flex}[dir] .mwBaK{cursor:pointer}.LG3cc,.ReactModalPortal,._1E2rR,._1HLi3,._2X1ls,._3NnBy,.glob_fontElementMap{font-family:Helvetica}.LG3cc{position:relative;height:100%;box-sizing:border-box;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.LG3cc *{-webkit-tap-highlight-color:transparent}.LG3cc .Tux6h{box-sizing:border-box}.LG3cc .Tux6h *,.LG3cc .Tux6h :after,.LG3cc .Tux6h :before{box-sizing:inherit}.LG3cc .Tux6h input{box-sizing:border-box}.LG3cc._1LOTO .Tux6h .DraftEditor-root:after{content:"";display:table}[dir] .LG3cc._1LOTO .Tux6h .DraftEditor-root:after{clear:both}[dir] .LG3cc._1LOTO .Tux6h .public-DraftEditorPlaceholder-root{margin:0}.Tux6h{display:flex;flex-direction:column;width:100%;height:100%;line-height:1.5;font-size:16px;color:#212121}.Tux6h:after{content:"";display:table}[dir] .Tux6h:after{clear:both}[dir] ._3Ecss{margin:2px 0}[dir] ._1g9ew,[dir] ._3Bzge+._3Bzge{margin-top:20px}[dir] ._2hXa7{margin:0}@media only screen and (max-width:640px){[dir] ._2hXa7{margin:0}}[dir] .j7VHc{margin:15px 18px}@media only screen and (max-width:640px){[dir] .j7VHc{margin:15px calc(18px + 5%)}}.jwLWP:empty{height:24px}.c1DFJ>*{white-space:pre-line!important}[dir] .c1DFJ>*{text-align:justify!important}.pjZF7{font-size:18px;line-height:26px;font-style:normal}[dir=ltr] .pjZF7{border-left-width:3px;border-left-style:solid;padding:6px 0 6px 18px}[dir=rtl] .pjZF7{border-right-width:3px;border-right-style:solid;padding:6px 18px 6px 0}._1pddf,._34qUI,._6PM_v{font:inherit}._34qUI{font-size:32px;line-height:42px}._6PM_v{font-size:28px;line-height:36px}._1pddf{font-size:22px;line-height:30px}._2b0WX,.yFBFi{font-family:Inconsolata,Menlo,Consolas,monospace;font-size:16px;line-height:26px;white-space:pre-wrap}[dir] ._2b0WX,[dir] .yFBFi{background-color:rgba(0,0,0,.05);padding:2px 25px}[dir] ._20neQ{transform:translateZ(0)}._3GHWr{flex:0 0 40px;height:100%}[dir] ._3GHWr{background:0 0;cursor:pointer;border:none}[dir=ltr] ._3GHWr{border-left:1px solid #ededed}[dir=rtl] ._3GHWr{border-right:1px solid #ededed}._3GHWr>i{display:inline-block;width:6px;height:6px}[dir] ._3GHWr>i{border:1px solid #333}[dir=ltr] ._3GHWr>i{border-width:0 0 1px 1px}[dir=rtl] ._3GHWr>i{border-width:0 1px 1px 0}[dir=ltr] ._2HUZx{margin-right:-3px;transform:rotate(45deg)}[dir=rtl] ._2HUZx{margin-left:-3px;transform:rotate(-45deg)}[dir=ltr] ._3Tew2{margin-right:3px;transform:rotate(225deg)}[dir=rtl] ._3Tew2{margin-left:3px;transform:rotate(-225deg)}.Z6Qnx{position:absolute;bottom:42px;width:320px;height:-webkit-max-content;height:-moz-max-content;height:max-content}[dir] .Z6Qnx{box-shadow:0 4px 8px 0 rgba(123,99,99,.1),0 0 4px 0 rgba(0,0,0,.1);background-color:#fff}._3hJOy{line-height:1.19;font-size:16px;display:flex;align-items:center;height:100%;color:#757575}[dir] ._3hJOy{cursor:pointer;padding:24px}[dir=ltr] ._3hJOy{border-left:1px solid #ededed}[dir=rtl] ._3hJOy{border-right:1px solid #ededed}._3hJOy:focus,._3hJOy:hover{color:#0661ff}._3hJOy:focus svg,._3hJOy:hover svg{fill:currentColor}._3hJOy._34Bmm{color:#0661ff}[dir=ltr] ._3hJOy ._1KfQU{padding-left:4px}[dir=rtl] ._3hJOy ._1KfQU{padding-right:4px}._3hJOy ._2OGqm{display:flex}[dir] ._3hJOy ._2OGqm{padding-bottom:1px}._2qJYG{color:#0261ff;text-decoration:none}[dir] ._1A33_:hover{cursor:pointer}._2X50f{display:flex}[dir=ltr] ._2X50f{margin-right:5px}[dir=rtl] ._2X50f{margin-left:5px}._12uJp{color:#0261ff;max-width:270px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-decoration:none}._12uJp:hover{text-decoration:underline}[dir] ._3cwQn:hover{cursor:pointer}@media only screen and (max-width:640px){._12uJp{max-width:160px}}.JL0i_,._2jvNz,._2zczp,.vaDeC{color:#898ea4}._3YD8l{color:#5e6687}._2y2gw{opacity:.7}._17UJV,._2jzgH,._3iTB1{color:#c76b29}._175c5{color:#c08b30}.qPGXG{color:#3d8fd1}.L_xhj{color:#22a2c9}.f4dmX{color:#6679cc}._14kSf{color:#c76b29}._2IfOi .L_xhj,._2c7DC,._3zzFe .L_xhj,._7xxQw{color:#22a2c9}.Ib7s2,._1NfyJ,._1x_Jg,._2emAu,._3ovq0{color:#ac9739}._3FK1t,._3G_D2,._3Qvix{color:#22a2c9}._1o4GH,._3cFQ7{color:#3d8fd1}._1_xbf{text-decoration:line-through}.sjqYJ{text-decoration:none}[dir] .sjqYJ{border-bottom:1px dotted #202746}.dIwL7{font-style:italic}._1JU_M,._3bhqB{font-weight:700}._3bhqB{color:#c94922}[dir] ._7xxQw{cursor:help}._1fYLo{color:#0261ff;text-decoration:none}._2N2cN span:hover{text-decoration:underline}._2rx-f{display:flex;font-size:14px;display:grid;grid-template-columns:auto -webkit-max-content;grid-template-columns:auto max-content}._2rx-f .K816z{display:flex}._1lQvA,._1oKPh,.glob_fontElementMap{font-family:Helvetica}[dir] .rD74g{padding:18px 0 15px}[dir] ._1hETE{margin:18px 0 13px}.PFaF-{height:146px}._1nnIo{display:flex;justify-content:space-between}._1oKPh{height:21px;font-size:14px;font-weight:300;line-height:1.5}[dir] ._1oKPh{padding:0;border:0;background:0 0;cursor:pointer}._22bIa{color:#0261ff}._1X1Er{color:#333}._2GF6I{width:100%;height:100%;overflow:hidden}[dir] ._2GF6I{border:0}.hnvPV{position:relative;height:100%;width:100%}._2hG3Z{position:absolute;top:0;bottom:0}[dir] ._2hG3Z{background:rgba(51,51,51,.05)}[dir=ltr] ._2hG3Z,[dir=rtl] ._2hG3Z{right:0;left:0}body{background-color:hsla(0,0%,100%,.75)}.content-editor-container{padding:3.5rem 0 0 3rem;max-height:calc(300px - 3.5rem);overflow-x:hidden;overflow-y:auto}div.Tux6h{font-size:14px} -------------------------------------------------------------------------------- /content-editor/app/src/ContentEditor/js/content-editor-events.js: -------------------------------------------------------------------------------- 1 | function onLoadContent(content) { 2 | const event = new CustomEvent('onLoadContent', { detail: content }); 3 | window.dispatchEvent(event); 4 | } 5 | 6 | window.addEventListener('onContentChange', function (e) { 7 | const content = e.detail; 8 | Microsoft.Dynamics.NAV.InvokeExtensibilityMethod('OnContentChange', [content]) 9 | }); 10 | 11 | window.LoadContent = function (content) { 12 | if (JSON.stringify(content) == '{}') 13 | onLoadContent(null); 14 | else 15 | onLoadContent(content); 16 | } 17 | -------------------------------------------------------------------------------- /content-editor/app/src/CustomerCardExt.PageExt.al: -------------------------------------------------------------------------------- 1 | pageextension 50120 CustomerCardExt extends "Customer Card" 2 | { 3 | layout 4 | { 5 | addafter(General) 6 | { 7 | group(About) 8 | { 9 | Caption = 'About'; 10 | 11 | usercontrol("ContentEditor"; ContentEditor) 12 | { 13 | trigger OnContentChange(Content: JsonObject) 14 | var 15 | ContentText: Text; 16 | OStream: OutStream; 17 | begin 18 | Detail.CreateOutStream(OStream, TextEncoding::UTF8); 19 | Content.WriteTo(OStream); 20 | Modify(); 21 | end; 22 | } 23 | } 24 | group(Twitter) 25 | { 26 | Caption = 'Twitter'; 27 | 28 | usercontrol("Twitter ContentEditor"; ContentEditor) 29 | { 30 | trigger OnContentChange(Content: JsonObject) 31 | var 32 | ContentText: Text; 33 | OStream: OutStream; 34 | begin 35 | Twitter.CreateOutStream(OStream, TextEncoding::UTF8); 36 | Content.WriteTo(OStream); 37 | Modify(); 38 | end; 39 | } 40 | } 41 | } 42 | } 43 | 44 | trigger OnAfterGetCurrRecord() 45 | begin 46 | LoadAbout(); 47 | LoadTwitter(); 48 | end; 49 | 50 | local procedure LoadAbout() 51 | var 52 | JObject: JsonObject; 53 | IStream: InStream; 54 | begin 55 | CalcFields(Detail); 56 | if Detail.HasValue() then begin 57 | Detail.CreateInStream(IStream, TextEncoding::UTF8); 58 | JObject.ReadFrom(IStream); 59 | end; 60 | 61 | CurrPage.ContentEditor.LoadContent(JObject); 62 | end; 63 | 64 | local procedure LoadTwitter() 65 | var 66 | JObject: JsonObject; 67 | IStream: InStream; 68 | begin 69 | CalcFields(Twitter); 70 | if Twitter.HasValue() then begin 71 | Twitter.CreateInStream(IStream, TextEncoding::UTF8); 72 | JObject.ReadFrom(IStream); 73 | end; 74 | 75 | CurrPage."Twitter ContentEditor".LoadContent(JObject); 76 | end; 77 | } -------------------------------------------------------------------------------- /content-editor/app/src/CustomerDetail.TableExt.al: -------------------------------------------------------------------------------- 1 | tableextension 50100 "Customer Detail" extends Customer 2 | { 3 | fields 4 | { 5 | field(50000; Detail; Blob) 6 | { 7 | DataClassification = CustomerContent; 8 | } 9 | 10 | field(50001; Twitter; Blob) 11 | { 12 | DataClassification = CustomerContent; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /content-editor/media/content-editor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msnraju/control-add-in-samples/75f92ebc107e9cdc68e1b5eb1af2f9ed3eca9a31/content-editor/media/content-editor.gif -------------------------------------------------------------------------------- /content-editor/react-app/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | /dest 15 | 16 | # misc 17 | .DS_Store 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | -------------------------------------------------------------------------------- /content-editor/react-app/README.md: -------------------------------------------------------------------------------- 1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | ## Available Scripts 4 | 5 | In the project directory, you can run: 6 | 7 | ### `yarn start` 8 | 9 | Runs the app in the development mode.
    10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 11 | 12 | The page will reload if you make edits.
    13 | You will also see any lint errors in the console. 14 | 15 | ### `yarn test` 16 | 17 | Launches the test runner in the interactive watch mode.
    18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 19 | 20 | ### `yarn build` 21 | 22 | Builds the app for production to the `build` folder.
    23 | It correctly bundles React in production mode and optimizes the build for the best performance. 24 | 25 | The build is minified and the filenames include the hashes.
    26 | Your app is ready to be deployed! 27 | 28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 29 | 30 | ### `yarn eject` 31 | 32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 33 | 34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 35 | 36 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 37 | 38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 39 | 40 | ## Learn More 41 | 42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 43 | 44 | To learn React, check out the [React documentation](https://reactjs.org/). 45 | 46 | ### Code Splitting 47 | 48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 49 | 50 | ### Analyzing the Bundle Size 51 | 52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 53 | 54 | ### Making a Progressive Web App 55 | 56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 57 | 58 | ### Advanced Configuration 59 | 60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 61 | 62 | ### Deployment 63 | 64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 65 | 66 | ### `yarn build` fails to minify 67 | 68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 69 | -------------------------------------------------------------------------------- /content-editor/react-app/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var concat = require('gulp-concat'); 3 | var cleanCss = require('gulp-clean-css'); 4 | 5 | const ControlAddInFolder = '../app/src/ContentEditor'; 6 | const ControlAddInName = 'content-editor'; 7 | 8 | gulp.task('pack-js', function () { 9 | return gulp.src(['build/static/js/*.js']) 10 | .pipe(concat(`${ControlAddInName}.js`)) 11 | // .pipe(minify()) 12 | .pipe(gulp.dest(`${ControlAddInFolder}/js`)); 13 | }); 14 | 15 | gulp.task('pack-css', function () { 16 | return gulp.src(['build/static/css/*.css']) 17 | .pipe(concat(`${ControlAddInName}.css`)) 18 | .pipe(cleanCss()) 19 | .pipe(gulp.dest(`${ControlAddInFolder}/css`)); 20 | }); 21 | 22 | gulp.task('default', gulp.series('pack-js', 'pack-css')); -------------------------------------------------------------------------------- /content-editor/react-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "react": "^16.13.1", 7 | "react-dom": "^16.13.1", 8 | "react-scripts": "3.4.3", 9 | "classnames": "^2.2.6", 10 | "wix-rich-content-editor": "^7.17.1", 11 | "wix-rich-content-plugin-code-block": "^7.18.1", 12 | "wix-rich-content-plugin-hashtag": "^7.18.1", 13 | "wix-rich-content-plugin-html": "^7.18.1", 14 | "wix-rich-content-plugin-link": "^7.18.1" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build && gulp" 19 | }, 20 | "eslintConfig": { 21 | "extends": "react-app" 22 | }, 23 | "browserslist": { 24 | "production": [ 25 | ">0.2%", 26 | "not dead", 27 | "not op_mini all" 28 | ], 29 | "development": [ 30 | "last 1 chrome version", 31 | "last 1 firefox version", 32 | "last 1 safari version" 33 | ] 34 | }, 35 | "devDependencies": { 36 | "gulp": "^4.0.2", 37 | "gulp-clean-css": "^4.3.0", 38 | "gulp-concat": "^2.6.1", 39 | "webpack": "^4.16.2", 40 | "webpack-cli": "^3.3.12", 41 | "webpack-dev-server": "^3.1.5" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /content-editor/react-app/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | React App 12 | 13 | 14 | 15 |
    16 | 17 | 18 | -------------------------------------------------------------------------------- /content-editor/react-app/src/ContentEditor.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: rgba(255, 255, 255, 0.75); 3 | } 4 | 5 | .content-editor-container { 6 | padding: 3.5rem 0 0 3rem; 7 | max-height: calc(300px - 3.5rem); 8 | overflow-x: hidden; 9 | overflow-y: auto; 10 | } 11 | 12 | 13 | div.Tux6h { 14 | font-size: 14px; 15 | } 16 | -------------------------------------------------------------------------------- /content-editor/react-app/src/ContentEditor.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { EditorState, RichContentEditor } from 'wix-rich-content-editor'; 4 | import { createLinkPlugin } from 'wix-rich-content-plugin-link'; 5 | import { createCodeBlockPlugin } from 'wix-rich-content-plugin-code-block'; 6 | import { createHashtagPlugin } from 'wix-rich-content-plugin-hashtag'; 7 | import { createHtmlPlugin } from 'wix-rich-content-plugin-html'; 8 | import 'wix-rich-content-editor-common/dist/styles.min.css'; 9 | import 'wix-rich-content-editor/dist/styles.min.css'; 10 | import 'wix-rich-content-plugin-link/dist/styles.min.css'; 11 | import 'wix-rich-content-plugin-code-block/dist/styles.min.css'; 12 | import 'wix-rich-content-plugin-hashtag/dist/styles.min.css'; 13 | import 'wix-rich-content-plugin-html/dist/styles.min.css'; 14 | import './ContentEditor.css'; 15 | 16 | import { 17 | convertFromRaw, 18 | convertToRaw, 19 | } from 'wix-rich-content-editor-common'; 20 | 21 | const PLUGINS = [createLinkPlugin, createCodeBlockPlugin, createHashtagPlugin, createHtmlPlugin]; 22 | const ON_LOAD_CONTENT_EVENT = 'onLoadContent'; 23 | const ON_CONTENT_CHANGE_EVENT = 'onContentChange'; 24 | 25 | window.addEventListener(ON_LOAD_CONTENT_EVENT, (e) => { 26 | ReactDOM.render( 27 | 28 | 29 | , 30 | document.getElementById('controlAddIn') 31 | ); 32 | }) 33 | 34 | class ContentEditor extends React.Component { 35 | constructor(props) { 36 | super(props); 37 | 38 | this.refsEditor = React.createRef(); 39 | if (this.props.content) { 40 | const contentState = convertFromRaw(this.props.content); 41 | this.state = { 42 | editorState: EditorState.createWithContent(contentState), 43 | } 44 | } else { 45 | this.state = { editorState: EditorState.createEmpty(), }; 46 | } 47 | 48 | this.onLoadContent = this.onLoadContent.bind(this); 49 | window.addEventListener(ON_LOAD_CONTENT_EVENT, this.onLoadContent) 50 | } 51 | 52 | onLoadContent(e) { 53 | if (!e.detail) 54 | return; 55 | 56 | const contentState = convertFromRaw(e.detail); 57 | this.setState({ 58 | editorState: EditorState.createWithContent(contentState), 59 | }); 60 | } 61 | 62 | onChange = editorState => { 63 | this.setState({ 64 | editorState, 65 | }); 66 | 67 | const rawContent = convertToRaw(editorState.getCurrentContent()); 68 | let event = new CustomEvent(ON_CONTENT_CHANGE_EVENT, { detail: rawContent }); 69 | window.dispatchEvent(event); 70 | }; 71 | 72 | componentDidMount() { 73 | this.refsEditor.current.focus(); 74 | } 75 | 76 | componentWillUnmount() { 77 | window.removeEventListener(ON_LOAD_CONTENT_EVENT, this.onLoadContent); 78 | } 79 | 80 | render() { 81 | return ( 82 |
    83 | 87 |
    88 | ); 89 | } 90 | } 91 | 92 | export default ContentEditor; 93 | -------------------------------------------------------------------------------- /content-editor/react-app/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import ContentEditor from './ContentEditor'; 4 | 5 | const rootEl = document.getElementById('root'); 6 | if (rootEl) { 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | rootEl 12 | ); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /content-editor/react-app/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path") 2 | const UglifyJsPlugin = require("uglifyjs-webpack-plugin") 3 | const glob = require("glob") 4 | 5 | module.exports = { 6 | entry: { 7 | "bundle.js": glob.sync("build/static/?(js|css)/*.?(js|css)").map(f => path.resolve(__dirname, f)), 8 | }, 9 | output: { 10 | filename: "build/static/js/bundle.min.js", 11 | }, 12 | module: { 13 | rules: [ 14 | { 15 | test: /\.css$/, 16 | use: ["style-loader", "css-loader"], 17 | }, 18 | ], 19 | }, 20 | plugins: [new UglifyJsPlugin()], 21 | } -------------------------------------------------------------------------------- /docs/readme.md: -------------------------------------------------------------------------------- 1 | # Why to use Control Add-ins (Overview with a simple Example) 2 | 3 | ## Introduction 4 | 5 | `Control Add-in` is a special type of object in Business Central to create `User Control`. In other words `Control Add-in` (User Control) is a web component developed using `JavaScript`, `HTML` and `CSS` that can interact with Business Central. You need `User Control` when you do not have the required control available in standard Business Central. Also you need `User Control` when you want to simplify User Interface (UI) for your Business Central User. 6 | 7 | ## Skills Required 8 | 9 | You need to have the following skills to develop `Control Add-ins`: 10 | 11 | • AL - Good 12 | • HTML - Basic 13 | • CSS - Basic 14 | • JavaScript - Basic 15 | 16 | If you are smart enough, you just need to know how to copy paste :) 17 | 18 | If you are new to [HTML](https://www.w3schools.com/html/), [CSS](https://www.w3schools.com/css/), and [JavaScript](https://www.w3schools.com/js/), in my opinion [w3shools.com](https://www.w3schools.com/html/) is the best place to learn quickly. 19 | 20 | ## Dos and don'ts 21 | 22 | You should try to create reusable `Control Add-ins`, you should avoid hard-coding. You should be able to use the same `User Control` in more than one page. 23 | 24 | For example: 25 | 26 | * A 'Map Control' can be used, in Customer, Vendor, Bank, Location pages. 27 | * A 'Status Indicator Control' can be used in Sales, Purchase, and Service Orders, may also be in Bank Reconciliation page. 28 | 29 | In the example given below, if you hard-code slides data in `Control Add-in` instead of sending as a parameter, you can not use this in other pages. 30 | 31 | ## No more talking - Let's create a Control Add-in 32 | 33 | We don’t need to develop `Control Add-in` from scratch. There are tons of open source web components available on the web. We just need to understand the component and convert it to `Control Add-in`. 34 | 35 | We are creating [Carousel](https://getbootstrap.com/docs/4.5/components/carousel/#with-captions) control using the [Bootstrap](https://getbootstrap.com/) component. 36 | 37 | We need to use the following resources for any bootstrap component: 38 | 39 | [CSS](https://getbootstrap.com/docs/4.5/getting-started/introduction/#css) 40 | ```html 41 | 42 | ``` 43 | 44 | [JS](https://getbootstrap.com/docs/4.5/getting-started/introduction/#js) 45 | ```html 46 | 47 | 48 | 49 | ``` 50 | 51 | [HTML](https://getbootstrap.com/docs/4.5/components/carousel/#with-captions) 52 | ```html 53 | 91 | ``` 92 | 93 | ### Control Add-in Object (CarouselControl.controladdin.al) 94 | This `Carousel Control` has `OnStartup` trigger, which will be triggered once the `User Control` is loaded. 95 | 96 | `SetCarouselData` is a function that will send the slides data to `Control Add-in`. 97 | 98 | ``` 99 | controladdin "Carousel Control" 100 | { 101 | HorizontalStretch = true; 102 | RequestedHeight = 200; 103 | 104 | // JS files required for Bootstrap 105 | Scripts = 'https://code.jquery.com/jquery-3.5.1.slim.min.js', 106 | 'https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js', 107 | 'https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js'; 108 | 109 | StartupScript = 'src/startup.js'; 110 | 111 | // Bootstrap css 112 | StyleSheets = 'https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css'; 113 | 114 | procedure SetCarouselData(Data: JsonObject); 115 | event OnStartup(); 116 | } 117 | ``` 118 | 119 | ### Startup Javascript file (startup.js) 120 | This `JavaScript` file will be loaded once the `User Control` is ready. We are invoking `OnStartup` trigger so that the hosting page can receive the event and send the data back to the `User Control`. 121 | 122 | ```javascript 123 | Microsoft.Dynamics.NAV.InvokeExtensibilityMethod('OnStartup') 124 | 125 | function carouselIndicators(slides) { 126 | var indicators = []; 127 | for (var i = 0; i < slides.length; i++) { 128 | var cssClass = i === 0 ? 'class="active"' : ''; 129 | indicators.push(`
  • `); 130 | } 131 | 132 | return ``; 133 | } 134 | 135 | function carouselItems(slides) { 136 | var carouselItems = []; 137 | for (var i = 0; i < slides.length; i++) { 138 | var slide = slides[i]; 139 | var cssClass = i === 0 ? 'active' : ''; 140 | 141 | carouselItems.push(` 142 | `); 149 | } 150 | 151 | return ``; 152 | } 153 | 154 | function carouselMarkup(data) { 155 | return ` 156 | `; 168 | } 169 | 170 | window.SetCarouselData = function (data) { 171 | try { 172 | var markup = carouselMarkup(data); 173 | document.getElementById('controlAddIn').innerHTML = markup; 174 | $('#carouselExampleCaptions').carousel(); 175 | console.log(markup); 176 | } catch (err) { 177 | console.log(err); 178 | } 179 | } 180 | ``` 181 | 182 | ### Page (CustomerListExt.PageExt.al) 183 | We are extending the `Customers` page to add `Carousel Control` at the top of the customers list. When the `OnStartup` event is triggered, we are preparing the `Json Object` that contains the slides data and sending it to `Carousel Control`. 184 | 185 | ``` 186 | pageextension 50100 CustomerListExt extends "Customer List" 187 | { 188 | layout 189 | { 190 | addbefore(Control1) 191 | { 192 | usercontrol(Carousel; "Carousel Control") 193 | { 194 | trigger OnStartup() 195 | var 196 | JObject: JsonObject; 197 | Slides: JsonArray; 198 | begin 199 | Slides.Add(AddSlide('Keep your promises', 'check before you make a promise', '//unsplash.it/1024/200')); 200 | Slides.Add(AddSlide('Never forget', 'always register your conversations to ensure you follow-up promptly', '//unsplash.it/1025/200')); 201 | Slides.Add(AddSlide('Qualify', 'be picky about which opportunities to spend time on', '//unsplash.it/1024/201')); 202 | JObject.Add('slides', Slides); 203 | CurrPage.Carousel.SetCarouselData(JObject); 204 | end; 205 | } 206 | } 207 | } 208 | 209 | local procedure AddSlide(Title: Text; Description: Text; Image: Text): JsonObject 210 | var 211 | Slide: JsonObject; 212 | begin 213 | Slide.Add('title', Title); 214 | Slide.Add('description', Description); 215 | Slide.Add('image', Image); 216 | exit(Slide); 217 | end; 218 | } 219 | ``` 220 | 221 | ## Carousel Control in Action 222 | ![Customers Screen](../media/carousel.gif) 223 | 224 | ## Conclusion 225 | 226 | If we think about it, The Users don't actually need training to work on portals just because they are intuitive. But in the case of Business Applications, we definitely need to provide training to the Business Users, where they already know their business more than us. Isn't it funny! It is simply because they are not provided proper and intuitive User Interfaces. I think we should try to provide proper UI to the Users so that it is convenient for their use. Proper UI means that we should not restrict ourself only to the available controls. Where ever required, we should definitely try to create `Control Add-ins` / `User Controls` for better user experience. 227 | 228 | Use `Control Add-ins` - Help customers!! 229 | 230 | You can download the source code from [Github]() 231 | 232 | Thank You 233 | -------------------------------------------------------------------------------- /media/carousel.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msnraju/control-add-in-samples/75f92ebc107e9cdc68e1b5eb1af2f9ed3eca9a31/media/carousel.gif --------------------------------------------------------------------------------