├── ux ├── fonts │ ├── Delicious-Roman.otf │ └── Delicious-Italic.otf ├── css │ ├── font-awesome │ │ ├── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ └── fontawesome-webfont.woff2 │ │ └── css │ │ │ └── font-awesome.min.css │ └── workbench.css └── workbench.html ├── package.json ├── .gitignore ├── LICENSE ├── cert ├── server.crt └── server.key ├── server.js ├── README.md └── js └── workbench.js /ux/fonts/Delicious-Roman.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pt-br/mc-workbench/master/ux/fonts/Delicious-Roman.otf -------------------------------------------------------------------------------- /ux/fonts/Delicious-Italic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pt-br/mc-workbench/master/ux/fonts/Delicious-Italic.otf -------------------------------------------------------------------------------- /ux/css/font-awesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pt-br/mc-workbench/master/ux/css/font-awesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /ux/css/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pt-br/mc-workbench/master/ux/css/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /ux/css/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pt-br/mc-workbench/master/ux/css/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /ux/css/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pt-br/mc-workbench/master/ux/css/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /ux/css/font-awesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pt-br/mc-workbench/master/ux/css/font-awesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mc-workbench", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node server.js" 7 | }, 8 | "dependencies": { 9 | "cheerio": "^0.19.0", 10 | "express": "^4.13.3", 11 | "serve-index": "^1.7.3" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directory 27 | node_modules 28 | 29 | # Optional npm cache directory 30 | .npm 31 | 32 | # Optional REPL history 33 | .node_repl_history 34 | 35 | # Widgets directory 36 | widgets 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Lucas P. Tavares 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 | -------------------------------------------------------------------------------- /cert/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDBjCCAe4CCQCOVmmRahQvwjANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB 3 | VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 4 | cyBQdHkgTHRkMB4XDTE1MTIxNTE3NTQzOVoXDTE2MTIxNDE3NTQzOVowRTELMAkG 5 | A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0 6 | IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 7 | ALVImuW90TtVPtZE1GQOSUAxi86HMOvGFcaBdMV8zL1MgNRb/DIzgWEsVist/QKn 8 | swmnLRSNbwkv7akx3KCuIdQYecyxh3GrqKk1glZU9ixva0DzdrSJUKpzYW6fWczW 9 | xX4LUOOahneJIG6D3bNnZAv3J59el/45LhdtZw7rNWyV94o9+WhHuXEOHQkDt4x+ 10 | DEDnTExuJOoFqyLFWOTPMiin3o9nW2vlYVpSPVwRuYje/yMcUJK3o2KVoDs8uf3J 11 | yZFPfBkErGYtqQBx6deIqQ9h7unLB2PJStx/PqI6u1ZuuKedHwFClZDNqv1wBZG4 12 | TwLPAkyTbeSu3LZu48V+jEMCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAcWPwevCE 13 | zeOG6qZCUruKnZcOntFr8pJm+uUgFrN46dVbURKdACjrqQuGXd+O2KObIx9ZdYIY 14 | FjtmTWSel8SdRHKeVU+EbDsOXAbpuRD1qzf0AVz7dZYsvRpVPvOmV8FY5ON0Yvqa 15 | g2OWspmxtdeqHhxMQ4ZrBvCg4bycZrQgywipnaWf/eTpVUUeP+8xYg0s/wVpixHq 16 | eISBTP++mOFAD0U9wIWyCmW3RfrdxJhElf/qfzz+WLxvW4daCfmQaF1mWc4H0iFZ 17 | SpSqt2n9gWf40lGhtLDhUT7NJFPBqLQfk4LLHKI0pBj7jC64xMj59h5TU3gH9+2b 18 | QuawUqHl9a6aEw== 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /cert/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpQIBAAKCAQEAtUia5b3RO1U+1kTUZA5JQDGLzocw68YVxoF0xXzMvUyA1Fv8 3 | MjOBYSxWKy39AqezCactFI1vCS/tqTHcoK4h1Bh5zLGHcauoqTWCVlT2LG9rQPN2 4 | tIlQqnNhbp9ZzNbFfgtQ45qGd4kgboPds2dkC/cnn16X/jkuF21nDus1bJX3ij35 5 | aEe5cQ4dCQO3jH4MQOdMTG4k6gWrIsVY5M8yKKfej2dba+VhWlI9XBG5iN7/IxxQ 6 | krejYpWgOzy5/cnJkU98GQSsZi2pAHHp14ipD2Hu6csHY8lK3H8+ojq7Vm64p50f 7 | AUKVkM2q/XAFkbhPAs8CTJNt5K7ctm7jxX6MQwIDAQABAoIBAQCenMkSbFNuI3bY 8 | SN7AMJO8u90ENdsC34zb4xbFWB1XH2G07Eqrrc7ss7stCo7NzObkckYKLnlRQ4Mg 9 | v4S3fcQRa9zd0RKdzUDD1BKW8L13QYFJEfvxmBdhG5TLElei1uNzFfmPOvueCPe8 10 | WloXB0ZNBdHAKia4g1UloE5Eil1zBASrxD6EQqp7XV/UPeItYhEWm+ZxvTvIlLip 11 | FgwvMvt7llXlnp5ifOXUn7TtpmDLthGwsjnboQMqeyhIvPby1iiMgjVTi4Plnghb 12 | QAXf1fsyCBPnHp8kOtpwxDhhoag9rogsOvvdE8mKCFpauDhlCCUHDeB/W5lpSxvu 13 | 3M+x/27ZAoGBAO/al2LVm/Vh/WZNaXchMvYcU7wbx7TZSV6s4NVzPwmeHbCT0CvT 14 | L/GE57o34W4eWbKdDaSsWJ0qbe+2u0yYsRIHSE72gajczgMpHbyL4wcX1LLDFrEu 15 | GRjMJss8QMHYPd1ke9Io2DDaZIX3TuG4+w4z9auIw5b18ih71Kt1M2g3AoGBAMF8 16 | q7d19pntUrZAmzf0BKOEjgEyk2c2ixXPqp7uOH6WeELnWcEN9q8zYgOKEnOmYtOa 17 | a5yC5vu0BYzmbwamO8C19cGpWrcQMq1E0cf6c5FCve4FbrhoUOEp+3eyxmM7yoMz 18 | XXtCHDU/H6uY/eD1RQTYGrcCi/9uQmN5jaQUPZ5VAoGBAM0vMlJaahCAw0XA83f1 19 | 7qKbmQZSvYT4XMuhGLWA4WxY1w03Zd4Xy+vQxmuHYlHRpOoncIRu61+H7IQkzhW4 20 | icHiePkT59eNDK+nfMjO4mgu+sXyHndz+AQ+oPE7mio50rKSQ1qFlmw0Z8oyxkhS 21 | 9nIwAPm9BZUe0QnQ5R3IJTIBAoGAK0c6lY+yOB3oaVGsJmjTfMvSg5wPcn+1vowz 22 | ytbYFiCMB9L9tXvtGKUyoD4LAIlQA6q/tUNmbRiIQUrtvJwEM4e/z7CU1OuvmigR 23 | kFyJ6wz1tL7MVD0pEiQ01kJLs7iVBKHBoCdabeKPr+9Joj7aUEoSN6s/K0Q7X0q6 24 | DuBkI/0CgYEAu8o/iuYeX63D9Q9ByKkyRauFmm+NxtSDRXuiQGnrQ33bMeMmy1oP 25 | aQKgIvNpUcWLxqD3sGG/ZwD5TIRWOLZ6kkM6tfG1WwFWQv/LNOrHuZ2tNy5nCkft 26 | wgOuccYu7K/aeAoOpWbOeoq8RduVL1c6NaopZIVn3Gt/7tJOhKik/R8= 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var serveIndex = require('serve-index') 3 | var app = express(); 4 | var fs = require('fs'); 5 | var path = require('path'); 6 | var http = require('http'); 7 | var https = require('https'); 8 | 9 | var privateKey = fs.readFileSync('cert/server.key', 'utf8'); 10 | var certificate = fs.readFileSync('cert/server.crt', 'utf8'); 11 | 12 | var credentials = {key: privateKey, cert: certificate}; 13 | 14 | app.use(function(req, res, next) { 15 | res.header("Access-Control-Allow-Origin", "*"); 16 | res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); 17 | // intercept OPTIONS method 18 | if ('OPTIONS' == req.method) { 19 | res.sendStatus(200); 20 | } 21 | else { 22 | next(); 23 | } 24 | }); 25 | 26 | /** 27 | * 28 | * Path to the moovcheckout research 29 | * 30 | * Change this path to match your moovcheckout-research repository. 31 | * e.g. /home/lucas/MyProjects/moovcheckout-research/ 32 | */ 33 | var widgetListBasePath = '/home/lucas/Github/moovcheckout-research/'; 34 | 35 | // Output folder - DON'T change this 36 | var outputFolder = 'widgets/'; 37 | // Output path 38 | var outputPath = outputFolder 39 | 40 | 41 | // Check if snippets dir exists, if not, create it 42 | if (!fs.existsSync(outputPath)){ 43 | fs.mkdirSync(outputPath); 44 | }; 45 | // Widget list path 46 | var widgetListFile = path.join(widgetListBasePath, 'catalyst-developer-docs/site-tagging/widget-list.md'); 47 | 48 | var writeWidget = function (widgetName, widgetTemplate) { 49 | var widgetOutputName = widgetName + '.json'; 50 | var widgetOutputContent = widgetTemplate; 51 | var widgetOutputPath = outputPath + widgetOutputName; 52 | 53 | fs.writeFile(widgetOutputPath, widgetOutputContent, function (err) { 54 | if (err) throw err; 55 | }); 56 | } 57 | 58 | fs.readFile(widgetListFile, function (err, data) { 59 | if (err) throw err; 60 | 61 | if (Buffer.isBuffer(data)){ 62 | var result = data.toString('utf8'); 63 | var widgets = result.split(/^.+\n-+$/gm).splice(5); 64 | 65 | widgets.forEach(function (widget) { 66 | widget = widget.trim(); 67 | widget = widget.replace(/\{Boolean\}/, ''); 68 | 69 | var widgetTemplate = widget.match(/\{([^```]*)}/g)[0]; 70 | var widgetName = widgetTemplate.match(/name:\s?'([^']*)?'/)[1]; 71 | var widgetDescription = widget.match(/^([^|]+)/m)[1].trim(); 72 | var widgetParams = widget.match(/^\|([^|]+)(\|.*?$)/gm).splice(2); 73 | 74 | widgetParams.forEach(function (line, index) { 75 | line = line.replace(/\n/m, '\n * ') 76 | .replace(/\|\s`(.*?)`\s\|(.*?)\s\|\s(.*?)(.*?)\s\|$/, '$1 {$2 } $3$4'); 77 | 78 | if(index === 0) { 79 | widgetParams[index] = '@param ' + line + '\n'; 80 | return; 81 | } 82 | 83 | widgetParams[index] = ' * @param ' + line + '\n'; 84 | }); 85 | 86 | writeWidget(widgetName, widgetTemplate); 87 | }); 88 | } 89 | }); 90 | 91 | app.use("/ux", express.static(__dirname + '/ux')); 92 | app.use('/widgets', serveIndex('widgets', {'icons': true})); 93 | app.use("/widgets", express.static(__dirname + '/widgets')); 94 | app.use("/js", express.static(__dirname + '/js')); 95 | 96 | var httpServer = http.createServer(app); 97 | var httpsServer = https.createServer(credentials, app); 98 | 99 | httpServer.listen(8080); 100 | httpsServer.listen(8443); 101 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MoovCheckout Workbench 2 | --- 3 | 4 | Made by [@pt-br](https://github.com/pt-br) 5 | 6 | Thanks to [William Lima](https://github.com/williammustaffa) and [Douglas Hipolito](https://github.com/douglashipolito) for the support. 7 | 8 | What is this tool? 9 | --- 10 | Workbench is an UI tool to work on [MoovCheckout](http://www.moovweb.com/moovcheckout/). 11 | 12 | Feel free to check out some [Screenshots](http://imgur.com/a/cqV6W). 13 | 14 | Features 15 | --- 16 | - Disable Actions from original site (Disable , inputs and buttons) 17 | - Get Selector by click 18 | - Map and Export widgets 19 | 20 | Dependencies 21 | --- 22 | To use Workbench, you'll need the following tools: 23 | - [Node.js](http://www.liquidweb.com/kb/how-to-install-node-js-via-nvm-node-version-manager-on-ubuntu-14-04-lts/) 24 | - [MoovCheckout Script Loader](https://github.com/pt-br/mc-loader) 25 | - Permission to clone [moovcheckout-research](https://github.com/moovweb/moovcheckout-research) repository. 26 | 27 | Installation 28 | --- 29 | 30 | - Install [Node.js](http://www.liquidweb.com/kb/how-to-install-node-js-via-nvm-node-version-manager-on-ubuntu-14-04-lts/) (if you already have Node.js, just ignore this step). 31 | - Install and configure [MoovCheckout Script Loader](https://github.com/intelimen/moovweb/tree/moovcheckout/tools/mc-loader) (installation instructions inside of its repository). 32 | 33 | - Clone [moovcheckout-research](https://github.com/moovweb/moovcheckout-research). 34 | 35 | - Clone [MoovCheckout Workbench](https://github.com/pt-br/mc-workbench) - Be sure to have write permissions on the folder you are cloning it. 36 | 37 | - Open the folder you cloned [MoovCheckout Workbench](https://github.com/pt-br/mc-workbench) into, and edit the file `server.js`. 38 | 39 | - Search for a variable called `widgetListBasePath`, you'll have to change its value to match the folder you cloned [moovcheckout-research](https://github.com/moovweb/moovcheckout-research) into. There's a comment on `server.js` file explaning how the value should look. 40 | 41 | - Open the folder you cloned [MoovCheckout Workbench](https://github.com/pt-br/mc-workbench) on a terminal and run 42 | `npm install` 43 | 44 | - Once your `server.js` is modified to track your [moovcheckout-research](https://github.com/moovweb/moovcheckout-research) local repository, be sure to mark it as `assume-unchanged`, so, git will "ignore" your change to `server.js`. To set this configuration, just run: 45 | 46 | `git update-index --assume-unchanged server.js` (on mc-workbench folder) 47 | 48 | - Done! 49 | 50 | Using the Workbench 51 | --- 52 | - Open the folder you cloned [MoovCheckout Workbench](https://github.com/pt-br/mc-workbench) on a terminal and run 53 | `npm start` everytime you need to start Workbench. (It will run a Node.js server, so you can leave it opened while you are working between projects) 54 | 55 | - Start your `dev-server` from MoovCheckout normally. 56 | 57 | - Open [MoovCheckout Script Loader](https://github.com/pt-br/mc-loader) on your browser and active the option 'Inject Workbench'. 58 | 59 | - If you are having troubles to see the Workbench, check the `console` logs and be sure to accept the `SSL certificate`. 60 | 61 | Developing new Features 62 | --- 63 | When developing new features, be aware to create a new branch. When the feature is ready, open a pull request to `moovcheckout` branch. 64 | 65 | If you need to make some improvement to `server.js`, just undo the `assume-unchanged` configuration by running: 66 | 67 | `git update-index --no-assume-unchanged server.js` 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /ux/workbench.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |
MoovCheckout Workbench
5 | 43 |
44 |
45 |
46 | 47 |
48 | Choose an option above to start working 49 |
50 |
51 |
52 |
53 |
Pick a Widget
54 | 55 |
    56 | 57 |
58 |
59 |
60 |
61 | 62 |
63 | 64 |
65 |
66 |
67 | 68 | 71 |
72 |
73 | 74 | 77 |
78 |
79 | 80 | 83 |
84 |
85 | 86 | 89 |
90 |
Selectors
91 |
92 | 93 |
94 |
95 |
96 |
Settings
97 |
98 | 99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
x
107 |
Here is your Widget
108 |
109 | 110 | 113 |
114 |
115 | Don't worry about tabs, it's already formated. 116 |
117 | 120 |
Copy to Clipboard
121 |
122 | 123 |
124 |
125 |
126 |
127 |
x
128 |
Selector Picker
129 |
130 | Just click on any element of the original site 131 |
132 | 133 |
Copy to Clipboard
134 |
135 | 136 |
137 |
138 | -------------------------------------------------------------------------------- /ux/css/workbench.css: -------------------------------------------------------------------------------- 1 | /***************************************************************************************** 2 | ****************************************************************************************** 3 | ****************************************************************************************** 4 | ****************************************************************************************** 5 | ****************************************************************************************** 6 | ************************************** Reset CSS *****************************************/ 7 | 8 | #mc-workbench-container html, #mc-workbench-container body, #mc-workbench-container span, #mc-workbench-container applet, #mc-workbench-container object, #mc-workbench-container iframe, 9 | #mc-workbench-container h1, h2, #mc-workbench-container h3, #mc-workbench-container h4, #mc-workbench-container h5, #mc-workbench-container h6, #mc-workbench-container p, #mc-workbench-container blockquote, #mc-workbench-container pre, 10 | #mc-workbench-container a, #mc-workbench-container abbr, #mc-workbench-container acronym, #mc-workbench-container address, #mc-workbench-container big, #mc-workbench-container cite, #mc-workbench-container code, 11 | #mc-workbench-container del, #mc-workbench-container dfn, #mc-workbench-container em, #mc-workbench-container img, #mc-workbench-container ins, #mc-workbench-container kbd, #mc-workbench-container q, #mc-workbench-container s, #mc-workbench-container samp, 12 | #mc-workbench-container small, #mc-workbench-container strike, #mc-workbench-container strong, #mc-workbench-container sub, #mc-workbench-container sup, #mc-workbench-container tt, #mc-workbench-container var, 13 | #mc-workbench-container b, #mc-workbench-container u, #mc-workbench-container center, 14 | #mc-workbench-container dl, #mc-workbench-container #mc-workbench-container dt, #mc-workbench-container dd, #mc-workbench-container ol, #mc-workbench-container ul, #mc-workbench-container li, 15 | #mc-workbench-container fieldset, #mc-workbench-container form, #mc-workbench-container label, #mc-workbench-container legend, 16 | #mc-workbench-container table, #mc-workbench-container caption, #mc-workbench-container tbody, #mc-workbench-container tfoot, #mc-workbench-container thead, #mc-workbench-container tr, #mc-workbench-container th, #mc-workbench-container td, 17 | #mc-workbench-container article, #mc-workbench-container aside, #mc-workbench-container canvas, #mc-workbench-container details, #mc-workbench-container embed, 18 | #mc-workbench-container figure, #mc-workbench-container figcaption, #mc-workbench-container footer, #mc-workbench-container header, #mc-workbench-container hgroup, 19 | #mc-workbench-container menu, #mc-workbench-container nav, #mc-workbench-container output, #mc-workbench-container ruby, #mc-workbench-container section, #mc-workbench-container summary, 20 | #mc-workbench-container time, #mc-workbench-container mark, #mc-workbench-container audio, #mc-workbench-container video { 21 | margin: 0; 22 | padding: 0; 23 | border: 0; 24 | font-size: 100%; 25 | font: inherit; 26 | vertical-align: baseline; 27 | } 28 | #mc-workbench-container article, #mc-workbench-container aside, #mc-workbench-container details, #mc-workbench-container figcaption, #mc-workbench-container figure, 29 | #mc-workbench-container footer, #mc-workbench-container header, #mc-workbench-container hgroup, #mc-workbench-container menu, #mc-workbench-container nav, #mc-workbench-container section { 30 | display: block; 31 | } 32 | #mc-workbench-container ol, #mc-workbench-container ul { 33 | list-style: none; 34 | } 35 | #mc-workbench-container blockquote, #mc-workbench-container q { 36 | quotes: none; 37 | } 38 | #mc-workbench-container blockquote:before, #mc-workbench-container blockquote:after, 39 | #mc-workbench-container input:before, #mc-workbench-container input:after, 40 | #mc-workbench-container q:before, #mc-workbench-container q:after { 41 | content: ''; 42 | content: none; 43 | } 44 | #mc-workbench-container table { 45 | border-collapse: collapse; 46 | border-spacing: 0; 47 | } 48 | #mc-workbench-container input { 49 | color: #333; 50 | vertical-align: inherit !important; 51 | z-index: inherit !important; 52 | outline: none !important; 53 | } 54 | #mc-workbench-container textarea { 55 | z-index: inherit !important; 56 | outline: none !important; 57 | } 58 | 59 | /***************************************************************************************** 60 | ****************************************************************************************** 61 | ****************************************************************************************** 62 | ****************************************************************************************** 63 | ****************************************************************************************** 64 | ********************************* End of reset CSS ***************************************/ 65 | ::-webkit-scrollbar { 66 | width: 1px; 67 | height: 10px; 68 | background-color: #D2CECE; 69 | } 70 | ::-webkit-scrollbar-thumb { 71 | background-color:#808080; 72 | } 73 | ::-webkit-input-placeholder { 74 | color: #9E9A9A !important; 75 | } 76 | @font-face { 77 | font-family: delFontRegular; 78 | src: url('./../fonts/Delicious-Roman.otf'); 79 | } 80 | #mc-workbench-container * { 81 | box-sizing: border-box !important; 82 | } 83 | #mc-workbench-container { 84 | position: fixed; 85 | width: 33.3%; 86 | z-index: 999999; 87 | height: inherit; 88 | top: 0; 89 | right: 0; 90 | border-left: 1px solid #D0D0D0; 91 | text-align: left; 92 | } 93 | #mc-workbench-body { 94 | height: 100%; 95 | } 96 | #mc-workbench-container, #mc-workbench-body { 97 | background: #fff; 98 | font-family: delFontRegular; 99 | cursor: pointer; 100 | font-size: 16px; 101 | overflow-y: scroll; 102 | overflow-x: hidden; 103 | } 104 | #mc-workbench-container div, #mc-workbench-container input[type="text"], 105 | #mc-workbench-container textarea { 106 | font-family: delFontRegular !important; 107 | } 108 | #mc-workbench-container .actions-disabled { 109 | color: #059A2E !important; 110 | } 111 | #mc-workbench-container .inactive, #mc-workbench-container .hide, 112 | #mc-workbench-container [data-not-mapped="true"], #mc-workbench-container [data-not-error="true"] { 113 | display: none !important; 114 | } 115 | #mc-workbench-container input[type="checkbox"] { 116 | top: 2px; 117 | position: relative; 118 | width: 24px!important; 119 | height: 24px!important; 120 | display: inline-block; 121 | -webkit-appearance: checkbox !important; 122 | } 123 | #mc-workbench-container .checkbox-label { 124 | position: relative; 125 | top: -5px; 126 | font-size: 14px; 127 | color: #333; 128 | } 129 | #mc-workbench-container .checkbox-label:before { 130 | display: none !important; 131 | } 132 | #mc-workbench-container .checkbox-container { 133 | padding: 10px; 134 | display: inline-block; 135 | width: 165px; 136 | } 137 | #mc-workbench-title { 138 | z-index: 666; 139 | text-align: center; 140 | padding: 14px; 141 | background: #E8E8E8; 142 | color: #3E3D3D; 143 | font-size: 22px; 144 | position: absolute; 145 | width: 100%; 146 | } 147 | #mc-workbench-menu { 148 | z-index: 666; 149 | position: absolute; 150 | width: 100%; 151 | top: 46px; 152 | list-style: none; 153 | padding: 0; 154 | margin: 0; 155 | display: -webkit-flex; 156 | display: flex; 157 | -webkit-flex-direction: row; 158 | flex-direction: row; 159 | -webkit-align-items: center; 160 | align-items: center; 161 | -webkit-justify-content: center; 162 | justify-content: center; 163 | } 164 | #mc-workbench-menu > li { 165 | flex: 1; 166 | background: white; 167 | border-bottom: 1px solid #D2CACA; 168 | border-right: 1px solid #D2CACA; 169 | text-align: center; 170 | } 171 | #mc-workbench-menu > li:last-of-type { 172 | border-right: 0; 173 | } 174 | #mc-workbench-menu > li > .mc-workbench-menu-text { 175 | color: #555; 176 | font-size: 18px !important; 177 | padding: 8px 0 5px; 178 | } 179 | #mc-workbench-menu .mc-workbench-menu-tip { 180 | display: block; 181 | font-size: 14px; 182 | width: 50px; 183 | margin: 2px auto; 184 | } 185 | #mc-workbench-workspace { 186 | top: 108px; 187 | position: relative; 188 | } 189 | #mc-workbench-widget-editor { 190 | padding-bottom: 50px; 191 | } 192 | #mc-workbench-widget-title, #mc-workbench-widget-name { 193 | color: #696969; 194 | padding: 15px 5px 10px; 195 | margin-top: 10px; 196 | border-bottom: 1px solid #70a2f9; 197 | font-size: 22px; 198 | text-align: center; 199 | } 200 | #mc-workbench-widget-search, #mc-workbench-prop-search { 201 | width: 100% !important; 202 | margin-top: 10px !important; 203 | padding: 10px !important; 204 | border: 0 !important; 205 | font-size: 16px !important; 206 | color: #6F6E6E !important; 207 | font-style: italic !important; 208 | border-bottom: 1px solid #DEDEDE !important; 209 | font-family: Arial !important; 210 | } 211 | #mc-workbench-widget-list li { 212 | background: white; 213 | color: #007C9E; 214 | padding: 10px 10px 10px; 215 | border-bottom: 1px solid #D2CACA; 216 | font-size: 16px !important; 217 | } 218 | #mc-workbench-selector-title, #mc-workbench-settings-title { 219 | font-size: 18px; 220 | color: #333; 221 | padding: 10px 10px 30px; 222 | } 223 | #mc-workbench-selector-container, #mc-workbench-settings-container { 224 | white-space: nowrap; 225 | padding: 0 10px; 226 | } 227 | #mc-workbench-container .mc-workbench-prop-label { 228 | display: block; 229 | text-align: left; 230 | color: #0D82A5; 231 | margin-bottom: 2px; 232 | font-size: 16px !important; 233 | } 234 | #mc-workbench-container .mc-workbench-prop-label[data-extra-type="modal"] { 235 | color: #0C8406; 236 | } 237 | #mc-workbench-container .mc-workbench-prop-label[data-extra-type="common"] { 238 | color: #D02442; 239 | } 240 | #mc-workbench-container .mc-workbench-prop-input { 241 | display: inline-block; 242 | width: 100% !important; 243 | height: 35px !important; 244 | border-radius: 2px !important; 245 | -webkit-appearance: none !important; 246 | border: 1px solid #C1C1C1 !important; 247 | padding: 7px !important; 248 | padding-right: 60px !important; 249 | margin-bottom: 20px !important; 250 | font-weight: normal !important; 251 | font-size: 14px !important; 252 | vertical-align: inherit !important; 253 | } 254 | #mc-workbench-container .mc-workbench-prop-button { 255 | display: inline-block; 256 | left: -47px; 257 | top: 0px; 258 | height: 35px; 259 | position: relative; 260 | background: #0D82A5; 261 | color: white; 262 | padding: 7px; 263 | font-size: 18px; 264 | text-align: center; 265 | vertical-align: top; 266 | } 267 | #mc-workbench-container .mc-workbench-prop-button.selected { 268 | background: #024456; 269 | } 270 | #mc-workbench-container .mc-workbench-prop-button[data-extra-type="modal"] { 271 | background: #138A3A; 272 | } 273 | #mc-workbench-container .mc-workbench-prop-button.selected[data-extra-type="modal"] { 274 | background: #076927; 275 | } 276 | #mc-workbench-container .mc-workbench-prop-button[data-extra-type="common"] { 277 | background: #D84C64; 278 | } 279 | #mc-workbench-container .mc-workbench-prop-button.selected[data-extra-type="common"] { 280 | background: #B52B43; 281 | } 282 | #mc-workbench-container .mc-workbench-prop-tip { 283 | margin-bottom: 5px; 284 | color: #8D8E8E; 285 | font-style: italic; 286 | top: -16px; 287 | font-size: 14px; 288 | position: relative; 289 | } 290 | #mc-workbench-export-modal-overlay, #mc-workbench-getselector-modal-overlay { 291 | z-index: 667; 292 | position: absolute; 293 | top: 0; 294 | background: rgba(33, 33, 33, 0.78); 295 | width: 100%; 296 | height: 100%; 297 | } 298 | #mc-workbench-export-modal, #mc-workbench-getselector-modal { 299 | z-index: 668; 300 | position: absolute; 301 | margin: auto; 302 | top: 20px; 303 | left: 0; 304 | right: 0; 305 | width: 90%; 306 | background: #E8E8E8; 307 | border-radius: 2px; 308 | border: 1px solid #D0D0D0; 309 | } 310 | #mc-workbench-export-modal-close, #mc-workbench-getselector-modal-close { 311 | background: #0D82A5; 312 | position: absolute; 313 | color: white; 314 | font-weight: bold; 315 | border-radius: 15px; 316 | height: 30px; 317 | width: 30px; 318 | right: -8px; 319 | top: -10px; 320 | font-size: 21px; 321 | text-align: center; 322 | line-height: 30px; 323 | } 324 | #mc-workbench-export-modal-title, #mc-workbench-getselector-modal-title { 325 | margin: 20px 10px 0; 326 | color: #0D82A7; 327 | border-bottom: 1px solid #0D82A7; 328 | padding-bottom: 4px; 329 | font-size: 21px; 330 | } 331 | #mc-workbench-export-modal-subtitle, #mc-workbench-getselector-modal-subtitle { 332 | margin: 10px; 333 | color: #555; 334 | font-size: 16px !important; 335 | } 336 | #mc-workbench-export-modal-box { 337 | resize: none !important; 338 | position: relative !important; 339 | margin: 10px auto !important; 340 | display: block !important; 341 | width: 95% !important; 342 | font-size: 16px !important; 343 | float: none !important; 344 | } 345 | #mc-workbench-getselector-modal-input { 346 | display: block !important; 347 | width: 95% !important; 348 | border-radius: 2px !important; 349 | -webkit-appearance: none !important; 350 | border: 1px solid #E2DFDF !important; 351 | padding: 7px !important; 352 | margin: auto; 353 | margin-bottom: 15px !important; 354 | font-weight: normal !important; 355 | font-size: 14px !important; 356 | } 357 | #mc-workbench-initial-box { 358 | width: 80%; 359 | max-width: 345px; 360 | margin: auto; 361 | top: 70px; 362 | height: 300px; 363 | position: relative; 364 | border: 4px solid #B9B9B9; 365 | border-radius: 20px; 366 | display: -webkit-flex; 367 | display: flex; 368 | -webkit-flex-direction: column; 369 | flex-direction: column; 370 | -webkit-align-items: center; 371 | align-items: center; 372 | -webkit-justify-content: center; 373 | justify-content: center; 374 | } 375 | #mc-workbench-export-modal-button, #mc-workbench-getselector-modal-button { 376 | margin: 10px auto !important; 377 | margin-bottom: 15px !important; 378 | display: block !important; 379 | width: 95% !important; 380 | text-align: center !important; 381 | padding: 10px !important; 382 | background: #0D82A5 !important; 383 | color: white !important; 384 | font-size: 16px !important; 385 | } 386 | #mc-workbench-export-modal-status, #mc-workbench-getselector-modal-status { 387 | color: #027502; 388 | margin: 0 10px; 389 | top: -8px; 390 | position: relative; 391 | } 392 | #mc-workbench-export-modal-status.error, #mc-workbench-getselector-modal-status.error { 393 | color: #C1012A; 394 | } 395 | #mc-workbench-initial-icon { 396 | font-size: 88px; 397 | color: #BFBDBD; 398 | } 399 | #mc-workbench-initial-text { 400 | width: 90%; 401 | text-align: center; 402 | font-size: 18px; 403 | line-height: 28px; 404 | font-weight: bold; 405 | color: #BFBDBD; 406 | text-transform: capitalize; 407 | } 408 | -------------------------------------------------------------------------------- /ux/css/font-awesome/css/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.6.3');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.6.3') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.6.3') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.6.3') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.6.3') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} 5 | -------------------------------------------------------------------------------- /js/workbench.js: -------------------------------------------------------------------------------- 1 | workbench = document.createElement('div'); 2 | widgets = []; 3 | isMapping = false; 4 | var savedExportText = ''; 5 | var body = document.body; 6 | var widgetSelectors = false; 7 | var widgetSettings = false; 8 | var grabbingSelector = false; 9 | var grabbingSimpleSelector = false; 10 | var currentProp = false; 11 | 12 | var initDelay = setInterval(function() { 13 | mcIframe = document.querySelector('#mc-created-iframe'); 14 | originalBody = document.querySelector('#mc-original-body'); 15 | 16 | if( originalBody ) { 17 | initialize(); 18 | } 19 | 20 | }, 200); 21 | 22 | function initialize() { 23 | 24 | clearInterval(initDelay); 25 | 26 | mcIframe.className = 'active'; 27 | mcIframe.style.width = '33.3%'; 28 | mcIframe.style.left = '33.3%'; 29 | originalBody.style.width = '33.3%'; 30 | 31 | injectWorkbench(); 32 | addListeners(); 33 | } 34 | 35 | function setMappingStatus(status) { 36 | localStorage.setItem('mc-workbench-is-mapping', status); 37 | } 38 | 39 | function getMappingStatus() { 40 | var mappingStatus = localStorage.getItem('mc-workbench-is-mapping'); 41 | return mappingStatus; 42 | } 43 | 44 | function updateMappingWidget(widgetName, widgetFile) { 45 | localStorage.setItem('mc-workbench-mapping-widget', widgetName); 46 | localStorage.setItem('mc-workbench-mapping-widget-file', widgetFile); 47 | localStorage.setItem('mc-workbench-mapping-props', ''); 48 | } 49 | 50 | function updateMappingProps(propId, propValue) { 51 | var mappingProps = localStorage.getItem("mc-workbench-mapping-props"); 52 | var newMappingProps = propId + '=' + propValue + ','; 53 | var updatedMappingProps = mappingProps + newMappingProps; 54 | 55 | localStorage.setItem('mc-workbench-mapping-props', updatedMappingProps); 56 | } 57 | 58 | function fillMappingProps() { 59 | var isModalChekbox = localStorage.getItem('mc-workbench-is-modal'); 60 | var commonPropsChekbox = localStorage.getItem('mc-workbench-common-props'); 61 | 62 | var mappingProps = localStorage.getItem("mc-workbench-mapping-props"); 63 | var mappingPropsArray = mappingProps.split(','); 64 | var mappingPropsLength = mappingPropsArray.length - 1; 65 | 66 | /* Check checkboxes if they were checked before */ 67 | if ( isModalChekbox == 'true' ) { 68 | var isModalElement = document.querySelector('#mc-workbench-selector-is-modal'); 69 | isModalElement.checked = true; 70 | isModal(isModalElement); 71 | } 72 | 73 | if ( commonPropsChekbox == 'true' ) { 74 | var commonPropsElement = document.querySelector('#mc-workbench-selector-common-selectors'); 75 | commonPropsElement.checked = true; 76 | commonProps(commonPropsElement); 77 | } 78 | 79 | for ( var i = 0; i < mappingPropsLength; i++ ) { 80 | var propId = mappingPropsArray[i].split('=')[0]; 81 | var propValue = mappingPropsArray[i].split('=')[1]; 82 | 83 | var propElement = document.querySelector('#' + propId); 84 | 85 | if ( propElement ) { 86 | propElement.value = propValue; 87 | } 88 | } 89 | } 90 | 91 | function resumeMappingWidget() { 92 | var resumeDelay = setInterval(function() { 93 | widgetSection = document.querySelector('#mc-workbench-widget-section'); 94 | if( widgetSection ) { 95 | clearInterval(resumeDelay); 96 | var widgetName = localStorage.getItem('mc-workbench-mapping-widget'); 97 | var widgetFile = localStorage.getItem('mc-workbench-mapping-widget-file'); 98 | var widgetEditorTitle = document.querySelector('#mc-workbench-widget-name'); 99 | var widgeEditor = document.querySelector('#mc-workbench-widget-editor'); 100 | var initialView = document.querySelector('#mc-workbench-initial-view'); 101 | 102 | initialView.className = 'inactive'; 103 | widgeEditor.className = 'active'; 104 | 105 | widgetEditorTitle.innerHTML = widgetName; 106 | getWidgetTemplate(widgetFile); 107 | } 108 | }, 200); 109 | } 110 | 111 | function addListeners() { 112 | originalBody.addEventListener('mousedown', function(e) { 113 | var selectorGenerator = new CssSelectorGenerator; 114 | var element = e.target; 115 | 116 | /* if match some workbench element, cancel the process */ 117 | if( element.id ) { 118 | if ( element.id.match(/mc\-workbench/) ) { 119 | return; 120 | } 121 | } 122 | if( element.getAttribute('class') ) { 123 | if ( element.className.match(/mc\-workbench/) ) { 124 | return; 125 | } 126 | } 127 | 128 | var selector = selectorGenerator.getSelector(element); 129 | processSelector(selector); 130 | }); 131 | 132 | var searchDelay = setInterval(function() { 133 | var widgetSearch = document.querySelector('#mc-workbench-widget-search'); 134 | var propSearch = document.querySelector('#mc-workbench-prop-search'); 135 | 136 | if( widgetSearch ) { 137 | widgetSearch.addEventListener('keyup', function(e) { 138 | filterWidgets(widgetSearch); 139 | }); 140 | widgetSearch.addEventListener('click', function(e) { 141 | widgetSearch.value = ''; 142 | filterWidgets(widgetSearch); 143 | }); 144 | 145 | propSearch.addEventListener('keyup', function(e) { 146 | filterProps(propSearch); 147 | }); 148 | propSearch.addEventListener('click', function(e) { 149 | propSearch.value = ''; 150 | filterProps(propSearch); 151 | }); 152 | 153 | clearInterval(searchDelay); 154 | } 155 | }, 200); 156 | } 157 | 158 | function filterWidgets(widgetSearch) { 159 | var searchQuery = widgetSearch.value; 160 | var regexQuery = new RegExp(searchQuery, "ig"); 161 | var widgetElements = document.querySelectorAll('#mc-workbench-widget-list > .widget'); 162 | 163 | [].forEach.call(widgetElements, function(currentWidget) { 164 | var widgetName = currentWidget.innerHTML; 165 | 166 | /* If doesn't match search query */ 167 | if( !widgetName.match(regexQuery) ) { 168 | /* Only add .hide to elements that doesn't have it already */ 169 | if ( !currentWidget.className.match(/hide/) ) { 170 | currentWidget.className = currentWidget.className + ' hide'; 171 | } 172 | } else { 173 | currentWidget.className = 'widget'; 174 | } 175 | }); 176 | } 177 | 178 | function filterProps(propSearch) { 179 | var searchQuery = propSearch.value; 180 | var regexQuery = new RegExp(searchQuery, "ig"); 181 | var propLabelSelector = document.querySelectorAll('#mc-workbench-selector-container > .mc-workbench-prop-label'); 182 | var propLabelSetting = document.querySelectorAll('#mc-workbench-settings-container > .mc-workbench-prop-label'); 183 | 184 | /* Search for 'selector' props */ 185 | [].forEach.call(propLabelSelector, function(currentPropLabel) { 186 | var propLabelName = currentPropLabel.innerHTML; 187 | var currentPropInput = currentPropLabel.nextElementSibling; 188 | var currentPropButton = currentPropInput.nextElementSibling; 189 | var currentPropTip = currentPropButton.nextElementSibling; 190 | 191 | /* Save button and tip classes, just in case they in use to get a selector */ 192 | var currentButtonClass = currentPropButton.className; 193 | var currentPropTip = currentPropTip.className; 194 | 195 | /* If doesn't match search query */ 196 | if( !propLabelName.match(regexQuery) ) { 197 | /* Only add .hide to elements that doesn't have it already */ 198 | if ( !currentPropLabel.className.match(/hide/) ) { 199 | currentPropLabel.className = currentPropLabel.className + ' hide'; 200 | currentPropInput.className = currentPropInput.className + ' hide'; 201 | currentPropButton.className = currentPropButton.className + ' hide'; 202 | currentPropTip.className = currentPropButton.className + ' hide'; 203 | } 204 | } else { 205 | 206 | currentButtonClass = currentButtonClass.split(/\shide/)[0]; 207 | currentPropTip = currentPropTip.split(/\shide/)[0]; 208 | 209 | currentPropLabel.className = 'mc-workbench-prop-label'; 210 | currentPropInput.className = 'mc-workbench-prop-input'; 211 | currentPropButton.className = currentButtonClass; 212 | currentPropTip.className = currentPropTip; 213 | } 214 | }); 215 | 216 | /* Search for 'settings' props */ 217 | [].forEach.call(propLabelSetting, function(currentPropLabel) { 218 | var propLabelName = currentPropLabel.innerHTML; 219 | var currentPropInput = currentPropLabel.nextElementSibling; 220 | var currentPropButton = currentPropInput.nextElementSibling; 221 | var currentPropTip = currentPropButton.nextElementSibling; 222 | 223 | /* Save button and tip classes, just in case they in use to get a selector */ 224 | var currentButtonClass = currentPropButton.className; 225 | var currentPropTip = currentPropTip.className; 226 | 227 | /* If doesn't match search query */ 228 | if( !propLabelName.match(regexQuery) ) { 229 | /* Only add .hide to elements that doesn't have it already */ 230 | if ( !currentPropLabel.className.match(/hide/) ) { 231 | currentPropLabel.className = currentPropLabel.className + ' hide'; 232 | currentPropInput.className = currentPropInput.className + ' hide'; 233 | currentPropButton.className = currentPropButton.className + ' hide'; 234 | currentPropTip.className = currentPropButton.className + ' hide'; 235 | } 236 | } else { 237 | currentPropLabel.className = 'mc-workbench-prop-label'; 238 | currentPropInput.className = 'mc-workbench-prop-input'; 239 | currentPropButton.className = currentButtonClass; 240 | currentPropTip.className = currentPropTip; 241 | } 242 | }); 243 | } 244 | 245 | function processSelector(selector) { 246 | // Verify if we have a prop waiting for selector 247 | if ( currentProp ) { 248 | currentProp.value = selector; 249 | 250 | var grabTip = currentProp.nextSibling.nextSibling; 251 | grabTip.className = grabTip.className + ' inactive'; 252 | 253 | var grabButtonSelected = document.querySelector('.mc-workbench-prop-button.selected'); 254 | grabButtonSelected.className = 'mc-workbench-prop-button'; 255 | 256 | updateMappingProps(currentProp.id, currentProp.value); 257 | 258 | currentProp = false; 259 | 260 | } 261 | 262 | // Verify if we have to provide a simple selector 263 | if ( grabbingSimpleSelector ) { 264 | var statusMessage = document.querySelector('#mc-workbench-getselector-modal-status'); 265 | var simpleSelectorInput = document.querySelector('#mc-workbench-getselector-modal-input'); 266 | 267 | statusMessage.innerHTML = ''; 268 | statusMessage.className = ''; 269 | 270 | simpleSelectorInput.value = selector; 271 | } 272 | } 273 | 274 | function copyWidgetToClipboard() { 275 | var widgetOutput = document.querySelector('#mc-workbench-export-modal-box'); 276 | var statusMessage = document.querySelector('#mc-workbench-export-modal-status'); 277 | 278 | widgetOutput.focus(); 279 | widgetOutput.select(); 280 | 281 | try { 282 | var successful = document.execCommand('copy'); 283 | statusMessage.innerHTML = 'Widget copied to clipboard.'; 284 | } catch (err) { 285 | statusMessage.className = 'error'; 286 | statusMessage.innerHTML = 'Error copying to clipboard, please copy it manually.'; 287 | } 288 | 289 | window.getSelection().removeAllRanges(); 290 | } 291 | 292 | function copySelectorToClipboard() { 293 | var selectorOutput = document.querySelector('#mc-workbench-getselector-modal-input'); 294 | var statusMessage = document.querySelector('#mc-workbench-getselector-modal-status'); 295 | 296 | selectorOutput.focus(); 297 | selectorOutput.select(); 298 | 299 | if( selectorOutput.value == '' ) { 300 | statusMessage.className = 'error'; 301 | statusMessage.innerHTML = 'Empty selector'; 302 | return; 303 | } 304 | 305 | try { 306 | var successful = document.execCommand('copy'); 307 | statusMessage.className = ''; 308 | statusMessage.innerHTML = 'Selector copied to clipboard.'; 309 | } catch (err) { 310 | statusMessage.className = 'error'; 311 | statusMessage.innerHTML = 'Error copying to clipboard, please copy it manually.'; 312 | } 313 | 314 | window.getSelection().removeAllRanges(); 315 | } 316 | 317 | function exportOnlyFields(checkbox) { 318 | var widgetName = document.querySelector('#mc-workbench-widget-name').innerHTML; 319 | var exportBox = document.querySelector('#mc-workbench-export-modal-box'); 320 | var exportText = exportBox.value; 321 | if ( checkbox.checked ) { 322 | savedExportText = exportText; 323 | exportText = exportText.replace('\{\n\t\tname: \'' + widgetName + '\',', ''); 324 | exportText = exportText.replace('\n\t\tselectors: {', ''); 325 | exportText = exportText.replace('\n\t\t},\n\t\tsettings: {', ''); 326 | exportText = exportText.replace('\n\t\t},\n\t},', ''); 327 | exportText = exportText.replace(/^\n\t\t\t/, ''); 328 | exportBox.value = exportText; 329 | } else { 330 | exportBox.value = savedExportText; 331 | } 332 | } 333 | 334 | function isModal(checkbox) { 335 | var modalSelectors = ['modalCloseButton', 'modalSubtitle', 'modalTitle']; 336 | if ( checkbox.checked ) { 337 | insertExtraSelectors(modalSelectors, 'modal'); 338 | localStorage.setItem('mc-workbench-is-modal', 'true'); 339 | } else { 340 | removeExtraSelectors(modalSelectors); 341 | localStorage.setItem('mc-workbench-is-modal', 'false'); 342 | } 343 | } 344 | 345 | function commonProps(checkbox) { 346 | var commonSelectors = ['className', 'hideIfExists', 'expectFromAutoClick', 'autoClick']; 347 | if ( checkbox.checked ) { 348 | insertExtraSelectors(commonSelectors, 'common'); 349 | localStorage.setItem('mc-workbench-common-props', 'true'); 350 | } else { 351 | removeExtraSelectors(commonSelectors); 352 | localStorage.setItem('mc-workbench-common-props', 'false'); 353 | } 354 | } 355 | 356 | function showOnlyError(checkbox) { 357 | var propLabelSelector = document.querySelectorAll('#mc-workbench-selector-container > .mc-workbench-prop-label'); 358 | var propLabelSetting = document.querySelectorAll('#mc-workbench-settings-container > .mc-workbench-prop-label'); 359 | 360 | if ( checkbox.checked ) { 361 | /* Search for 'selector' props */ 362 | [].forEach.call(propLabelSelector, function(currentPropLabel) { 363 | var propLabelName = currentPropLabel.innerHTML; 364 | var currentPropInput = currentPropLabel.nextElementSibling; 365 | var currentPropButton = currentPropInput.nextElementSibling; 366 | var currentPropTip = currentPropButton.nextElementSibling; 367 | 368 | /* If doesn't matches with 'error' */ 369 | if( !propLabelName.match(/error/gi) ) { 370 | currentPropLabel.setAttribute('data-not-error', 'true'); 371 | currentPropInput.setAttribute('data-not-error', 'true'); 372 | currentPropButton.setAttribute('data-not-error', 'true'); 373 | currentPropTip.setAttribute('data-not-error', 'true'); 374 | } 375 | }); 376 | 377 | /* Search for 'settings' props */ 378 | [].forEach.call(propLabelSetting, function(currentPropLabel) { 379 | var propLabelName = currentPropLabel.innerHTML; 380 | var currentPropInput = currentPropLabel.nextElementSibling; 381 | var currentPropButton = currentPropInput.nextElementSibling; 382 | var currentPropTip = currentPropButton.nextElementSibling; 383 | 384 | /* If doesn't have value */ 385 | if( !propLabelName.match(/error/gi) ) { 386 | currentPropLabel.setAttribute('data-not-error', 'true'); 387 | currentPropInput.setAttribute('data-not-error', 'true'); 388 | currentPropButton.setAttribute('data-not-error', 'true'); 389 | currentPropTip.setAttribute('data-not-error', 'true'); 390 | } 391 | }); 392 | 393 | } else { 394 | /* Search for 'selector' props */ 395 | [].forEach.call(propLabelSelector, function(currentPropLabel) { 396 | var propLabelName = currentPropLabel.innerHTML; 397 | var currentPropInput = currentPropLabel.nextElementSibling; 398 | var currentPropButton = currentPropInput.nextElementSibling; 399 | var currentPropTip = currentPropButton.nextElementSibling; 400 | 401 | /* If doesn't have value */ 402 | if( !propLabelName.match(/error/gi) ) { 403 | currentPropLabel.setAttribute('data-not-error', ''); 404 | currentPropInput.setAttribute('data-not-error', ''); 405 | currentPropButton.setAttribute('data-not-error', ''); 406 | currentPropTip.setAttribute('data-not-error', ''); 407 | } 408 | }); 409 | 410 | /* Search for 'settings' props */ 411 | [].forEach.call(propLabelSetting, function(currentPropLabel) { 412 | var propLabelName = currentPropLabel.innerHTML; 413 | var currentPropInput = currentPropLabel.nextElementSibling; 414 | var currentPropButton = currentPropInput.nextElementSibling; 415 | var currentPropTip = currentPropButton.nextElementSibling; 416 | 417 | /* If doesn't have value */ 418 | if( !propLabelName.match(/error/gi) ) { 419 | currentPropLabel.setAttribute('data-not-error', ''); 420 | currentPropInput.setAttribute('data-not-error', ''); 421 | currentPropButton.setAttribute('data-not-error', ''); 422 | currentPropTip.setAttribute('data-not-error', ''); 423 | } 424 | }); 425 | } 426 | } 427 | 428 | function showOnlyMapped(checkbox) { 429 | var propLabelSelector = document.querySelectorAll('#mc-workbench-selector-container > .mc-workbench-prop-label'); 430 | var propLabelSetting = document.querySelectorAll('#mc-workbench-settings-container > .mc-workbench-prop-label'); 431 | 432 | if ( checkbox.checked ) { 433 | /* Search for 'selector' props */ 434 | [].forEach.call(propLabelSelector, function(currentPropLabel) { 435 | var propLabelName = currentPropLabel.innerHTML; 436 | var currentPropInput = currentPropLabel.nextElementSibling; 437 | var currentPropButton = currentPropInput.nextElementSibling; 438 | var currentPropTip = currentPropButton.nextElementSibling; 439 | 440 | /* If doesn't have value */ 441 | if( currentPropInput.value == '' ) { 442 | currentPropLabel.setAttribute('data-not-mapped', 'true'); 443 | currentPropInput.setAttribute('data-not-mapped', 'true'); 444 | currentPropButton.setAttribute('data-not-mapped', 'true'); 445 | currentPropTip.setAttribute('data-not-mapped', 'true'); 446 | } 447 | }); 448 | 449 | /* Search for 'settings' props */ 450 | [].forEach.call(propLabelSetting, function(currentPropLabel) { 451 | var propLabelName = currentPropLabel.innerHTML; 452 | var currentPropInput = currentPropLabel.nextElementSibling; 453 | var currentPropButton = currentPropInput.nextElementSibling; 454 | var currentPropTip = currentPropButton.nextElementSibling; 455 | 456 | /* If doesn't have value */ 457 | if( currentPropInput.value == '' ) { 458 | currentPropLabel.setAttribute('data-not-mapped', 'true'); 459 | currentPropInput.setAttribute('data-not-mapped', 'true'); 460 | currentPropButton.setAttribute('data-not-mapped', 'true'); 461 | currentPropTip.setAttribute('data-not-mapped', 'true'); 462 | } 463 | }); 464 | 465 | } else { 466 | /* Search for 'selector' props */ 467 | [].forEach.call(propLabelSelector, function(currentPropLabel) { 468 | var propLabelName = currentPropLabel.innerHTML; 469 | var currentPropInput = currentPropLabel.nextElementSibling; 470 | var currentPropButton = currentPropInput.nextElementSibling; 471 | var currentPropTip = currentPropButton.nextElementSibling; 472 | 473 | /* If doesn't have value */ 474 | if( currentPropInput.value == '' ) { 475 | currentPropLabel.setAttribute('data-not-mapped', ''); 476 | currentPropInput.setAttribute('data-not-mapped', ''); 477 | currentPropButton.setAttribute('data-not-mapped', ''); 478 | currentPropTip.setAttribute('data-not-mapped', ''); 479 | } 480 | }); 481 | 482 | /* Search for 'settings' props */ 483 | [].forEach.call(propLabelSetting, function(currentPropLabel) { 484 | var propLabelName = currentPropLabel.innerHTML; 485 | var currentPropInput = currentPropLabel.nextElementSibling; 486 | var currentPropButton = currentPropInput.nextElementSibling; 487 | var currentPropTip = currentPropButton.nextElementSibling; 488 | 489 | /* If doesn't have value */ 490 | if( currentPropInput.value == '' ) { 491 | currentPropLabel.setAttribute('data-not-mapped', ''); 492 | currentPropInput.setAttribute('data-not-mapped', ''); 493 | currentPropButton.setAttribute('data-not-mapped', ''); 494 | currentPropTip.setAttribute('data-not-mapped', ''); 495 | } 496 | }); 497 | } 498 | } 499 | 500 | function insertExtraSelectors(arrayOfSelectors, extraType) { 501 | var selectorContainer = document.querySelector('#mc-workbench-selector-container'); 502 | arrayOfSelectors.forEach(function(currentElement) { 503 | 504 | var selectorLabel = document.createElement('label'); 505 | var selectorElement = document.createElement('input'); 506 | var selectorButton = document.createElement('div'); 507 | var selectorTip = document.createElement('div'); 508 | 509 | selectorLabel.className = 'mc-workbench-prop-label'; 510 | selectorLabel.for = currentElement + '-selector'; 511 | selectorLabel.innerHTML = currentElement; 512 | selectorLabel.setAttribute('data-extra', currentElement); 513 | selectorLabel.setAttribute('data-extra-type', extraType); 514 | 515 | selectorElement.type = "text"; 516 | selectorElement.className = 'mc-workbench-prop-input'; 517 | selectorElement.name = currentElement; 518 | selectorElement.id = currentElement + '-selector'; 519 | selectorElement.setAttribute('data-extra', currentElement); 520 | selectorElement.setAttribute('data-extra-type', extraType); 521 | 522 | selectorButton.className = 'mc-workbench-prop-button'; 523 | selectorButton.setAttribute('data-prop', selectorElement.id); 524 | selectorButton.setAttribute('onclick', 'grabSelector()'); 525 | selectorButton.innerHTML = 'Grab'; 526 | selectorButton.setAttribute('data-extra', currentElement); 527 | selectorButton.setAttribute('data-extra-type', extraType); 528 | 529 | selectorTip.className = 'mc-workbench-prop-tip inactive'; 530 | selectorTip.innerHTML = 'Now, just click on some element in the original site'; 531 | selectorTip.setAttribute('data-extra', currentElement); 532 | 533 | selectorContainer.insertBefore(selectorTip, selectorContainer.firstChild); 534 | selectorContainer.insertBefore(selectorButton, selectorContainer.firstChild); 535 | selectorContainer.insertBefore(selectorElement, selectorContainer.firstChild); 536 | selectorContainer.insertBefore(selectorLabel, selectorContainer.firstChild); 537 | }); 538 | } 539 | 540 | function removeExtraSelectors(arrayOfSelectors) { 541 | var selectorContainer = document.querySelector('#mc-workbench-selector-container'); 542 | var extraSelectors = document.querySelectorAll('#mc-workbench-selector-container > [data-extra]'); 543 | arrayOfSelectors.forEach(function(currentElement) { 544 | [].forEach.call(extraSelectors, function(currentExtraSelector) { 545 | var dataExtra = currentExtraSelector.getAttribute('data-extra'); 546 | if ( dataExtra == currentElement ) { 547 | selectorContainer.removeChild(currentExtraSelector); 548 | } 549 | }); 550 | }); 551 | } 552 | 553 | function grabSelector() { 554 | grabbingSelector = true; 555 | var grabButton = event.target; 556 | var grabProp = grabButton.getAttribute('data-prop'); 557 | // Reset any opened tip 558 | var grabTip = document.querySelector('.mc-workbench-prop-tip.active'); 559 | if ( grabTip ) { 560 | grabTip.className = 'mc-workbench-prop-tip inactive'; 561 | } 562 | // Reset any grab button 563 | var grabButtonSelected = document.querySelector('.mc-workbench-prop-button.selected'); 564 | if ( grabButtonSelected ) { 565 | grabButtonSelected.className = 'mc-workbench-prop-button'; 566 | } 567 | 568 | grabTip = grabButton.nextElementSibling; 569 | grabTip.className = 'mc-workbench-prop-tip active'; 570 | grabButton.className = grabButton.className + ' selected'; 571 | currentProp = document.querySelector('#'+grabProp); 572 | } 573 | 574 | function toggleMCIframe() { 575 | if( mcIframe.className.match(/^active/) ) { 576 | mcIframe.className = 'inactive'; 577 | mcIframe.style.display = 'none'; 578 | originalBody.style.width = '50%'; 579 | workbench.style.width = '50%'; 580 | } else { 581 | mcIframe.className = 'active'; 582 | mcIframe.style.display = 'block'; 583 | originalBody.style.width = '33.3%'; 584 | workbench.style.width = '33.3%'; 585 | } 586 | } 587 | 588 | function disableActions() { 589 | var disableMenuText = document.querySelector('#mc-workbench-disable-actions'); 590 | var element = originalBody.querySelectorAll('a, select, input, button'); 591 | 592 | disableMenuText.className = 'mc-workbench-menu-text actions-disabled'; 593 | [].forEach.call(element, function(currentElement) { 594 | 595 | if ( !currentElement.id.match(/mc-workbench/) ) { 596 | $(currentElement).unbind(); 597 | currentElement.setAttribute('onclick', 'return false'); 598 | 599 | switch(currentElement.tagName.toLowerCase()) { 600 | case 'a': 601 | var href = currentElement.href; 602 | currentElement.setAttribute('data-href', href); 603 | currentElement.setAttribute('href', ''); 604 | break; 605 | case 'select': 606 | currentElement.innerHTML = ''; 607 | break; 608 | case 'input': 609 | // If it needs some extra implementation 610 | break; 611 | case 'button': 612 | // If it needs some extra implementation 613 | break; 614 | } 615 | } 616 | }); 617 | } 618 | 619 | function getUx() { 620 | var xhr = new XMLHttpRequest(); 621 | xhr.open('GET', 'https://localhost:8443/ux/workbench.html', true); 622 | xhr.onreadystatechange = function() { 623 | if (xhr.readyState == 4) { 624 | var response = xhr.responseText.trim(); 625 | workbench.innerHTML = response; 626 | } 627 | } 628 | xhr.send(); 629 | } 630 | 631 | function getWidgetNames() { 632 | var xhr = new XMLHttpRequest(); 633 | xhr.open('GET', 'https://localhost:8443/widgets', true); 634 | xhr.onreadystatechange = function() { 635 | if (xhr.readyState == 4) { 636 | var response = xhr.responseText.trim(); 637 | var regex = /name\"\>(.*?)\<\/span\>/g; 638 | var response = response.match(regex); 639 | 640 | var responseIndex = response.length; 641 | 642 | for( var i = 0; i < responseIndex; i++ ) { 643 | var match = regex.exec(response); 644 | widgets.push(match[1]); 645 | } 646 | } 647 | } 648 | xhr.send(); 649 | } 650 | 651 | function getWidgetTemplate(widgetFile) { 652 | var xhr = new XMLHttpRequest(); 653 | xhr.open('GET', 'https://localhost:8443/widgets/' + widgetFile, true); 654 | xhr.onreadystatechange = function() { 655 | if (xhr.readyState == 4) { 656 | var widgetResult = JSON.stringify(xhr.responseText.trim()); 657 | processWidgetFields(widgetResult); 658 | } 659 | } 660 | xhr.send(); 661 | } 662 | 663 | function processWidgetFields(widgetResult) { 664 | var widgetTemplate = widgetResult; 665 | 666 | /* Process selectors (if widget has selectors) */ 667 | if( widgetResult.match(/selectors/) ) { 668 | widgetSelectors = widgetTemplate.replace(/settings.*/g, ''); 669 | widgetSelectors = widgetSelectors.replace(/selectors:\s\{\\n\s*/g, ''); 670 | widgetSelectors = widgetSelectors.replace(/\\n\s*/g, ''); 671 | widgetSelectors = widgetSelectors.match(/(\w*?)\:/g, ''); 672 | 673 | /* Remove first element, it's the 'name' of the widget */ 674 | widgetSelectors.shift(); 675 | 676 | [].forEach.call(widgetSelectors, function(currentSelector, currentIndex) { 677 | currentSelector = currentSelector.replace(/\:/, ''); 678 | widgetSelectors[currentIndex] = currentSelector; 679 | }); 680 | } else { 681 | widgetSelectors = false; 682 | console.log("Widget doesn't have selectors"); 683 | } 684 | 685 | /* Process settings (if widget has settings) */ 686 | if( widgetResult.match(/settings/) ) { 687 | widgetSettings = widgetTemplate.replace(/selectors:\s\{\\n\s*.*settings:\s\{\\n\s*/g, ''); 688 | widgetSettings = widgetSettings.replace(/\\n\s*/g, ''); 689 | widgetSettings = widgetSettings.match(/(\w*?)\:/g, ''); 690 | 691 | /* Remove first element, it's the 'name' of the widget */ 692 | widgetSettings.shift(); 693 | 694 | [].forEach.call(widgetSettings, function(currentSetting, currentIndex) { 695 | currentSetting = currentSetting.replace(/\:/, ''); 696 | widgetSettings[currentIndex] = currentSetting; 697 | }); 698 | } else { 699 | widgetSettings = false; 700 | console.log("Widget doesn't have settings"); 701 | } 702 | 703 | buildWidgetInterface(); 704 | } 705 | 706 | function buildWidgetInterface() { 707 | /* Build selectors */ 708 | // Verify if widget has selectors 709 | var selectorSection = document.querySelector('#mc-workbench-selector-section'); 710 | if( widgetSelectors ) { 711 | var selectorContainer = document.querySelector('#mc-workbench-selector-container'); 712 | var selectorIndex = widgetSelectors.length; 713 | 714 | selectorSection.className = 'active'; 715 | 716 | for( var i = 0; i < selectorIndex; i++ ) { 717 | var selectorLabel = document.createElement('label'); 718 | var selectorElement = document.createElement('input'); 719 | var selectorButton = document.createElement('div'); 720 | var selectorTip = document.createElement('div'); 721 | 722 | selectorLabel.className = 'mc-workbench-prop-label'; 723 | selectorLabel.for = widgetSelectors[i] + '-selector'; 724 | selectorLabel.innerHTML = widgetSelectors[i]; 725 | 726 | selectorElement.type = "text"; 727 | selectorElement.className = 'mc-workbench-prop-input'; 728 | selectorElement.name = widgetSelectors[i]; 729 | selectorElement.id = widgetSelectors[i] + '-selector'; 730 | 731 | selectorButton.className = 'mc-workbench-prop-button'; 732 | selectorButton.setAttribute('data-prop', selectorElement.id); 733 | selectorButton.setAttribute('onclick', 'grabSelector()'); 734 | selectorButton.innerHTML = 'Grab'; 735 | 736 | selectorTip.className = 'mc-workbench-prop-tip inactive'; 737 | selectorTip.innerHTML = 'Now, just click on some element in the original site'; 738 | 739 | selectorContainer.appendChild(selectorLabel); 740 | selectorContainer.appendChild(selectorElement); 741 | selectorContainer.appendChild(selectorButton); 742 | selectorContainer.appendChild(selectorTip); 743 | } 744 | } else { 745 | selectorSection.className = 'inactive'; 746 | } 747 | 748 | // Verify if widget has settings 749 | var settingsSection = document.querySelector('#mc-workbench-settings-section'); 750 | if( widgetSettings ) { 751 | var settingsContainer = document.querySelector('#mc-workbench-settings-container'); 752 | var settingsIndex = widgetSettings.length; 753 | 754 | settingsSection.className = 'active'; 755 | 756 | for( var i = 0; i < settingsIndex; i++ ) { 757 | var settingLabel = document.createElement('label'); 758 | var settingElement = document.createElement('input'); 759 | var settingButton = document.createElement('div'); 760 | var settingTip = document.createElement('div'); 761 | 762 | settingLabel.className = 'mc-workbench-prop-label'; 763 | settingLabel.for = widgetSettings[i] + '-setting'; 764 | settingLabel.innerHTML = widgetSettings[i]; 765 | 766 | settingElement.type = "text"; 767 | settingElement.className = 'mc-workbench-prop-input'; 768 | settingElement.name = widgetSettings[i]; 769 | settingElement.id = widgetSettings[i] + '-setting'; 770 | 771 | settingButton.className = 'mc-workbench-prop-button'; 772 | settingButton.setAttribute('data-prop', settingElement.id); 773 | settingButton.setAttribute('onclick', 'grabSelector()'); 774 | settingButton.innerHTML = 'Grab'; 775 | 776 | settingTip.className = 'mc-workbench-prop-tip inactive'; 777 | settingTip.innerHTML = 'Now, just click on some element in the original site'; 778 | 779 | settingsContainer.appendChild(settingLabel); 780 | settingsContainer.appendChild(settingElement); 781 | settingsContainer.appendChild(settingButton); 782 | settingsContainer.appendChild(settingTip); 783 | } 784 | } else { 785 | settingsSection.className = 'inactive'; 786 | } 787 | 788 | // If returning from a refresh 789 | if ( isMapping == 'true' ) { 790 | fillMappingProps(); 791 | } 792 | } 793 | 794 | function startWidgetEditor() { 795 | var widgetElement = event.target; 796 | var widgetName = event.target.innerHTML; 797 | var widgetFile = event.target.getAttribute('data-file'); 798 | var widgetEditorTitle = document.querySelector('#mc-workbench-widget-name'); 799 | var widgetSection = document.querySelector('#mc-workbench-widget-section'); 800 | var widgeEditor = document.querySelector('#mc-workbench-widget-editor'); 801 | 802 | widgetSection.className = 'inactive'; 803 | destroyWidgetList(); 804 | widgeEditor.className = 'active'; 805 | 806 | widgetEditorTitle.innerHTML = widgetName; 807 | 808 | getWidgetTemplate(widgetFile); 809 | 810 | isMapping = true; 811 | setMappingStatus(isMapping); 812 | 813 | updateMappingWidget(widgetName, widgetFile); 814 | } 815 | 816 | function buildWidgetList() { 817 | var widgetList = document.querySelector('#mc-workbench-widget-list'); 818 | var widgetIndex = widgets.length; 819 | for( var i = 0; i < widgetIndex; i++ ) { 820 | var widgetFile = widgets[i]; 821 | var widgetName = widgets[i].replace(/(\.txt|\.json)/, ''); 822 | var widgetElement = document.createElement('li'); 823 | widgetElement.className = 'widget'; 824 | widgetElement.setAttribute('data-file', widgetFile); 825 | widgetElement.setAttribute('onclick', 'startWidgetEditor()'); 826 | widgetElement.innerHTML = widgetName; 827 | widgetList.appendChild(widgetElement); 828 | } 829 | } 830 | 831 | function destroyWidgetList() { 832 | var widgetList = document.querySelector('#mc-workbench-widget-list'); 833 | widgetList.innerHTML = ''; 834 | } 835 | 836 | function destroyWidgetEditor() { 837 | var widgetEditorSelector = document.querySelector('#mc-workbench-selector-container'); 838 | var widgetEditorSettings = document.querySelector('#mc-workbench-settings-container'); 839 | widgetEditorSelector.innerHTML = ''; 840 | widgetEditorSettings.innerHTML = ''; 841 | } 842 | 843 | function startMapping() { 844 | var widgetSection = document.querySelector('#mc-workbench-widget-section'); 845 | var widgetEditor = document.querySelector('#mc-workbench-widget-editor'); 846 | var initialView = document.querySelector('#mc-workbench-initial-view'); 847 | var isModalCheckbox = document.querySelector('#mc-workbench-selector-common-selectors'); 848 | var commonPropsCheckbox = document.querySelector('#mc-workbench-selector-is-modal'); 849 | var searchWidget = document.querySelector('#mc-workbench-widget-search'); 850 | var searchProp = document.querySelector('#mc-workbench-prop-search'); 851 | 852 | // Reset checked isModal checkbox 853 | isModalCheckbox.checked = false; 854 | var isModalChekbox = localStorage.setItem('mc-workbench-is-modal', 'false'); 855 | 856 | // Reset checked commonProps checkbox 857 | commonPropsCheckbox.checked = false; 858 | var commonPropsChekbox = localStorage.setItem('mc-workbench-common-props', 'false'); 859 | 860 | // Reset widget search field 861 | searchWidget.value = ''; 862 | 863 | // Reset prop search field 864 | searchProp.value = ''; 865 | 866 | // Reset isMapping status 867 | isMapping = false; 868 | setMappingStatus(isMapping); 869 | 870 | widgetEditor.className = 'inactive'; 871 | destroyWidgetEditor(); 872 | 873 | if( widgetSection.className.match(/^active/) ) { 874 | widgetSection.className = 'inactive'; 875 | initialView.className = 'active'; 876 | destroyWidgetList(); 877 | } else { 878 | widgetSection.className = 'active'; 879 | initialView.className = 'inactive'; 880 | buildWidgetList(); 881 | } 882 | } 883 | 884 | function injectWorkbench() { 885 | 886 | // Get widget names 887 | getWidgetNames(); 888 | 889 | // Get UX 890 | getUx(); 891 | workbench.id = 'mc-workbench-container'; 892 | body.appendChild(workbench); 893 | 894 | // Get if a widget was in mapping process before refresh 895 | isMapping = getMappingStatus(); 896 | if( isMapping == 'true' ) { 897 | resumeMappingWidget(); 898 | } 899 | } 900 | 901 | function closeGetSelectorModal() { 902 | var getSelectorModal = document.querySelector('#mc-workbench-getselector-modal'); 903 | var getSelectorModalOverlay = document.querySelector('#mc-workbench-getselector-modal-overlay'); 904 | var getSelectorInput = document.querySelector('#mc-workbench-getselector-modal-input'); 905 | var statusMessage = document.querySelector('#mc-workbench-getselector-modal-status'); 906 | 907 | getSelectorModal.className = 'inactive'; 908 | getSelectorModalOverlay.className = 'inactive'; 909 | getSelectorInput.value = ''; 910 | statusMessage.innerHTML = ''; 911 | statusMessage.className = ''; 912 | 913 | grabbingSimpleSelector = false; 914 | } 915 | 916 | function openGetSelectorModal() { 917 | var getSelectorModal = document.querySelector('#mc-workbench-getselector-modal'); 918 | var getSelectorModalOverlay = document.querySelector('#mc-workbench-getselector-modal-overlay'); 919 | 920 | getSelectorModal.className = 'active'; 921 | getSelectorModalOverlay.className = 'active'; 922 | 923 | grabbingSimpleSelector = true; 924 | } 925 | 926 | function closeExportModal() { 927 | var exportModal = document.querySelector('#mc-workbench-export-modal'); 928 | var exportModalOverlay = document.querySelector('#mc-workbench-export-modal-overlay'); 929 | var statusMessage = document.querySelector('#mc-workbench-export-modal-status'); 930 | var exportOnlyFieldsCheckbox = document.querySelector('#mc-workbench-selector-only-fields'); 931 | exportModal.className = 'inactive'; 932 | exportModalOverlay.className = 'inactive'; 933 | statusMessage.innerHTML = ''; 934 | statusMessage.className = ''; 935 | exportOnlyFieldsCheckbox.checked = false; 936 | } 937 | 938 | function openExportModal(schema) { 939 | var exportModal = document.querySelector('#mc-workbench-export-modal'); 940 | var exportModalOverlay = document.querySelector('#mc-workbench-export-modal-overlay'); 941 | var exportBox = document.querySelector('#mc-workbench-export-modal-box'); 942 | exportModal.className = 'active'; 943 | exportModalOverlay.className = 'active'; 944 | exportBox.value = schema; 945 | 946 | //exportBox.style.height = 'auto'; 947 | exportBox.setAttribute('style', 'height: auto !important'); 948 | var newHeight = exportBox.scrollHeight + 6; 949 | //exportBox.style.height = newHeight+'px'; 950 | exportBox.setAttribute('style', 'height: ' + newHeight + 'px !important'); 951 | } 952 | 953 | function exportSchema() { 954 | /* Verify if we have any active widget to export */ 955 | if ( widgetSelectors || widgetSettings ) { 956 | var selectorInputs = document.querySelectorAll('#mc-workbench-selector-container > .mc-workbench-prop-input'); 957 | var settingInputs = document.querySelectorAll('#mc-workbench-settings-container > .mc-workbench-prop-input'); 958 | var selectorProps = []; 959 | var settingProps = []; 960 | 961 | [].forEach.call(selectorInputs, function(currentInput) { 962 | /* Check if it's not empty */ 963 | if ( currentInput.value != '' ) { 964 | selectorProps.push(currentInput.id); 965 | } 966 | }); 967 | 968 | [].forEach.call(settingInputs, function(currentInput) { 969 | /* Check if it's not empty */ 970 | if ( currentInput.value != '' ) { 971 | settingProps.push(currentInput.id); 972 | } 973 | }); 974 | 975 | var schema = buildSchema(selectorProps, settingProps); 976 | openExportModal(schema); 977 | 978 | } else { 979 | alert('You don\'t have any active widget to export'); 980 | } 981 | } 982 | 983 | function buildSchema(selectorProps, settingProps) { 984 | var widgetName = document.querySelector('#mc-workbench-widget-name').innerHTML; 985 | var schemaString = '{' + 986 | '\n\t\tname: \'' + widgetName + '\','; 987 | 988 | /* If widget has selectors */ 989 | if(selectorProps.length > 0) { 990 | var selectorsString = '\n\t\tselectors: {'; 991 | 992 | schemaString = schemaString.concat(selectorsString); 993 | 994 | [].forEach.call(selectorProps, function(currentProp) { 995 | var currentPropElement = document.querySelector('#mc-workbench-selector-container > #' + currentProp); 996 | var propName = currentPropElement.name; 997 | var propValue = currentPropElement.value; 998 | 999 | var propString = '\n\t\t\t' + propName + ': ' + '\'' + propValue + '\','; 1000 | 1001 | schemaString = schemaString.concat(propString); 1002 | }); 1003 | 1004 | var closeSelectorsString = '\n\t\t},'; 1005 | schemaString = schemaString.concat(closeSelectorsString); 1006 | } 1007 | 1008 | /* If widget has settings */ 1009 | if(settingProps.length > 0) { 1010 | var settingsString = '\n\t\tsettings: {'; 1011 | 1012 | schemaString = schemaString.concat(settingsString); 1013 | 1014 | [].forEach.call(settingProps, function(currentProp) { 1015 | var currentPropElement = document.querySelector('#mc-workbench-settings-container > #' + currentProp); 1016 | var propName = currentPropElement.name; 1017 | var propValue = currentPropElement.value; 1018 | 1019 | var propString = '\n\t\t\t' + propName + ': ' + '\'' + propValue + '\','; 1020 | 1021 | schemaString = schemaString.concat(propString); 1022 | }); 1023 | 1024 | var closeSettingsString = '\n\t\t},'; 1025 | schemaString = schemaString.concat(closeSettingsString); 1026 | } 1027 | 1028 | var endString = '\n\t},'; 1029 | 1030 | schemaString = schemaString.concat(endString); 1031 | return schemaString; 1032 | } 1033 | 1034 | /* 1035 | CSS Selector Generator, v1.0.4 1036 | by Riki Fridrich (http://fczbkk.com) 1037 | https://github.com/fczbkk/css-selector-generator/ 1038 | */ 1039 | (function(){var t,e,n=[].indexOf||function(t){for(var e=0,n=this.length;n>e;e++)if(e in this&&this[e]===t)return e;return-1};t=function(){function t(t){null==t&&(t={}),this.options={},this.setOptions(this.default_options),this.setOptions(t)}return t.prototype.default_options={selectors:["id","class","tag","nthchild"]},t.prototype.setOptions=function(t){var e,n,r;null==t&&(t={}),n=[];for(e in t)r=t[e],this.default_options.hasOwnProperty(e)?n.push(this.options[e]=r):n.push(void 0);return n},t.prototype.isElement=function(t){return!(1!==(null!=t?t.nodeType:void 0))},t.prototype.getParents=function(t){var e,n;if(n=[],this.isElement(t))for(e=t;this.isElement(e);)n.push(e),e=e.parentNode;return n},t.prototype.getTagSelector=function(t){return this.sanitizeItem(t.tagName.toLowerCase())},t.prototype.sanitizeItem=function(t){var e;return e=t.split("").map(function(t){return":"===t?"\\"+":".charCodeAt(0).toString(16).toUpperCase()+" ":/[ !"#$%&'()*+,.\/;<=>?@\[\\\]^`{|}~]/.test(t)?"\\"+t:escape(t).replace(/\%/g,"\\")}),e.join("")},t.prototype.getIdSelector=function(t){var e,n;return e=t.getAttribute("id"),null==e||""===e||/\s/.exec(e)||/^\d/.exec(e)||(n="#"+this.sanitizeItem(e),1!==t.ownerDocument.querySelectorAll(n).length)?null:n},t.prototype.getClassSelectors=function(t){var e,n,r;return r=[],"HTML"===t.tagName?r:(e=t.getAttribute("class"),null!=e&&(e=e.replace(/\s+/g," "),e=e.replace(/^\s|\s$/g,""),""!==e&&(r=function(){var t,r,o,i;for(o=e.split(/\s+/),i=[],t=0,r=o.length;r>t;t++)n=o[t],i.push("."+this.sanitizeItem(n));return i}.call(this))),r)},t.prototype.getAttributeSelectors=function(t){var e,r,o,i,s,l,u;for(u=[],r=["id","class"],s=t.attributes,o=0,i=s.length;i>o;o++)e=s[o],l=e.nodeName,n.call(r,l)<0&&u.push("["+e.nodeName+"="+e.nodeValue+"]");return u},t.prototype.getNthChildSelector=function(t){var e,n,r,o,i,s;if(o=t.parentNode,null!=o)for(e=0,s=o.childNodes,n=0,r=s.length;r>n;n++)if(i=s[n],this.isElement(i)&&(e++,i===t))return":nth-child("+e+")";return null},t.prototype.testSelector=function(t,e){var n,r;return n=!1,null!=e&&""!==e&&(r=t.ownerDocument.querySelectorAll(e),1===r.length&&r[0]===t&&(n=!0)),n},t.prototype.getAllSelectors=function(t){var e;return e={t:null,i:null,c:null,a:null,n:null},n.call(this.options.selectors,"tag")>=0&&(e.t=this.getTagSelector(t)),n.call(this.options.selectors,"id")>=0&&(e.i=this.getIdSelector(t)),n.call(this.options.selectors,"class")>=0&&(e.c=this.getClassSelectors(t)),n.call(this.options.selectors,"attribute")>=0&&(e.a=this.getAttributeSelectors(t)),n.call(this.options.selectors,"nthchild")>=0&&(e.n=this.getNthChildSelector(t)),e},t.prototype.testUniqueness=function(t,e){var n,r;return r=t.parentNode,n=r.querySelectorAll(e),1===n.length&&n[0]===t},t.prototype.testCombinations=function(t,e,n){var r,o,i,s,l,u,c;for(u=this.getCombinations(e),o=0,s=u.length;s>o;o++)if(r=u[o],this.testUniqueness(t,r))return r;if(null!=n)for(c=e.map(function(t){return n+t}),i=0,l=c.length;l>i;i++)if(r=c[i],this.testUniqueness(t,r))return r;return null},t.prototype.getUniqueSelector=function(t){var e,n,r,o,i,s;for(s=this.getAllSelectors(t),o=this.options.selectors,n=0,r=o.length;r>n;n++)switch(i=o[n]){case"id":if(null!=s.i)return s.i;break;case"tag":if(null!=s.t&&this.testUniqueness(t,s.t))return s.t;break;case"class":if(null!=s.c&&0!==s.c.length&&(e=this.testCombinations(t,s.c,s.t)))return e;break;case"attribute":if(null!=s.a&&0!==s.a.length&&(e=this.testCombinations(t,s.a,s.t)))return e;break;case"nthchild":if(null!=s.n)return s.n}return"*"},t.prototype.getSelector=function(t){var e,n,r,o,i,s,l,u,c,a;for(e=[],l=this.getParents(t),r=0,i=l.length;i>r;r++)n=l[r],c=this.getUniqueSelector(n),null!=c&&e.push(c);for(a=[],o=0,s=e.length;s>o;o++)if(n=e[o],a.unshift(n),u=a.join(" > "),this.testSelector(t,u))return u;return null},t.prototype.getCombinations=function(t){var e,n,r,o,i,s,l;for(null==t&&(t=[]),l=[[]],e=r=0,i=t.length-1;i>=0?i>=r:r>=i;e=i>=0?++r:--r)for(n=o=0,s=l.length-1;s>=0?s>=o:o>=s;n=s>=0?++o:--o)l.push(l[n].concat(t[e]));return l.shift(),l=l.sort(function(t,e){return t.length-e.length}),l=l.map(function(t){return t.join("")})},t}(),("undefined"!=typeof define&&null!==define?define.amd:void 0)?define([],function(){return t}):(e="undefined"!=typeof exports&&null!==exports?exports:this,e.CssSelectorGenerator=t)}).call(this); 1040 | --------------------------------------------------------------------------------