├── .gitignore ├── src ├── session-src │ ├── .gitignore │ ├── package-lock.json │ ├── index.js │ ├── package.json │ └── src │ │ ├── managers │ │ ├── DataManagers.js │ │ └── LogManager.js │ │ ├── ScriptLoader.js │ │ └── Session.js ├── client-src │ ├── assets │ │ ├── css │ │ │ └── style.css │ │ └── fonts │ │ │ ├── typeface-roboto │ │ │ ├── files-hash.json │ │ │ ├── files │ │ │ │ ├── roboto-latin-300.woff │ │ │ │ ├── roboto-latin-300.woff2 │ │ │ │ ├── roboto-latin-400.woff │ │ │ │ ├── roboto-latin-400.woff2 │ │ │ │ ├── roboto-latin-500.woff │ │ │ │ └── roboto-latin-500.woff2 │ │ │ ├── README.md │ │ │ ├── index.css │ │ │ └── package.json │ │ │ └── material-icons │ │ │ ├── files │ │ │ └── icons.woff2 │ │ │ └── index.css │ ├── index.server.template.html │ ├── readme.md │ ├── comps │ │ ├── Upload.jsx │ │ ├── Config.jsx │ │ ├── Hideable.jsx │ │ ├── Debug.jsx │ │ ├── PluginItem.jsx │ │ ├── Navigator.jsx │ │ ├── BrowseItem.jsx │ │ └── Home.jsx │ ├── comps-bootstrap │ │ ├── Config.jsx │ │ ├── Upload.jsx │ │ ├── Debug.jsx │ │ ├── backup │ │ │ ├── css │ │ │ │ ├── style.css │ │ │ │ ├── bootstrap-4.1.3-dist │ │ │ │ │ └── css │ │ │ │ │ │ ├── bootstrap-reboot.min.css │ │ │ │ │ │ ├── bootstrap-reboot.css │ │ │ │ │ │ ├── bootstrap-reboot.min.css.map │ │ │ │ │ │ └── bootstrap-grid.min.css │ │ │ │ └── popper.min.js │ │ │ └── index.html │ │ ├── Decal.jsx │ │ ├── AppBS.jsx │ │ ├── PluginItem.jsx │ │ ├── BrowseItem.jsx │ │ ├── Navigator.jsx │ │ └── Home.jsx │ ├── index.js │ ├── controller.js │ └── App.jsx ├── index.template.html ├── index.html ├── host │ ├── main.jsx │ ├── index.jsx │ └── JSON.jsx └── libs │ └── CSInterface.js ├── kap.gif ├── .babelrc ├── assets ├── icons │ └── favicon.ico └── templates │ ├── .debug.template.js │ └── manifest.template.xml.js ├── pluginrc.js ├── package.json ├── readme.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | /dist/ 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /src/session-src/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /kap.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HendrixString/adobe-cep-react-create/HEAD/kap.gif -------------------------------------------------------------------------------- /src/client-src/assets/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0px; 3 | overflow: hidden 4 | } 5 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "env", 4 | "react", 5 | "stage-2" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /assets/icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HendrixString/adobe-cep-react-create/HEAD/assets/icons/favicon.ico -------------------------------------------------------------------------------- /src/session-src/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "session", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1 5 | } 6 | -------------------------------------------------------------------------------- /src/client-src/assets/fonts/typeface-roboto/files-hash.json: -------------------------------------------------------------------------------- 1 | {"hash":"5da83aae9cc1b95ba5433e6a414145c8","updatedAt":"2018-01-24T02:15:56.414Z"} -------------------------------------------------------------------------------- /src/session-src/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import session from './src/Session.js' 6 | 7 | window.session = session 8 | -------------------------------------------------------------------------------- /src/client-src/assets/fonts/material-icons/files/icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HendrixString/adobe-cep-react-create/HEAD/src/client-src/assets/fonts/material-icons/files/icons.woff2 -------------------------------------------------------------------------------- /src/client-src/assets/fonts/typeface-roboto/files/roboto-latin-300.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HendrixString/adobe-cep-react-create/HEAD/src/client-src/assets/fonts/typeface-roboto/files/roboto-latin-300.woff -------------------------------------------------------------------------------- /src/client-src/assets/fonts/typeface-roboto/files/roboto-latin-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HendrixString/adobe-cep-react-create/HEAD/src/client-src/assets/fonts/typeface-roboto/files/roboto-latin-300.woff2 -------------------------------------------------------------------------------- /src/client-src/assets/fonts/typeface-roboto/files/roboto-latin-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HendrixString/adobe-cep-react-create/HEAD/src/client-src/assets/fonts/typeface-roboto/files/roboto-latin-400.woff -------------------------------------------------------------------------------- /src/client-src/assets/fonts/typeface-roboto/files/roboto-latin-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HendrixString/adobe-cep-react-create/HEAD/src/client-src/assets/fonts/typeface-roboto/files/roboto-latin-400.woff2 -------------------------------------------------------------------------------- /src/client-src/assets/fonts/typeface-roboto/files/roboto-latin-500.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HendrixString/adobe-cep-react-create/HEAD/src/client-src/assets/fonts/typeface-roboto/files/roboto-latin-500.woff -------------------------------------------------------------------------------- /src/client-src/assets/fonts/typeface-roboto/files/roboto-latin-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HendrixString/adobe-cep-react-create/HEAD/src/client-src/assets/fonts/typeface-roboto/files/roboto-latin-500.woff2 -------------------------------------------------------------------------------- /src/client-src/index.server.template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Export Example App 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /src/client-src/readme.md: -------------------------------------------------------------------------------- 1 | #### UI 2 | 3 | right now I am using `Material-UI` 4 | I also have a `Bootstrap` version (but you will have to setup it's dependencies like 5 | css and js.) 6 | 7 | #### two app skins 8 | I wrote one app with `Bootstrap` and the other with `Material-UI` 9 | -------------------------------------------------------------------------------- /src/index.template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Export Example App 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/client-src/comps/Upload.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react' 6 | 7 | export default class Upload extends React.Component { 8 | 9 | render() { 10 | return ( 11 |
12 |

Upload

13 |
14 | ) 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/session-src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "session", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "postinstall": "mkdir -p node_modules" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": {} 13 | } 14 | -------------------------------------------------------------------------------- /src/client-src/comps-bootstrap/Config.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react' 6 | 7 | export default class Config extends React.Component { 8 | 9 | render() { 10 | 11 | return ( 12 |
13 |

Config

14 |
15 | ) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/client-src/comps-bootstrap/Upload.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react' 6 | 7 | export default class Upload extends React.Component { 8 | 9 | render() { 10 | return ( 11 |
12 |

Upload

13 |
14 | ) 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/client-src/comps-bootstrap/Debug.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react' 6 | 7 | export default class Debug extends React.Component { 8 | 9 | render() { 10 | 11 | return ( 12 |
13 |

Debug

14 |
15 | ) 16 | 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/client-src/comps/Config.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react' 6 | 7 | export default class Config extends React.Component { 8 | 9 | render() { 10 | 11 | return ( 12 |
13 |

Config

