├── main ├── app │ ├── views │ │ ├── addLinks.hbs │ │ ├── uploader.hbs │ │ ├── initialize.hbs │ │ ├── adjust.hbs │ │ ├── finish.hbs │ │ ├── generate.hbs │ │ ├── onboarding.hbs │ │ ├── editor.hbs │ │ └── settings.hbs │ ├── assets │ │ ├── img │ │ │ ├── test.jpg │ │ │ ├── rotation.svg │ │ │ ├── kiss.svg │ │ │ ├── selfie.svg │ │ │ ├── camera.svg │ │ │ └── happy.svg │ │ ├── fonts │ │ │ ├── BlendaScript.otf │ │ │ └── FiraSans-UltraLight.otf │ │ ├── data │ │ │ └── filters.json │ │ └── css │ │ │ ├── croppie.css │ │ │ ├── style.css │ │ │ └── instagram.min.css │ ├── util │ │ ├── readFileSync.js │ │ └── generator.js │ ├── index.html │ └── app.js └── main.js ├── .npmrc ├── program ├── fonts │ ├── BlendaScript.otf │ └── FiraSans-UltraLight.otf └── css │ ├── style.css │ └── instagram.min.css ├── .prettierrc.js ├── .eslintrc.js ├── bin └── cli.js ├── .vscode └── settings.json ├── license ├── readme.md ├── package.json ├── .gitignore └── images └── selfie.svg /main/app/views/addLinks.hbs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /main/app/assets/img/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarthology/proGramCLI/HEAD/main/app/assets/img/test.jpg -------------------------------------------------------------------------------- /program/fonts/BlendaScript.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarthology/proGramCLI/HEAD/program/fonts/BlendaScript.otf -------------------------------------------------------------------------------- /main/app/assets/fonts/BlendaScript.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarthology/proGramCLI/HEAD/main/app/assets/fonts/BlendaScript.otf -------------------------------------------------------------------------------- /program/fonts/FiraSans-UltraLight.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarthology/proGramCLI/HEAD/program/fonts/FiraSans-UltraLight.otf -------------------------------------------------------------------------------- /main/app/assets/fonts/FiraSans-UltraLight.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarthology/proGramCLI/HEAD/main/app/assets/fonts/FiraSans-UltraLight.otf -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 80, 3 | tabWidth: 2, 4 | useTabs: true, 5 | semi: true, 6 | singleQuote: true, 7 | trailingComma: 'none', 8 | bracketSpacing: true, 9 | arrowParens: 'avoid', 10 | endOfLine: 'lf' 11 | }; 12 | -------------------------------------------------------------------------------- /main/app/views/uploader.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |

Please choose a new Picture