14 |
15 | ) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Export Example App 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/client-src/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react' 6 | import ReactDOM from 'react-dom' 7 | import App from './App.jsx' 8 | import controller from './Controller.js' 9 | 10 | import './assets/fonts/typeface-roboto/index.css'; 11 | import './assets/fonts/material-icons/index.css'; 12 | import './assets/css/style.css'; 13 | 14 | ReactDOM.render(, 15 | document.getElementById('root') 16 | ) 17 | -------------------------------------------------------------------------------- /src/session-src/src/managers/DataManagers.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import LogManager from './LogManager.js' 6 | 7 | export default class DataManagers { 8 | _manager_log = undefined 9 | 10 | constructor() { 11 | 12 | } 13 | 14 | init() { 15 | this._manager_log = new LogManager() 16 | 17 | this._manager_log.init() 18 | } 19 | 20 | /** 21 | * get log - the log manager 22 | * 23 | * @return {LogManager} the log manager 24 | */ 25 | get log() { 26 | return this._manager_log 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/client-src/assets/fonts/material-icons/index.css: -------------------------------------------------------------------------------- 1 | /* fallback */ 2 | @font-face { 3 | font-family: 'Material Icons'; 4 | font-style: normal; 5 | font-weight: 400; 6 | src: url('./files/icons.woff2') format('woff2'); 7 | } 8 | 9 | .material-icons { 10 | font-family: 'Material Icons'; 11 | font-weight: normal; 12 | font-style: normal; 13 | font-size: 24px; 14 | line-height: 1; 15 | letter-spacing: normal; 16 | text-transform: none; 17 | display: inline-block; 18 | white-space: nowrap; 19 | word-wrap: normal; 20 | direction: ltr; 21 | -webkit-font-feature-settings: 'liga'; 22 | -webkit-font-smoothing: antialiased; 23 | } 24 | -------------------------------------------------------------------------------- /assets/templates/.debug.template.js: -------------------------------------------------------------------------------- 1 | module.exports = (props) => 2 | ` 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ` 19 | -------------------------------------------------------------------------------- /src/client-src/comps-bootstrap/backup/css/style.css: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | 13 | * { 14 | } 15 | -------------------------------------------------------------------------------- /src/host/main.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Adobe. All rights reserved. 3 | This file is licensed to you under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy 5 | of the License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under 8 | the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS 9 | OF ANY KIND, either express or implied. See the License for the specific language 10 | governing permissions and limitations under the License. 11 | */ 12 | #include "./JSON.jsx" 13 | 14 | // alert(JSON.stringify(a)) 15 | 16 | function test_host(obj_string) { 17 | // alert(obj_string) 18 | res = JSON.parse(obj_string) 19 | // alert(res) 20 | return 'hola from extendscript ' + res.name 21 | } 22 | -------------------------------------------------------------------------------- /src/client-src/comps-bootstrap/Decal.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react' 6 | 7 | function colorToCss(color) { 8 | return { 9 | backgroundColor: color 10 | } 11 | } 12 | 13 | export default class Decal extends React.Component { 14 | 15 | render() { 16 | var {title, desc, imgSrc, color} = this.props 17 | 18 | return ( 19 |
21 | 23 |
24 |
{title}
25 | {desc} 26 |
27 |
28 | ) 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/client-src/comps-bootstrap/backup/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Export Example App 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/host/index.jsx: -------------------------------------------------------------------------------- 1 | if(typeof($)=='undefined') 2 | $={} 3 | 4 | $._ext = { 5 | //Evaluate a file and catch the exception. 6 | evalFile : function(path) { 7 | try { 8 | $.evalFile(path); 9 | } catch (e) {alert("Exception:" + e)} 10 | }, 11 | // Evaluate all the files in the given folder 12 | evalFiles: function(jsxFolderPath) { 13 | var folder = new Folder(jsxFolderPath) 14 | if (folder.exists) { 15 | var jsxFiles = folder.getFiles("*.jsx") 16 | for (var i = 0; i < jsxFiles.length; i++) { 17 | var jsxFile = jsxFiles[i] 18 | $._ext.evalFile(jsxFile) 19 | } 20 | } 21 | } 22 | } 23 | 24 | // // fileName is a String (with the .jsx extension included) 25 | // function loadJSX(fileName) { 26 | // var csInterface = new CSInterface(); 27 | // var extensionRoot = csInterface.getSystemPath(SystemPath.EXTENSION) + "/jsx/"; 28 | // csInterface.evalScript('$.evalFile("' + extensionRoot + fileName + '")'); 29 | // } 30 | -------------------------------------------------------------------------------- /src/client-src/comps/Hideable.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react'; 6 | 7 | /** 8 | * simple wrapper component that supports visibility 9 | */ 10 | export default class Hideable extends React.Component { 11 | constructor(props) { 12 | super(props) 13 | } 14 | 15 | invisibleStyle = { 16 | display: 'none' 17 | } 18 | 19 | visibleStyle = { 20 | display: 'block' 21 | } 22 | 23 | visStyle(on) { 24 | return on ? this.visibleStyle : this.invisibleStyle 25 | } 26 | 27 | render() { 28 | const { visible, invisible, style, className} = this.props 29 | const resolved = visible ? true : false 30 | 31 | var mergedStyle = this.visStyle(resolved) 32 | 33 | if(style) 34 | mergedStyle = Object.assign(style, mergedStyle) 35 | 36 | return ( 37 |
38 | {this.props.children} 39 |
40 | ) 41 | 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /pluginrc.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const root = __dirname 3 | const srcFolder = path.join(root, "src") 4 | const destFolder = path.join(root, "dist") 5 | const certPath = path.join(destFolder, "cert.p12") 6 | module.exports = { 7 | extensionBundleId: 'com.hendrix.demo', 8 | extensionBundleName: 'demo', 9 | extensionBundleVersion: '1.0.1', 10 | cepVersion: '7.0', 11 | panelName: 'hendrix demo', 12 | width: '400', 13 | height: '600', 14 | root: root, 15 | sourceFolder: srcFolder, 16 | destinationFolder: destFolder, 17 | certificate : { 18 | customCert: { 19 | path: '', 20 | password: 'password' 21 | }, 22 | selfSign: { 23 | country: 'US', 24 | province: 'CA', 25 | org: 'org', 26 | name: 'name', 27 | password: 'password', 28 | locality: 'locality', 29 | orgUnit: 'orgUnit', 30 | email: 'your@email.com', 31 | output: certPath 32 | } 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/client-src/assets/fonts/typeface-roboto/README.md: -------------------------------------------------------------------------------- 1 | 2 | # typeface-roboto 3 | 4 | The CSS and web font files to easily self-host “Roboto”. 5 | 6 | ## Install 7 | 8 | `npm install --save typeface-roboto` 9 | 10 | ## Use 11 | 12 | Typefaces assume you’re using webpack to process CSS and files. Each typeface 13 | package includes all necessary font files (woff2, woff, eot, ttf, svg) and 14 | a CSS file with font-face declarations pointing at these files. 15 | 16 | You will need to have webpack setup to load css and font files. Many tools built 17 | with Webpack will work out of the box with Typefaces such as [Gatsby](https://github.com/gatsbyjs/gatsby) 18 | and [Create React App](https://github.com/facebookincubator/create-react-app). 19 | 20 | To use, simply require the package in your project’s entry file e.g. 21 | 22 | ```javascript 23 | // Load Roboto typeface 24 | require('typeface-roboto') 25 | ``` 26 | 27 | ## About the Typefaces project. 28 | 29 | Our goal is to add all open source fonts to NPM to simplify using great fonts in 30 | our web projects. We’re currently maintaining 856 typeface packages 31 | including all typefaces on Google Fonts. 32 | 33 | If your favorite typeface isn’t published yet, [let us know](https://github.com/KyleAMathews/typefaces) 34 | and we’ll add it! 35 | -------------------------------------------------------------------------------- /src/client-src/assets/fonts/typeface-roboto/index.css: -------------------------------------------------------------------------------- 1 | /* roboto-300normal - latin */ 2 | @font-face { 3 | font-family: 'Roboto'; 4 | font-style: normal; 5 | font-display: swap; 6 | font-weight: 300; 7 | src: 8 | local('Roboto Light '), 9 | local('Roboto-Light'), 10 | url('./files/roboto-latin-300.woff2') format('woff2'), /* Super Modern Browsers */ 11 | url('./files/roboto-latin-300.woff') format('woff'); /* Modern Browsers */ 12 | } 13 | 14 | /* roboto-400normal - latin */ 15 | @font-face { 16 | font-family: 'Roboto'; 17 | font-style: normal; 18 | font-display: swap; 19 | font-weight: 400; 20 | src: 21 | local('Roboto Regular '), 22 | local('Roboto-Regular'), 23 | url('./files/roboto-latin-400.woff2') format('woff2'), /* Super Modern Browsers */ 24 | url('./files/roboto-latin-400.woff') format('woff'); /* Modern Browsers */ 25 | } 26 | 27 | /* roboto-500normal - latin */ 28 | @font-face { 29 | font-family: 'Roboto'; 30 | font-style: normal; 31 | font-display: swap; 32 | font-weight: 500; 33 | src: 34 | local('Roboto Medium '), 35 | local('Roboto-Medium'), 36 | url('./files/roboto-latin-500.woff2') format('woff2'), /* Super Modern Browsers */ 37 | url('./files/roboto-latin-500.woff') format('woff'); /* Modern Browsers */ 38 | } 39 | -------------------------------------------------------------------------------- /src/client-src/comps/Debug.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react' 6 | import { Hook, Console, Decode } from 'console-feed' 7 | 8 | const styles = { 9 | root: { 10 | width: '100%', 11 | height: '100%', 12 | } 13 | } 14 | 15 | /** 16 | * display chrome debugger tools console 17 | */ 18 | export default class Debug extends React.Component { 19 | constructor(props) { 20 | super(props) 21 | } 22 | 23 | state = { 24 | logs: [] 25 | } 26 | 27 | componentDidMount() { 28 | // iniitial logz 29 | const { rawLogz } = this.props 30 | 31 | // also listen 32 | Hook(window.console, (log) => { 33 | this.setState((state) => { 34 | var logz = state.logs.slice() 35 | logz.push(Decode(log)) 36 | return { 37 | logs: logz 38 | } 39 | 40 | }) 41 | 42 | }) 43 | 44 | // replay initial logs 45 | console.log(...rawLogz) 46 | } 47 | 48 | render() { 49 | 50 | return ( 51 |
52 | 53 |
54 | ) 55 | 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/session-src/src/managers/LogManager.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | 6 | /** 7 | * log management 8 | * 9 | */ 10 | export default class LogManager { 11 | _logs = [] 12 | 13 | constructor() { 14 | 15 | } 16 | 17 | init() { 18 | this.log('initing...') 19 | 20 | var log = console.log 21 | 22 | if(console === undefined) 23 | return 24 | var that = this 25 | // override the console.log method 26 | console.log = function () { 27 | // log.call(this, 'My Console!!!') 28 | // log.apply(this, Array.prototype.slice.call(arguments)) 29 | // retain older console.log functionality 30 | log.call(this, ...arguments) 31 | // save the log internally 32 | that.addRawLog(...arguments) 33 | } 34 | 35 | } 36 | 37 | /** 38 | * addLog - collect log 39 | * 40 | * @param {Object} val anything 41 | * 42 | */ 43 | addRawLog(val) { 44 | this._logs.push(val) 45 | } 46 | 47 | get rawLogs() { 48 | return this._logs 49 | } 50 | 51 | get name() { 52 | return 'LogManager:: ' 53 | } 54 | 55 | log(val) { 56 | return `${this.name} ${val}` 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/client-src/assets/fonts/typeface-roboto/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "typeface-roboto", 3 | "_id": "typeface-roboto@0.0.54", 4 | "_inBundle": false, 5 | "_integrity": "sha512-sOFA1FXgP0gOgBYlS6irwq6hHYA370KE3dPlgYEJHL3PJd5X8gQE0RmL79ONif6fL5JZuGDj+rtOrFeOqz5IZQ==", 6 | "_location": "/typeface-roboto", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "tag", 10 | "registry": true, 11 | "raw": "typeface-roboto", 12 | "name": "typeface-roboto", 13 | "escapedName": "typeface-roboto", 14 | "rawSpec": "", 15 | "saveSpec": null, 16 | "fetchSpec": "latest" 17 | }, 18 | "_requiredBy": [ 19 | "#USER", 20 | "/" 21 | ], 22 | "_resolved": "https://registry.npmjs.org/typeface-roboto/-/typeface-roboto-0.0.54.tgz", 23 | "_shasum": "8f02c9a18d1cfa7f49381a6ff0d21ff061f38ad2", 24 | "_spec": "typeface-roboto", 25 | "_where": "/Users/tshalev/hendrix/sugar/plugin/cep/test2", 26 | "author": { 27 | "name": "Kyle Mathews", 28 | "email": "mathews.kyle@gmail.com" 29 | }, 30 | "bundleDependencies": false, 31 | "deprecated": false, 32 | "description": "Roboto typeface", 33 | "keywords": [ 34 | "typeface", 35 | "font", 36 | "font family", 37 | "google fonts", 38 | "roboto" 39 | ], 40 | "license": "MIT", 41 | "main": "index.css", 42 | "name": "typeface-roboto", 43 | "repository": { 44 | "type": "git", 45 | "url": "https://github.com/KyleAMathews/typefaces/tree/master/packages/roboto" 46 | }, 47 | "version": "0.0.54" 48 | } 49 | -------------------------------------------------------------------------------- /src/client-src/comps-bootstrap/AppBS.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react' 6 | 7 | import Home from './comps-bootstrap/Home.jsx' 8 | import Debug from './comps-bootstrap/Debug.jsx' 9 | import Config from './comps-bootstrap/Config.jsx' 10 | import Upload from './comps-bootstrap/Upload.jsx' 11 | import Navigator from './comps-bootstrap/Navigator.jsx' 12 | 13 | import session from './core/Session.js' 14 | 15 | /** 16 | * main app component 17 | * 18 | */ 19 | export default class App extends React.Component { 20 | 21 | constructor() { 22 | super() 23 | 24 | this.onExecutePlugin = this.onExecutePlugin.bind(this) 25 | 26 | // navigator data 27 | this.data = [ 28 | {title: 'Home', isActive: true, comp: }, 29 | {title: 'Upload', comp: }, 30 | {title: 'Config', comp: }, 31 | {title: 'Debug', comp: } 32 | ] 33 | 34 | } 35 | 36 | /** 37 | * execute the plugin 38 | * 39 | * @param {type} options description 40 | */ 41 | onExecutePlugin(options) { 42 | console.log('App:: onExecutePlugin') 43 | console.log(options) 44 | // here disable UI 45 | session.invokePlugin(options) 46 | // here enable ui 47 | } 48 | 49 | render() { 50 | 51 | return ( 52 |
53 | 54 |
55 | ) 56 | 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/client-src/controller.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | /** 6 | * the main plugin session. This can enter the node modules as 7 | * well as the host 8 | * 9 | */ 10 | class Controller { 11 | 12 | constructor() { 13 | //super() 14 | 15 | this.init() 16 | } 17 | 18 | /** 19 | * init - session 20 | * 21 | */ 22 | init() { 23 | this.log('client controller is initing...') 24 | this.log(`do we have session ? ${this.hasSession()}`) 25 | 26 | this.log('client controller has inited') 27 | } 28 | 29 | /** 30 | * invoke the plugin 31 | * 32 | * @param {{textures:boolean, masks:boolean, info: boolean, flatten:boolean}} options for plugin 33 | * 34 | * @return {object} describes how well the execution of plugin was 35 | */ 36 | invokePlugin(options) { 37 | this.log('invokePlugin') 38 | console.log(options) 39 | 40 | if(!this.hasSession()) 41 | return 42 | 43 | session.invokePlugin(options) 44 | .then(res => console.log(res)) 45 | .catch(err => console.log(err)) 46 | } 47 | 48 | 49 | /** 50 | * get logz - get raw logz from log manager 51 | * 52 | * @return {array} description 53 | */ 54 | get logz() { 55 | if(!this.hasSession()) 56 | return [] 57 | 58 | return session.managers.log.rawLogs 59 | } 60 | 61 | /** 62 | * do we have access to session services ? 63 | * 64 | * @return {boolean} true/false 65 | */ 66 | hasSession() { 67 | return window.session!==undefined 68 | } 69 | 70 | /** 71 | * log some info with session prefix 72 | * 73 | * @param {string} val what to log 74 | */ 75 | log(val) { 76 | console.log(`${this.name} ${val}`) 77 | } 78 | 79 | get name() { 80 | return 'Client Controller:: ' 81 | } 82 | 83 | } 84 | 85 | var controller = new Controller() 86 | 87 | export default controller 88 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cep-test", 3 | "version": "1.0.0", 4 | "description": "demo for CEP", 5 | "main": "./client-src/src/index.js", 6 | "scripts": { 7 | "build": "node ./scripts/build.js", 8 | "start": "npm run client:dev-server", 9 | "client:dev-server": "webpack-dev-server --config ./build-scripts/webpack.client.config.js --env.target=web --mode development --open", 10 | "build:dev": "node ./build-scripts/build.js development", 11 | "build:prod": "node ./build-scripts/build.js production", 12 | "deploy:dev": "node ./build-scripts/deploy.js development", 13 | "deploy:prod": "node ./build-scripts/deploy.js production", 14 | "archive": "node ./build-scripts/archive.js", 15 | "release:dev": "npm run build:dev && npm run deploy:dev", 16 | "release:prod": "npm run build:prod && npm run deploy:prod && npm run archive", 17 | "postinstall": "mkdirp src/session-src/node_modules", 18 | "b": "babel ./client/js --out-dir ./client/out", 19 | "test": "echo \"Error: no test specified\" && exit 1" 20 | }, 21 | "author": "Tomer Shalev (HendrixString)", 22 | "license": "ISC", 23 | "devDependencies": { 24 | "babel-cli": "^6.26.0", 25 | "babel-core": "^6.26.3", 26 | "babel-loader": "^7.1.5", 27 | "babel-preset-env": "^1.7.0", 28 | "babel-preset-react": "^6.24.1", 29 | "babel-preset-stage-2": "^6.24.1", 30 | "chalk": "^2.4.1", 31 | "copy-webpack-plugin": "^4.5.2", 32 | "css-loader": "^1.0.0", 33 | "extract-text-webpack-plugin": "^4.0.0-beta.0", 34 | "file-loader": "^1.1.11", 35 | "hard-source-webpack-plugin": "^0.12.0", 36 | "html-webpack-plugin": "^3.2.0", 37 | "mini-css-extract-plugin": "^0.4.1", 38 | "mkdirp": "^0.5.1", 39 | "style-loader": "^0.21.0", 40 | "webpack": "^4.16.2", 41 | "webpack-cli": "^3.1.0", 42 | "webpack-dev-server": "^3.7.2", 43 | "webpack-node-externals": "^1.7.2", 44 | "zxp-sign-cmd": "^1.0.0" 45 | }, 46 | "dependencies": { 47 | "@material-ui/core": "^1.4.2", 48 | "@material-ui/icons": "^2.0.0", 49 | "console-feed": "^2.8.3", 50 | "react": "^16.4.1", 51 | "react-dom": "^16.4.1" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/client-src/comps-bootstrap/PluginItem.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react' 6 | 7 | var roundedStyle = { 8 | width: '32px', 9 | height: '32px', 10 | backgroundColor: 'rgb(69 122 251)' 11 | } 12 | 13 | function getStyle(color) { 14 | return { 15 | width: '32px', 16 | height: '32px', 17 | backgroundColor: color 18 | } 19 | } 20 | 21 | /** 22 | * general plugin item that lives inside thw Home content 23 | * 24 | */ 25 | export default class PluginItem extends React.Component { 26 | 27 | constructor() { 28 | super() 29 | 30 | this.cbRef = React.createRef() 31 | } 32 | 33 | /** 34 | * get isChecked 35 | * 36 | * @return {type} description 37 | */ 38 | get isChecked() { 39 | return this.cbRef.current.checked 40 | } 41 | 42 | set check(val) { 43 | this.cbRef.current.checked = val 44 | } 45 | 46 | render() { 47 | const { index, title, desc, color, checked } = this.props; 48 | var attr = {} 49 | var defaultChecked = checked==='true' ? true : false 50 | var checkId = `check${index}` 51 | var style = getStyle(color ? color : 'rgb(69, 122, 251)') 52 | 53 | return ( 54 |
55 |
56 |
57 |
58 | {title} 59 | 60 |
61 | 63 |
65 | 66 |
67 | {desc} 68 |
69 |
70 | ) 71 | 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/client-src/comps/PluginItem.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react' 6 | import ListItem from "@material-ui/core/ListItem"; 7 | import ListItemSecondaryAction from "@material-ui/core/ListItemSecondaryAction"; 8 | import ListItemText from "@material-ui/core/ListItemText"; 9 | import Checkbox from "@material-ui/core/Checkbox"; 10 | import IconButton from "@material-ui/core/IconButton"; 11 | import Icon from '@material-ui/core/Icon'; 12 | 13 | /** 14 | * general plugin item that lives inside thw Home content 15 | * 16 | */ 17 | export default class PluginItem extends React.Component { 18 | 19 | constructor() { 20 | super() 21 | 22 | this.cbRef = React.createRef() 23 | } 24 | 25 | state = { 26 | checked: true 27 | } 28 | 29 | internal_check(on) { 30 | this.setState({ 31 | checked: on 32 | }) 33 | } 34 | 35 | handleToggle = () => { 36 | const { checked } = this.state 37 | 38 | this.setState({ 39 | checked: !checked 40 | }) 41 | 42 | } 43 | 44 | /** 45 | * get isChecked 46 | * 47 | * @return {type} description 48 | */ 49 | get isChecked() { 50 | return this.state.checked 51 | } 52 | 53 | set check(val) { 54 | this.internal_check(val) 55 | } 56 | 57 | render() { 58 | const { index, title, desc, icon } = this.props 59 | const { checked } = this.state 60 | 61 | return ( 62 | 69 | 73 | 74 | 75 | {icon} 76 | 77 | 78 | ) 79 | 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/client-src/comps-bootstrap/BrowseItem.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react' 6 | 7 | const INPUT_DEFAULT = "Choose folder" 8 | 9 | const lblStyle = { 10 | overflow:'hidden', 11 | display:'inline-block', 12 | textOverflow: 'ellipsis', 13 | whiteSpace: 'nowrap' 14 | } 15 | /** 16 | * general browse item 17 | * 18 | */ 19 | export default class BrowseItem extends React.Component { 20 | 21 | constructor() { 22 | super() 23 | 24 | this.onClick = this.onClick.bind(this) 25 | this.lblRef = React.createRef() 26 | } 27 | 28 | hello() { 29 | return 'hello from tomer' 30 | } 31 | 32 | 33 | /** 34 | * onClick - clicking the input 35 | * 36 | */ 37 | onClick(e) { 38 | console.log('BrowseItem::onClick') 39 | var path = 'path demo' 40 | 41 | // test if we are inside the adobe-cep runtime 42 | if(window.cep) { 43 | var result = window.cep.fs.showOpenDialog(false, true, 'Select a Folder', null, null) 44 | 45 | path = result.data 46 | } 47 | 48 | this.lblRef.current.innerHTML = path 49 | } 50 | 51 | /** 52 | * return path or undefined if it was not set 53 | * 54 | * @return {string|undefined} the path 55 | */ 56 | get path() { 57 | var raw = this.lblRef.current.innerHTML 58 | var isValid = raw.trim() !== INPUT_DEFAULT 59 | 60 | return isValid ? raw : undefined 61 | } 62 | 63 | render() { 64 | const {} = this.props; 65 | 66 | return ( 67 |
68 |
69 | 72 | 74 |
75 |
76 | ) 77 | 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/client-src/comps-bootstrap/Navigator.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react' 6 | 7 | function colorToCss(color) { 8 | return { 9 | backgroundColor: color 10 | } 11 | } 12 | 13 | /** 14 | * react component for creating a bootstrap 4 tab navigator. 15 | * configurable with data. 16 | */ 17 | export default class Navigator extends React.Component { 18 | 19 | constructor() { 20 | super() 21 | } 22 | 23 | /** 24 | * tabFactory - create a tab item 25 | * 26 | * @param {type} data description 27 | * @return {type} description 28 | */ 29 | tabFactory(data, index) { 30 | var title = data.title.toLowerCase() 31 | var isActive = data.isActive ? true : false 32 | var className = `nav-item nav-link ${isActive ? 'active' : ''}` 33 | 34 | return {data.title} 37 | } 38 | 39 | /** 40 | * tabFactory - create a tab content container 41 | * 42 | * @param {type} data description 43 | * @return {type} description 44 | */ 45 | tabContentFactory(data, index) { 46 | var title = data.title.toLowerCase() 47 | var isActive = data.isActive ? true : false 48 | var className = `tab-pane fade ${isActive ? 'show active' : ''}` 49 | 50 | return ( 51 |
53 | {data.comp} 54 |
55 | ) 56 | } 57 | 58 | render() { 59 | const { data } = this.props 60 | console.log(data) 61 | 62 | return ( 63 |
64 | 69 | 72 |
73 | ) 74 | 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/session-src/src/ScriptLoader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | /** 6 | * load jsx scripts dynamically 7 | */ 8 | class ScriptLoader { 9 | EvalScript_ErrMessage = "EvalScript error." 10 | 11 | constructor() { 12 | this.cs = new CSInterface() 13 | } 14 | 15 | get cs() { 16 | return this._cs 17 | } 18 | 19 | set cs(val) { 20 | this._cs = val 21 | } 22 | 23 | /** 24 | * loadJSX - load a jsx file dynamically, this 25 | * will also load all of it's includes which is desirable 26 | * 27 | * @param {type} fileName the file name 28 | * @return {type} description 29 | */ 30 | loadJSX(fileName) { 31 | var cs = this.cs 32 | var extensionRoot = cs.getSystemPath(SystemPath.EXTENSION) + "/host/"; 33 | 34 | cs.evalScript('$.evalFile("' + extensionRoot + fileName + '")'); 35 | } 36 | 37 | /** 38 | * evalScript - evaluate a JSX script 39 | * 40 | * @param {type} functionName the string name of the function to invoke 41 | * @param {type} params the params object 42 | * @return {Promise} a promise 43 | */ 44 | evalScript(functionName, params) { 45 | var params_string = params ? JSON.stringify(params) : '' 46 | var eval_string = `${functionName}('${params_string}')` 47 | var that = this 48 | 49 | return new Promise((resolve, reject) => { 50 | 51 | var callback = function(eval_res) { 52 | // console.log('weird' + eval_res) 53 | if(typeof eval_res === 'string') { 54 | // console.log(eval_res) 55 | if(eval_res.toLowerCase().indexOf('error') != -1) { 56 | that.log('err eval') 57 | reject(that.createScriptError(eval_res)) 58 | 59 | return 60 | } 61 | } 62 | 63 | that.log('success eval') 64 | 65 | resolve(eval_res) 66 | 67 | return 68 | } 69 | 70 | that.cs.evalScript(eval_string, callback) 71 | }) 72 | 73 | } 74 | 75 | createScriptError(reason, data) { 76 | return {reason, data} 77 | } 78 | 79 | /** 80 | * log some info with session prefix 81 | * 82 | * @param {string} val what to log 83 | */ 84 | log(val) { 85 | console.log(`${this.name} ${val}`) 86 | } 87 | 88 | get name() { 89 | return 'ScriptLoader:: ' 90 | } 91 | 92 | } 93 | 94 | var scriptLoader = new ScriptLoader() 95 | 96 | export default scriptLoader 97 | -------------------------------------------------------------------------------- /src/client-src/App.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react' 6 | 7 | import Home from './comps/Home.jsx' 8 | import Debug from './comps/Debug.jsx' 9 | import Config from './comps/Config.jsx' 10 | import Upload from './comps/Upload.jsx' 11 | import Navigator from './comps/Navigator.jsx' 12 | 13 | import purple from '@material-ui/core/colors/purple'; 14 | import green from '@material-ui/core/colors/green'; 15 | import indigo from '@material-ui/core/colors/indigo'; 16 | import pink from '@material-ui/core/colors/pink'; 17 | import red from '@material-ui/core/colors/red'; 18 | import orange from '@material-ui/core/colors/amber'; 19 | import cyan from '@material-ui/core/colors/cyan'; 20 | 21 | import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles' 22 | 23 | const theme = createMuiTheme({ 24 | palette: { 25 | type:'dark', 26 | primary: cyan, 27 | secondary: pink, 28 | error: red, 29 | contrastThreshold: 3, 30 | tonalOffset: 0.2, 31 | 32 | }, 33 | status: { 34 | danger: 'orange', 35 | }, 36 | typography: { 37 | // In Japanese the characters are usually larger. 38 | fontSize: 12, 39 | }, 40 | 41 | }) 42 | 43 | const styles = { 44 | root: { 45 | width: '100%', 46 | height: '100vh' 47 | } 48 | } 49 | 50 | /** 51 | * main app component 52 | * 53 | */ 54 | export default class App extends React.Component { 55 | _controller = undefined 56 | 57 | constructor(props) { 58 | super(props) 59 | 60 | // controller 61 | this._controller = props.controller 62 | // navigator data 63 | this.data = [ 64 | {title: 'Home', icon: 'home', comp: }, 65 | {title: 'Upload', icon: 'cloud_upload', comp: }, 66 | {title: 'Config', icon: 'settings', comp: }, 67 | {title: 'Debug', icon: 'bug_report', comp: } 68 | ] 69 | 70 | } 71 | 72 | onNavigateChange = (index, title) => { 73 | console.log(`onNavigateChange:: ${index}, ${title}`) 74 | } 75 | 76 | /** 77 | * get controller 78 | * 79 | * @return {Controller} 80 | */ 81 | get controller() { 82 | return this._controller 83 | } 84 | 85 | /** 86 | * execute the plugin 87 | * 88 | * @param {type} options description 89 | */ 90 | onExecutePlugin = (options) => { 91 | console.log('App:: onExecutePlugin') 92 | // here disable UI 93 | this._controller.invokePlugin(options) 94 | // here enable ui 95 | } 96 | 97 | render() { 98 | 99 | return ( 100 |
101 | 102 | 103 | 104 |
105 | ) 106 | 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/client-src/comps-bootstrap/Home.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react' 6 | 7 | import Decal from './Decal.jsx' 8 | import PluginItem from './PluginItem.jsx' 9 | import BrowseItem from './BrowseItem.jsx' 10 | 11 | function colorToCss(color) { 12 | return { 13 | backgroundColor: color 14 | } 15 | } 16 | 17 | /** 18 | * Home tab content 19 | * 20 | */ 21 | export default class Home extends React.Component { 22 | 23 | constructor() { 24 | super() 25 | 26 | this.export_onClick = this.export_onClick.bind(this) 27 | this.textureItemRef = React.createRef() 28 | this.masksItemRef = React.createRef() 29 | this.infoItemRef = React.createRef() 30 | this.flattenItemRef = React.createRef() 31 | this.browseItemRef = React.createRef() 32 | } 33 | 34 | /** 35 | * export button was clicked 36 | * 37 | */ 38 | export_onClick(e) { 39 | var folderPath = this.browseItemRef.current.path 40 | var isTexturesChecked = this.textureItemRef.current.isChecked 41 | var isMasksChecked = this.masksItemRef.current.isChecked 42 | var isInfoChecked = this.infoItemRef.current.isChecked 43 | var isFlattenChecked = this.flattenItemRef.current.isChecked 44 | 45 | var { onExecutePlugin } = this.props 46 | 47 | onExecutePlugin({ 48 | folderPath, isTexturesChecked, isMasksChecked, isInfoChecked, isFlattenChecked 49 | }) 50 | } 51 | 52 | render() { 53 | return ( 54 |
55 | 57 | 58 |
59 |
configurations
60 | 61 | 64 | 67 | 70 | 73 | 74 | 75 | 76 | Export 77 | 78 |
79 | 80 |
81 | ) 82 | 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/client-src/comps/Navigator.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react' 6 | import Paper from '@material-ui/core/Paper' 7 | import Tabs from '@material-ui/core/Tabs' 8 | import Tab from '@material-ui/core/Tab' 9 | import Icon from '@material-ui/core/Icon' 10 | import AppBar from '@material-ui/core/AppBar'; 11 | import withStyles from '@material-ui/core/styles/withStyles'; 12 | 13 | import Hideable from './Hideable.jsx' 14 | 15 | const styles = theme => ({ 16 | root: { 17 | flexDirection: 'column', 18 | width: '100%', 19 | height: '100%', 20 | display: 'flex', 21 | backgroundColor: theme.palette.background.paper 22 | }, 23 | contentContainer: { 24 | height: '100%', 25 | overflow: 'scroll', 26 | overflowX: 'hidden' 27 | } 28 | }) 29 | 30 | /** 31 | * react component for creating a material-ui tab navigator. 32 | * configurable with data. 33 | */ 34 | class Navigator extends React.Component { 35 | 36 | constructor(props) { 37 | super(props) 38 | } 39 | 40 | state = { 41 | activeTabIndex: 0, 42 | } 43 | 44 | handleChange = (event, value) => { 45 | this.setState({ activeTabIndex: value }) 46 | 47 | // notidy observer 48 | const {data, onNavigateChange} = this.props 49 | 50 | if(onNavigateChange) 51 | onNavigateChange(value, data[value].title) 52 | } 53 | 54 | /** 55 | * tabFactory - create a tab item 56 | * 57 | * @param {type} data description 58 | * @return {type} description 59 | */ 60 | tabFactory(data, index) { 61 | var title = data.title.toUpperCase() 62 | var icon = data.icon 63 | 64 | return {icon}} label={title}/> 65 | } 66 | 67 | /** 68 | * tabFactory - create a tab content container 69 | *{data.comp} 70 | * @param {type} data description 71 | * @return {type} description 72 | */ 73 | tabContentFactory(data, index, active, classes) { 74 | var title = data.title.toLowerCase() 75 | var comp = data.comp 76 | 77 | return ( 78 | {comp} 79 | ) 80 | } 81 | 82 | render() { 83 | const { data , classes} = this.props 84 | const { activeTabIndex } = this.state; 85 | 86 | return ( 87 |
88 | 89 | 93 | 94 | {data.map((item,i) => this.tabFactory(item, i))} 95 | 96 | 97 |
98 | {data.map((item,i) => this.tabContentFactory(item, i, activeTabIndex===i, classes))} 99 |
100 |
101 | ) 102 | 103 | } 104 | 105 | } 106 | 107 | export default withStyles(styles)(Navigator); 108 | -------------------------------------------------------------------------------- /src/host/JSON.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * JSON - from: https://github.com/douglascrockford/JSON-js 3 | */ 4 | if(typeof JSON!=='object'){JSON={};}(function(){'use strict';function f(n){return n<10?'0'+n:n;}function this_value(){return this.valueOf();}if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+f(this.getUTCMonth()+1)+'-'+f(this.getUTCDate())+'T'+f(this.getUTCHours())+':'+f(this.getUTCMinutes())+':'+f(this.getUTCSeconds())+'Z':null;};Boolean.prototype.toJSON=this_value;Number.prototype.toJSON=this_value;String.prototype.toJSON=this_value;}var cx,escapable,gap,indent,meta,rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}if(typeof rep==='function'){value=rep.call(holder,key,value);}switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i ({ 20 | margin: { 21 | margin: theme.spacing.unit, 22 | }, 23 | // cssLabel: { 24 | // '&$cssFocused': { 25 | // color: purple[500], 26 | // }, 27 | // }, 28 | // cssFocused: {}, 29 | // cssUnderline: { 30 | // '&:after': { 31 | // borderBottomColor: purple[500], 32 | // }, 33 | // }, 34 | folder: { 35 | marginRight: theme.spacing.unit * 3.5 36 | } 37 | }) 38 | 39 | /** 40 | * general browse item 41 | * 42 | */ 43 | class BrowseItem extends React.Component { 44 | 45 | constructor(props) { 46 | super(props) 47 | 48 | this.lblRef = React.createRef() 49 | } 50 | 51 | /** 52 | * onClick - clicking the input 53 | * 54 | */ 55 | onClick = (e) => { 56 | this.lblRef.current.focus() 57 | var path = this.lblRef.current.value 58 | 59 | // test if we are inside the adobe-cep runtime 60 | if(window.cep) { 61 | var result = window.cep.fs.showOpenDialog(false, 62 | true, 'Select a Folder', null, null) 63 | 64 | path = result.data 65 | } 66 | 67 | this.lblRef.current.value = path 68 | } 69 | 70 | /** 71 | * return path or undefined if it was not set 72 | * 73 | * @return {string|undefined} the path 74 | */ 75 | get path() { 76 | return this.lblRef.current.value 77 | } 78 | 79 | render() { 80 | const {classes} = this.props; 81 | 82 | return ( 83 | 86 | 87 | 88 | 92 | Choose Folder... 93 | 94 | 97 | 98 | 99 | 100 | 101 | folder_open 102 | 103 | 104 | 105 | 106 | 107 | ) 108 | 109 | } 110 | 111 | } 112 | 113 | export default withStyles(styles)(BrowseItem); 114 | -------------------------------------------------------------------------------- /src/session-src/src/Session.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import EventEmitter from 'events' 6 | import scriptLoader from './ScriptLoader' 7 | import DataManagers from './managers/DataManagers.js' 8 | /** 9 | * the main plugin session. This can enter the node modules as 10 | * well as the host 11 | * 12 | */ 13 | class Session { 14 | 15 | _managers = new DataManagers() 16 | 17 | constructor() { 18 | //super() 19 | 20 | this.init() 21 | } 22 | 23 | /** 24 | * init - session 25 | * 26 | */ 27 | init() { 28 | // init before everything so I can intercept console.log 29 | this._managers.init() 30 | this.log('session is initing...') 31 | // load jsx file dynamically 32 | this.log('loading the main jsx file') 33 | scriptLoader.loadJSX('main.jsx') 34 | 35 | // some testing 36 | this.test() 37 | // var fs = require('fs-extra') 38 | //console.log(fs) 39 | 40 | this.log('session is inited') 41 | } 42 | 43 | 44 | /** 45 | * get data managers 46 | * 47 | * @return {type} description 48 | */ 49 | get managers() { 50 | return this._managers 51 | } 52 | 53 | /** 54 | * scriptLoader - get the script loader 55 | * 56 | */ 57 | scriptLoader() { 58 | return scriptLoader 59 | } 60 | 61 | /** 62 | * test - let's test things 63 | * 64 | */ 65 | test() { 66 | var obj = { 67 | name: 'tomer' 68 | } 69 | 70 | scriptLoader.evalScript('test_host', obj).then((res) => { 71 | this.log('result is ' + res) 72 | }) 73 | } 74 | 75 | /** 76 | * invoke the plugin 77 | * 78 | * @param {{textures:boolean, masks:boolean, info: boolean, flatten:boolean}} options for plugin 79 | * 80 | * @return {object} describes how well the execution of plugin was 81 | */ 82 | invokePlugin(options) { 83 | const { folderPath, isFlattenChecked, 84 | isInfoChecked, isInspectVisibleChecked, 85 | isMasksChecked, isTexturesChecked, 86 | isMeaningfulNamesChecked, isHierarchicalChecked} = options 87 | 88 | // i reparse everything to detect failures 89 | const pluginData = { 90 | destinationFolder: folderPath, 91 | exportInfoJson: isInfoChecked, 92 | inspectOnlyVisibleLayers: isInspectVisibleChecked, 93 | exportMasks: isMasksChecked, 94 | exportTextures: isTexturesChecked, 95 | flatten: !isHierarchicalChecked, 96 | namePrefix: isMeaningfulNamesChecked ? 'layer' : undefined 97 | } 98 | 99 | var that = this 100 | 101 | return new Promise((resolve, reject) => { 102 | 103 | scriptLoader.evalScript('invoke_document_worker', pluginData) 104 | .then((res) => { 105 | resolve(JSON.parse(res)) 106 | }) 107 | .catch(err => { 108 | reject(err) 109 | }) 110 | 111 | }) 112 | 113 | } 114 | 115 | /** 116 | * log some info with session prefix 117 | * 118 | * @param {string} val what to log 119 | */ 120 | log(val) { 121 | console.log(`${this.name} ${val}`) 122 | } 123 | 124 | get name() { 125 | return 'Session:: ' 126 | } 127 | 128 | } 129 | 130 | var session = new Session() 131 | 132 | export default session 133 | -------------------------------------------------------------------------------- /assets/templates/manifest.template.xml.js: -------------------------------------------------------------------------------- 1 | module.exports = (props) => 2 | ` 3 | 4 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | ./index.html 40 | ./host/index.jsx 41 | 42 | --enable-nodejs 43 | --allow-file-access 44 | --allow-file-access-from-files 45 | 46 | 47 | 48 | true 49 | 50 | 51 | Panel 52 | ${props.panelName} 53 | 54 | 55 | ${props.width} 56 | ${props.height} 57 | 58 | 59 | ${props.width} 60 | ${props.height} 61 | 62 | 63 | ${props.width} 64 | ${props.height} 65 | 66 | 67 | 68 | ./icons/favicon.ico 69 | ./icons/favicon.ico 70 | ./icons/favicon.ico 71 | ./icons/favicon.ico 72 | 73 | 74 | 75 | 76 | 77 | ` 78 | -------------------------------------------------------------------------------- /src/client-src/comps-bootstrap/backup/css/bootstrap-4.1.3-dist/css/bootstrap-reboot.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v4.1.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2018 The Bootstrap Authors 4 | * Copyright 2011-2018 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) 7 | */*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important} 8 | /*# sourceMappingURL=bootstrap-reboot.min.css.map */ -------------------------------------------------------------------------------- /src/client-src/comps/Home.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Tomer Riko Shalev 3 | */ 4 | 5 | import React from 'react' 6 | import Paper from "@material-ui/core/Paper" 7 | import List from "@material-ui/core/List" 8 | import Button from "@material-ui/core/Button" 9 | import withStyles from '@material-ui/core/styles/withStyles' 10 | 11 | import PluginItem from './PluginItem.jsx' 12 | import BrowseItem from './BrowseItem.jsx' 13 | 14 | const styles = theme => ({ 15 | root: { 16 | paddingTop:theme.spacing.unit * 1 17 | }, 18 | paper: { 19 | display:'flex', 20 | flexDirection: 'column' 21 | }, 22 | export: { 23 | margin: theme.spacing.unit * 3, 24 | alignSelf: 'flex-end' 25 | } 26 | }) 27 | 28 | /** 29 | * Home tab content 30 | * 31 | */ 32 | class Home extends React.Component { 33 | 34 | constructor() { 35 | super() 36 | 37 | this.textureItemRef = React.createRef() 38 | this.masksItemRef = React.createRef() 39 | this.infoItemRef = React.createRef() 40 | this.hierarchicalItemRef = React.createRef() 41 | this.inspectVisibleItemRef = React.createRef() 42 | this.browseItemRef = React.createRef() 43 | this.namesItemRef = React.createRef() 44 | } 45 | 46 | /** 47 | * export button was clicked 48 | * 49 | */ 50 | export_onClick = (e) => { 51 | var folderPath = this.browseItemRef.current.path 52 | var isTexturesChecked = this.textureItemRef.current.isChecked 53 | var isMasksChecked = this.masksItemRef.current.isChecked 54 | var isInfoChecked = this.infoItemRef.current.isChecked 55 | var isHierarchicalChecked = this.hierarchicalItemRef.current.isChecked 56 | var isInspectVisibleChecked = this.inspectVisibleItemRef.current.isChecked 57 | var isMeaningfulNamesChecked = this.namesItemRef.current.isChecked 58 | 59 | var { onExecutePlugin } = this.props 60 | 61 | onExecutePlugin({ 62 | folderPath, 63 | isTexturesChecked, 64 | isMasksChecked, 65 | isInfoChecked, 66 | isMeaningfulNamesChecked, 67 | isHierarchicalChecked, 68 | isInspectVisibleChecked 69 | }) 70 | } 71 | 72 | render() { 73 | const { classes } = this.props; 74 | 75 | return ( 76 |
77 | 78 | 79 | 81 | 83 | 85 | 87 | 89 | 91 | 92 | 93 | 97 | 98 | 99 |
100 | ) 101 | 102 | } 103 | 104 | } 105 | 106 | export default withStyles(styles)(Home); 107 | -------------------------------------------------------------------------------- /src/client-src/comps-bootstrap/backup/css/bootstrap-4.1.3-dist/css/bootstrap-reboot.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v4.1.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2018 The Bootstrap Authors 4 | * Copyright 2011-2018 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) 7 | */ 8 | *, 9 | *::before, 10 | *::after { 11 | box-sizing: border-box; 12 | } 13 | 14 | html { 15 | font-family: sans-serif; 16 | line-height: 1.15; 17 | -webkit-text-size-adjust: 100%; 18 | -ms-text-size-adjust: 100%; 19 | -ms-overflow-style: scrollbar; 20 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 21 | } 22 | 23 | @-ms-viewport { 24 | width: device-width; 25 | } 26 | 27 | article, aside, figcaption, figure, footer, header, hgroup, main, nav, section { 28 | display: block; 29 | } 30 | 31 | body { 32 | margin: 0; 33 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 34 | font-size: 1rem; 35 | font-weight: 400; 36 | line-height: 1.5; 37 | color: #212529; 38 | text-align: left; 39 | background-color: #fff; 40 | } 41 | 42 | [tabindex="-1"]:focus { 43 | outline: 0 !important; 44 | } 45 | 46 | hr { 47 | box-sizing: content-box; 48 | height: 0; 49 | overflow: visible; 50 | } 51 | 52 | h1, h2, h3, h4, h5, h6 { 53 | margin-top: 0; 54 | margin-bottom: 0.5rem; 55 | } 56 | 57 | p { 58 | margin-top: 0; 59 | margin-bottom: 1rem; 60 | } 61 | 62 | abbr[title], 63 | abbr[data-original-title] { 64 | text-decoration: underline; 65 | -webkit-text-decoration: underline dotted; 66 | text-decoration: underline dotted; 67 | cursor: help; 68 | border-bottom: 0; 69 | } 70 | 71 | address { 72 | margin-bottom: 1rem; 73 | font-style: normal; 74 | line-height: inherit; 75 | } 76 | 77 | ol, 78 | ul, 79 | dl { 80 | margin-top: 0; 81 | margin-bottom: 1rem; 82 | } 83 | 84 | ol ol, 85 | ul ul, 86 | ol ul, 87 | ul ol { 88 | margin-bottom: 0; 89 | } 90 | 91 | dt { 92 | font-weight: 700; 93 | } 94 | 95 | dd { 96 | margin-bottom: .5rem; 97 | margin-left: 0; 98 | } 99 | 100 | blockquote { 101 | margin: 0 0 1rem; 102 | } 103 | 104 | dfn { 105 | font-style: italic; 106 | } 107 | 108 | b, 109 | strong { 110 | font-weight: bolder; 111 | } 112 | 113 | small { 114 | font-size: 80%; 115 | } 116 | 117 | sub, 118 | sup { 119 | position: relative; 120 | font-size: 75%; 121 | line-height: 0; 122 | vertical-align: baseline; 123 | } 124 | 125 | sub { 126 | bottom: -.25em; 127 | } 128 | 129 | sup { 130 | top: -.5em; 131 | } 132 | 133 | a { 134 | color: #007bff; 135 | text-decoration: none; 136 | background-color: transparent; 137 | -webkit-text-decoration-skip: objects; 138 | } 139 | 140 | a:hover { 141 | color: #0056b3; 142 | text-decoration: underline; 143 | } 144 | 145 | a:not([href]):not([tabindex]) { 146 | color: inherit; 147 | text-decoration: none; 148 | } 149 | 150 | a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus { 151 | color: inherit; 152 | text-decoration: none; 153 | } 154 | 155 | a:not([href]):not([tabindex]):focus { 156 | outline: 0; 157 | } 158 | 159 | pre, 160 | code, 161 | kbd, 162 | samp { 163 | font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 164 | font-size: 1em; 165 | } 166 | 167 | pre { 168 | margin-top: 0; 169 | margin-bottom: 1rem; 170 | overflow: auto; 171 | -ms-overflow-style: scrollbar; 172 | } 173 | 174 | figure { 175 | margin: 0 0 1rem; 176 | } 177 | 178 | img { 179 | vertical-align: middle; 180 | border-style: none; 181 | } 182 | 183 | svg { 184 | overflow: hidden; 185 | vertical-align: middle; 186 | } 187 | 188 | table { 189 | border-collapse: collapse; 190 | } 191 | 192 | caption { 193 | padding-top: 0.75rem; 194 | padding-bottom: 0.75rem; 195 | color: #6c757d; 196 | text-align: left; 197 | caption-side: bottom; 198 | } 199 | 200 | th { 201 | text-align: inherit; 202 | } 203 | 204 | label { 205 | display: inline-block; 206 | margin-bottom: 0.5rem; 207 | } 208 | 209 | button { 210 | border-radius: 0; 211 | } 212 | 213 | button:focus { 214 | outline: 1px dotted; 215 | outline: 5px auto -webkit-focus-ring-color; 216 | } 217 | 218 | input, 219 | button, 220 | select, 221 | optgroup, 222 | textarea { 223 | margin: 0; 224 | font-family: inherit; 225 | font-size: inherit; 226 | line-height: inherit; 227 | } 228 | 229 | button, 230 | input { 231 | overflow: visible; 232 | } 233 | 234 | button, 235 | select { 236 | text-transform: none; 237 | } 238 | 239 | button, 240 | html [type="button"], 241 | [type="reset"], 242 | [type="submit"] { 243 | -webkit-appearance: button; 244 | } 245 | 246 | button::-moz-focus-inner, 247 | [type="button"]::-moz-focus-inner, 248 | [type="reset"]::-moz-focus-inner, 249 | [type="submit"]::-moz-focus-inner { 250 | padding: 0; 251 | border-style: none; 252 | } 253 | 254 | input[type="radio"], 255 | input[type="checkbox"] { 256 | box-sizing: border-box; 257 | padding: 0; 258 | } 259 | 260 | input[type="date"], 261 | input[type="time"], 262 | input[type="datetime-local"], 263 | input[type="month"] { 264 | -webkit-appearance: listbox; 265 | } 266 | 267 | textarea { 268 | overflow: auto; 269 | resize: vertical; 270 | } 271 | 272 | fieldset { 273 | min-width: 0; 274 | padding: 0; 275 | margin: 0; 276 | border: 0; 277 | } 278 | 279 | legend { 280 | display: block; 281 | width: 100%; 282 | max-width: 100%; 283 | padding: 0; 284 | margin-bottom: .5rem; 285 | font-size: 1.5rem; 286 | line-height: inherit; 287 | color: inherit; 288 | white-space: normal; 289 | } 290 | 291 | progress { 292 | vertical-align: baseline; 293 | } 294 | 295 | [type="number"]::-webkit-inner-spin-button, 296 | [type="number"]::-webkit-outer-spin-button { 297 | height: auto; 298 | } 299 | 300 | [type="search"] { 301 | outline-offset: -2px; 302 | -webkit-appearance: none; 303 | } 304 | 305 | [type="search"]::-webkit-search-cancel-button, 306 | [type="search"]::-webkit-search-decoration { 307 | -webkit-appearance: none; 308 | } 309 | 310 | ::-webkit-file-upload-button { 311 | font: inherit; 312 | -webkit-appearance: button; 313 | } 314 | 315 | output { 316 | display: inline-block; 317 | } 318 | 319 | summary { 320 | display: list-item; 321 | cursor: pointer; 322 | } 323 | 324 | template { 325 | display: none; 326 | } 327 | 328 | [hidden] { 329 | display: none !important; 330 | } 331 | /*# sourceMappingURL=bootstrap-reboot.css.map */ -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## Create Adobe-CEP extension 2 | ### Adobe-CEP with React, Material-UI, Native Node modules, Webpack, Babel and ExtendScript 3 | 4 | 5 | 6 | this Adobe-CEP extension creator bootstraps for creating Adobe CC extensions easily with 7 | modern web technologies and with native node.js modules for session logic 8 | and with support for extendscript (host app). It is built in a semi opinionated 9 | way so you can focus on writing your great extensions. 10 | 11 | #### how to build 12 | first run `npm install`, then choose 13 | - `npm run build:dev` / `npm run build:prod` - will build into `./dist` folder 14 | - `npm run deploy:dev` / `npm run deploy:prod` - will deploy `./dist` folder into the extension folder. 15 | if in dev mode, it will create a **symbolic link**, otherwise it will copy the entire folder. 16 | - `npm run archive` will create a self signed certificate and sign a **ZXP** package ready to publish 17 | - `npm run release:dev` / `npm run release:prod` - will build, deploy and archive (in production) 18 | 19 | the output is a `./dist` extension folder 20 | ``` 21 | dist 22 | com.package.name/ 23 | index.html 24 | .debug 25 | CSXS/ 26 | manifest.xml 27 | icons/ 28 | favicon.ico 29 | node_modules/ 30 | host/ 31 | index.js 32 | client-dist/ 33 | bundle.js 34 | main.css 35 | session-dist/ 36 | bundle.js 37 | host/ 38 | libs/ 39 | CSInterface.js 40 | ``` 41 | 42 | #### how to customize 43 | start with `./pluginrc.js`, this is the plugin config I created, here is an example 44 | ```javascript 45 | module.exports = { 46 | extensionBundleId: 'com.hendrix.demo', 47 | extensionBundleName: 'demo', 48 | extensionBundleVersion: '1.0.1', 49 | cepVersion: '7.0', 50 | panelName: 'hendrix demo', 51 | width: '400', 52 | height: '600', 53 | root: root, 54 | sourceFolder: srcFolder, 55 | destinationFolder: destFolder, 56 | certificate : { 57 | customCert: { 58 | path: '', 59 | password: 'password' 60 | }, 61 | selfSign: { 62 | country: 'US', 63 | province: 'CA', 64 | org: 'org', 65 | name: 'name', 66 | password: 'password', 67 | locality: 'locality', 68 | orgUnit: 'orgUnit', 69 | email: 'your@email.com', 70 | output: certPath 71 | } 72 | 73 | } 74 | 75 | } 76 | ``` 77 | when build is happening, then the build will pickup your package id and panel name 78 | and other configurations from this file and will use it against a template that will 79 | generate the `./dist/CSXS/manifest.xml` and `.debug` (in dev mode) file for you. 80 | also, I added support for a custom certificate and for a self-signed certificate. 81 | feel free to modify the contents of the `assets` folder for you own need. 82 | 83 | #### how to debug 84 | debugging is achieved through the chrome debugger 85 | - release a dev build with `npm run release:dev` 86 | - inside Adobe, open the extension, you may have to restart if this is the first time. 87 | - open a browser at the following location http://localhost:`PORT`/ (See port number in .debug file) 88 | 89 | ### what does this include ? 90 | this bootstrap is composed of three parts 91 | 92 | #### Front end side 93 | inside `src/client-src` you have the entry point for creating ReactJS application. 94 | installing modules is against the project root, see `/project.json`. 95 | a nice feature, that it has is that you can use `webpack-dev-server` to see 96 | your UI results with watching at the browser, simply use: 97 | - `npm start` or 98 | - `npm run client:dev-server` 99 | this will generate the template html for you and run it in your browser, 100 | and will rebuild on code changes which is nice to have. 101 | 102 | #### back end side / session (using node modules) 103 | inside `src/session-src` you have the entry point for using native node.js modules. 104 | Adobe-CEP supports instantiating Node.js runtime as well as Chromium but I believe 105 | most developers would like to use the power of Node.js for doing IO. 106 | 107 | Adobe-CEP does provide it's native IO for disk access and also using Chromium 108 | you can use the browser `Fetch` api, but it can lead to very bad code structuring. 109 | 110 | I inject the `session` object in the `window` object and therefore it is accessible 111 | even from the front end side. 112 | Also notice, that this folder has it's own `node-modules` separate from the root folder, 113 | this is because, they are built differently from the Front end side. 114 | 115 | using node modules can enhance the functionality. 116 | 117 | #### ExtendScript side 118 | inside `src/host`, you will put you `jsx` files, by default I will load `index.jsx`, 119 | but I highly advise to use the session to load a `jsx` file dynamically so it can pick 120 | up it's `#include` dependencies otherwise it won't (this is a known issue) 121 | 122 | #### Webpack side 123 | so why am I using **Webpack** ? 124 | without webpack, you will have to require modules by absolute path, which is not nice, 125 | also I wanted to enjoy a better ES6 syntax. 126 | 127 | why are there separate **Webpack** configs for `client` and `session`? 128 | very good question. It boils down to the following fact, the client/front-end side, uses 129 | pure web technologies and can be bundeled with all of it's dependencies and it has a classic 130 | `web` target for webpack. 131 | the `session` side uses native node.js modules and has a `node` target in it's config, they 132 | are not to be mixed together or else subtle configuration will not work. this is equivalent 133 | to other projects using `electron`, also, it is not advisable to bundle native node.js modules, 134 | this is not efficient. 135 | 136 | #### Build scripts 137 | inside `/build-scripts`, you will find the webpack configs and also the build and deploy 138 | scripts. They use no-fancy node modules to keep things simple (no libs like Gulp). 139 | 140 | you can find: 141 | - `/build-script/build.js development/production` this will build the entire thing 142 | - `/build-script/deploy.js development/production` this will deploy the entire thing into 143 | the adobe extensions folder in debug mode currently, I still need to sign the extension 144 | - `/build-script/archive.js` this will archive the distribution in **ZXP** format, ready to be published 145 | 146 | #### FAQ 147 | **Q:** how do I add more web development modules (like redux) ? 148 | **A:** simply `npm install redux` from the root `./` directory 149 | 150 | **Q:** how do I add more session native node modules (like fs-extra) ? 151 | **A:** simply `npm install fs-extra` from the `./src/session-src` directory, when building occurs, these 152 | modules will be copied to the `./dist` folder. 153 | 154 | **Q:** how do I add some js lib without npm ? 155 | **A:** simply edit `./src/index.html` 156 | 157 | **Q:** how do I add some extendscript files ? 158 | **A:** you must add them to `./src/host/` folder and then you have two choices. one, is to edit 159 | `./assets/CSXS/manifest.xml` file to declare them, or load them at runtime dynamically (better, you can read 160 | about it more later) 161 | 162 | #### How to install 163 | - for dev mode with chrome debugging, simply `npm run release:dev` 164 | - for prod mode with **zxp** signed package, simply `npm run release:prod`, to install the zxp package, 165 | i advise the following resource: 166 | - http://install.anastasiy.com/ 167 | - http://zxpinstaller.com/ 168 | - https://github.com/Adobe-CEP/Getting-Started-guides/tree/master/Package%20Distribute%20Install 169 | - http://uberplugins.cc/help/how-to-install-photoshop-extension/ 170 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/client-src/comps-bootstrap/backup/css/popper.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) Federico Zivolo 2018 3 | Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT). 4 | */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=getComputedStyle(e,null);return t?o[t]:o}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function r(e){return 11===e?re:10===e?pe:re||pe}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1=o.clientWidth&&n>=o.clientHeight}),l=0a[e]&&!t.escapeWithReference&&(n=J(f[o],a[e]-('right'===e?f.width:f.height))),ae({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=le({},f,m[t](e))}),e.offsets.popper=f,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!q(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-us[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,y=t(e.instance.popper),w=parseFloat(y['margin'+f],10),E=parseFloat(y['border'+f+'Width'],10),v=b-e.offsets.popper[m]-w-E;return v=$(J(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},ae(n,m,Q(v)),ae(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case he.FLIP:p=[n,i];break;case he.CLOCKWISE:p=z(n);break;case he.COUNTERCLOCKWISE:p=z(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)f(l.top)||'bottom'===n&&f(a.top)f(o.right),g=f(a.top)f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,y=-1!==['top','bottom'].indexOf(n),w=!!t.flipVariations&&(y&&'start'===r&&h||y&&'end'===r&&c||!y&&'start'===r&&g||!y&&'end'===r&&u);(m||b||w)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),w&&(r=G(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=le({},e.offsets.popper,C(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport'},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!q(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=D(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottomo.right||t.top>o.bottom||t.right` in some cases.\n@at-root {\n @-ms-viewport {\n width: device-width;\n }\n}\n\n// stylelint-disable selector-list-comma-newline-after\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n// stylelint-enable selector-list-comma-newline-after\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use the\n// the `inherit` value on things like `` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n font-size: $font-size-base;\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Suppress the focus outline on elements that cannot be accessed via keyboard.\n// This prevents an unwanted focus outline from appearing around elements that\n// might still respond to pointer events.\n//\n// Credit: https://github.com/suitcss/base\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `

`-`

` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n// stylelint-enable selector-list-comma-newline-after\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `

`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Remove the bottom border in Firefox 39-.\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Duplicate behavior to the data-* attribute for our tooltip plugin\n\nabbr[title],\nabbr[data-original-title] { // 4\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 1\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\ndfn {\n font-style: italic; // Add the correct font style in Android 4.3-\n}\n\n// stylelint-disable font-weight-notation\nb,\nstrong {\n font-weight: bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n// stylelint-enable font-weight-notation\n\nsmall {\n font-size: 80%; // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n -webkit-text-decoration-skip: objects; // Remove gaps in links underline in iOS 8+ and Safari 8+.\n\n @include hover {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href)\n// which have not been made explicitly keyboard-focusable (without tabindex).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n\n @include hover-focus {\n color: inherit;\n text-decoration: none;\n }\n\n &:focus {\n outline: 0;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-monospace;\n font-size: 1em; // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n // We have @viewport set which causes scrollbars to overlap content in IE11 and Edge, so\n // we force a non-overlapping, non-auto-hiding scrollbar to counteract.\n -ms-overflow-style: scrollbar;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg {\n // Workaround for the SVG overflow bug in IE10/11 is still required.\n // See https://github.com/twbs/bootstrap/issues/26878\n overflow: hidden;\n vertical-align: middle;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $table-caption-color;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n // Matches default `` alignment by inheriting from the ``, or the\n // closest parent with a set `text-align`.\n text-align: inherit;\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: $label-margin-bottom;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n border-radius: 0;\n}\n\n// Work around a Firefox/IE bug where the transparent `button` background\n// results in a loss of the default `button` focus styles.\n//\n// Credit: https://github.com/suitcss/base/\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n// controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\nbutton,\nhtml [type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; // 2\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box; // 1. Add the correct box sizing in IE 10-\n padding: 0; // 2. Remove the padding in IE 10-\n}\n\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n // Remove the default appearance of temporal inputs to avoid a Mobile Safari\n // bug where setting a custom line-height prevents text from being vertically\n // centered within the input.\n // See https://bugs.webkit.org/show_bug.cgi?id=139848\n // and https://github.com/twbs/bootstrap/issues/11266\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto; // Remove the default vertical scrollbar in IE.\n // Textareas should really only resize vertically so they don't break their (horizontal) containers.\n resize: vertical;\n}\n\nfieldset {\n // Browsers set a default `min-width: min-content;` on fieldsets,\n // unlike e.g. `

`s, which have `min-width: 0;` by default.\n // So we reset that to ensure fieldsets behave more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359\n // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n min-width: 0;\n // Reset the default outline behavior of fieldsets so they don't affect page layout.\n padding: 0;\n margin: 0;\n border: 0;\n}\n\n// 1. Correct the text wrapping in Edge and IE.\n// 2. Correct the color inheritance from `fieldset` elements in IE.\nlegend {\n display: block;\n width: 100%;\n max-width: 100%; // 1\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit; // 2\n white-space: normal; // 1\n}\n\nprogress {\n vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.\n}\n\n// Correct the cursor style of increment and decrement buttons in Chrome.\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n outline-offset: -2px; // 2. Correct the outline style in Safari.\n -webkit-appearance: none;\n}\n\n//\n// Remove the inner padding and cancel buttons in Chrome and Safari on macOS.\n//\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// 1. Correct the inability to style clickable types in iOS and Safari.\n// 2. Change font properties to `inherit` in Safari.\n//\n\n::-webkit-file-upload-button {\n font: inherit; // 2\n -webkit-appearance: button; // 1\n}\n\n//\n// Correct element displays\n//\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item; // Add the correct display in all browsers\n cursor: pointer;\n}\n\ntemplate {\n display: none; // Add the correct display in IE\n}\n\n// Always hide an element with the `hidden` HTML attribute (from PureCSS).\n// Needed for proper display in IE 10-.\n[hidden] {\n display: none !important;\n}\n","/*!\n * Bootstrap Reboot v4.1.3 (https://getbootstrap.com/)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -ms-text-size-adjust: 100%;\n -ms-overflow-style: scrollbar;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\n@-ms-viewport {\n width: device-width;\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\ndfn {\n font-style: italic;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n -webkit-text-decoration-skip: objects;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):focus {\n outline: 0;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\nbutton,\nhtml [type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n/*# sourceMappingURL=bootstrap-reboot.css.map */","/*!\n * Bootstrap Reboot v4.1.3 (https://getbootstrap.com/)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -ms-text-size-adjust: 100%;\n -ms-overflow-style: scrollbar;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\n@-ms-viewport {\n width: device-width;\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\ndfn {\n font-style: italic;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n -webkit-text-decoration-skip: objects;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):focus {\n outline: 0;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\nbutton,\nhtml [type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\n/*# sourceMappingURL=bootstrap-reboot.css.map */","// Hover mixin and `$enable-hover-media-query` are deprecated.\n//\n// Originally added during our alphas and maintained during betas, this mixin was\n// designed to prevent `:hover` stickiness on iOS-an issue where hover styles\n// would persist after initial touch.\n//\n// For backward compatibility, we've kept these mixins and updated them to\n// always return their regular pseudo-classes instead of a shimmed media query.\n//\n// Issue: https://github.com/twbs/bootstrap/issues/25195\n\n@mixin hover {\n &:hover { @content; }\n}\n\n@mixin hover-focus {\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin plain-hover-focus {\n &,\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin hover-focus-active {\n &:hover,\n &:focus,\n &:active {\n @content;\n }\n}\n"]} -------------------------------------------------------------------------------- /src/client-src/comps-bootstrap/backup/css/bootstrap-4.1.3-dist/css/bootstrap-grid.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Grid v4.1.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2018 The Bootstrap Authors 4 | * Copyright 2011-2018 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | */@-ms-viewport{width:device-width}html{box-sizing:border-box;-ms-overflow-style:scrollbar}*,::after,::before{box-sizing:inherit}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}} 7 | /*# sourceMappingURL=bootstrap-grid.min.css.map */ -------------------------------------------------------------------------------- /src/libs/CSInterface.js: -------------------------------------------------------------------------------- 1 | /************************************************************************************************** 2 | * 3 | * ADOBE SYSTEMS INCORPORATED 4 | * Copyright 2013 Adobe Systems Incorporated 5 | * All Rights Reserved. 6 | * 7 | * NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the 8 | * terms of the Adobe license agreement accompanying it. If you have received this file from a 9 | * source other than Adobe, then your use, modification, or distribution of it requires the prior 10 | * written permission of Adobe. 11 | * 12 | **************************************************************************************************/ 13 | 14 | /** CSInterface - v8.0.0 */ 15 | 16 | /** 17 | * Stores constants for the window types supported by the CSXS infrastructure. 18 | */ 19 | function CSXSWindowType() 20 | { 21 | } 22 | 23 | /** Constant for the CSXS window type Panel. */ 24 | CSXSWindowType._PANEL = "Panel"; 25 | 26 | /** Constant for the CSXS window type Modeless. */ 27 | CSXSWindowType._MODELESS = "Modeless"; 28 | 29 | /** Constant for the CSXS window type ModalDialog. */ 30 | CSXSWindowType._MODAL_DIALOG = "ModalDialog"; 31 | 32 | /** EvalScript error message */ 33 | EvalScript_ErrMessage = "EvalScript error."; 34 | 35 | /** 36 | * @class Version 37 | * Defines a version number with major, minor, micro, and special 38 | * components. The major, minor and micro values are numeric; the special 39 | * value can be any string. 40 | * 41 | * @param major The major version component, a positive integer up to nine digits long. 42 | * @param minor The minor version component, a positive integer up to nine digits long. 43 | * @param micro The micro version component, a positive integer up to nine digits long. 44 | * @param special The special version component, an arbitrary string. 45 | * 46 | * @return A new \c Version object. 47 | */ 48 | function Version(major, minor, micro, special) 49 | { 50 | this.major = major; 51 | this.minor = minor; 52 | this.micro = micro; 53 | this.special = special; 54 | } 55 | 56 | /** 57 | * The maximum value allowed for a numeric version component. 58 | * This reflects the maximum value allowed in PlugPlug and the manifest schema. 59 | */ 60 | Version.MAX_NUM = 999999999; 61 | 62 | /** 63 | * @class VersionBound 64 | * Defines a boundary for a version range, which associates a \c Version object 65 | * with a flag for whether it is an inclusive or exclusive boundary. 66 | * 67 | * @param version The \c #Version object. 68 | * @param inclusive True if this boundary is inclusive, false if it is exclusive. 69 | * 70 | * @return A new \c VersionBound object. 71 | */ 72 | function VersionBound(version, inclusive) 73 | { 74 | this.version = version; 75 | this.inclusive = inclusive; 76 | } 77 | 78 | /** 79 | * @class VersionRange 80 | * Defines a range of versions using a lower boundary and optional upper boundary. 81 | * 82 | * @param lowerBound The \c #VersionBound object. 83 | * @param upperBound The \c #VersionBound object, or null for a range with no upper boundary. 84 | * 85 | * @return A new \c VersionRange object. 86 | */ 87 | function VersionRange(lowerBound, upperBound) 88 | { 89 | this.lowerBound = lowerBound; 90 | this.upperBound = upperBound; 91 | } 92 | 93 | /** 94 | * @class Runtime 95 | * Represents a runtime related to the CEP infrastructure. 96 | * Extensions can declare dependencies on particular 97 | * CEP runtime versions in the extension manifest. 98 | * 99 | * @param name The runtime name. 100 | * @param version A \c #VersionRange object that defines a range of valid versions. 101 | * 102 | * @return A new \c Runtime object. 103 | */ 104 | function Runtime(name, versionRange) 105 | { 106 | this.name = name; 107 | this.versionRange = versionRange; 108 | } 109 | 110 | /** 111 | * @class Extension 112 | * Encapsulates a CEP-based extension to an Adobe application. 113 | * 114 | * @param id The unique identifier of this extension. 115 | * @param name The localizable display name of this extension. 116 | * @param mainPath The path of the "index.html" file. 117 | * @param basePath The base path of this extension. 118 | * @param windowType The window type of the main window of this extension. 119 | Valid values are defined by \c #CSXSWindowType. 120 | * @param width The default width in pixels of the main window of this extension. 121 | * @param height The default height in pixels of the main window of this extension. 122 | * @param minWidth The minimum width in pixels of the main window of this extension. 123 | * @param minHeight The minimum height in pixels of the main window of this extension. 124 | * @param maxWidth The maximum width in pixels of the main window of this extension. 125 | * @param maxHeight The maximum height in pixels of the main window of this extension. 126 | * @param defaultExtensionDataXml The extension data contained in the default \c ExtensionDispatchInfo section of the extension manifest. 127 | * @param specialExtensionDataXml The extension data contained in the application-specific \c ExtensionDispatchInfo section of the extension manifest. 128 | * @param requiredRuntimeList An array of \c Runtime objects for runtimes required by this extension. 129 | * @param isAutoVisible True if this extension is visible on loading. 130 | * @param isPluginExtension True if this extension has been deployed in the Plugins folder of the host application. 131 | * 132 | * @return A new \c Extension object. 133 | */ 134 | function Extension(id, name, mainPath, basePath, windowType, width, height, minWidth, minHeight, maxWidth, maxHeight, 135 | defaultExtensionDataXml, specialExtensionDataXml, requiredRuntimeList, isAutoVisible, isPluginExtension) 136 | { 137 | this.id = id; 138 | this.name = name; 139 | this.mainPath = mainPath; 140 | this.basePath = basePath; 141 | this.windowType = windowType; 142 | this.width = width; 143 | this.height = height; 144 | this.minWidth = minWidth; 145 | this.minHeight = minHeight; 146 | this.maxWidth = maxWidth; 147 | this.maxHeight = maxHeight; 148 | this.defaultExtensionDataXml = defaultExtensionDataXml; 149 | this.specialExtensionDataXml = specialExtensionDataXml; 150 | this.requiredRuntimeList = requiredRuntimeList; 151 | this.isAutoVisible = isAutoVisible; 152 | this.isPluginExtension = isPluginExtension; 153 | } 154 | 155 | /** 156 | * @class CSEvent 157 | * A standard JavaScript event, the base class for CEP events. 158 | * 159 | * @param type The name of the event type. 160 | * @param scope The scope of event, can be "GLOBAL" or "APPLICATION". 161 | * @param appId The unique identifier of the application that generated the event. 162 | * @param extensionId The unique identifier of the extension that generated the event. 163 | * 164 | * @return A new \c CSEvent object 165 | */ 166 | function CSEvent(type, scope, appId, extensionId) 167 | { 168 | this.type = type; 169 | this.scope = scope; 170 | this.appId = appId; 171 | this.extensionId = extensionId; 172 | } 173 | 174 | /** Event-specific data. */ 175 | CSEvent.prototype.data = ""; 176 | 177 | /** 178 | * @class SystemPath 179 | * Stores operating-system-specific location constants for use in the 180 | * \c #CSInterface.getSystemPath() method. 181 | * @return A new \c SystemPath object. 182 | */ 183 | function SystemPath() 184 | { 185 | } 186 | 187 | /** The path to user data. */ 188 | SystemPath.USER_DATA = "userData"; 189 | 190 | /** The path to common files for Adobe applications. */ 191 | SystemPath.COMMON_FILES = "commonFiles"; 192 | 193 | /** The path to the user's default document folder. */ 194 | SystemPath.MY_DOCUMENTS = "myDocuments"; 195 | 196 | /** @deprecated. Use \c #SystemPath.Extension. */ 197 | SystemPath.APPLICATION = "application"; 198 | 199 | /** The path to current extension. */ 200 | SystemPath.EXTENSION = "extension"; 201 | 202 | /** The path to hosting application's executable. */ 203 | SystemPath.HOST_APPLICATION = "hostApplication"; 204 | 205 | /** 206 | * @class ColorType 207 | * Stores color-type constants. 208 | */ 209 | function ColorType() 210 | { 211 | } 212 | 213 | /** RGB color type. */ 214 | ColorType.RGB = "rgb"; 215 | 216 | /** Gradient color type. */ 217 | ColorType.GRADIENT = "gradient"; 218 | 219 | /** Null color type. */ 220 | ColorType.NONE = "none"; 221 | 222 | /** 223 | * @class RGBColor 224 | * Stores an RGB color with red, green, blue, and alpha values. 225 | * All values are in the range [0.0 to 255.0]. Invalid numeric values are 226 | * converted to numbers within this range. 227 | * 228 | * @param red The red value, in the range [0.0 to 255.0]. 229 | * @param green The green value, in the range [0.0 to 255.0]. 230 | * @param blue The blue value, in the range [0.0 to 255.0]. 231 | * @param alpha The alpha (transparency) value, in the range [0.0 to 255.0]. 232 | * The default, 255.0, means that the color is fully opaque. 233 | * 234 | * @return A new RGBColor object. 235 | */ 236 | function RGBColor(red, green, blue, alpha) 237 | { 238 | this.red = red; 239 | this.green = green; 240 | this.blue = blue; 241 | this.alpha = alpha; 242 | } 243 | 244 | /** 245 | * @class Direction 246 | * A point value in which the y component is 0 and the x component 247 | * is positive or negative for a right or left direction, 248 | * or the x component is 0 and the y component is positive or negative for 249 | * an up or down direction. 250 | * 251 | * @param x The horizontal component of the point. 252 | * @param y The vertical component of the point. 253 | * 254 | * @return A new \c Direction object. 255 | */ 256 | function Direction(x, y) 257 | { 258 | this.x = x; 259 | this.y = y; 260 | } 261 | 262 | /** 263 | * @class GradientStop 264 | * Stores gradient stop information. 265 | * 266 | * @param offset The offset of the gradient stop, in the range [0.0 to 1.0]. 267 | * @param rgbColor The color of the gradient at this point, an \c #RGBColor object. 268 | * 269 | * @return GradientStop object. 270 | */ 271 | function GradientStop(offset, rgbColor) 272 | { 273 | this.offset = offset; 274 | this.rgbColor = rgbColor; 275 | } 276 | 277 | /** 278 | * @class GradientColor 279 | * Stores gradient color information. 280 | * 281 | * @param type The gradient type, must be "linear". 282 | * @param direction A \c #Direction object for the direction of the gradient 283 | (up, down, right, or left). 284 | * @param numStops The number of stops in the gradient. 285 | * @param gradientStopList An array of \c #GradientStop objects. 286 | * 287 | * @return A new \c GradientColor object. 288 | */ 289 | function GradientColor(type, direction, numStops, arrGradientStop) 290 | { 291 | this.type = type; 292 | this.direction = direction; 293 | this.numStops = numStops; 294 | this.arrGradientStop = arrGradientStop; 295 | } 296 | 297 | /** 298 | * @class UIColor 299 | * Stores color information, including the type, anti-alias level, and specific color 300 | * values in a color object of an appropriate type. 301 | * 302 | * @param type The color type, 1 for "rgb" and 2 for "gradient". 303 | The supplied color object must correspond to this type. 304 | * @param antialiasLevel The anti-alias level constant. 305 | * @param color A \c #RGBColor or \c #GradientColor object containing specific color information. 306 | * 307 | * @return A new \c UIColor object. 308 | */ 309 | function UIColor(type, antialiasLevel, color) 310 | { 311 | this.type = type; 312 | this.antialiasLevel = antialiasLevel; 313 | this.color = color; 314 | } 315 | 316 | /** 317 | * @class AppSkinInfo 318 | * Stores window-skin properties, such as color and font. All color parameter values are \c #UIColor objects except that systemHighlightColor is \c #RGBColor object. 319 | * 320 | * @param baseFontFamily The base font family of the application. 321 | * @param baseFontSize The base font size of the application. 322 | * @param appBarBackgroundColor The application bar background color. 323 | * @param panelBackgroundColor The background color of the extension panel. 324 | * @param appBarBackgroundColorSRGB The application bar background color, as sRGB. 325 | * @param panelBackgroundColorSRGB The background color of the extension panel, as sRGB. 326 | * @param systemHighlightColor The highlight color of the extension panel, if provided by the host application. Otherwise, the operating-system highlight color. 327 | * 328 | * @return AppSkinInfo object. 329 | */ 330 | function AppSkinInfo(baseFontFamily, baseFontSize, appBarBackgroundColor, panelBackgroundColor, appBarBackgroundColorSRGB, panelBackgroundColorSRGB, systemHighlightColor) 331 | { 332 | this.baseFontFamily = baseFontFamily; 333 | this.baseFontSize = baseFontSize; 334 | this.appBarBackgroundColor = appBarBackgroundColor; 335 | this.panelBackgroundColor = panelBackgroundColor; 336 | this.appBarBackgroundColorSRGB = appBarBackgroundColorSRGB; 337 | this.panelBackgroundColorSRGB = panelBackgroundColorSRGB; 338 | this.systemHighlightColor = systemHighlightColor; 339 | } 340 | 341 | /** 342 | * @class HostEnvironment 343 | * Stores information about the environment in which the extension is loaded. 344 | * 345 | * @param appName The application's name. 346 | * @param appVersion The application's version. 347 | * @param appLocale The application's current license locale. 348 | * @param appUILocale The application's current UI locale. 349 | * @param appId The application's unique identifier. 350 | * @param isAppOnline True if the application is currently online. 351 | * @param appSkinInfo An \c #AppSkinInfo object containing the application's default color and font styles. 352 | * 353 | * @return A new \c HostEnvironment object. 354 | */ 355 | function HostEnvironment(appName, appVersion, appLocale, appUILocale, appId, isAppOnline, appSkinInfo) 356 | { 357 | this.appName = appName; 358 | this.appVersion = appVersion; 359 | this.appLocale = appLocale; 360 | this.appUILocale = appUILocale; 361 | this.appId = appId; 362 | this.isAppOnline = isAppOnline; 363 | this.appSkinInfo = appSkinInfo; 364 | } 365 | 366 | /** 367 | * @class HostCapabilities 368 | * Stores information about the host capabilities. 369 | * 370 | * @param EXTENDED_PANEL_MENU True if the application supports panel menu. 371 | * @param EXTENDED_PANEL_ICONS True if the application supports panel icon. 372 | * @param DELEGATE_APE_ENGINE True if the application supports delegated APE engine. 373 | * @param SUPPORT_HTML_EXTENSIONS True if the application supports HTML extensions. 374 | * @param DISABLE_FLASH_EXTENSIONS True if the application disables FLASH extensions. 375 | * 376 | * @return A new \c HostCapabilities object. 377 | */ 378 | function HostCapabilities(EXTENDED_PANEL_MENU, EXTENDED_PANEL_ICONS, DELEGATE_APE_ENGINE, SUPPORT_HTML_EXTENSIONS, DISABLE_FLASH_EXTENSIONS) 379 | { 380 | this.EXTENDED_PANEL_MENU = EXTENDED_PANEL_MENU; 381 | this.EXTENDED_PANEL_ICONS = EXTENDED_PANEL_ICONS; 382 | this.DELEGATE_APE_ENGINE = DELEGATE_APE_ENGINE; 383 | this.SUPPORT_HTML_EXTENSIONS = SUPPORT_HTML_EXTENSIONS; 384 | this.DISABLE_FLASH_EXTENSIONS = DISABLE_FLASH_EXTENSIONS; // Since 5.0.0 385 | } 386 | 387 | /** 388 | * @class ApiVersion 389 | * Stores current api version. 390 | * 391 | * Since 4.2.0 392 | * 393 | * @param major The major version 394 | * @param minor The minor version. 395 | * @param micro The micro version. 396 | * 397 | * @return ApiVersion object. 398 | */ 399 | function ApiVersion(major, minor, micro) 400 | { 401 | this.major = major; 402 | this.minor = minor; 403 | this.micro = micro; 404 | } 405 | 406 | /** 407 | * @class MenuItemStatus 408 | * Stores flyout menu item status 409 | * 410 | * Since 5.2.0 411 | * 412 | * @param menuItemLabel The menu item label. 413 | * @param enabled True if user wants to enable the menu item. 414 | * @param checked True if user wants to check the menu item. 415 | * 416 | * @return MenuItemStatus object. 417 | */ 418 | function MenuItemStatus(menuItemLabel, enabled, checked) 419 | { 420 | this.menuItemLabel = menuItemLabel; 421 | this.enabled = enabled; 422 | this.checked = checked; 423 | } 424 | 425 | /** 426 | * @class ContextMenuItemStatus 427 | * Stores the status of the context menu item. 428 | * 429 | * Since 5.2.0 430 | * 431 | * @param menuItemID The menu item id. 432 | * @param enabled True if user wants to enable the menu item. 433 | * @param checked True if user wants to check the menu item. 434 | * 435 | * @return MenuItemStatus object. 436 | */ 437 | function ContextMenuItemStatus(menuItemID, enabled, checked) 438 | { 439 | this.menuItemID = menuItemID; 440 | this.enabled = enabled; 441 | this.checked = checked; 442 | } 443 | //------------------------------ CSInterface ---------------------------------- 444 | 445 | /** 446 | * @class CSInterface 447 | * This is the entry point to the CEP extensibility infrastructure. 448 | * Instantiate this object and use it to: 449 | *
    450 | *
  • Access information about the host application in which an extension is running
  • 451 | *
  • Launch an extension
  • 452 | *
  • Register interest in event notifications, and dispatch events
  • 453 | *
454 | * 455 | * @return A new \c CSInterface object 456 | */ 457 | function CSInterface() 458 | { 459 | } 460 | 461 | /** 462 | * User can add this event listener to handle native application theme color changes. 463 | * Callback function gives extensions ability to fine-tune their theme color after the 464 | * global theme color has been changed. 465 | * The callback function should be like below: 466 | * 467 | * @example 468 | * // event is a CSEvent object, but user can ignore it. 469 | * function OnAppThemeColorChanged(event) 470 | * { 471 | * // Should get a latest HostEnvironment object from application. 472 | * var skinInfo = JSON.parse(window.__adobe_cep__.getHostEnvironment()).appSkinInfo; 473 | * // Gets the style information such as color info from the skinInfo, 474 | * // and redraw all UI controls of your extension according to the style info. 475 | * } 476 | */ 477 | CSInterface.THEME_COLOR_CHANGED_EVENT = "com.adobe.csxs.events.ThemeColorChanged"; 478 | 479 | /** The host environment data object. */ 480 | CSInterface.prototype.hostEnvironment = window.__adobe_cep__ ? JSON.parse(window.__adobe_cep__.getHostEnvironment()) : null; 481 | 482 | /** Retrieves information about the host environment in which the 483 | * extension is currently running. 484 | * 485 | * @return A \c #HostEnvironment object. 486 | */ 487 | CSInterface.prototype.getHostEnvironment = function() 488 | { 489 | this.hostEnvironment = JSON.parse(window.__adobe_cep__.getHostEnvironment()); 490 | return this.hostEnvironment; 491 | }; 492 | 493 | /** Closes this extension. */ 494 | CSInterface.prototype.closeExtension = function() 495 | { 496 | window.__adobe_cep__.closeExtension(); 497 | }; 498 | 499 | /** 500 | * Retrieves a path for which a constant is defined in the system. 501 | * 502 | * @param pathType The path-type constant defined in \c #SystemPath , 503 | * 504 | * @return The platform-specific system path string. 505 | */ 506 | CSInterface.prototype.getSystemPath = function(pathType) 507 | { 508 | var path = decodeURI(window.__adobe_cep__.getSystemPath(pathType)); 509 | var OSVersion = this.getOSInformation(); 510 | if (OSVersion.indexOf("Windows") >= 0) 511 | { 512 | path = path.replace("file:///", ""); 513 | } 514 | else if (OSVersion.indexOf("Mac") >= 0) 515 | { 516 | path = path.replace("file://", ""); 517 | } 518 | return path; 519 | }; 520 | 521 | /** 522 | * Evaluates a JavaScript script, which can use the JavaScript DOM 523 | * of the host application. 524 | * 525 | * @param script The JavaScript script. 526 | * @param callback Optional. A callback function that receives the result of execution. 527 | * If execution fails, the callback function receives the error message \c EvalScript_ErrMessage. 528 | */ 529 | CSInterface.prototype.evalScript = function(script, callback) 530 | { 531 | if(callback === null || callback === undefined) 532 | { 533 | callback = function(result){}; 534 | } 535 | window.__adobe_cep__.evalScript(script, callback); 536 | }; 537 | 538 | /** 539 | * Retrieves the unique identifier of the application. 540 | * in which the extension is currently running. 541 | * 542 | * @return The unique ID string. 543 | */ 544 | CSInterface.prototype.getApplicationID = function() 545 | { 546 | var appId = this.hostEnvironment.appId; 547 | return appId; 548 | }; 549 | 550 | /** 551 | * Retrieves host capability information for the application 552 | * in which the extension is currently running. 553 | * 554 | * @return A \c #HostCapabilities object. 555 | */ 556 | CSInterface.prototype.getHostCapabilities = function() 557 | { 558 | var hostCapabilities = JSON.parse(window.__adobe_cep__.getHostCapabilities() ); 559 | return hostCapabilities; 560 | }; 561 | 562 | /** 563 | * Triggers a CEP event programmatically. Yoy can use it to dispatch 564 | * an event of a predefined type, or of a type you have defined. 565 | * 566 | * @param event A \c CSEvent object. 567 | */ 568 | CSInterface.prototype.dispatchEvent = function(event) 569 | { 570 | if (typeof event.data == "object") 571 | { 572 | event.data = JSON.stringify(event.data); 573 | } 574 | 575 | window.__adobe_cep__.dispatchEvent(event); 576 | }; 577 | 578 | /** 579 | * Registers an interest in a CEP event of a particular type, and 580 | * assigns an event handler. 581 | * The event infrastructure notifies your extension when events of this type occur, 582 | * passing the event object to the registered handler function. 583 | * 584 | * @param type The name of the event type of interest. 585 | * @param listener The JavaScript handler function or method. 586 | * @param obj Optional, the object containing the handler method, if any. 587 | * Default is null. 588 | */ 589 | CSInterface.prototype.addEventListener = function(type, listener, obj) 590 | { 591 | window.__adobe_cep__.addEventListener(type, listener, obj); 592 | }; 593 | 594 | /** 595 | * Removes a registered event listener. 596 | * 597 | * @param type The name of the event type of interest. 598 | * @param listener The JavaScript handler function or method that was registered. 599 | * @param obj Optional, the object containing the handler method, if any. 600 | * Default is null. 601 | */ 602 | CSInterface.prototype.removeEventListener = function(type, listener, obj) 603 | { 604 | window.__adobe_cep__.removeEventListener(type, listener, obj); 605 | }; 606 | 607 | /** 608 | * Loads and launches another extension, or activates the extension if it is already loaded. 609 | * 610 | * @param extensionId The extension's unique identifier. 611 | * @param startupParams Not currently used, pass "". 612 | * 613 | * @example 614 | * To launch the extension "help" with ID "HLP" from this extension, call: 615 | * requestOpenExtension("HLP", ""); 616 | * 617 | */ 618 | CSInterface.prototype.requestOpenExtension = function(extensionId, params) 619 | { 620 | window.__adobe_cep__.requestOpenExtension(extensionId, params); 621 | }; 622 | 623 | /** 624 | * Retrieves the list of extensions currently loaded in the current host application. 625 | * The extension list is initialized once, and remains the same during the lifetime 626 | * of the CEP session. 627 | * 628 | * @param extensionIds Optional, an array of unique identifiers for extensions of interest. 629 | * If omitted, retrieves data for all extensions. 630 | * 631 | * @return Zero or more \c #Extension objects. 632 | */ 633 | CSInterface.prototype.getExtensions = function(extensionIds) 634 | { 635 | var extensionIdsStr = JSON.stringify(extensionIds); 636 | var extensionsStr = window.__adobe_cep__.getExtensions(extensionIdsStr); 637 | 638 | var extensions = JSON.parse(extensionsStr); 639 | return extensions; 640 | }; 641 | 642 | /** 643 | * Retrieves network-related preferences. 644 | * 645 | * @return A JavaScript object containing network preferences. 646 | */ 647 | CSInterface.prototype.getNetworkPreferences = function() 648 | { 649 | var result = window.__adobe_cep__.getNetworkPreferences(); 650 | var networkPre = JSON.parse(result); 651 | 652 | return networkPre; 653 | }; 654 | 655 | /** 656 | * Initializes the resource bundle for this extension with property values 657 | * for the current application and locale. 658 | * To support multiple locales, you must define a property file for each locale, 659 | * containing keyed display-string values for that locale. 660 | * See localization documentation for Extension Builder and related products. 661 | * 662 | * Keys can be in the 663 | * form key.value="localized string", for use in HTML text elements. 664 | * For example, in this input element, the localized \c key.value string is displayed 665 | * instead of the empty \c value string: 666 | * 667 | * 668 | * 669 | * @return An object containing the resource bundle information. 670 | */ 671 | CSInterface.prototype.initResourceBundle = function() 672 | { 673 | var resourceBundle = JSON.parse(window.__adobe_cep__.initResourceBundle()); 674 | var resElms = document.querySelectorAll('[data-locale]'); 675 | for (var n = 0; n < resElms.length; n++) 676 | { 677 | var resEl = resElms[n]; 678 | // Get the resource key from the element. 679 | var resKey = resEl.getAttribute('data-locale'); 680 | if (resKey) 681 | { 682 | // Get all the resources that start with the key. 683 | for (var key in resourceBundle) 684 | { 685 | if (key.indexOf(resKey) === 0) 686 | { 687 | var resValue = resourceBundle[key]; 688 | if (key.length == resKey.length) 689 | { 690 | resEl.innerHTML = resValue; 691 | } 692 | else if ('.' == key.charAt(resKey.length)) 693 | { 694 | var attrKey = key.substring(resKey.length + 1); 695 | resEl[attrKey] = resValue; 696 | } 697 | } 698 | } 699 | } 700 | } 701 | return resourceBundle; 702 | }; 703 | 704 | /** 705 | * Writes installation information to a file. 706 | * 707 | * @return The file path. 708 | */ 709 | CSInterface.prototype.dumpInstallationInfo = function() 710 | { 711 | return window.__adobe_cep__.dumpInstallationInfo(); 712 | }; 713 | 714 | /** 715 | * Retrieves version information for the current Operating System, 716 | * See http://www.useragentstring.com/pages/Chrome/ for Chrome \c navigator.userAgent values. 717 | * 718 | * @return A string containing the OS version, or "unknown Operation System". 719 | * If user customizes the User Agent by setting CEF command parameter "--user-agent", only 720 | * "Mac OS X" or "Windows" will be returned. 721 | */ 722 | CSInterface.prototype.getOSInformation = function() 723 | { 724 | var userAgent = navigator.userAgent; 725 | 726 | if ((navigator.platform == "Win32") || (navigator.platform == "Windows")) 727 | { 728 | var winVersion = "Windows"; 729 | var winBit = ""; 730 | if (userAgent.indexOf("Windows") > -1) 731 | { 732 | if (userAgent.indexOf("Windows NT 5.0") > -1) 733 | { 734 | winVersion = "Windows 2000"; 735 | } 736 | else if (userAgent.indexOf("Windows NT 5.1") > -1) 737 | { 738 | winVersion = "Windows XP"; 739 | } 740 | else if (userAgent.indexOf("Windows NT 5.2") > -1) 741 | { 742 | winVersion = "Windows Server 2003"; 743 | } 744 | else if (userAgent.indexOf("Windows NT 6.0") > -1) 745 | { 746 | winVersion = "Windows Vista"; 747 | } 748 | else if (userAgent.indexOf("Windows NT 6.1") > -1) 749 | { 750 | winVersion = "Windows 7"; 751 | } 752 | else if (userAgent.indexOf("Windows NT 6.2") > -1) 753 | { 754 | winVersion = "Windows 8"; 755 | } 756 | else if (userAgent.indexOf("Windows NT 6.3") > -1) 757 | { 758 | winVersion = "Windows 8.1"; 759 | } 760 | else if (userAgent.indexOf("Windows NT 10") > -1) 761 | { 762 | winVersion = "Windows 10"; 763 | } 764 | 765 | if (userAgent.indexOf("WOW64") > -1 || userAgent.indexOf("Win64") > -1) 766 | { 767 | winBit = " 64-bit"; 768 | } 769 | else 770 | { 771 | winBit = " 32-bit"; 772 | } 773 | } 774 | 775 | return winVersion + winBit; 776 | } 777 | else if ((navigator.platform == "MacIntel") || (navigator.platform == "Macintosh")) 778 | { 779 | var result = "Mac OS X"; 780 | 781 | if (userAgent.indexOf("Mac OS X") > -1) 782 | { 783 | result = userAgent.substring(userAgent.indexOf("Mac OS X"), userAgent.indexOf(")")); 784 | result = result.replace(/_/g, "."); 785 | } 786 | 787 | return result; 788 | } 789 | 790 | return "Unknown Operation System"; 791 | }; 792 | 793 | /** 794 | * Opens a page in the default system browser. 795 | * 796 | * Since 4.2.0 797 | * 798 | * @param url The URL of the page/file to open, or the email address. 799 | * Must use HTTP/HTTPS/file/mailto protocol. For example: 800 | * "http://www.adobe.com" 801 | * "https://github.com" 802 | * "file:///C:/log.txt" 803 | * "mailto:test@adobe.com" 804 | * 805 | * @return One of these error codes:\n 806 | *
    \n 807 | *
  • NO_ERROR - 0
  • \n 808 | *
  • ERR_UNKNOWN - 1
  • \n 809 | *
  • ERR_INVALID_PARAMS - 2
  • \n 810 | *
  • ERR_INVALID_URL - 201
  • \n 811 | *
\n 812 | */ 813 | CSInterface.prototype.openURLInDefaultBrowser = function(url) 814 | { 815 | return cep.util.openURLInDefaultBrowser(url); 816 | }; 817 | 818 | /** 819 | * Retrieves extension ID. 820 | * 821 | * Since 4.2.0 822 | * 823 | * @return extension ID. 824 | */ 825 | CSInterface.prototype.getExtensionID = function() 826 | { 827 | return window.__adobe_cep__.getExtensionId(); 828 | }; 829 | 830 | /** 831 | * Retrieves the scale factor of screen. 832 | * On Windows platform, the value of scale factor might be different from operating system's scale factor, 833 | * since host application may use its self-defined scale factor. 834 | * 835 | * Since 4.2.0 836 | * 837 | * @return One of the following float number. 838 | *
    \n 839 | *
  • -1.0 when error occurs
  • \n 840 | *
  • 1.0 means normal screen
  • \n 841 | *
  • >1.0 means HiDPI screen
  • \n 842 | *
\n 843 | */ 844 | CSInterface.prototype.getScaleFactor = function() 845 | { 846 | return window.__adobe_cep__.getScaleFactor(); 847 | }; 848 | 849 | /** 850 | * Set a handler to detect any changes of scale factor. This only works on Mac. 851 | * 852 | * Since 4.2.0 853 | * 854 | * @param handler The function to be called when scale factor is changed. 855 | * 856 | */ 857 | CSInterface.prototype.setScaleFactorChangedHandler = function(handler) 858 | { 859 | window.__adobe_cep__.setScaleFactorChangedHandler(handler); 860 | }; 861 | 862 | /** 863 | * Retrieves current API version. 864 | * 865 | * Since 4.2.0 866 | * 867 | * @return ApiVersion object. 868 | * 869 | */ 870 | CSInterface.prototype.getCurrentApiVersion = function() 871 | { 872 | var apiVersion = JSON.parse(window.__adobe_cep__.getCurrentApiVersion()); 873 | return apiVersion; 874 | }; 875 | 876 | /** 877 | * Set panel flyout menu by an XML. 878 | * 879 | * Since 5.2.0 880 | * 881 | * Register a callback function for "com.adobe.csxs.events.flyoutMenuClicked" to get notified when a 882 | * menu item is clicked. 883 | * The "data" attribute of event is an object which contains "menuId" and "menuName" attributes. 884 | * 885 | * Register callback functions for "com.adobe.csxs.events.flyoutMenuOpened" and "com.adobe.csxs.events.flyoutMenuClosed" 886 | * respectively to get notified when flyout menu is opened or closed. 887 | * 888 | * @param menu A XML string which describes menu structure. 889 | * An example menu XML: 890 | * 891 | * 892 | * 893 | * 894 | * 895 | * 896 | * 897 | * 898 | * 899 | * 900 | * 901 | * 902 | */ 903 | CSInterface.prototype.setPanelFlyoutMenu = function(menu) 904 | { 905 | if ("string" != typeof menu) 906 | { 907 | return; 908 | } 909 | 910 | window.__adobe_cep__.invokeSync("setPanelFlyoutMenu", menu); 911 | }; 912 | 913 | /** 914 | * Updates a menu item in the extension window's flyout menu, by setting the enabled 915 | * and selection status. 916 | * 917 | * Since 5.2.0 918 | * 919 | * @param menuItemLabel The menu item label. 920 | * @param enabled True to enable the item, false to disable it (gray it out). 921 | * @param checked True to select the item, false to deselect it. 922 | * 923 | * @return false when the host application does not support this functionality (HostCapabilities.EXTENDED_PANEL_MENU is false). 924 | * Fails silently if menu label is invalid. 925 | * 926 | * @see HostCapabilities.EXTENDED_PANEL_MENU 927 | */ 928 | CSInterface.prototype.updatePanelMenuItem = function(menuItemLabel, enabled, checked) 929 | { 930 | var ret = false; 931 | if (this.getHostCapabilities().EXTENDED_PANEL_MENU) 932 | { 933 | var itemStatus = new MenuItemStatus(menuItemLabel, enabled, checked); 934 | ret = window.__adobe_cep__.invokeSync("updatePanelMenuItem", JSON.stringify(itemStatus)); 935 | } 936 | return ret; 937 | }; 938 | 939 | 940 | /** 941 | * Set context menu by XML string. 942 | * 943 | * Since 5.2.0 944 | * 945 | * There are a number of conventions used to communicate what type of menu item to create and how it should be handled. 946 | * - an item without menu ID or menu name is disabled and is not shown. 947 | * - if the item name is "---" (three hyphens) then it is treated as a separator. The menu ID in this case will always be NULL. 948 | * - Checkable attribute takes precedence over Checked attribute. 949 | * - a PNG icon. For optimal display results please supply a 16 x 16px icon as larger dimensions will increase the size of the menu item. 950 | The Chrome extension contextMenus API was taken as a reference. 951 | https://developer.chrome.com/extensions/contextMenus 952 | * - the items with icons and checkable items cannot coexist on the same menu level. The former take precedences over the latter. 953 | * 954 | * @param menu A XML string which describes menu structure. 955 | * @param callback The callback function which is called when a menu item is clicked. The only parameter is the returned ID of clicked menu item. 956 | * 957 | * @description An example menu XML: 958 | * 959 | * 960 | * 961 | * 962 | * 963 | * 964 | * 965 | * 966 | * 967 | * 968 | * 969 | */ 970 | CSInterface.prototype.setContextMenu = function(menu, callback) 971 | { 972 | if ("string" != typeof menu) 973 | { 974 | return; 975 | } 976 | 977 | window.__adobe_cep__.invokeAsync("setContextMenu", menu, callback); 978 | }; 979 | 980 | /** 981 | * Set context menu by JSON string. 982 | * 983 | * Since 6.0.0 984 | * 985 | * There are a number of conventions used to communicate what type of menu item to create and how it should be handled. 986 | * - an item without menu ID or menu name is disabled and is not shown. 987 | * - if the item label is "---" (three hyphens) then it is treated as a separator. The menu ID in this case will always be NULL. 988 | * - Checkable attribute takes precedence over Checked attribute. 989 | * - a PNG icon. For optimal display results please supply a 16 x 16px icon as larger dimensions will increase the size of the menu item. 990 | The Chrome extension contextMenus API was taken as a reference. 991 | * - the items with icons and checkable items cannot coexist on the same menu level. The former take precedences over the latter. 992 | https://developer.chrome.com/extensions/contextMenus 993 | * 994 | * @param menu A JSON string which describes menu structure. 995 | * @param callback The callback function which is called when a menu item is clicked. The only parameter is the returned ID of clicked menu item. 996 | * 997 | * @description An example menu JSON: 998 | * 999 | * { 1000 | * "menu": [ 1001 | * { 1002 | * "id": "menuItemId1", 1003 | * "label": "testExample1", 1004 | * "enabled": true, 1005 | * "checkable": true, 1006 | * "checked": false, 1007 | * "icon": "./image/small_16X16.png" 1008 | * }, 1009 | * { 1010 | * "id": "menuItemId2", 1011 | * "label": "testExample2", 1012 | * "menu": [ 1013 | * { 1014 | * "id": "menuItemId2-1", 1015 | * "label": "testExample2-1", 1016 | * "menu": [ 1017 | * { 1018 | * "id": "menuItemId2-1-1", 1019 | * "label": "testExample2-1-1", 1020 | * "enabled": false, 1021 | * "checkable": true, 1022 | * "checked": true 1023 | * } 1024 | * ] 1025 | * }, 1026 | * { 1027 | * "id": "menuItemId2-2", 1028 | * "label": "testExample2-2", 1029 | * "enabled": true, 1030 | * "checkable": true, 1031 | * "checked": true 1032 | * } 1033 | * ] 1034 | * }, 1035 | * { 1036 | * "label": "---" 1037 | * }, 1038 | * { 1039 | * "id": "menuItemId3", 1040 | * "label": "testExample3", 1041 | * "enabled": false, 1042 | * "checkable": true, 1043 | * "checked": false 1044 | * } 1045 | * ] 1046 | * } 1047 | * 1048 | */ 1049 | CSInterface.prototype.setContextMenuByJSON = function(menu, callback) 1050 | { 1051 | if ("string" != typeof menu) 1052 | { 1053 | return; 1054 | } 1055 | 1056 | window.__adobe_cep__.invokeAsync("setContextMenuByJSON", menu, callback); 1057 | }; 1058 | 1059 | /** 1060 | * Updates a context menu item by setting the enabled and selection status. 1061 | * 1062 | * Since 5.2.0 1063 | * 1064 | * @param menuItemID The menu item ID. 1065 | * @param enabled True to enable the item, false to disable it (gray it out). 1066 | * @param checked True to select the item, false to deselect it. 1067 | */ 1068 | CSInterface.prototype.updateContextMenuItem = function(menuItemID, enabled, checked) 1069 | { 1070 | var itemStatus = new ContextMenuItemStatus(menuItemID, enabled, checked); 1071 | ret = window.__adobe_cep__.invokeSync("updateContextMenuItem", JSON.stringify(itemStatus)); 1072 | }; 1073 | 1074 | /** 1075 | * Get the visibility status of an extension window. 1076 | * 1077 | * Since 6.0.0 1078 | * 1079 | * @return true if the extension window is visible; false if the extension window is hidden. 1080 | */ 1081 | CSInterface.prototype.isWindowVisible = function() 1082 | { 1083 | return window.__adobe_cep__.invokeSync("isWindowVisible", ""); 1084 | }; 1085 | 1086 | /** 1087 | * Resize extension's content to the specified dimensions. 1088 | * 1. Works with modal and modeless extensions in all Adobe products. 1089 | * 2. Extension's manifest min/max size constraints apply and take precedence. 1090 | * 3. For panel extensions 1091 | * 3.1 This works in all Adobe products except: 1092 | * * Premiere Pro 1093 | * * Prelude 1094 | * * After Effects 1095 | * 3.2 When the panel is in certain states (especially when being docked), 1096 | * it will not change to the desired dimensions even when the 1097 | * specified size satisfies min/max constraints. 1098 | * 1099 | * Since 6.0.0 1100 | * 1101 | * @param width The new width 1102 | * @param height The new height 1103 | */ 1104 | CSInterface.prototype.resizeContent = function(width, height) 1105 | { 1106 | window.__adobe_cep__.resizeContent(width, height); 1107 | }; 1108 | 1109 | /** 1110 | * Register the invalid certificate callback for an extension. 1111 | * This callback will be triggered when the extension tries to access the web site that contains the invalid certificate on the main frame. 1112 | * But if the extension does not call this function and tries to access the web site containing the invalid certificate, a default error page will be shown. 1113 | * 1114 | * Since 6.1.0 1115 | * 1116 | * @param callback the callback function 1117 | */ 1118 | CSInterface.prototype.registerInvalidCertificateCallback = function(callback) 1119 | { 1120 | return window.__adobe_cep__.registerInvalidCertificateCallback(callback); 1121 | }; 1122 | 1123 | /** 1124 | * Register an interest in some key events to prevent them from being sent to the host application. 1125 | * 1126 | * This function works with modeless extensions and panel extensions. 1127 | * Generally all the key events will be sent to the host application for these two extensions if the current focused element 1128 | * is not text input or dropdown, 1129 | * If you want to intercept some key events and want them to be handled in the extension, please call this function 1130 | * in advance to prevent them being sent to the host application. 1131 | * 1132 | * Since 6.1.0 1133 | * 1134 | * @param keyEventsInterest A JSON string describing those key events you are interested in. A null object or 1135 | an empty string will lead to removing the interest 1136 | * 1137 | * This JSON string should be an array, each object has following keys: 1138 | * 1139 | * keyCode: [Required] represents an OS system dependent virtual key code identifying 1140 | * the unmodified value of the pressed key. 1141 | * ctrlKey: [optional] a Boolean that indicates if the control key was pressed (true) or not (false) when the event occurred. 1142 | * altKey: [optional] a Boolean that indicates if the alt key was pressed (true) or not (false) when the event occurred. 1143 | * shiftKey: [optional] a Boolean that indicates if the shift key was pressed (true) or not (false) when the event occurred. 1144 | * metaKey: [optional] (Mac Only) a Boolean that indicates if the Meta key was pressed (true) or not (false) when the event occurred. 1145 | * On Macintosh keyboards, this is the command key. To detect Windows key on Windows, please use keyCode instead. 1146 | * An example JSON string: 1147 | * 1148 | * [ 1149 | * { 1150 | * "keyCode": 48 1151 | * }, 1152 | * { 1153 | * "keyCode": 123, 1154 | * "ctrlKey": true 1155 | * }, 1156 | * { 1157 | * "keyCode": 123, 1158 | * "ctrlKey": true, 1159 | * "metaKey": true 1160 | * } 1161 | * ] 1162 | * 1163 | */ 1164 | CSInterface.prototype.registerKeyEventsInterest = function(keyEventsInterest) 1165 | { 1166 | return window.__adobe_cep__.registerKeyEventsInterest(keyEventsInterest); 1167 | }; 1168 | 1169 | /** 1170 | * Set the title of the extension window. 1171 | * This function works with modal and modeless extensions in all Adobe products, and panel extensions in Photoshop, InDesign, InCopy, Illustrator, Flash Pro and Dreamweaver. 1172 | * 1173 | * Since 6.1.0 1174 | * 1175 | * @param title The window title. 1176 | */ 1177 | CSInterface.prototype.setWindowTitle = function(title) 1178 | { 1179 | window.__adobe_cep__.invokeSync("setWindowTitle", title); 1180 | }; 1181 | 1182 | /** 1183 | * Get the title of the extension window. 1184 | * This function works with modal and modeless extensions in all Adobe products, and panel extensions in Photoshop, InDesign, InCopy, Illustrator, Flash Pro and Dreamweaver. 1185 | * 1186 | * Since 6.1.0 1187 | * 1188 | * @return The window title. 1189 | */ 1190 | CSInterface.prototype.getWindowTitle = function() 1191 | { 1192 | return window.__adobe_cep__.invokeSync("getWindowTitle", ""); 1193 | }; 1194 | --------------------------------------------------------------------------------