6 |
7 | Upload Image 8 |
9 |
-------------------------------------------------------------------------------- /main/app/views/initialize.hbs: -------------------------------------------------------------------------------- 1 |
2 | 5 |
6 | 7 |
8 |
9 | Let's get started 10 |
11 |
12 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | commonjs: true, 5 | es6: true, 6 | node: true 7 | }, 8 | extends: ['eslint:recommended', 'prettier'], 9 | globals: { 10 | Atomics: 'readonly', 11 | SharedArrayBuffer: 'readonly' 12 | }, 13 | parserOptions: { 14 | ecmaVersion: 2018 15 | }, 16 | rules: { 17 | 'no-console': 'off', 18 | 'no-unused-vars': 'off', 19 | 'no-undef': 'off' 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /main/app/views/adjust.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | 6 |
7 |
8 |
Back
9 |
Add Filters
10 |
11 |
-------------------------------------------------------------------------------- /main/app/util/readFileSync.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // NATIVE IMPORTS 4 | const fs = require('fs'); 5 | 6 | /** 7 | * This is a wrapper function for the `fs` module's `readFile` function. 8 | * @param {string} file - The path to the file to be read 9 | * @returns {string} The data read from the file 10 | */ 11 | function readFileSync(file) { 12 | return fs.readFileSync(file, { encoding: 'utf8' }); 13 | } 14 | 15 | module.exports = readFileSync; 16 | -------------------------------------------------------------------------------- /main/app/views/finish.hbs: -------------------------------------------------------------------------------- 1 |
2 |

Congratulations, Your files are generated.

3 |
4 | 5 |
6 |
7 | See Files 8 |
9 |
10 | Open in Browser 11 |
12 |
-------------------------------------------------------------------------------- /bin/cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { spawn } = require('child_process'); 4 | const electron = require('electron'); 5 | const path = require('path'); 6 | 7 | const serverPath = path.join(__dirname, '../main/main.js'); 8 | 9 | const args = [serverPath] 10 | .concat([].concat(process.argv).splice(2)) 11 | .concat('--not-packaged=true'); 12 | 13 | const proc = spawn(electron, args, { stdio: 'inherit' }); 14 | proc.on('close', code => { 15 | process.exit(code); 16 | }); 17 | -------------------------------------------------------------------------------- /main/app/views/generate.hbs: -------------------------------------------------------------------------------- 1 |
2 |

Your image is ready

3 |
4 |
5 | 6 |
7 |
8 |
9 | Generate 10 |
11 |
12 | Add More Photos 13 |
14 |
-------------------------------------------------------------------------------- /main/app/views/onboarding.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Click to Upload Image

4 |
5 |
6 |
7 |
8 |
9 | 10 |
11 |
12 | 13 |
14 |
15 |
16 | Save Profile 17 |
18 |
-------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "workbench.colorCustomizations": { 3 | "activityBar.background": "#fbed80", 4 | "activityBar.foreground": "#15202b", 5 | "activityBar.inactiveForeground": "#15202b99", 6 | "activityBarBadge.background": "#06b9a5", 7 | "activityBarBadge.foreground": "#15202b", 8 | "titleBar.activeBackground": "#f9e64f", 9 | "titleBar.inactiveBackground": "#f9e64f99", 10 | "titleBar.activeForeground": "#15202b", 11 | "titleBar.inactiveForeground": "#15202b99", 12 | "statusBar.background": "#f9e64f", 13 | "statusBarItem.hoverBackground": "#f7df1e", 14 | "statusBar.foreground": "#15202b" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /main/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | program 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |

proGram

17 |
18 |
19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /main/app/views/editor.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 |
7 | {{#each filters}} 8 |
9 |

{{name}}

10 |
11 | 12 |
13 |
14 | {{/each}} 15 |
16 |
17 |
Back
18 |
Finish
19 |
20 | -------------------------------------------------------------------------------- /main/app/views/settings.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Settings

4 |
5 |
6 |

Edit Profile

7 |
8 |
9 |

Edit Links

10 |
11 |
12 |

Contribute

13 |
14 |
15 |

Support

16 |
17 |
18 |

Tweet some ❤️

19 |
20 |
21 | 22 |
23 |
24 | 25 |
26 |
27 |

Thanks and Love from Team XenoX 🔥

28 |
29 |
30 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Sarthak Sharma 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ![](https://i.imgur.com/hVwW8R4.png) 2 | 3 | ## Program CLI 4 | 5 | ProGram is a CLI based, self-hosted photo sharing app. You can think of it as Instagram for programmers who want to keep their data secure while still being able to showcase their best shots in a cool gallery style. 6 | 7 | ## Screenshots 8 | 9 | ![](https://i.imgur.com/pEvghU3.gif) 10 | 11 | ## Prerequisites 12 | 13 | Before running this locally you must have these installed. 14 | 15 | - Node 16 | - Electron 17 | 18 | ## Installing 19 | 20 | ``` 21 | $ npm i -g programcli 22 | $ program 23 | ``` 24 | 25 | ## Development 26 | 27 | It's really easy, just follow these steps below 28 | 29 | ```sh 30 | $ git clone https://github.com/sarthology/proGramCLI.git 31 | $ cd proGramCLI 32 | $ npm install 33 | $ npm link 34 | ``` 35 | 36 | Now to run program you can either `npm run dev` or simply type `program` 37 | 38 | That's it. 39 | 40 | ## Contributing 41 | 42 | Feel free to contribute to this project and treat it like your own. 😊 43 | 44 | ## Useful Links 45 | 46 | - Website: [https://sarthology.github.io/proGramCLI/](https://sarthology.github.io/proGramCLI/) 47 | 48 | ## License 49 | 50 | MIT License 51 | 52 | ## Author 53 | 54 | [Sarthak Sharma](https://twitter.com/sarthology) 55 | 56 | ## Acknowledgments 57 | 58 | Icons used from [flaticon](https://flaticon.com). 59 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "programcli", 3 | "version": "0.0.7", 4 | "description": "", 5 | "main": "main/main.js", 6 | "bin": { 7 | "program": "./bin/cli.js" 8 | }, 9 | "scripts": { 10 | "start": "electron main/main.js --not-packaged=true", 11 | "dev": "electron main/main.js --not-packaged=true --debug=true" 12 | }, 13 | "files": [ 14 | "bin", 15 | "images", 16 | "main", 17 | "program" 18 | ], 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/sarthology/proGramCLI.git" 22 | }, 23 | "keywords": [], 24 | "author": "Sarthak Sharma (https://sarthak.it)", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/sarthology/proGramCLI/issues" 28 | }, 29 | "homepage": "https://github.com/sarthology/proGramCLI#readme", 30 | "husky": { 31 | "hooks": { 32 | "pre-commit": "lint-staged" 33 | } 34 | }, 35 | "lint-staged": { 36 | "*.{js,json,md}": [ 37 | "prettier --write", 38 | "git add" 39 | ] 40 | }, 41 | "devDependencies": { 42 | "eslint": "^5.16.0", 43 | "eslint-config-prettier": "^4.2.0", 44 | "eslint-plugin-prettier": "^3.1.0", 45 | "husky": "^2.3.0", 46 | "lint-staged": "^8.1.7", 47 | "prettier": "^1.17.1" 48 | }, 49 | "dependencies": { 50 | "croppie": "^2.6.4", 51 | "electron": "4.0.1", 52 | "fs-extra": "^8.1.0", 53 | "handlebars": "^4.1.2", 54 | "meow": "^5.0.0", 55 | "update-notifier": "^3.0.0" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /main/app/util/generator.js: -------------------------------------------------------------------------------- 1 | const generator = (profile, feed) => { 2 | return ` 3 | 4 | 5 | 6 | 7 | 8 | proGram 9 | 10 | 11 | 12 | 13 |
14 |
15 |

proGram

16 |
17 |
18 |
19 |
20 | 21 |
22 |
23 |

${profile.name}

24 |

${profile.username}

25 |
26 |

${profile.bio}

27 |
28 |
29 |
30 |
31 | 32 |
33 | ${feed 34 | .map( 35 | post => `
36 |
37 | 38 |
39 |
` 40 | ) 41 | .join('')} 42 |
43 | 44 | 45 | `; 46 | }; 47 | 48 | module.exports = generator; 49 | -------------------------------------------------------------------------------- /main/app/assets/img/rotation.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Optional REPL history 57 | .node_repl_history 58 | 59 | # Output of 'npm pack' 60 | *.tgz 61 | 62 | # Yarn Integrity file 63 | .yarn-integrity 64 | 65 | # dotenv environment variables file 66 | .env 67 | .env.test 68 | 69 | # parcel-bundler cache (https://parceljs.org/) 70 | .cache 71 | 72 | # next.js build output 73 | .next 74 | 75 | # nuxt.js build output 76 | .nuxt 77 | 78 | # vuepress build output 79 | .vuepress/dist 80 | 81 | # Serverless directories 82 | .serverless/ 83 | 84 | # FuseBox cache 85 | .fusebox/ 86 | 87 | # DynamoDB Local files 88 | .dynamodb/ 89 | 90 | # Output file 91 | output/ 92 | -------------------------------------------------------------------------------- /main/app/assets/data/filters.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "name": "1977", "class": "filter-1977" }, 3 | { "name": "Aden", "class": "filter-aden" }, 4 | { "name": "Amaro", "class": "filter-amaro" }, 5 | { "name": "Ashby", "class": "filter-ashby" }, 6 | { "name": "Brannan", "class": "filter-brannan" }, 7 | { "name": "Brooklyn", "class": "filter-brooklyn" }, 8 | { "name": "Charmes", "class": "filter-charmes" }, 9 | { "name": "Clarendon", "class": "filter-clarendon" }, 10 | { "name": "Crema", "class": "filter-crema" }, 11 | { "name": "Dogpatch", "class": "filter-dogpatch" }, 12 | { "name": "Earlybird", "class": "filter-earlybird" }, 13 | { "name": "Gingham", "class": "filter-gingham" }, 14 | { "name": "Ginza", "class": "filter-ginza" }, 15 | { "name": "Hefe", "class": "filter-hefe" }, 16 | { "name": "Helena", "class": "filter-helena" }, 17 | { "name": "Hudson", "class": "filter-hudson" }, 18 | { "name": "Inkwell", "class": "filter-inkwell" }, 19 | { "name": "Kelvin", "class": "filter-kelvin" }, 20 | { "name": "Kuno", "class": "filter-juno" }, 21 | { "name": "Lark", "class": "filter-lark" }, 22 | { "name": "Lo-Fi", "class": "filter-lofi" }, 23 | { "name": "Ludwig", "class": "filter-ludwig" }, 24 | { "name": "Maven", "class": "filter-maven" }, 25 | { "name": "Mayfair", "class": "filter-mayfair" }, 26 | { "name": "Moon", "class": "filter-moon" }, 27 | { "name": "Nashville", "class": "filter-nashville" }, 28 | { "name": "Perpetua", "class": "filter-perpetua" }, 29 | { "name": "Poprocket", "class": "filter-poprocket" }, 30 | { "name": "Reyes", "class": "filter-reyes" }, 31 | { "name": "Rise", "class": "filter-rise" }, 32 | { "name": "Sierra", "class": "filter-sierra" }, 33 | { "name": "Skyline", "class": "filter-skyline" }, 34 | { "name": "Slumber", "class": "filter-slumber" }, 35 | { "name": "Stinson", "class": "filter-stinson" }, 36 | { "name": "Sutro", "class": "filter-sutro" }, 37 | { "name": "Toaster", "class": "filter-toaster" }, 38 | { "name": "Valencia", "class": "filter-valencia" }, 39 | { "name": "Vesper", "class": "filter-vesper" }, 40 | { "name": "Walden", "class": "filter-walden" }, 41 | { "name": "Willow", "class": "filter-willow" }, 42 | { "name": "X-Pro II", "class": "filter-xpro-ii" } 43 | ] 44 | -------------------------------------------------------------------------------- /main/main.js: -------------------------------------------------------------------------------- 1 | const { app, BrowserWindow, ipcMain, dialog } = require('electron'); 2 | const path = require('path'); 3 | const updateNotifier = require('update-notifier'); 4 | const pkg = require('../package.json'); 5 | const meow = require('meow'); 6 | 7 | const main = path.join(__dirname, '..', 'main', 'app/index.html'); 8 | let win; 9 | 10 | const cli = meow( 11 | ` 12 | Usage 13 | $ program 14 | 15 | Options 16 | --settings, -s Open settings page to edit profile 17 | 18 | Examples 19 | $ program 20 | 21 | $ program --settings 22 | `, 23 | { 24 | flags: { 25 | settings: { 26 | type: 'boolean', 27 | alias: 's' 28 | }, 29 | version: { 30 | alias: 'v' 31 | }, 32 | help: { 33 | alias: 'h' 34 | } 35 | } 36 | } 37 | ); 38 | 39 | const { 40 | flags: { settings } 41 | } = cli; 42 | 43 | function createWindow() { 44 | win = new BrowserWindow({ 45 | title: 'Program', 46 | width: 400, 47 | height: 700, 48 | resizable: false, 49 | frame: false, 50 | titleBarStyle: 'hidden', 51 | webPreferences: { 52 | nodeIntegration: true 53 | } 54 | }); 55 | 56 | win.loadFile(main); 57 | } 58 | 59 | ipcMain.on('requestedSettings', () => { 60 | win.webContents.send('settings', settings); 61 | }); 62 | 63 | ipcMain.on('getDirectory', (event, arg) => { 64 | dialog.showOpenDialog({ properties: ['openDirectory'] }, dir => { 65 | if (dir) { 66 | win.webContents.send('directoryAdded', dir[0]); 67 | } else { 68 | win.webContents.send('directoryNotAdded'); 69 | } 70 | }); 71 | }); 72 | 73 | ipcMain.on('getImage', (event, arg) => { 74 | dialog.showOpenDialog({ properties: ['openFile'] }, filePaths => { 75 | if (filePaths) win.webContents.send('imgAdded', filePaths[0]); 76 | }); 77 | }); 78 | 79 | ipcMain.on('uploadProfile', (event, arg) => { 80 | dialog.showOpenDialog({ properties: ['openFile'] }, filePaths => { 81 | if (filePaths) win.webContents.send('profileAdded', filePaths[0]); 82 | }); 83 | }); 84 | 85 | app.on('ready', createWindow); 86 | 87 | // Checks for available update and returns an instance 88 | const notifier = updateNotifier({ 89 | pkg, 90 | updateCheckInterval: 1000 * 60 * 60 * 1 91 | }); 92 | 93 | // Notify using the built-in convenience method 94 | notifier.notify(); 95 | -------------------------------------------------------------------------------- /program/css/style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: blenda; 3 | src: url(../fonts/BlendaScript.otf); 4 | } 5 | @font-face { 6 | font-family: fira; 7 | src: url(../fonts/FiraSans-UltraLight.otf); 8 | } 9 | * { 10 | font-family: "fira"; 11 | } 12 | body { 13 | margin: 0; 14 | } 15 | 16 | .title h1 { 17 | margin: 10px 15px; 18 | font-family: "blenda"; 19 | } 20 | .title { 21 | border-bottom: 1px solid #e3e3e3; 22 | } 23 | .profile { 24 | display: grid; 25 | grid-template-columns: 1fr 4fr; 26 | width: 70%; 27 | margin: 0 auto; 28 | } 29 | .picture { 30 | width: 150px; 31 | height: 150px; 32 | border-radius: 60%; 33 | overflow: hidden; 34 | margin: 15px; 35 | } 36 | .profile img { 37 | width: 100%; 38 | } 39 | .details { 40 | margin-top: 20px; 41 | } 42 | .details > h1, 43 | h4 { 44 | margin: 0; 45 | font-weight: 100; 46 | } 47 | .details h4 { 48 | color: #a1a1a1; 49 | } 50 | .program { 51 | margin: 10px; 52 | width: 300px; 53 | height: 300px; 54 | overflow: hidden; 55 | cursor: pointer; 56 | } 57 | .proto-graph { 58 | display: grid; 59 | grid-template-columns: 1fr 1fr 1fr; 60 | width: 70%; 61 | margin: 0 auto; 62 | } 63 | .program img { 64 | width: 100%; 65 | } 66 | figure { 67 | margin: 0; 68 | } 69 | .links{ 70 | display: flex; 71 | width:100%; 72 | flex-wrap: wrap; 73 | } 74 | .links img{ 75 | width: 25px; 76 | height: 25px; 77 | margin-right: 13px; 78 | margin-bottom: 10px; 79 | } 80 | .divider { 81 | height: 50px; 82 | border-top: 1px solid #e3e3e3; 83 | border-bottom: 1px solid #e3e3e3; 84 | margin-bottom: 30px; 85 | } 86 | 87 | @media (max-width: 414px) { 88 | header { 89 | text-align: center; 90 | } 91 | .proto-graph { 92 | width: 100%; 93 | grid-template-columns: 1fr; 94 | } 95 | .program { 96 | margin: 10px auto; 97 | } 98 | .details { 99 | text-align: center; 100 | } 101 | .picture { 102 | margin: 0 auto; 103 | margin-top: 11px; 104 | } 105 | .links{ 106 | justify-content: center; 107 | } 108 | .profile { 109 | grid-template-columns: 1fr; 110 | width: 80%; 111 | } 112 | } 113 | 114 | @media (min-width: 500px) and (max-width: 800px) { 115 | header { 116 | text-align: center; 117 | } 118 | .proto-graph { 119 | width: 100%; 120 | grid-template-columns: 1fr 1fr; 121 | } 122 | .program { 123 | margin: 10px auto; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /main/app/assets/css/croppie.css: -------------------------------------------------------------------------------- 1 | .croppie-container { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | 6 | .croppie-container .cr-image { 7 | z-index: -1; 8 | position: absolute; 9 | top: 0; 10 | left: 0; 11 | transform-origin: 0 0; 12 | max-height: none; 13 | max-width: none; 14 | } 15 | 16 | .croppie-container .cr-boundary { 17 | position: relative; 18 | overflow: hidden; 19 | margin: 0 auto; 20 | z-index: 1; 21 | width: 100%; 22 | height: 100%; 23 | } 24 | 25 | .croppie-container .cr-viewport, 26 | .croppie-container .cr-resizer { 27 | position: absolute; 28 | border: 2px solid #fff; 29 | margin: auto; 30 | top: 0; 31 | bottom: 0; 32 | right: 0; 33 | left: 0; 34 | box-shadow: 0 0 2000px 2000px rgba(0, 0, 0, 0.5); 35 | z-index: 0; 36 | } 37 | 38 | .croppie-container .cr-resizer { 39 | z-index: 2; 40 | box-shadow: none; 41 | pointer-events: none; 42 | } 43 | 44 | .croppie-container .cr-resizer-vertical, 45 | .croppie-container .cr-resizer-horisontal { 46 | position: absolute; 47 | pointer-events: all; 48 | } 49 | 50 | .croppie-container .cr-resizer-vertical::after, 51 | .croppie-container .cr-resizer-horisontal::after { 52 | display: block; 53 | position: absolute; 54 | box-sizing: border-box; 55 | border: 1px solid black; 56 | background: #fff; 57 | width: 10px; 58 | height: 10px; 59 | content: ''; 60 | } 61 | 62 | .croppie-container .cr-resizer-vertical { 63 | bottom: -5px; 64 | cursor: row-resize; 65 | width: 100%; 66 | height: 10px; 67 | } 68 | 69 | .croppie-container .cr-resizer-vertical::after { 70 | left: 50%; 71 | margin-left: -5px; 72 | } 73 | 74 | .croppie-container .cr-resizer-horisontal { 75 | right: -5px; 76 | cursor: col-resize; 77 | width: 10px; 78 | height: 100%; 79 | } 80 | 81 | .croppie-container .cr-resizer-horisontal::after { 82 | top: 50%; 83 | margin-top: -5px; 84 | } 85 | 86 | .croppie-container .cr-original-image { 87 | display: none; 88 | } 89 | 90 | .croppie-container .cr-vp-circle { 91 | border-radius: 50%; 92 | } 93 | 94 | .croppie-container .cr-overlay { 95 | z-index: 1; 96 | position: absolute; 97 | cursor: move; 98 | touch-action: none; 99 | } 100 | 101 | .croppie-container .cr-slider-wrap { 102 | width: 75%; 103 | margin: 15px auto; 104 | text-align: center; 105 | } 106 | 107 | .croppie-result { 108 | position: relative; 109 | overflow: hidden; 110 | } 111 | 112 | .croppie-result img { 113 | position: absolute; 114 | } 115 | 116 | .croppie-container .cr-image, 117 | .croppie-container .cr-overlay, 118 | .croppie-container .cr-viewport { 119 | -webkit-transform: translateZ(0); 120 | -moz-transform: translateZ(0); 121 | -ms-transform: translateZ(0); 122 | transform: translateZ(0); 123 | } 124 | 125 | /*************************************/ 126 | /***** STYLING RANGE INPUT ***********/ 127 | /*************************************/ 128 | /*http://brennaobrien.com/blog/2014/05/style-input-type-range-in-every-browser.html */ 129 | /*************************************/ 130 | 131 | .cr-slider { 132 | -webkit-appearance: none; 133 | /*removes default webkit styles*/ 134 | /*border: 1px solid white; *//*fix for FF unable to apply focus style bug */ 135 | width: 300px; 136 | /*required for proper track sizing in FF*/ 137 | max-width: 100%; 138 | padding-top: 8px; 139 | padding-bottom: 8px; 140 | background-color: transparent; 141 | } 142 | 143 | .cr-slider::-webkit-slider-runnable-track { 144 | width: 100%; 145 | height: 3px; 146 | background: rgba(0, 0, 0, 0.5); 147 | border: 0; 148 | border-radius: 3px; 149 | } 150 | 151 | .cr-slider::-webkit-slider-thumb { 152 | -webkit-appearance: none; 153 | border: none; 154 | height: 16px; 155 | width: 16px; 156 | border-radius: 50%; 157 | background: #ddd; 158 | margin-top: -6px; 159 | } 160 | 161 | .cr-slider:focus { 162 | outline: none; 163 | } 164 | /* 165 | .cr-slider:focus::-webkit-slider-runnable-track { 166 | background: #ccc; 167 | } 168 | */ 169 | 170 | .cr-slider::-moz-range-track { 171 | width: 100%; 172 | height: 3px; 173 | background: rgba(0, 0, 0, 0.5); 174 | border: 0; 175 | border-radius: 3px; 176 | } 177 | 178 | .cr-slider::-moz-range-thumb { 179 | border: none; 180 | height: 16px; 181 | width: 16px; 182 | border-radius: 50%; 183 | background: #ddd; 184 | margin-top: -6px; 185 | } 186 | 187 | /*hide the outline behind the border*/ 188 | .cr-slider:-moz-focusring { 189 | outline: 1px solid white; 190 | outline-offset: -1px; 191 | } 192 | 193 | .cr-slider::-ms-track { 194 | width: 100%; 195 | height: 5px; 196 | background: transparent; 197 | /*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */ 198 | border-color: transparent;/*leave room for the larger thumb to overflow with a transparent border */ 199 | border-width: 6px 0; 200 | color: transparent;/*remove default tick marks*/ 201 | } 202 | .cr-slider::-ms-fill-lower { 203 | background: rgba(0, 0, 0, 0.5); 204 | border-radius: 10px; 205 | } 206 | .cr-slider::-ms-fill-upper { 207 | background: rgba(0, 0, 0, 0.5); 208 | border-radius: 10px; 209 | } 210 | .cr-slider::-ms-thumb { 211 | border: none; 212 | height: 16px; 213 | width: 16px; 214 | border-radius: 50%; 215 | background: #ddd; 216 | margin-top:1px; 217 | } 218 | .cr-slider:focus::-ms-fill-lower { 219 | background: rgba(0, 0, 0, 0.5); 220 | } 221 | .cr-slider:focus::-ms-fill-upper { 222 | background: rgba(0, 0, 0, 0.5); 223 | } 224 | /*******************************************/ 225 | 226 | /***********************************/ 227 | /* Rotation Tools */ 228 | /***********************************/ 229 | .cr-rotate-controls { 230 | position: absolute; 231 | bottom: 5px; 232 | left: 5px; 233 | z-index: 1; 234 | } 235 | .cr-rotate-controls button { 236 | border: 0; 237 | background: none; 238 | } 239 | .cr-rotate-controls i:before { 240 | display: inline-block; 241 | font-style: normal; 242 | font-weight: 900; 243 | font-size: 22px; 244 | } 245 | .cr-rotate-l i:before { 246 | content: '↺'; 247 | } 248 | .cr-rotate-r i:before { 249 | content: '↻'; 250 | } 251 | -------------------------------------------------------------------------------- /main/app/assets/css/style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: blenda; 3 | src: url(../fonts/BlendaScript.otf); 4 | } 5 | @font-face { 6 | font-family: fira; 7 | src: url(../fonts/FiraSans-UltraLight.otf); 8 | } 9 | * { 10 | font-family: 'fira'; 11 | } 12 | body { 13 | margin: 0; 14 | } 15 | header { 16 | padding: 10px 0; 17 | border-bottom: 1px solid #e3e3e3; 18 | } 19 | .content { 20 | text-align: center; 21 | } 22 | .profile-header { 23 | margin-top: 50px; 24 | } 25 | .created-image img { 26 | object-fit: cover; 27 | height: 300px; 28 | width: 300px; 29 | } 30 | .created-image figure { 31 | width: 300px; 32 | height: 300px; 33 | margin: 0 auto; 34 | margin: 25px auto 10px; 35 | } 36 | #view { 37 | margin-top: 1px; 38 | } 39 | .darkBackground { 40 | background: #535358; 41 | } 42 | .image img { 43 | width: 100%; 44 | } 45 | .image { 46 | width: 400px; 47 | height: 400px; 48 | overflow: hidden; 49 | } 50 | .style { 51 | margin-left: 10px; 52 | padding: 5px; 53 | font-family: sans-serif; 54 | cursor: pointer; 55 | text-align: center; 56 | } 57 | .style figure { 58 | width: 100px; 59 | height: 100px; 60 | overflow: hidden; 61 | } 62 | .style p { 63 | margin: 5px; 64 | } 65 | .title { 66 | font-family: 'blenda'; 67 | text-align: center; 68 | font-weight: 100; 69 | margin: 0; 70 | font-size: 24px; 71 | } 72 | .filters { 73 | display: flex; 74 | overflow: scroll; 75 | margin: 15px 0; 76 | } 77 | ::-webkit-scrollbar { 78 | display: none; 79 | } 80 | .demo { 81 | width: 100px; 82 | } 83 | figure { 84 | margin: 0; 85 | } 86 | .img-upload { 87 | width: 50%; 88 | background: #5a94ff; 89 | text-align: center; 90 | color: #fff; 91 | font-weight: 900; 92 | margin: 0 auto; 93 | padding: 12px 20px; 94 | margin-top: 50px; 95 | cursor: pointer; 96 | } 97 | .upload-message { 98 | text-align: center; 99 | font-size: 20px; 100 | color: #868080; 101 | } 102 | .icon-camera, 103 | .user-icon { 104 | display: grid; 105 | } 106 | 107 | .icon-camera img { 108 | width: 200px; 109 | margin: 100px auto 30px; 110 | } 111 | 112 | .user-icon img { 113 | width: 200px; 114 | margin: 70px auto 20px; 115 | } 116 | 117 | .adjustImg { 118 | width: 400px; 119 | height: 600px; 120 | } 121 | 122 | .main-controls .controls { 123 | padding: 15px; 124 | text-align: center; 125 | font-weight: bolder; 126 | cursor: pointer; 127 | } 128 | .back { 129 | border-top: 1px solid #dedede; 130 | color: #737377; 131 | background: white; 132 | } 133 | .add-filters { 134 | background: #5a94ff; 135 | color: white; 136 | } 137 | .main-controls { 138 | display: grid; 139 | grid-template-columns: 1fr 1fr; 140 | position: absolute; 141 | width: 100%; 142 | bottom: 0; 143 | z-index: 10; 144 | } 145 | .rotate img { 146 | width: 20px; 147 | padding: 10px; 148 | background: #151414d4; 149 | position: absolute; 150 | margin-top: -70px; 151 | right: 20px; 152 | z-index: 10; 153 | } 154 | .rotate { 155 | cursor: pointer; 156 | } 157 | 158 | .content { 159 | padding: 20px; 160 | } 161 | 162 | .input-group input { 163 | font-size: 18px; 164 | padding: 10px 10px 10px 5px; 165 | display: block; 166 | width: 95%; 167 | border: none; 168 | border-bottom: 1px solid #757575; 169 | } 170 | 171 | input:focus, 172 | textarea:focus { 173 | outline: none; 174 | } 175 | 176 | .upload { 177 | width: 150px; 178 | margin: 0 auto; 179 | height: 150px; 180 | font-size: 20px; 181 | text-align: center; 182 | border-radius: 60%; 183 | border: 1px solid #e3e3e3; 184 | color: #8a8686; 185 | margin-top: 65px; 186 | cursor: pointer; 187 | } 188 | .upload p { 189 | margin-top: 35%; 190 | } 191 | .bio textarea { 192 | border: none; 193 | margin: 20px 0px; 194 | width: 95%; 195 | border-bottom: 1px solid #757575; 196 | font-size: 18px; 197 | height: 100px; 198 | } 199 | 200 | .input-group { 201 | margin-top: 40px; 202 | } 203 | 204 | #adjustProfile { 205 | display: none; 206 | width: 150px; 207 | height: 150px; 208 | margin: 0 auto; 209 | margin-top: 65px; 210 | } 211 | .dano img { 212 | width: 280px; 213 | margin: 0px auto; 214 | -webkit-animation-name: danny; 215 | animation-name: danny; 216 | -webkit-animation-duration: 2s; 217 | animation-duration: 2s; 218 | -webkit-animation-fill-mode: both; 219 | animation-fill-mode: both; 220 | } 221 | 222 | .dano { 223 | display: grid; 224 | margin-bottom: 100px; 225 | } 226 | 227 | .welcome { 228 | width: 100%; 229 | height: 100%; 230 | position: absolute; 231 | background: white; 232 | top: 0; 233 | } 234 | .logo { 235 | margin-top: 80px; 236 | } 237 | .logo h1 { 238 | text-align: center; 239 | font-family: 'blenda'; 240 | margin: 40px 0; 241 | } 242 | 243 | @keyframes danny { 244 | from { 245 | margin-left: -180px; 246 | } 247 | 248 | 10% { 249 | transform: rotate(15deg); 250 | } 251 | 25% { 252 | transform: rotate(-5deg); 253 | } 254 | 30% { 255 | transform: rotate(15deg); 256 | } 257 | 40% { 258 | transform: rotate(-5deg); 259 | } 260 | 261 | 50% { 262 | transform: rotate(15deg); 263 | } 264 | 265 | 65% { 266 | transform: rotate(-5deg); 267 | } 268 | 269 | 75% { 270 | transform: rotate(15deg); 271 | } 272 | 273 | to { 274 | margin-left: 60px; 275 | transform: none; 276 | } 277 | } 278 | 279 | .open-browser { 280 | background: #46ea8b; 281 | margin-top: 10px; 282 | } 283 | .dano-bye img { 284 | width: 200px; 285 | } 286 | .finish-head { 287 | font-size: 25px; 288 | margin: 40px auto; 289 | } 290 | .danob { 291 | width: 75%; 292 | } 293 | .settings { 294 | display: grid; 295 | grid-template-columns: 1fr; 296 | } 297 | .setting { 298 | border-bottom: 1px solid #e3e3e3; 299 | cursor: pointer; 300 | } 301 | .setting p { 302 | padding-left: 35px; 303 | font-weight: bold; 304 | } 305 | .setting-group { 306 | font-size: 16px; 307 | font-weight: bold; 308 | padding-left: 15px; 309 | border-bottom: 1px solid #e3e3e3; 310 | } 311 | .setting-group p { 312 | margin: 15px 0; 313 | } 314 | .thanks-message { 315 | text-align: center; 316 | font-weight: bold; 317 | font-size: 14px; 318 | } 319 | .thanks-img img { 320 | width: 200px; 321 | margin: 20px auto; 322 | } 323 | .thanks-img { 324 | display: grid; 325 | } 326 | .add-more { 327 | background: white; 328 | color: #696565; 329 | margin-top: 10px; 330 | border: 1px solid #bbbaba; 331 | } 332 | -------------------------------------------------------------------------------- /main/app/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | //Dependencies 4 | const handlebars = require('handlebars'); 5 | const Croppie = require('croppie'); 6 | const { ipcRenderer, shell } = require('electron'); 7 | const path = require('path'); 8 | const fs = require('fs-extra'); 9 | const crypto = require('crypto'); 10 | const os = require('os'); 11 | 12 | // utils 13 | const generator = require('./util/generator'); 14 | 15 | const homedir = os.homedir(); 16 | const config = path.resolve(homedir, '.programrc.json'); 17 | 18 | const rawdata = fs.readFileSync( 19 | path.resolve(__dirname, './assets/data/filters.json') 20 | ); 21 | const filters = JSON.parse(rawdata); 22 | 23 | const readFileSync = require('./util/readFileSync'); 24 | 25 | const currentPost = {}; 26 | let instaImage = null; 27 | let viewport, profileAdjust; 28 | let filter = null; 29 | let outputDir; 30 | 31 | //Views 32 | const editor = readFileSync(path.resolve(__dirname, './views/editor.hbs')); 33 | const uploader = readFileSync(path.resolve(__dirname, './views/uploader.hbs')); 34 | const adjust = readFileSync(path.resolve(__dirname, './views/adjust.hbs')); 35 | const finish = readFileSync(path.resolve(__dirname, './views/finish.hbs')); 36 | const settings = readFileSync(path.resolve(__dirname, './views/settings.hbs')); 37 | const onboarding = readFileSync( 38 | path.resolve(__dirname, './views/onboarding.hbs') 39 | ); 40 | const generate = readFileSync(path.resolve(__dirname, './views/generate.hbs')); 41 | const initialize = readFileSync( 42 | path.resolve(__dirname, './views/initialize.hbs') 43 | ); 44 | 45 | window.onload = event => { 46 | changeView(initialize); 47 | }; 48 | 49 | ipcRenderer.on('imgAdded', (event, arg) => { 50 | instaImage = arg; 51 | changeView(adjust); 52 | }); 53 | 54 | ipcRenderer.on('profileAdded', (event, arg) => { 55 | document.getElementsByClassName('upload')[0].style = 'display:none'; 56 | document.getElementById('adjustProfile').style = 'display:block'; 57 | profileAdjust = new Croppie(document.getElementById('adjustProfile'), { 58 | url: arg, 59 | enableOrientation: true, 60 | viewport: { 61 | width: 150, 62 | height: 150, 63 | type: 'circle' 64 | } 65 | }); 66 | }); 67 | 68 | const changeFilter = selectedFilter => { 69 | let canvas = document.getElementById('canvas'); 70 | canvas.classList = ''; 71 | canvas.classList.add(selectedFilter); 72 | filter = selectedFilter; 73 | 74 | // save currentPost filter 75 | currentPost.filter = selectedFilter; 76 | }; 77 | 78 | const saveProfile = () => { 79 | profileAdjust.result({ type: 'base64', size: 'original' }).then(newImage => { 80 | let profileImage = newImage; 81 | 82 | const name = document.getElementById('name').value; 83 | const bio = document.getElementById('bio').value; 84 | 85 | const dataDir = path.resolve(outputDir, 'data'); 86 | const imageDir = path.resolve(outputDir, 'assets', 'images'); 87 | 88 | const userFile = path.resolve(dataDir, 'profile.json'); 89 | const imagePath = path.resolve(imageDir, name + '.png'); 90 | 91 | const relativePath = path.relative(outputDir, imagePath); 92 | 93 | if (!fs.existsSync(dataDir)) fs.ensureDirSync(dataDir); 94 | if (!fs.existsSync(imageDir)) fs.ensureDirSync(imageDir); 95 | 96 | const imageDataURI = newImage.replace(/^data:image\/png;base64,/, ''); 97 | fs.writeFileSync(imagePath, imageDataURI, 'base64'); 98 | 99 | const userData = { 100 | name, 101 | bio, 102 | profilePic: relativePath 103 | }; 104 | 105 | fs.writeFileSync(userFile, JSON.stringify(userData, null, 4)); 106 | 107 | changeView(uploader); 108 | }); 109 | }; 110 | 111 | const editProfile = () => { 112 | changeView(onboarding); 113 | 114 | const profileFile = path.resolve(outputDir, 'data', 'profile.json'); 115 | const profileData = fs.readFileSync(profileFile); 116 | const profile = JSON.parse(profileData); 117 | 118 | document.getElementById('bio').value = profile.bio; 119 | document.getElementById('name').value = profile.name; 120 | 121 | document.getElementsByClassName('upload')[0].style = 'display:none'; 122 | document.getElementById('adjustProfile').style = 'display:block'; 123 | 124 | profileAdjust = new Croppie(document.getElementById('adjustProfile'), { 125 | url: path.resolve(outputDir, profile.profilePic), 126 | enableOrientation: true, 127 | viewport: { 128 | width: 150, 129 | height: 150, 130 | type: 'circle' 131 | } 132 | }); 133 | }; 134 | 135 | const showProfile = () => { 136 | // generate random name/id for cropped image 137 | const seed = crypto.randomBytes(20); 138 | 139 | const uniqueName = crypto 140 | .createHash('sha1') 141 | .update(seed) 142 | .digest('hex'); 143 | 144 | const imageDir = path.resolve(outputDir, 'assets', 'images'); 145 | 146 | const imagePath = path.resolve(imageDir, uniqueName + '.png'); 147 | const feedFile = path.resolve(outputDir, 'data', 'feed.json'); 148 | 149 | // load existing feed if it exists 150 | const feedData = fs.existsSync(feedFile) 151 | ? JSON.parse(fs.readFileSync(feedFile)) 152 | : []; 153 | 154 | // save the cropped image 155 | const imageDataURI = instaImage.replace(/^data:image\/png;base64,/, ''); 156 | fs.writeFileSync(imagePath, imageDataURI, 'base64'); 157 | 158 | currentPost.imagePath = path.relative(outputDir, imagePath); 159 | 160 | currentPost.date = new Date(); 161 | feedData.push(currentPost); 162 | 163 | fs.writeFileSync(feedFile, JSON.stringify(feedData)); 164 | 165 | changeView(generate); 166 | }; 167 | 168 | const generateIndex = () => { 169 | const feedFile = path.resolve(outputDir, 'data', 'feed.json'); 170 | const profileFile = path.resolve(outputDir, 'data', 'profile.json'); 171 | const index = path.resolve(outputDir, 'index.html'); 172 | 173 | const feedData = fs.readFileSync(feedFile); 174 | const profileData = fs.readFileSync(profileFile); 175 | 176 | const feed = JSON.parse(feedData); 177 | const profile = JSON.parse(profileData); 178 | 179 | const html = generator(profile, feed); 180 | 181 | fs.writeFileSync(index, html); 182 | changeView(finish); 183 | }; 184 | 185 | const imgUpload = () => { 186 | ipcRenderer.send('getImage'); 187 | }; 188 | 189 | const addFilters = () => { 190 | document.getElementById('view').removeAttribute('class'); 191 | viewport.result({ type: 'base64', size: 'original' }).then(newImage => { 192 | instaImage = newImage; 193 | changeView(editor); 194 | }); 195 | }; 196 | 197 | const uploadProfile = () => { 198 | ipcRenderer.send('uploadProfile'); 199 | }; 200 | 201 | const onboardMe = () => { 202 | if (fs.existsSync(config)) { 203 | outputDir = JSON.parse(fs.readFileSync(config)).programPath; 204 | 205 | const profile = path.resolve(outputDir, 'data', 'profile.json'); 206 | if (fs.existsSync(profile)) { 207 | ipcRenderer.send('requestedSettings'); 208 | ipcRenderer.on('settings', (event, settingsRequested) => { 209 | settingsRequested ? changeView(settings) : changeView(uploader); 210 | }); 211 | } else { 212 | changeView(onboarding); 213 | } 214 | } else { 215 | ipcRenderer.send('getDirectory'); 216 | ipcRenderer.on('directoryAdded', (event, dir) => { 217 | outputDir = path.resolve(dir, 'program'); 218 | 219 | const source = path.resolve(__dirname, '..', '..', 'program'); 220 | 221 | fs.copySync(source, outputDir); 222 | 223 | if (!fs.existsSync(config)) { 224 | fs.writeFileSync( 225 | config, 226 | JSON.stringify({ 227 | programPath: outputDir 228 | }) 229 | ); 230 | } 231 | 232 | changeView(onboarding); 233 | }); 234 | 235 | ipcRenderer.on('directoryNotAdded', () => { 236 | document.getElementById('initializeMessage').textContent = 237 | 'Select program directory'; 238 | }); 239 | } 240 | }; 241 | 242 | const goBackTo = page => { 243 | document.getElementById('view').removeAttribute('class'); 244 | page === 'adjust' ? changeView(adjust) : changeView(uploader); 245 | }; 246 | 247 | const changeView = view => { 248 | const template = handlebars.compile(view, { strict: true }); 249 | const result = template({ 250 | filters: filters, 251 | instaImage: instaImage, 252 | filter: filter 253 | }); 254 | 255 | document.getElementById('view').innerHTML = result; 256 | if (view === adjust) cropImage(instaImage); 257 | }; 258 | 259 | const addMore = () => changeView(uploader); 260 | 261 | const gotoSettings = () => changeView(settings); 262 | 263 | const cropImage = () => { 264 | document.getElementById('view').setAttribute('class', 'darkBackground'); 265 | viewport = new Croppie(document.getElementById('adjustImg'), { 266 | url: instaImage, 267 | showZoomer: false, 268 | enableOrientation: true, 269 | viewport: { 270 | width: 300, 271 | height: 300 272 | } 273 | }); 274 | }; 275 | const rotateImage = () => { 276 | viewport.rotate(90); 277 | }; 278 | 279 | const openFinder = () => { 280 | shell.showItemInFolder(outputDir); 281 | }; 282 | 283 | const openBrowser = () => { 284 | shell.openItem(outputDir + '/index.html'); 285 | }; 286 | 287 | const contribute = () => { 288 | shell.openItem('https://github.com/sarthology/proGramCLI'); 289 | }; 290 | 291 | const support = () => { 292 | shell.openItem('https://www.paypal.me/Sarthakit'); 293 | }; 294 | 295 | const tweet = () => { 296 | shell.openItem('https://twitter.com/sarthology'); 297 | }; 298 | -------------------------------------------------------------------------------- /main/app/assets/img/kiss.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 10 | 12 | 13 | 18 | 23 | 24 | 27 | 30 | 32 | 35 | 37 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 51 | 55 | 58 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /program/css/instagram.min.css: -------------------------------------------------------------------------------- 1 | /*! Instagram.css v0.1.4 | MIT License | github.com/picturepan2/instagram.css */[class*=filter]{position:relative}[class*=filter]::before{display:block;height:100%;left:0;position:absolute;top:0;width:100%;z-index:1}.filter-1977{-webkit-filter:sepia(.5) hue-rotate(-30deg) saturate(1.4);filter:sepia(.5) hue-rotate(-30deg) saturate(1.4)}.filter-aden{-webkit-filter:sepia(.2) brightness(1.15) saturate(1.4);filter:sepia(.2) brightness(1.15) saturate(1.4)}.filter-aden::before{background:rgba(125,105,24,.1);content:"";mix-blend-mode:multiply}.filter-amaro{-webkit-filter:sepia(.35) contrast(1.1) brightness(1.2) saturate(1.3);filter:sepia(.35) contrast(1.1) brightness(1.2) saturate(1.3)}.filter-amaro::before{background:rgba(125,105,24,.2);content:"";mix-blend-mode:overlay}.filter-ashby{-webkit-filter:sepia(.5) contrast(1.2) saturate(1.8);filter:sepia(.5) contrast(1.2) saturate(1.8)}.filter-ashby::before{background:rgba(125,105,24,.35);content:"";mix-blend-mode:lighten}.filter-brannan{-webkit-filter:sepia(.4) contrast(1.25) brightness(1.1) saturate(.9) hue-rotate(-2deg);filter:sepia(.4) contrast(1.25) brightness(1.1) saturate(.9) hue-rotate(-2deg)}.filter-brooklyn{-webkit-filter:sepia(.25) contrast(1.25) brightness(1.25) hue-rotate(5deg);filter:sepia(.25) contrast(1.25) brightness(1.25) hue-rotate(5deg)}.filter-brooklyn::before{background:rgba(127,187,227,.2);content:"";mix-blend-mode:overlay}.filter-charmes{-webkit-filter:sepia(.25) contrast(1.25) brightness(1.25) saturate(1.35) hue-rotate(-5deg);filter:sepia(.25) contrast(1.25) brightness(1.25) saturate(1.35) hue-rotate(-5deg)}.filter-charmes::before{background:rgba(125,105,24,.25);content:"";mix-blend-mode:darken}.filter-clarendon{-webkit-filter:sepia(.15) contrast(1.25) brightness(1.25) hue-rotate(5deg);filter:sepia(.15) contrast(1.25) brightness(1.25) hue-rotate(5deg)}.filter-clarendon::before{background:rgba(127,187,227,.4);content:"";mix-blend-mode:overlay}.filter-crema{-webkit-filter:sepia(.5) contrast(1.25) brightness(1.15) saturate(.9) hue-rotate(-2deg);filter:sepia(.5) contrast(1.25) brightness(1.15) saturate(.9) hue-rotate(-2deg)}.filter-crema::before{background:rgba(125,105,24,.2);content:"";mix-blend-mode:multiply}.filter-dogpatch{-webkit-filter:sepia(.35) saturate(1.1) contrast(1.5);filter:sepia(.35) saturate(1.1) contrast(1.5)}.filter-earlybird{-webkit-filter:sepia(.25) contrast(1.25) brightness(1.15) saturate(.9) hue-rotate(-5deg);filter:sepia(.25) contrast(1.25) brightness(1.15) saturate(.9) hue-rotate(-5deg)}.filter-earlybird::before{background:radial-gradient(circle closest-corner,transparent 0,rgba(125,105,24,.2) 100%);background:-o-radial-gradient(circle closest-corner,transparent 0,rgba(125,105,24,.2) 100%);background:-moz-radial-gradient(circle closest-corner,transparent 0,rgba(125,105,24,.2) 100%);background:-webkit-radial-gradient(circle closest-corner,transparent 0,rgba(125,105,24,.2) 100%);content:"";mix-blend-mode:multiply}.filter-gingham{-webkit-filter:contrast(1.1) brightness(1.1);filter:contrast(1.1) brightness(1.1)}.filter-gingham::before{background:#e6e6e6;content:"";mix-blend-mode:soft-light}.filter-ginza{-webkit-filter:sepia(.25) contrast(1.15) brightness(1.2) saturate(1.35) hue-rotate(-5deg);filter:sepia(.25) contrast(1.15) brightness(1.2) saturate(1.35) hue-rotate(-5deg)}.filter-ginza::before{background:rgba(125,105,24,.15);content:"";mix-blend-mode:darken}.filter-hefe{-webkit-filter:sepia(.4) contrast(1.5) brightness(1.2) saturate(1.4) hue-rotate(-10deg);filter:sepia(.4) contrast(1.5) brightness(1.2) saturate(1.4) hue-rotate(-10deg)}.filter-hefe::before{background:radial-gradient(circle closest-corner,transparent 0,rgba(0,0,0,.25) 100%);background:-o-radial-gradient(circle closest-corner,transparent 0,rgba(0,0,0,.25) 100%);background:-moz-radial-gradient(circle closest-corner,transparent 0,rgba(0,0,0,.25) 100%);background:-webkit-radial-gradient(circle closest-corner,transparent 0,rgba(0,0,0,.25) 100%);content:"";mix-blend-mode:multiply}.filter-helena{-webkit-filter:sepia(.5) contrast(1.05) brightness(1.05) saturate(1.35);filter:sepia(.5) contrast(1.05) brightness(1.05) saturate(1.35)}.filter-helena::before{background:rgba(158,175,30,.25);content:"";mix-blend-mode:overlay}.filter-hudson{-webkit-filter:sepia(.25) contrast(1.2) brightness(1.2) saturate(1.05) hue-rotate(-15deg);filter:sepia(.25) contrast(1.2) brightness(1.2) saturate(1.05) hue-rotate(-15deg)}.filter-hudson::before{background:radial-gradient(circle closest-corner,transparent 25%,rgba(25,62,167,.25) 100%);background:-o-radial-gradient(circle closest-corner,transparent 25%,rgba(25,62,167,.25) 100%);background:-moz-radial-gradient(circle closest-corner,transparent 25%,rgba(25,62,167,.25) 100%);background:-webkit-radial-gradient(circle closest-corner,transparent 25%,rgba(25,62,167,.25) 100%);content:"";mix-blend-mode:multiply}.filter-inkwell{-webkit-filter:brightness(1.25) contrast(.85) grayscale(1);filter:brightness(1.25) contrast(.85) grayscale(1)}.filter-juno{-webkit-filter:sepia(.35) contrast(1.15) brightness(1.15) saturate(1.8);filter:sepia(.35) contrast(1.15) brightness(1.15) saturate(1.8)}.filter-juno::before{background:rgba(127,187,227,.2);content:"";mix-blend-mode:overlay}.filter-kelvin{-webkit-filter:sepia(.15) contrast(1.5) brightness(1.1) hue-rotate(-10deg);filter:sepia(.15) contrast(1.5) brightness(1.1) hue-rotate(-10deg)}.filter-kelvin::before{background:radial-gradient(circle closest-corner,rgba(128,78,15,.25) 0,rgba(128,78,15,.5) 100%);background:-o-radial-gradient(circle closest-corner,rgba(128,78,15,.25) 0,rgba(128,78,15,.5) 100%);background:-moz-radial-gradient(circle closest-corner,rgba(128,78,15,.25) 0,rgba(128,78,15,.5) 100%);background:-webkit-radial-gradient(circle closest-corner,rgba(128,78,15,.25) 0,rgba(128,78,15,.5) 100%);content:"";mix-blend-mode:overlay}.filter-lark{-webkit-filter:sepia(.25) contrast(1.2) brightness(1.3) saturate(1.25);filter:sepia(.25) contrast(1.2) brightness(1.3) saturate(1.25)}.filter-lofi{-webkit-filter:saturate(1.1) contrast(1.5);filter:saturate(1.1) contrast(1.5)}.filter-ludwig{-webkit-filter:sepia(.25) contrast(1.05) brightness(1.05) saturate(2);filter:sepia(.25) contrast(1.05) brightness(1.05) saturate(2)}.filter-ludwig::before{background:rgba(125,105,24,.1);content:"";mix-blend-mode:overlay}.filter-maven{-webkit-filter:sepia(.35) contrast(1.05) brightness(1.05) saturate(1.75);filter:sepia(.35) contrast(1.05) brightness(1.05) saturate(1.75)}.filter-maven::before{background:rgba(158,175,30,.25);content:"";mix-blend-mode:darken}.filter-mayfair{-webkit-filter:contrast(1.1) brightness(1.15) saturate(1.1);filter:contrast(1.1) brightness(1.15) saturate(1.1)}.filter-mayfair::before{background:radial-gradient(circle closest-corner,transparent 0,rgba(175,105,24,.4) 100%);background:-o-radial-gradient(circle closest-corner,transparent 0,rgba(175,105,24,.4) 100%);background:-moz-radial-gradient(circle closest-corner,transparent 0,rgba(175,105,24,.4) 100%);background:-webkit-radial-gradient(circle closest-corner,transparent 0,rgba(175,105,24,.4) 100%);content:"";mix-blend-mode:multiply}.filter-moon{-webkit-filter:brightness(1.4) contrast(.95) saturate(0) sepia(.35);filter:brightness(1.4) contrast(.95) saturate(0) sepia(.35)}.filter-nashville{-webkit-filter:sepia(.25) contrast(1.5) brightness(.9) hue-rotate(-15deg);filter:sepia(.25) contrast(1.5) brightness(.9) hue-rotate(-15deg)}.filter-nashville::before{background:radial-gradient(circle closest-corner,rgba(128,78,15,.5) 0,rgba(128,78,15,.65) 100%);background:-o-radial-gradient(circle closest-corner,rgba(128,78,15,.5) 0,rgba(128,78,15,.65) 100%);background:-moz-radial-gradient(circle closest-corner,rgba(128,78,15,.5) 0,rgba(128,78,15,.65) 100%);background:-webkit-radial-gradient(circle closest-corner,rgba(128,78,15,.5) 0,rgba(128,78,15,.65) 100%);content:"";mix-blend-mode:screen}.filter-perpetua{-webkit-filter:contrast(1.1) brightness(1.25) saturate(1.1);filter:contrast(1.1) brightness(1.25) saturate(1.1)}.filter-perpetua::before{background:linear-gradient(to bottom,rgba(0,91,154,.25),rgba(230,193,61,.25));background:-o-linear-gradient(top,rgba(0,91,154,.25),rgba(230,193,61,.25));background:-moz-linear-gradient(top,rgba(0,91,154,.25),rgba(230,193,61,.25));background:-webkit-linear-gradient(top,rgba(0,91,154,.25),rgba(230,193,61,.25));background:-webkit-gradient(linear,left top,left bottom,from(rgba(0,91,154,.25)),to(rgba(230,193,61,.25)));content:"";mix-blend-mode:multiply}.filter-poprocket{-webkit-filter:sepia(.15) brightness(1.2);filter:sepia(.15) brightness(1.2)}.filter-poprocket::before{background:radial-gradient(circle closest-corner,rgba(206,39,70,.75) 40%,#000 80%);background:-o-radial-gradient(circle closest-corner,rgba(206,39,70,.75) 40%,#000 80%);background:-moz-radial-gradient(circle closest-corner,rgba(206,39,70,.75) 40%,#000 80%);background:-webkit-radial-gradient(circle closest-corner,rgba(206,39,70,.75) 40%,#000 80%);content:"";mix-blend-mode:screen}.filter-reyes{-webkit-filter:sepia(.75) contrast(.75) brightness(1.25) saturate(1.4);filter:sepia(.75) contrast(.75) brightness(1.25) saturate(1.4)}.filter-rise{-webkit-filter:sepia(.25) contrast(1.25) brightness(1.2) saturate(.9);filter:sepia(.25) contrast(1.25) brightness(1.2) saturate(.9)}.filter-rise::before{background:radial-gradient(circle closest-corner,transparent 0,rgba(230,193,61,.25) 100%);background:-o-radial-gradient(circle closest-corner,transparent 0,rgba(230,193,61,.25) 100%);background:-moz-radial-gradient(circle closest-corner,transparent 0,rgba(230,193,61,.25) 100%);background:-webkit-radial-gradient(circle closest-corner,transparent 0,rgba(230,193,61,.25) 100%);content:"";mix-blend-mode:lighten}.filter-sierra{-webkit-filter:sepia(.25) contrast(1.5) brightness(.9) hue-rotate(-15deg);filter:sepia(.25) contrast(1.5) brightness(.9) hue-rotate(-15deg)}.filter-sierra::before{background:radial-gradient(circle closest-corner,rgba(128,78,15,.5) 0,rgba(0,0,0,.65) 100%);background:-o-radial-gradient(circle closest-corner,rgba(128,78,15,.5) 0,rgba(0,0,0,.65) 100%);background:-moz-radial-gradient(circle closest-corner,rgba(128,78,15,.5) 0,rgba(0,0,0,.65) 100%);background:-webkit-radial-gradient(circle closest-corner,rgba(128,78,15,.5) 0,rgba(0,0,0,.65) 100%);content:"";mix-blend-mode:screen}.filter-skyline{-webkit-filter:sepia(.15) contrast(1.25) brightness(1.25) saturate(1.2);filter:sepia(.15) contrast(1.25) brightness(1.25) saturate(1.2)}.filter-slumber{-webkit-filter:sepia(.35) contrast(1.25) saturate(1.25);filter:sepia(.35) contrast(1.25) saturate(1.25)}.filter-slumber::before{background:rgba(125,105,24,.2);content:"";mix-blend-mode:darken}.filter-stinson{-webkit-filter:sepia(.35) contrast(1.25) brightness(1.1) saturate(1.25);filter:sepia(.35) contrast(1.25) brightness(1.1) saturate(1.25)}.filter-stinson::before{background:rgba(125,105,24,.45);content:"";mix-blend-mode:lighten}.filter-sutro{-webkit-filter:sepia(.4) contrast(1.2) brightness(.9) saturate(1.4) hue-rotate(-10deg);filter:sepia(.4) contrast(1.2) brightness(.9) saturate(1.4) hue-rotate(-10deg)}.filter-sutro::before{background:radial-gradient(circle closest-corner,transparent 50%,rgba(0,0,0,.5) 90%);background:-o-radial-gradient(circle closest-corner,transparent 50%,rgba(0,0,0,.5) 90%);background:-moz-radial-gradient(circle closest-corner,transparent 50%,rgba(0,0,0,.5) 90%);background:-webkit-radial-gradient(circle closest-corner,transparent 50%,rgba(0,0,0,.5) 90%);content:"";mix-blend-mode:darken}.filter-toaster{-webkit-filter:sepia(.25) contrast(1.5) brightness(.95) hue-rotate(-15deg);filter:sepia(.25) contrast(1.5) brightness(.95) hue-rotate(-15deg)}.filter-toaster::before{background:radial-gradient(circle,#804e0f,rgba(0,0,0,.25));background:-o-radial-gradient(circle,#804e0f,rgba(0,0,0,.25));background:-moz-radial-gradient(circle,#804e0f,rgba(0,0,0,.25));background:-webkit-radial-gradient(circle,#804e0f,rgba(0,0,0,.25));content:"";mix-blend-mode:screen}.filter-valencia{-webkit-filter:sepia(.25) contrast(1.1) brightness(1.1);filter:sepia(.25) contrast(1.1) brightness(1.1)}.filter-valencia::before{background:rgba(230,193,61,.1);content:"";mix-blend-mode:lighten}.filter-vesper{-webkit-filter:sepia(.35) contrast(1.15) brightness(1.2) saturate(1.3);filter:sepia(.35) contrast(1.15) brightness(1.2) saturate(1.3)}.filter-vesper::before{background:rgba(125,105,24,.25);content:"";mix-blend-mode:overlay}.filter-walden{-webkit-filter:sepia(.35) contrast(.8) brightness(1.25) saturate(1.4);filter:sepia(.35) contrast(.8) brightness(1.25) saturate(1.4)}.filter-walden::before{background:rgba(229,240,128,.5);content:"";mix-blend-mode:darken}.filter-willow{-webkit-filter:brightness(1.2) contrast(.85) saturate(.05) sepia(.2);filter:brightness(1.2) contrast(.85) saturate(.05) sepia(.2)}.filter-xpro-ii{-webkit-filter:sepia(.45) contrast(1.25) brightness(1.75) saturate(1.3) hue-rotate(-5deg);filter:sepia(.45) contrast(1.25) brightness(1.75) saturate(1.3) hue-rotate(-5deg)}.filter-xpro-ii::before{background:radial-gradient(circle closest-corner,rgba(0,91,154,.35) 0,rgba(0,0,0,.65) 100%);background:-o-radial-gradient(circle closest-corner,rgba(0,91,154,.35) 0,rgba(0,0,0,.65) 100%);background:-moz-radial-gradient(circle closest-corner,rgba(0,91,154,.35) 0,rgba(0,0,0,.65) 100%);background:-webkit-radial-gradient(circle closest-corner,rgba(0,91,154,.35) 0,rgba(0,0,0,.65) 100%);content:"";mix-blend-mode:multiply} -------------------------------------------------------------------------------- /main/app/assets/css/instagram.min.css: -------------------------------------------------------------------------------- 1 | /*! Instagram.css v0.1.4 | MIT License | github.com/picturepan2/instagram.css */[class*=filter]{position:relative}[class*=filter]::before{display:block;height:100%;left:0;position:absolute;top:0;width:100%;z-index:1}.filter-1977{-webkit-filter:sepia(.5) hue-rotate(-30deg) saturate(1.4);filter:sepia(.5) hue-rotate(-30deg) saturate(1.4)}.filter-aden{-webkit-filter:sepia(.2) brightness(1.15) saturate(1.4);filter:sepia(.2) brightness(1.15) saturate(1.4)}.filter-aden::before{background:rgba(125,105,24,.1);content:"";mix-blend-mode:multiply}.filter-amaro{-webkit-filter:sepia(.35) contrast(1.1) brightness(1.2) saturate(1.3);filter:sepia(.35) contrast(1.1) brightness(1.2) saturate(1.3)}.filter-amaro::before{background:rgba(125,105,24,.2);content:"";mix-blend-mode:overlay}.filter-ashby{-webkit-filter:sepia(.5) contrast(1.2) saturate(1.8);filter:sepia(.5) contrast(1.2) saturate(1.8)}.filter-ashby::before{background:rgba(125,105,24,.35);content:"";mix-blend-mode:lighten}.filter-brannan{-webkit-filter:sepia(.4) contrast(1.25) brightness(1.1) saturate(.9) hue-rotate(-2deg);filter:sepia(.4) contrast(1.25) brightness(1.1) saturate(.9) hue-rotate(-2deg)}.filter-brooklyn{-webkit-filter:sepia(.25) contrast(1.25) brightness(1.25) hue-rotate(5deg);filter:sepia(.25) contrast(1.25) brightness(1.25) hue-rotate(5deg)}.filter-brooklyn::before{background:rgba(127,187,227,.2);content:"";mix-blend-mode:overlay}.filter-charmes{-webkit-filter:sepia(.25) contrast(1.25) brightness(1.25) saturate(1.35) hue-rotate(-5deg);filter:sepia(.25) contrast(1.25) brightness(1.25) saturate(1.35) hue-rotate(-5deg)}.filter-charmes::before{background:rgba(125,105,24,.25);content:"";mix-blend-mode:darken}.filter-clarendon{-webkit-filter:sepia(.15) contrast(1.25) brightness(1.25) hue-rotate(5deg);filter:sepia(.15) contrast(1.25) brightness(1.25) hue-rotate(5deg)}.filter-clarendon::before{background:rgba(127,187,227,.4);content:"";mix-blend-mode:overlay}.filter-crema{-webkit-filter:sepia(.5) contrast(1.25) brightness(1.15) saturate(.9) hue-rotate(-2deg);filter:sepia(.5) contrast(1.25) brightness(1.15) saturate(.9) hue-rotate(-2deg)}.filter-crema::before{background:rgba(125,105,24,.2);content:"";mix-blend-mode:multiply}.filter-dogpatch{-webkit-filter:sepia(.35) saturate(1.1) contrast(1.5);filter:sepia(.35) saturate(1.1) contrast(1.5)}.filter-earlybird{-webkit-filter:sepia(.25) contrast(1.25) brightness(1.15) saturate(.9) hue-rotate(-5deg);filter:sepia(.25) contrast(1.25) brightness(1.15) saturate(.9) hue-rotate(-5deg)}.filter-earlybird::before{background:radial-gradient(circle closest-corner,transparent 0,rgba(125,105,24,.2) 100%);background:-o-radial-gradient(circle closest-corner,transparent 0,rgba(125,105,24,.2) 100%);background:-moz-radial-gradient(circle closest-corner,transparent 0,rgba(125,105,24,.2) 100%);background:-webkit-radial-gradient(circle closest-corner,transparent 0,rgba(125,105,24,.2) 100%);content:"";mix-blend-mode:multiply}.filter-gingham{-webkit-filter:contrast(1.1) brightness(1.1);filter:contrast(1.1) brightness(1.1)}.filter-gingham::before{background:#e6e6e6;content:"";mix-blend-mode:soft-light}.filter-ginza{-webkit-filter:sepia(.25) contrast(1.15) brightness(1.2) saturate(1.35) hue-rotate(-5deg);filter:sepia(.25) contrast(1.15) brightness(1.2) saturate(1.35) hue-rotate(-5deg)}.filter-ginza::before{background:rgba(125,105,24,.15);content:"";mix-blend-mode:darken}.filter-hefe{-webkit-filter:sepia(.4) contrast(1.5) brightness(1.2) saturate(1.4) hue-rotate(-10deg);filter:sepia(.4) contrast(1.5) brightness(1.2) saturate(1.4) hue-rotate(-10deg)}.filter-hefe::before{background:radial-gradient(circle closest-corner,transparent 0,rgba(0,0,0,.25) 100%);background:-o-radial-gradient(circle closest-corner,transparent 0,rgba(0,0,0,.25) 100%);background:-moz-radial-gradient(circle closest-corner,transparent 0,rgba(0,0,0,.25) 100%);background:-webkit-radial-gradient(circle closest-corner,transparent 0,rgba(0,0,0,.25) 100%);content:"";mix-blend-mode:multiply}.filter-helena{-webkit-filter:sepia(.5) contrast(1.05) brightness(1.05) saturate(1.35);filter:sepia(.5) contrast(1.05) brightness(1.05) saturate(1.35)}.filter-helena::before{background:rgba(158,175,30,.25);content:"";mix-blend-mode:overlay}.filter-hudson{-webkit-filter:sepia(.25) contrast(1.2) brightness(1.2) saturate(1.05) hue-rotate(-15deg);filter:sepia(.25) contrast(1.2) brightness(1.2) saturate(1.05) hue-rotate(-15deg)}.filter-hudson::before{background:radial-gradient(circle closest-corner,transparent 25%,rgba(25,62,167,.25) 100%);background:-o-radial-gradient(circle closest-corner,transparent 25%,rgba(25,62,167,.25) 100%);background:-moz-radial-gradient(circle closest-corner,transparent 25%,rgba(25,62,167,.25) 100%);background:-webkit-radial-gradient(circle closest-corner,transparent 25%,rgba(25,62,167,.25) 100%);content:"";mix-blend-mode:multiply}.filter-inkwell{-webkit-filter:brightness(1.25) contrast(.85) grayscale(1);filter:brightness(1.25) contrast(.85) grayscale(1)}.filter-juno{-webkit-filter:sepia(.35) contrast(1.15) brightness(1.15) saturate(1.8);filter:sepia(.35) contrast(1.15) brightness(1.15) saturate(1.8)}.filter-juno::before{background:rgba(127,187,227,.2);content:"";mix-blend-mode:overlay}.filter-kelvin{-webkit-filter:sepia(.15) contrast(1.5) brightness(1.1) hue-rotate(-10deg);filter:sepia(.15) contrast(1.5) brightness(1.1) hue-rotate(-10deg)}.filter-kelvin::before{background:radial-gradient(circle closest-corner,rgba(128,78,15,.25) 0,rgba(128,78,15,.5) 100%);background:-o-radial-gradient(circle closest-corner,rgba(128,78,15,.25) 0,rgba(128,78,15,.5) 100%);background:-moz-radial-gradient(circle closest-corner,rgba(128,78,15,.25) 0,rgba(128,78,15,.5) 100%);background:-webkit-radial-gradient(circle closest-corner,rgba(128,78,15,.25) 0,rgba(128,78,15,.5) 100%);content:"";mix-blend-mode:overlay}.filter-lark{-webkit-filter:sepia(.25) contrast(1.2) brightness(1.3) saturate(1.25);filter:sepia(.25) contrast(1.2) brightness(1.3) saturate(1.25)}.filter-lofi{-webkit-filter:saturate(1.1) contrast(1.5);filter:saturate(1.1) contrast(1.5)}.filter-ludwig{-webkit-filter:sepia(.25) contrast(1.05) brightness(1.05) saturate(2);filter:sepia(.25) contrast(1.05) brightness(1.05) saturate(2)}.filter-ludwig::before{background:rgba(125,105,24,.1);content:"";mix-blend-mode:overlay}.filter-maven{-webkit-filter:sepia(.35) contrast(1.05) brightness(1.05) saturate(1.75);filter:sepia(.35) contrast(1.05) brightness(1.05) saturate(1.75)}.filter-maven::before{background:rgba(158,175,30,.25);content:"";mix-blend-mode:darken}.filter-mayfair{-webkit-filter:contrast(1.1) brightness(1.15) saturate(1.1);filter:contrast(1.1) brightness(1.15) saturate(1.1)}.filter-mayfair::before{background:radial-gradient(circle closest-corner,transparent 0,rgba(175,105,24,.4) 100%);background:-o-radial-gradient(circle closest-corner,transparent 0,rgba(175,105,24,.4) 100%);background:-moz-radial-gradient(circle closest-corner,transparent 0,rgba(175,105,24,.4) 100%);background:-webkit-radial-gradient(circle closest-corner,transparent 0,rgba(175,105,24,.4) 100%);content:"";mix-blend-mode:multiply}.filter-moon{-webkit-filter:brightness(1.4) contrast(.95) saturate(0) sepia(.35);filter:brightness(1.4) contrast(.95) saturate(0) sepia(.35)}.filter-nashville{-webkit-filter:sepia(.25) contrast(1.5) brightness(.9) hue-rotate(-15deg);filter:sepia(.25) contrast(1.5) brightness(.9) hue-rotate(-15deg)}.filter-nashville::before{background:radial-gradient(circle closest-corner,rgba(128,78,15,.5) 0,rgba(128,78,15,.65) 100%);background:-o-radial-gradient(circle closest-corner,rgba(128,78,15,.5) 0,rgba(128,78,15,.65) 100%);background:-moz-radial-gradient(circle closest-corner,rgba(128,78,15,.5) 0,rgba(128,78,15,.65) 100%);background:-webkit-radial-gradient(circle closest-corner,rgba(128,78,15,.5) 0,rgba(128,78,15,.65) 100%);content:"";mix-blend-mode:screen}.filter-perpetua{-webkit-filter:contrast(1.1) brightness(1.25) saturate(1.1);filter:contrast(1.1) brightness(1.25) saturate(1.1)}.filter-perpetua::before{background:linear-gradient(to bottom,rgba(0,91,154,.25),rgba(230,193,61,.25));background:-o-linear-gradient(top,rgba(0,91,154,.25),rgba(230,193,61,.25));background:-moz-linear-gradient(top,rgba(0,91,154,.25),rgba(230,193,61,.25));background:-webkit-linear-gradient(top,rgba(0,91,154,.25),rgba(230,193,61,.25));background:-webkit-gradient(linear,left top,left bottom,from(rgba(0,91,154,.25)),to(rgba(230,193,61,.25)));content:"";mix-blend-mode:multiply}.filter-poprocket{-webkit-filter:sepia(.15) brightness(1.2);filter:sepia(.15) brightness(1.2)}.filter-poprocket::before{background:radial-gradient(circle closest-corner,rgba(206,39,70,.75) 40%,#000 80%);background:-o-radial-gradient(circle closest-corner,rgba(206,39,70,.75) 40%,#000 80%);background:-moz-radial-gradient(circle closest-corner,rgba(206,39,70,.75) 40%,#000 80%);background:-webkit-radial-gradient(circle closest-corner,rgba(206,39,70,.75) 40%,#000 80%);content:"";mix-blend-mode:screen}.filter-reyes{-webkit-filter:sepia(.75) contrast(.75) brightness(1.25) saturate(1.4);filter:sepia(.75) contrast(.75) brightness(1.25) saturate(1.4)}.filter-rise{-webkit-filter:sepia(.25) contrast(1.25) brightness(1.2) saturate(.9);filter:sepia(.25) contrast(1.25) brightness(1.2) saturate(.9)}.filter-rise::before{background:radial-gradient(circle closest-corner,transparent 0,rgba(230,193,61,.25) 100%);background:-o-radial-gradient(circle closest-corner,transparent 0,rgba(230,193,61,.25) 100%);background:-moz-radial-gradient(circle closest-corner,transparent 0,rgba(230,193,61,.25) 100%);background:-webkit-radial-gradient(circle closest-corner,transparent 0,rgba(230,193,61,.25) 100%);content:"";mix-blend-mode:lighten}.filter-sierra{-webkit-filter:sepia(.25) contrast(1.5) brightness(.9) hue-rotate(-15deg);filter:sepia(.25) contrast(1.5) brightness(.9) hue-rotate(-15deg)}.filter-sierra::before{background:radial-gradient(circle closest-corner,rgba(128,78,15,.5) 0,rgba(0,0,0,.65) 100%);background:-o-radial-gradient(circle closest-corner,rgba(128,78,15,.5) 0,rgba(0,0,0,.65) 100%);background:-moz-radial-gradient(circle closest-corner,rgba(128,78,15,.5) 0,rgba(0,0,0,.65) 100%);background:-webkit-radial-gradient(circle closest-corner,rgba(128,78,15,.5) 0,rgba(0,0,0,.65) 100%);content:"";mix-blend-mode:screen}.filter-skyline{-webkit-filter:sepia(.15) contrast(1.25) brightness(1.25) saturate(1.2);filter:sepia(.15) contrast(1.25) brightness(1.25) saturate(1.2)}.filter-slumber{-webkit-filter:sepia(.35) contrast(1.25) saturate(1.25);filter:sepia(.35) contrast(1.25) saturate(1.25)}.filter-slumber::before{background:rgba(125,105,24,.2);content:"";mix-blend-mode:darken}.filter-stinson{-webkit-filter:sepia(.35) contrast(1.25) brightness(1.1) saturate(1.25);filter:sepia(.35) contrast(1.25) brightness(1.1) saturate(1.25)}.filter-stinson::before{background:rgba(125,105,24,.45);content:"";mix-blend-mode:lighten}.filter-sutro{-webkit-filter:sepia(.4) contrast(1.2) brightness(.9) saturate(1.4) hue-rotate(-10deg);filter:sepia(.4) contrast(1.2) brightness(.9) saturate(1.4) hue-rotate(-10deg)}.filter-sutro::before{background:radial-gradient(circle closest-corner,transparent 50%,rgba(0,0,0,.5) 90%);background:-o-radial-gradient(circle closest-corner,transparent 50%,rgba(0,0,0,.5) 90%);background:-moz-radial-gradient(circle closest-corner,transparent 50%,rgba(0,0,0,.5) 90%);background:-webkit-radial-gradient(circle closest-corner,transparent 50%,rgba(0,0,0,.5) 90%);content:"";mix-blend-mode:darken}.filter-toaster{-webkit-filter:sepia(.25) contrast(1.5) brightness(.95) hue-rotate(-15deg);filter:sepia(.25) contrast(1.5) brightness(.95) hue-rotate(-15deg)}.filter-toaster::before{background:radial-gradient(circle,#804e0f,rgba(0,0,0,.25));background:-o-radial-gradient(circle,#804e0f,rgba(0,0,0,.25));background:-moz-radial-gradient(circle,#804e0f,rgba(0,0,0,.25));background:-webkit-radial-gradient(circle,#804e0f,rgba(0,0,0,.25));content:"";mix-blend-mode:screen}.filter-valencia{-webkit-filter:sepia(.25) contrast(1.1) brightness(1.1);filter:sepia(.25) contrast(1.1) brightness(1.1)}.filter-valencia::before{background:rgba(230,193,61,.1);content:"";mix-blend-mode:lighten}.filter-vesper{-webkit-filter:sepia(.35) contrast(1.15) brightness(1.2) saturate(1.3);filter:sepia(.35) contrast(1.15) brightness(1.2) saturate(1.3)}.filter-vesper::before{background:rgba(125,105,24,.25);content:"";mix-blend-mode:overlay}.filter-walden{-webkit-filter:sepia(.35) contrast(.8) brightness(1.25) saturate(1.4);filter:sepia(.35) contrast(.8) brightness(1.25) saturate(1.4)}.filter-walden::before{background:rgba(229,240,128,.5);content:"";mix-blend-mode:darken}.filter-willow{-webkit-filter:brightness(1.2) contrast(.85) saturate(.05) sepia(.2);filter:brightness(1.2) contrast(.85) saturate(.05) sepia(.2)}.filter-xpro-ii{-webkit-filter:sepia(.45) contrast(1.25) brightness(1.75) saturate(1.3) hue-rotate(-5deg);filter:sepia(.45) contrast(1.25) brightness(1.75) saturate(1.3) hue-rotate(-5deg)}.filter-xpro-ii::before{background:radial-gradient(circle closest-corner,rgba(0,91,154,.35) 0,rgba(0,0,0,.65) 100%);background:-o-radial-gradient(circle closest-corner,rgba(0,91,154,.35) 0,rgba(0,0,0,.65) 100%);background:-moz-radial-gradient(circle closest-corner,rgba(0,91,154,.35) 0,rgba(0,0,0,.65) 100%);background:-webkit-radial-gradient(circle closest-corner,rgba(0,91,154,.35) 0,rgba(0,0,0,.65) 100%);content:"";mix-blend-mode:multiply} -------------------------------------------------------------------------------- /images/selfie.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 12 | 13 | 15 | 16 | 18 | 20 | 21 | 25 | 29 | 30 | 33 | 36 | 38 | 41 | 43 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 60 | 63 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /main/app/assets/img/selfie.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 12 | 13 | 15 | 16 | 18 | 20 | 21 | 25 | 29 | 30 | 33 | 36 | 38 | 41 | 43 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 60 | 63 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /main/app/assets/img/camera.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 11 | 14 | 17 | 21 | 23 | 25 | 26 | 30 | 34 | 35 | 38 | 41 | 43 | 46 | 48 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 62 | 64 | 67 | 69 | 70 | 71 | 72 | 74 | 76 | 77 | 78 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /main/app/assets/img/happy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | 17 | 23 | 26 | 28 | 30 | 31 | 36 | 41 | 42 | 45 | 48 | 51 | 53 | 55 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 72 | 75 | 80 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | --------------------------------------------------------------------------------