├── .gitignore
├── LICENSE
├── README.md
├── assets
├── crx
│ ├── css
│ │ ├── reset.css
│ │ └── style.css
│ ├── html
│ │ └── embed.html
│ ├── img
│ │ └── icon.png
│ ├── js
│ │ ├── background.js
│ │ └── embed.js
│ └── manifest.json
└── icons
│ ├── fallback
│ ├── A.png
│ ├── B.png
│ ├── C.png
│ ├── D.png
│ ├── E.png
│ ├── F.png
│ ├── G.png
│ ├── H.png
│ ├── I.png
│ ├── J.png
│ ├── K.png
│ ├── L.png
│ ├── M.png
│ ├── N.png
│ ├── O.png
│ ├── P.png
│ ├── Q.png
│ ├── R.png
│ ├── S.png
│ ├── T.png
│ ├── U.png
│ ├── V.png
│ ├── W.png
│ ├── X.png
│ ├── Y.png
│ └── Z.png
│ ├── keep.google.com.png
│ ├── messenger.com.png
│ ├── web.whatsapp.com.png
│ └── youtube.com.png
├── lib
├── middleware
│ ├── error.js
│ └── redirect.js
└── routes
│ ├── applicationize.js
│ └── now.js
├── package-lock.json
├── package.json
├── public
├── css
│ ├── bootstrap-colorpicker.min.css
│ ├── bootstrap.css
│ ├── bootstrap.min.css
│ ├── custom.css
│ ├── flexslider.css
│ ├── less
│ │ └── theme.less
│ ├── lightbox.min.css
│ ├── theme-red.css
│ ├── theme.css
│ └── themify-icons.css
├── fonts
│ ├── themify.eot
│ ├── themify.svg
│ ├── themify.ttf
│ └── themify.woff
├── img
│ ├── bootstrap-colorpicker
│ │ ├── alpha-horizontal.png
│ │ ├── alpha.png
│ │ ├── hue-horizontal.png
│ │ ├── hue.png
│ │ └── saturation.png
│ ├── cover.jpg
│ ├── favicon.png
│ ├── fork.png
│ ├── lightbox
│ │ ├── close.png
│ │ ├── loading.gif
│ │ ├── next.png
│ │ └── prev.png
│ ├── logo-dark.png
│ ├── logo-light.png
│ ├── preview.png
│ └── screenshots
│ │ └── install.png
├── index.html
├── js
│ ├── applicationizer.js
│ ├── bootstrap-colorpicker.min.js
│ ├── bootstrap.js
│ ├── bootstrap.min.js
│ ├── flexslider.min.js
│ ├── jquery.min.js
│ ├── lightbox.min.js
│ ├── masonry.min.js
│ ├── parallax.js
│ ├── scripts.js
│ └── smooth-scroll.min.js
└── now.html
└── server.js
/.gitignore:
--------------------------------------------------------------------------------
1 | DEPLOY
2 | .vscode/
3 | .idea/
4 | .elasticbeanstalk/
5 | node_modules/
6 | typings/
7 | staging/
8 | ssl/
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Applicationize
2 | [](https://gitter.im/eladnava/applicationize?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
3 |
4 | > **Note:** Applicationize is no longer supported. Google Chrome has officially stopped running Packaged Apps, rendering Applicationize unusable. Google Chrome now comes with a built-in feature called Application Shortcuts. It basically makes it possible to convert any web page (or web app) into a desktop app by clicking the hamburger icon in the top right -> More Tools -> "Create Shortcut" and ticking "Open as window". It is recommended to migrate to using this built-in feature, or consider an alternative solution such as [nativefier](https://github.com/nativefier/nativefier).
5 |
6 | Applicationize converts your favorite web apps into desktop apps with their own dedicated launcher icon.
7 |
8 | It generates a Google Chrome extension that embeds your favorite [SPA](https://en.wikipedia.org/wiki/Single-page_application) web app and places a custom shortcut icon in your app launcher when you install it.
9 |
10 | https://applicationize.me/
11 |
12 | ## Demo
13 |
14 | Here's a screenshot of Facebook Messenger (messenger.com) running as an applicationized desktop app:
15 |
16 |
17 |
18 |
19 | ## How to Use
20 |
21 | 1. Go to https://applicationize.me/now
22 | 2. Enter a URL to any web app, such as https://web.whatsapp.com/
23 | 3. Press `Enter` and download the generated Chrome extension
24 | 4. Open a new tab and navigate to `chrome://extensions/`
25 | 5. Drag the downloaded `.crx` file from its download folder to the extensions page to install it
26 |
27 | That's it! Your applicationized web app is now available via your app launcher. We recommend pinning it to your application dock or system taskbar!
28 |
29 | ## Keyboard Shortcuts
30 |
31 | * CTRL / CMD + [ to go back
32 | * CTRL / CMD + ] to go forward
33 | * CTRL / CMD + + to zoom in
34 | * CTRL / CMD + - to zoom out
35 | * CTRL / CMD + 0 to reset zoom
36 | * CTRL / CMD + P to print page
37 | * CTRL / CMD + F to find in page
38 | * CTRL / CMD + R to refresh the page
39 | * CTRL / CMD + L to copy current page URL
40 | * CTRL + CMD + F to enter full screen mode (ALT + CTRL + F on Windows)
41 |
42 | ## Contributing
43 |
44 | * If you find a bug or wish to make some kind of change, please create an issue first
45 | * Make sure your code conventions are in-line with the project's code style
46 | * Make your commits and PRs as tiny as possible - one feature or bugfix at a time
47 | * Write detailed commit messages, in-line with the project's commit naming conventions
48 |
49 | ## Running the Server
50 |
51 | Run the following commands in the root directory of this project:
52 |
53 | ```shell
54 | npm install
55 | npm start
56 | ```
57 |
58 | Then, visit [http://localhost:8080/](http://localhost:8080/) to browse to your local instance of Applicationize.
59 |
60 | ## Contributors
61 |
62 | Thanks to the following individuals and organizations who help pay for hosting & domain renewal:
63 |
64 | * [@guidokok](https://github.com/guidokok) - Guido Bedarida
65 | * [Seam.es](https://seam.es) - we design & build for the web; stitch by stitch
66 | * [Fan Studio UK](https://www.fanstudio.co.uk/) - we specialize in mobile game app development and gamification strategies for startups and enterprise clients
67 |
68 |
69 |
70 | ## License
71 |
72 | Apache 2.0
73 |
--------------------------------------------------------------------------------
/assets/crx/css/reset.css:
--------------------------------------------------------------------------------
1 | /* http://meyerweb.com/eric/tools/css/reset/
2 | v2.0 | 20110126
3 | License: none (public domain)
4 | */
5 |
6 | html, body, div, span, applet, object, iframe,
7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
8 | a, abbr, acronym, address, big, cite, code,
9 | del, dfn, em, img, ins, kbd, q, s, samp,
10 | small, strike, strong, sub, sup, tt, var,
11 | b, u, i, center,
12 | dl, dt, dd, ol, ul, li,
13 | fieldset, form, label, legend,
14 | table, caption, tbody, tfoot, thead, tr, th, td,
15 | article, aside, canvas, details, embed,
16 | figure, figcaption, footer, header, hgroup,
17 | menu, nav, output, ruby, section, summary,
18 | time, mark, audio, video {
19 | margin: 0;
20 | padding: 0;
21 | border: 0;
22 | font-size: 100%;
23 | font: inherit;
24 | vertical-align: baseline;
25 | }
26 | /* HTML5 display-role reset for older browsers */
27 | article, aside, details, figcaption, figure,
28 | footer, header, hgroup, menu, nav, section {
29 | display: block;
30 | }
31 | body {
32 | line-height: 1;
33 | }
34 | ol, ul {
35 | list-style: none;
36 | }
37 | blockquote, q {
38 | quotes: none;
39 | }
40 | blockquote:before, blockquote:after,
41 | q:before, q:after {
42 | content: '';
43 | content: none;
44 | }
45 | table {
46 | border-collapse: collapse;
47 | border-spacing: 0;
48 | }
--------------------------------------------------------------------------------
/assets/crx/css/style.css:
--------------------------------------------------------------------------------
1 | webview {
2 | width: 100vw;
3 | height: 100vh;
4 | }
5 |
6 | #find-box {
7 | top: 0;
8 | right: 70px;
9 | width: 250px;
10 | display: none;
11 | position: absolute;
12 | background: #f1f1f1;
13 | border: 1px solid #eee;
14 | border-radius: 0 0 3px 3px;
15 | }
16 |
17 | #find-text {
18 | width: 92%;
19 | margin: 4px;
20 | padding: 5px;
21 | background: #fff;
22 | border-radius: 3px;
23 | border: 1px solid #e6e6e6;
24 | }
25 |
26 | #dialog-box {
27 | top: 0;
28 | width: 360px;
29 | left: -180px;
30 | display: none;
31 | position: absolute;
32 | background: #fff;
33 | border-radius: 3px;
34 | margin: 30px 0 0 50%;
35 | box-shadow: 1px 5px 15px 0px rgba(0, 0, 0, 0.34);
36 | }
37 |
38 | #dialog-box-text {
39 | padding: 20px;
40 | font-size: 13px;
41 | font-family: Arial, Helvetica, sans-serif;
42 | }
43 |
44 | #dialog-box-input {
45 | padding: 5px;
46 | display: none;
47 | margin: 0 20px 20px 20px;
48 | width: calc(100% - 45px);
49 | }
50 |
51 | .dialog-box-button {
52 | bottom: 0;
53 | width: 70px;
54 | height: 27px;
55 | float: right;
56 | color: #444;
57 | font-size: 12px;
58 | position: relative;
59 | margin: 0 11px 20px 0;
60 | border-radius: 2px;
61 | border: 1px solid rgba(0, 0, 0, 0.25);
62 | text-shadow: 0 1px 0 rgb(240, 240, 240);
63 | background-image: -webkit-linear-gradient(#ededed, #ededed 38%, #dedede);
64 | box-shadow: 0 1px 0 rgba(0, 0, 0, 0.08), inset 0 1px 2px rgba(255, 255, 255, 0.75);
65 | }
--------------------------------------------------------------------------------
/assets/crx/html/embed.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Applicationize
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
Example dialog text
21 |
22 |
Cancel
23 |
OK
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/assets/crx/img/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/crx/img/icon.png
--------------------------------------------------------------------------------
/assets/crx/js/background.js:
--------------------------------------------------------------------------------
1 | // This will be injected dynamically at extension creation time
2 | var appConfig = {inject-background-script-config};
3 |
4 | /**
5 | * Listens for the app launching then creates the window
6 | *
7 | * @see http://developer.chrome.com/apps/app.runtime.html
8 | * @see http://developer.chrome.com/apps/app.window.html
9 | */
10 | chrome.app.runtime.onLaunched.addListener(function () {
11 | runApp();
12 | });
13 |
14 | /**
15 | * Listens for the app restarting then re-creates the window.
16 | *
17 | * @see http://developer.chrome.com/apps/app.runtime.html
18 | */
19 | chrome.app.runtime.onRestarted.addListener(function () {
20 | runApp();
21 | });
22 |
23 | /**
24 | * Creates the window for the application.
25 | *
26 | * @see http://developer.chrome.com/apps/app.window.html
27 | */
28 | function runApp() {
29 | // Creat a new Chrome app window
30 | chrome.app.window.create('html/embed.html', appConfig.chromeAppWindow, onWindowLoaded());
31 | }
32 |
33 | /**
34 | * Called before the contentWindow's onload event
35 | *
36 | * @see http://developer.chrome.com/apps/app.window.html
37 | */
38 | function onWindowLoaded(popup) {
39 | return function (win) {
40 | // On window loaded event
41 | win.contentWindow.onload = function () {
42 | // Get webview
43 | var webview = win.contentWindow.document.getElementById('webview');
44 |
45 | // Override default user agent if provided
46 | if (appConfig.userAgent) {
47 | webview.setUserAgentOverride(appConfig.userAgent);
48 | }
49 |
50 | // Sign up for 'permissionrequest' event
51 | webview.addEventListener('permissionrequest', function (e) {
52 | // Allow all permission requests
53 | e.request.allow();
54 | });
55 |
56 | // Sign up for 'newwindow' event
57 | // Emitted when a target='_blank' link is clicked within the webview
58 | webview.addEventListener('newwindow', function (e) {
59 | // Parse target window URL to extract hostname
60 | var parsedUrl = document.createElement('a');
61 | parsedUrl.href = e.targetUrl;
62 |
63 | // Popup?
64 | if (e.initialWidth > 0 && e.initialHeight > 0) {
65 | // Open it in a popup window with a set width and height
66 | return chrome.app.window.create('html/embed.html', { frame: { type: 'chrome' }, innerBounds: { width: e.initialWidth, height: e.initialHeight } }, onWindowLoaded(e));
67 | }
68 | // Open app links internally?
69 | else if (appConfig.behavior.internalLinks && parsedUrl.hostname.includes(appConfig.hostname)) {
70 | return chrome.app.window.create('html/embed.html', { frame: { type: 'chrome' }, innerBounds: appConfig.chromeAppWindow.innerBounds }, onWindowLoaded(e));
71 | }
72 |
73 | // Open the link in a new browser tab/window
74 | win.contentWindow.open(e.targetUrl);
75 | });
76 |
77 | // Is this a popup window?
78 | if (popup) {
79 | // Override webview source with popup's target URL
80 | webview.src = popup.targetUrl;
81 |
82 | // Attach original calling window to popup webview (accessible via window.opener)
83 | popup.window.attach(webview);
84 | }
85 | };
86 | };
87 | }
88 |
--------------------------------------------------------------------------------
/assets/crx/js/embed.js:
--------------------------------------------------------------------------------
1 | // Get webview element
2 | var webview = document.getElementById('webview');
3 |
4 | // Get find box elements
5 | var findBox = document.getElementById('find-box');
6 | var findInput = document.getElementById('find-text');
7 |
8 | // Get dialog box elements
9 | var dialogBox = document.getElementById("dialog-box");
10 | var dialogOk = document.getElementById("dialog-box-ok");
11 | var dialogText = document.getElementById("dialog-box-text");
12 | var dialogInput = document.getElementById("dialog-box-input");
13 | var dialogCancel = document.getElementById("dialog-box-cancel");
14 |
15 | // Initial page zoom factor
16 | var zoomFactor = 1.0;
17 |
18 | // Listen to keydown event
19 | window.addEventListener('keydown', function (e) {
20 | // Check whether CTRL on Windows or CMD on Mac is pressed
21 | var modifierActive = (navigator.platform.startsWith('Mac')) ? e.metaKey : e.ctrlKey;
22 | var altModifierActive = (navigator.platform.startsWith('Mac')) ? e.ctrlKey : e.altKey;
23 |
24 | // Enter full screen mode (CMD/ALT + CTRL + F)
25 | if (modifierActive && altModifierActive && e.keyCode == 'F'.charCodeAt(0)) {
26 | // Get current focused window
27 | var window = chrome.app.window.current();
28 |
29 | // Check if currently full screen
30 | if (!window.isFullscreen()) {
31 | // Enter full screen mode
32 | window.fullscreen();
33 | }
34 | else {
35 | // Exit full screen mode
36 | window.restore();
37 | }
38 |
39 | // Prevent other shortcut checks
40 | return;
41 | }
42 |
43 | // Refresh the page (CTRL/CMD + R)
44 | if (modifierActive && e.keyCode == 'R'.charCodeAt(0)) {
45 | webview.reload();
46 | }
47 |
48 | // Find in page (CTRL/CMD + F)
49 | if (modifierActive && e.keyCode == 'F'.charCodeAt(0)) {
50 | // Show the find box
51 | findBox.style.display = 'block';
52 |
53 | // Focus the find input
54 | findInput.focus();
55 |
56 | // Select all existing text (if any)
57 | findInput.select();
58 | }
59 |
60 | // Copy URL (CTRL/CMD + L)
61 | if (modifierActive && e.keyCode == 'L'.charCodeAt(0)) {
62 | // Copy webview source to clipboard
63 | copyToClipboard(webview.src, 'text/plain');
64 | }
65 |
66 | // Print (CTRL/CMD + P)
67 | if (modifierActive && e.keyCode == 'P'.charCodeAt(0)) {
68 | webview.print();
69 | }
70 |
71 | // Zoom in (CTRL/CMD +)
72 | if (modifierActive && e.keyCode == 187) {
73 | zoomFactor += 0.1;
74 | webview.setZoom(zoomFactor);
75 | }
76 |
77 | // Zoom out (CTRL/CMD -)
78 | if (modifierActive && e.keyCode == 189) {
79 | zoomFactor -= 0.1;
80 |
81 | // Don't let zoom drop below 0.2
82 | if (zoomFactor <= 0.2) {
83 | zoomFactor = 0.2;
84 | }
85 |
86 | webview.setZoom(zoomFactor);
87 | }
88 |
89 | // Reset zoom (CTRL/CMD + 0)
90 | if (modifierActive && e.keyCode == '0'.charCodeAt(0)) {
91 | zoomFactor = 1.0;
92 | webview.setZoom(zoomFactor);
93 | }
94 | });
95 |
96 | // Listen for webview load event
97 | webview.addEventListener('contentload', function () {
98 | // Execute JS script within webview
99 | webview.executeScript({
100 | // Send a Chrome runtime message every time the keydown event is fired within webview
101 | code: `window.addEventListener('keydown', function (e) {
102 | chrome.runtime.sendMessage({ event: 'keydown', params: { ctrlKey: e.ctrlKey, metaKey: e.metaKey, altKey: e.altKey, keyCode: e.keyCode } });
103 | });`});
104 | });
105 |
106 | // Listen for Chrome runtime messages
107 | chrome.runtime.onMessage.addListener(
108 | function (request, sender, sendResponse) {
109 | // Check for keydown event
110 | if (request.event === 'keydown') {
111 | // Invoke the local window's keydown event handler
112 | window.dispatchEvent(new KeyboardEvent('keydown',request.params));
113 | }
114 | }
115 | );
116 |
117 | // Find input: listen to keydown event
118 | findInput.addEventListener('keyup', function (e) {
119 | // Search for current input text
120 | webview.find(findInput.value, { matchCase: false });
121 |
122 | // Escape key
123 | if (e.keyCode === 27) {
124 | webview.stopFinding();
125 | findBox.style.display = 'none';
126 | }
127 | });
128 |
129 | function copyToClipboard(str, mimetype) {
130 | // Listen for 'oncopy' event
131 | document.oncopy = function (event) {
132 | event.clipboardData.setData(mimetype, str);
133 | event.preventDefault();
134 | };
135 |
136 | // Execute browser command 'Copy'
137 | document.execCommand("Copy", false, null);
138 | }
139 |
140 | // Custom alert dialog popup
141 | var dialogController;
142 |
143 | // Listen for dialog cancellation button click
144 | dialogCancel.addEventListener('click', function () {
145 | // Send cancellation
146 | dialogController.cancel();
147 |
148 | // Hide dialog box
149 | dialogBox.style.display = 'none';
150 | });
151 |
152 | // Listen for dialog OK button click
153 | dialogOk.addEventListener('click', function () {
154 | // Send OK value
155 | dialogController.ok(dialogInput.value);
156 |
157 | // Hide dialog box
158 | dialogBox.style.display = 'none';
159 | });
160 |
161 | // Listen for dialog event on webview for new alert dialogs
162 | webview.addEventListener('dialog', function (e) {
163 | // Prevent default logic
164 | e.preventDefault();
165 |
166 | // Extract dialog type and text
167 | var text = e.messageText;
168 | var dialogType = e.messageType;
169 |
170 | // Keep a reference to dialog object
171 | dialogController = e.dialog;
172 |
173 | // Set dialog text
174 | dialogText.innerHTML = text;
175 |
176 | // Reset dialog input
177 | dialogInput.value = '';
178 |
179 | // Hide it by default
180 | dialogInput.style.display = 'none';
181 |
182 | // Alert?
183 | if (dialogType == 'alert') {
184 | // Hide cancel button
185 | dialogCancel.style.display = 'none';
186 | }
187 | else {
188 | // Another type of dialog, show cancel button
189 | dialogCancel.style.display = 'block';
190 |
191 | // Prompt?
192 | if (dialogType == 'prompt') {
193 | // Show text input field
194 | dialogInput.style.display = 'block';
195 | }
196 | }
197 |
198 | // Show dialog box
199 | dialogBox.style.display = 'block';
200 | });
--------------------------------------------------------------------------------
/assets/crx/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "manifest_version": 2,
3 | "name": "Applicationize",
4 | "description": "A shortcut app generated via Applicationize.",
5 | "version": "1.0",
6 | "icons": {
7 | "128": "img/icon.png"
8 | },
9 | "app": {
10 | "background": {
11 | "scripts": [
12 | "js/background.js"
13 | ],
14 | "pages": [
15 | "html/embed.html"
16 | ]
17 | }
18 | },
19 | "permissions": [
20 | "webview",
21 | "fullscreen"
22 | ]
23 | }
--------------------------------------------------------------------------------
/assets/icons/fallback/A.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/A.png
--------------------------------------------------------------------------------
/assets/icons/fallback/B.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/B.png
--------------------------------------------------------------------------------
/assets/icons/fallback/C.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/C.png
--------------------------------------------------------------------------------
/assets/icons/fallback/D.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/D.png
--------------------------------------------------------------------------------
/assets/icons/fallback/E.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/E.png
--------------------------------------------------------------------------------
/assets/icons/fallback/F.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/F.png
--------------------------------------------------------------------------------
/assets/icons/fallback/G.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/G.png
--------------------------------------------------------------------------------
/assets/icons/fallback/H.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/H.png
--------------------------------------------------------------------------------
/assets/icons/fallback/I.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/I.png
--------------------------------------------------------------------------------
/assets/icons/fallback/J.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/J.png
--------------------------------------------------------------------------------
/assets/icons/fallback/K.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/K.png
--------------------------------------------------------------------------------
/assets/icons/fallback/L.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/L.png
--------------------------------------------------------------------------------
/assets/icons/fallback/M.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/M.png
--------------------------------------------------------------------------------
/assets/icons/fallback/N.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/N.png
--------------------------------------------------------------------------------
/assets/icons/fallback/O.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/O.png
--------------------------------------------------------------------------------
/assets/icons/fallback/P.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/P.png
--------------------------------------------------------------------------------
/assets/icons/fallback/Q.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/Q.png
--------------------------------------------------------------------------------
/assets/icons/fallback/R.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/R.png
--------------------------------------------------------------------------------
/assets/icons/fallback/S.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/S.png
--------------------------------------------------------------------------------
/assets/icons/fallback/T.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/T.png
--------------------------------------------------------------------------------
/assets/icons/fallback/U.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/U.png
--------------------------------------------------------------------------------
/assets/icons/fallback/V.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/V.png
--------------------------------------------------------------------------------
/assets/icons/fallback/W.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/W.png
--------------------------------------------------------------------------------
/assets/icons/fallback/X.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/X.png
--------------------------------------------------------------------------------
/assets/icons/fallback/Y.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/Y.png
--------------------------------------------------------------------------------
/assets/icons/fallback/Z.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/fallback/Z.png
--------------------------------------------------------------------------------
/assets/icons/keep.google.com.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/keep.google.com.png
--------------------------------------------------------------------------------
/assets/icons/messenger.com.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/messenger.com.png
--------------------------------------------------------------------------------
/assets/icons/web.whatsapp.com.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/web.whatsapp.com.png
--------------------------------------------------------------------------------
/assets/icons/youtube.com.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/assets/icons/youtube.com.png
--------------------------------------------------------------------------------
/lib/middleware/error.js:
--------------------------------------------------------------------------------
1 | // Error middleware
2 | module.exports = function error() {
3 | // Return generator function
4 | return function* error(next) {
5 | try {
6 | yield next;
7 | } catch (err) {
8 | // Set response status code
9 | this.status = err.status || 500;
10 | this.body = { error: err.message || 'An unexpected error occurred.' };
11 |
12 | // Log to console
13 | console.log('Unhandled exception', err);
14 |
15 | // Emit app-wide error
16 | //this.app.emit('error', err, this);
17 | }
18 | };
19 | };
--------------------------------------------------------------------------------
/lib/middleware/redirect.js:
--------------------------------------------------------------------------------
1 | module.exports = function httpsRedirect() {
2 | // Redirect users to HTTPS endpoint
3 | return function* (next) {
4 | // Didn't request 'https://' endpoint?
5 | if (this.protocol !== 'https' && this.hostname !== 'localhost') {
6 | // Redirect to HTTPS endpoint with same path
7 | return this.redirect('https://' + this.host + this.url);
8 | }
9 |
10 | // Execute downstream middleware
11 | yield next;
12 | };
13 | };
--------------------------------------------------------------------------------
/lib/routes/applicationize.js:
--------------------------------------------------------------------------------
1 | var os = require('os');
2 | var url = require('url');
3 | var pem = require('pem');
4 | var path = require('path');
5 | var zlib = require('zlib');
6 | var fs = require('fs-extra');
7 | var stream = require('stream');
8 | var request = require('request');
9 | var cheerio = require('cheerio');
10 | var thunkify = require('thunkify');
11 | var validator = require('validator');
12 |
13 | // Convert callbacks to thunks
14 | var requestThunk = thunkify(request);
15 | var createCertificate = thunkify(pem.createCertificate);
16 |
17 | // CRX packaging module, instantiated with the `new` keyword
18 | var Extension = require('crx');
19 |
20 | // Workaround for #114: os.tmpDir is not a function (on Node 14+)
21 | // https://stackoverflow.com/a/62163963/1123355
22 | if (!os.tmpDir && os.tmpdir) {
23 | os.tmpDir = os.tmpdir;
24 | }
25 |
26 | // POST /generate
27 | module.exports = function* () {
28 | // Build .crx config for the provided URL
29 | var crxConfig = yield buildCrxConfig(this);
30 |
31 | // Generate the .crx file based on the config
32 | var crxBuffer = yield generateCrx(crxConfig);
33 |
34 | // Wrap in a .zip to work around the CRX_REQUIRED_PROOF_MISSING error
35 | var zipBuffer = yield generateZipArchive(crxBuffer);
36 |
37 | // Send zip file to the browser (save to disk)
38 | sendZipFile(this, crxConfig, zipBuffer);
39 | };
40 |
41 | function* buildCrxConfig(ctx) {
42 | // Get target URL from input
43 | var url = ctx.body.url;
44 |
45 | // Bad input?
46 | if (!url) {
47 | throw { status: 400, message: 'Please provide a URL to continue.' };
48 | }
49 |
50 | // Parse and validate the input URL (may throw an error)
51 | var parsedUrl = parseUrl(url);
52 |
53 | // Prepare crx object with default values
54 | var crxConfig = {
55 | url: parsedUrl.href, // href appends trailing slash to hostnames
56 | hostname: parsedUrl.hostname,
57 | parsedUrl: parsedUrl,
58 | title: parsedUrl.hostname,
59 | filename: parsedUrl.hostname + '.crx'
60 | };
61 |
62 | // Normalize hostname for custom use-cases
63 | crxConfig.host = parsedUrl.hostname.toLowerCase().replace('www.', '');
64 |
65 | var $;
66 |
67 | try {
68 | // Execute GET request to provided URL - may fail for internal URLs, continue anyway
69 | $ = yield getPageDOM(crxConfig.url);
70 | }
71 | catch (exc) {
72 | // Ignore exception, continue execution ($ is optional)
73 | }
74 |
75 | // Get extension title and handle custom cases
76 | crxConfig.title = getCrxTitle($, crxConfig, ctx);
77 |
78 | // Get extension icon path (either from default host icons, page DOM, or a user-uploaded icon)
79 | crxConfig.icon = yield getCrxIcon($, crxConfig, ctx);
80 |
81 | // Get extension frame color (advanced option)
82 | crxConfig.frameColor = getCrxFrameColor(ctx);
83 |
84 | // Get extra permissions (advanced options)
85 | crxConfig.permissions = getExtraPermissions(ctx);
86 |
87 | // Get custom user agent (optional)
88 | crxConfig.userAgent = ctx.body.userAgent;
89 |
90 | // Check whether user wants internal links
91 | crxConfig.internalLinks = ctx.body.internalLinks !== undefined;
92 |
93 | // Return the extension configuration object
94 | return crxConfig;
95 | }
96 |
97 | function* getCrxIcon($, crxConfig, ctx) {
98 | // Read any uploaded files from the post body (do this before reading from parts.fields)
99 | var customIcon = ctx.body.files.icon;
100 |
101 | // Check if the user uploaded a custom icon
102 | if (customIcon && customIcon.size > 0 && customIcon.type == 'image/png') {
103 | // Store tmp icon path and delete it afterwards
104 | crxConfig.tmpIconPath = customIcon.path;
105 |
106 | // Return the path to the uploaded custom icon
107 | return customIcon.path;
108 | }
109 | else {
110 | // Remove invalid uploaded files
111 | fs.removeSync(customIcon.path);
112 | }
113 |
114 | // Check if we have a default icon for this host (if so, it should override the web app's favicon)
115 | var defaultHostIcon = getDefaultHostIconPath(crxConfig);
116 |
117 | // Got one?
118 | if (defaultHostIcon) {
119 | // Return it as the icon's path
120 | return defaultHostIcon;
121 | }
122 |
123 | // Got page DOM?
124 | if ($) {
125 | // Shortcut icon selectors (first ones are the highest quality)
126 | var selectors = [
127 | 'link[rel="fluid-icon"]',
128 | 'link[rel="apple-touch-icon"]',
129 | 'link[rel="icon"]',
130 | 'link[rel="shortcut icon"]'
131 | ];
132 |
133 | // The actual href value of one of these selectors
134 | var linkHref;
135 |
136 | // Traverse selectors, find first one that exists
137 | for (var i in selectors) {
138 | // Get element by selector
139 | var element = $(selectors[i]);
140 |
141 | // Found it?
142 | if (element.length > 0) {
143 | // Set linkHref to 's href attribute
144 | linkHref = element.attr('href');
145 | break;
146 | }
147 | }
148 |
149 | // Got a valid image URL?
150 | if (linkHref) {
151 | // Construct a temporary upload path on the server
152 | var tmpUploadPath = path.join(os.tmpdir(), Math.random().toString() + '.png');
153 |
154 | // Convert relative icon path to absolute
155 | var absoluteIconUrl = url.resolve(crxConfig.url, linkHref);
156 |
157 | // Resolve succeeded?
158 | if (absoluteIconUrl) {
159 | // Download it locally to the tmp path
160 | yield downloadFile(absoluteIconUrl, tmpUploadPath);
161 | }
162 |
163 | // Store tmp icon path and delete it afterwards
164 | crxConfig.tmpIconPath = tmpUploadPath;
165 |
166 | // Return the path to the downloaded icon
167 | return tmpUploadPath;
168 | }
169 | }
170 |
171 | // Fallback to generic letter icon: grab first char of hostname (hopefully a letter)
172 | var letter = crxConfig.parsedUrl.hostname.substring(0, 1).toUpperCase();
173 |
174 | // Not an English letter?
175 | if (!letter.match(/[A-Z]/)) {
176 | // Use default applicationize icon
177 | return null;
178 | }
179 |
180 | // Build path to placeholder letter icon
181 | return path.join(__dirname, '../../assets/icons/fallback/' + letter + '.png');
182 | }
183 |
184 | function getCrxTitle($, crxConfig, ctx) {
185 | // Specified a custom title for the extension?
186 | if (ctx.body.title) {
187 | // Return it (it should override all other title extraction mechanisms)
188 | return ctx.body.title;
189 | }
190 |
191 | // No DOM?
192 | if (!$) {
193 | // Return current extension title (the web app's hostname)
194 | return crxConfig.title;
195 | }
196 |
197 | // Extract extension title from the dom's tag
198 | var title = $('title').text().trim() || crxConfig.parsedUrl.hostname;
199 |
200 | // Handle custom use-cases per hostname
201 | switch (crxConfig.host) {
202 | case 'messenger.com':
203 | // Fix weird 0x8234 chars in FB messenger
204 | title = 'Messenger';
205 | break;
206 | case 'keep.google.com':
207 | // Avoid "Sign In - Google Accounts"
208 | title = 'Google Keep';
209 | break;
210 | }
211 |
212 | return title;
213 | }
214 |
215 | function getExtraPermissions(ctx) {
216 | // Extra permissions list
217 | var permissions = [];
218 |
219 | // Notifications
220 | if (ctx.body.notifications) {
221 | permissions.push('notifications');
222 | }
223 |
224 | // Microphone
225 | if (ctx.body.audioCapture) {
226 | permissions.push('audioCapture');
227 | }
228 |
229 | // Webcam
230 | if (ctx.body.videoCapture) {
231 | permissions.push('videoCapture');
232 | }
233 |
234 | // We're good to go
235 | return permissions;
236 | }
237 |
238 | function getCrxFrameColor(ctx) {
239 | // Extract frame color from input
240 | var frameColor = ctx.body.frameColor;
241 |
242 | // Didn't specify a custom frame color for the extension?
243 | if (!frameColor) {
244 | // Use default frame color
245 | return null;
246 | }
247 |
248 | // Make sure it's a valid hex value (Chrome won't accept anything else)
249 | if (!validator.isHexColor(frameColor)) {
250 | throw { status: 400, message: 'Please provide a valid hex color value to customize the frame color.' };
251 | }
252 |
253 | // We're good to go
254 | return frameColor;
255 | }
256 |
257 | function parseUrl(targetUrl) {
258 | // Parse URL (to retrieve hostname and verify its validity)
259 | var parsedUrl = url.parse(targetUrl);
260 |
261 | // Parse failed?
262 | if (!parsedUrl || !parsedUrl.protocol || !parsedUrl.host || parsedUrl.protocol.indexOf('http') == -1) {
263 | throw { status: 400, message: 'Please provide a valid URL for your extension. (It must start with http(s)://)' };
264 | }
265 |
266 | // Valid URL
267 | return parsedUrl;
268 | }
269 |
270 | function* getPageDOM(url) {
271 | // Prepare request (send fake browser user-agent header)
272 | var req = {
273 | url: url,
274 | timeout: 7000,
275 | headers: {
276 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36'
277 | }
278 | };
279 |
280 | // Actually execute the request
281 | var response = yield requestThunk(req);
282 |
283 | // Load DOM into Cheerio (HTML parser)
284 | return cheerio.load(response[0].body);
285 | }
286 |
287 | function* generateZipArchive(crxBuffer) {
288 | // Create temporary stream for CRX buffer
289 | var bufferStream = new stream.PassThrough();
290 |
291 | // Write CRX buffer to stream
292 | bufferStream.end(crxBuffer);
293 |
294 | // Pipe CRX buffer into a new GZip archive
295 | return bufferStream.pipe(zlib.createGzip());
296 | }
297 |
298 | function* generateCrx(crxConfig) {
299 | // Generate pem certificate
300 | var cert = yield createCertificate({ days: 365 * 10, selfSigned: true });
301 |
302 | // Init new .crx extension with our private key
303 | var crx = new Extension({ privateKey: cert.clientKey });
304 |
305 | // Tmp crx staging path
306 | var crxPath = path.join(__dirname, '../../assets/staging');
307 |
308 | // Clear all files from previous staging runs
309 | fs.removeSync(crxPath);
310 |
311 | // Copy crx files to tmp staging directory
312 | fs.copySync(path.join(__dirname, '../../assets/crx'), crxPath)
313 |
314 | // Load extension manifest and default icon
315 | yield crx.load(crxPath);
316 |
317 | // Do we have a local icon to copy over?
318 | if (crxConfig.icon && fs.existsSync(crxConfig.icon)) {
319 | // Set target copy path as current extension icon's path
320 | var copyToPath = crx.path + '/' + crx.manifest.icons['128'];
321 |
322 | // Copy the local file to the current extension's folder, where the icon currently resides
323 | yield copyLocalFile(crxConfig.icon, copyToPath);
324 |
325 | // Delete tmp file if exists
326 | if (crxConfig.tmpIconPath) {
327 | fs.removeSync(crxConfig.tmpIconPath);
328 | }
329 | }
330 |
331 | // Customize the crx's manifest.json file
332 | customizeManifestFile(crxConfig, crx);
333 |
334 | // Customize the crx's embed.html file
335 | customizeEmbedFile(crxConfig, crx);
336 |
337 | // Customize the crx's background.js file
338 | customizeBackgroundScript(crxConfig, crx);
339 |
340 | // Pack the extension into a .crx and return its buffer
341 | var crxBuffer = yield crx.pack();
342 |
343 | // Return buffer
344 | return crxBuffer;
345 | }
346 |
347 | function getDefaultHostIconPath(crxConfig) {
348 | // Build path to the default icon for this host
349 | var iconPath = path.join(__dirname, '../../assets/icons/' + crxConfig.host + '.png');
350 |
351 | try {
352 | // Check if icon exists
353 | fs.accessSync(iconPath, fs.F_OK);
354 | }
355 | catch (err) {
356 | // No such file
357 | return null;
358 | }
359 |
360 | // File exists
361 | return iconPath;
362 | }
363 |
364 | function customizeManifestFile(crxConfig, crx) {
365 | // Build path to manifest.json
366 | var manifestPath = crx.path + '/manifest.json';
367 |
368 | // Read its contents (JSON)
369 | var json = fs.readFileSync(manifestPath, 'utf8');
370 |
371 | // Parse manifest.json
372 | var manifest = JSON.parse(json);
373 |
374 | // Set extension title to page title or custom title
375 | manifest.name = crxConfig.title;
376 |
377 | // Any custom permissions?
378 | if (crxConfig.permissions) {
379 | manifest.permissions = manifest.permissions.concat(crxConfig.permissions);
380 | }
381 |
382 | // Convert back to json string
383 | json = JSON.stringify(manifest);
384 |
385 | // Overwrite the manifest file with the new json
386 | fs.writeFileSync(manifestPath, json);
387 | }
388 |
389 | function customizeEmbedFile(crxConfig, crx) {
390 | // Build path to embed.html
391 | var embedPath = crx.path + '/' + crx.manifest.app.background.pages[0];
392 |
393 | // Read its contents
394 | var html = fs.readFileSync(embedPath, 'utf8');
395 |
396 | // Load DOM into Cheerio (HTML parser)
397 | var $ = cheerio.load(html);
398 |
399 | // Set page title to crx title
400 | $('title').text(crxConfig.title);
401 |
402 | // Set webview source to applicationized URL
403 | $('webview').attr('src', crxConfig.url);
404 |
405 | // Convert back to html string
406 | html = $.html();
407 |
408 | // Overwrite the embed file with the new html
409 | fs.writeFileSync(embedPath, html);
410 | }
411 |
412 | function customizeBackgroundScript(crxConfig, crx) {
413 | // Config object to inject into background.js
414 | var appConfig = {
415 | // App hostname to load in webview
416 | hostname: crxConfig.hostname,
417 | // Pass in a custom user agent
418 | userAgent: crxConfig.userAgent,
419 | // Custom behavior params
420 | behavior: {
421 | // Whether to open external links in Chrome or in a new Applicationize window
422 | internalLinks: crxConfig.internalLinks
423 | },
424 | // Default params for `chrome.app.window.create` in `background.js`
425 | chromeAppWindow: {
426 | id: 'embed',
427 | frame: {
428 | type: 'chrome'
429 | },
430 | innerBounds: {
431 | 'width': 1180,
432 | 'height': 900
433 | }
434 | }
435 | };
436 |
437 | // User picked a custom frame color?
438 | if (crxConfig.frameColor) {
439 | // Insert it into the chrome app window params
440 | appConfig.chromeAppWindow.frame.color = crxConfig.frameColor;
441 | }
442 |
443 | // Build path to background.js
444 | var scriptPath = crx.path + '/' + crx.manifest.app.background.scripts[0];
445 |
446 | // Read its contents
447 | var js = fs.readFileSync(scriptPath, 'utf8');
448 |
449 | // Inject chrome app window params into background.js file (replace {inject-background-script-config} with stringified JSON)
450 | js = js.replace(/{inject-background-script-config}/, JSON.stringify(appConfig));
451 |
452 | // Overwrite the background script with the modified contents
453 | fs.writeFileSync(scriptPath, js);
454 | }
455 |
456 | function sendZipFile(request, crxConfig, zipBuffer) {
457 | // Set content-type to .zip extension mime type
458 | request.set('content-type', 'application/zip');
459 |
460 | // Set extension filename
461 | request.set('content-disposition', 'attachment; filename=' + crxConfig.filename + '.zip');
462 |
463 | // Set the request body to the .zip file buffer
464 | request.body = zipBuffer;
465 | }
466 |
467 | function downloadFile(url, filePath) {
468 | // Promisify the request
469 | return new Promise(function (resolve, reject) {
470 | try {
471 | // Create write stream
472 | var stream = fs.createWriteStream(filePath);
473 |
474 | // Wait for finish event
475 | stream.on('finish', function () {
476 | // Resolve the promise
477 | return resolve(true);
478 | });
479 |
480 | // Listen for errors
481 | stream.on('error', function (error) {
482 | // Log the error
483 | console.log('downloadFile error: ', error);
484 | });
485 |
486 | // Pipe the request to a file
487 | return request(url).pipe(stream);
488 | } catch (e) {
489 | // Failed
490 | return reject(e);
491 | }
492 | });
493 | }
494 |
495 | function copyLocalFile(from, to) {
496 | // Promisify the request
497 | return new Promise(function (resolve, reject) {
498 | try {
499 | // Ensure the source file exists
500 | if (!fs.existsSync(from)) {
501 | return reject('The source file does not exist.');
502 | }
503 |
504 | // Create write stream
505 | var writeStream = fs.createWriteStream(to);
506 |
507 | // Wait for finish event
508 | writeStream.on('finish', function () {
509 | // End the stream
510 | writeStream.end();
511 |
512 | // Resolve the promise
513 | return resolve(true);
514 | });
515 |
516 | // Listen for errors
517 | writeStream.on('error', function (error) {
518 | // Log the error
519 | console.log('copyLocalFile error: ', error);
520 | });
521 |
522 | // Pipe the "from" stream into the "to" stream
523 | fs.createReadStream(from).pipe(writeStream);
524 | } catch (e) {
525 | // Failed
526 | return reject(e);
527 | }
528 | });
529 | }
--------------------------------------------------------------------------------
/lib/routes/now.js:
--------------------------------------------------------------------------------
1 | var send = require('koa-send');
2 |
3 | // GET /now
4 | module.exports = function* () {
5 | // Send HTML file
6 | yield send(this, './public/now.html');
7 | };
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "applicationize",
3 | "version": "1.0.0",
4 | "repository": {
5 | "type": "git",
6 | "url": "https://github.com/eladnava/applicationize"
7 | },
8 | "description": "Applicationize your favorite web apps by wrapping them inside a Chrome extension that runs standalone like a native desktop app.",
9 | "main": "server.js",
10 | "scripts": {
11 | "start": "forever start -l /home/node/server.log --append server.js",
12 | "stop": "forever stop 0",
13 | "restart": "npm stop; npm start"
14 | },
15 | "author": "Elad Nava",
16 | "license": "Apache-2.0",
17 | "dependencies": {
18 | "cheerio": "1.0.0-rc.12",
19 | "crx": "^5.0.1",
20 | "fs-extra": "^7.0.1",
21 | "koa": "1.1.2",
22 | "koa-better-body": "^2.0.1",
23 | "koa-route": "2.4.2",
24 | "koa-send": "^3.2.0",
25 | "koa-static": "1.5.2",
26 | "pem": "^1.14.2",
27 | "request": "^2.88.0",
28 | "thunkify": "2.1.2",
29 | "validator": "^13.7.0"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/public/css/bootstrap-colorpicker.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap Colorpicker v2.3.3
3 | * http://mjolnic.github.io/bootstrap-colorpicker/
4 | *
5 | * Originally written by (c) 2012 Stefan Petre
6 | * Licensed under the Apache License v2.0
7 | * http://www.apache.org/licenses/LICENSE-2.0.txt
8 | *
9 | */.colorpicker-saturation{width:100px;height:100px;background-image:url(../img/bootstrap-colorpicker/saturation.png);cursor:crosshair;float:left}.colorpicker-saturation i{display:block;height:5px;width:5px;border:1px solid #000;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;position:absolute;top:0;left:0;margin:-4px 0 0 -4px}.colorpicker-saturation i b{display:block;height:5px;width:5px;border:1px solid #fff;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.colorpicker-alpha,.colorpicker-hue{width:15px;height:100px;float:left;cursor:row-resize;margin-left:4px;margin-bottom:4px}.colorpicker-alpha i,.colorpicker-hue i{display:block;height:1px;background:#000;border-top:1px solid #fff;position:absolute;top:0;left:0;width:100%;margin-top:-1px}.colorpicker-hue{background-image:url(../img/bootstrap-colorpicker/hue.png)}.colorpicker-alpha{background-image:url(../img/bootstrap-colorpicker/alpha.png);display:none}.colorpicker-alpha,.colorpicker-hue,.colorpicker-saturation{background-size:contain}.colorpicker{padding:4px;min-width:130px;margin-top:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;z-index:2500}.colorpicker:after,.colorpicker:before{display:table;content:"";line-height:0}.colorpicker:after{clear:both}.colorpicker:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,.2);position:absolute;top:-7px;left:6px}.colorpicker:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;top:-6px;left:7px}.colorpicker div{position:relative}.colorpicker.colorpicker-with-alpha{min-width:140px}.colorpicker.colorpicker-with-alpha .colorpicker-alpha{display:block}.colorpicker-color{height:10px;margin-top:5px;clear:both;background-image:url(../img/bootstrap-colorpicker/alpha.png);background-position:0 100%}.colorpicker-color div{height:10px}.colorpicker-selectors{display:none;height:10px;margin-top:5px;clear:both}.colorpicker-selectors i{cursor:pointer;float:left;height:10px;width:10px}.colorpicker-selectors i+i{margin-left:3px}.colorpicker-element .add-on i,.colorpicker-element .input-group-addon i{display:inline-block;cursor:pointer;height:16px;vertical-align:text-top;width:16px}.colorpicker.colorpicker-inline{position:relative;display:inline-block;float:none;z-index:auto}.colorpicker.colorpicker-horizontal{width:110px;min-width:110px;height:auto}.colorpicker.colorpicker-horizontal .colorpicker-saturation{margin-bottom:4px}.colorpicker.colorpicker-horizontal .colorpicker-color{width:100px}.colorpicker.colorpicker-horizontal .colorpicker-alpha,.colorpicker.colorpicker-horizontal .colorpicker-hue{width:100px;height:15px;float:left;cursor:col-resize;margin-left:0;margin-bottom:4px}.colorpicker.colorpicker-horizontal .colorpicker-alpha i,.colorpicker.colorpicker-horizontal .colorpicker-hue i{display:block;height:15px;background:#fff;position:absolute;top:0;left:0;width:1px;border:none;margin-top:0}.colorpicker.colorpicker-horizontal .colorpicker-hue{background-image:url(../img/bootstrap-colorpicker/hue-horizontal.png)}.colorpicker.colorpicker-horizontal .colorpicker-alpha{background-image:url(../img/bootstrap-colorpicker/alpha-horizontal.png)}.colorpicker.colorpicker-hidden{display:none}.colorpicker.colorpicker-visible{display:block}.colorpicker-inline.colorpicker-visible{display:inline-block}.colorpicker-right:before{left:auto;right:6px}.colorpicker-right:after{left:auto;right:7px}.colorpicker-no-arrow:before{border-right:0;border-left:0}.colorpicker-no-arrow:after{border-right:0;border-left:0}
10 | /*# sourceMappingURL=bootstrap-colorpicker.min.css.map */
--------------------------------------------------------------------------------
/public/css/custom.css:
--------------------------------------------------------------------------------
1 | .overlay:before {
2 | background: #000;
3 | opacity: 0.5;
4 | }
5 |
6 | .slogan-container {
7 | top: 15%;
8 | }
9 |
10 | .cover .align-bottom {
11 | bottom: 10%;
12 | }
13 |
14 | .feature .icon {
15 | opacity: 0.8;
16 | color: #e31d3b;
17 | }
18 |
19 | .checkbox-option {
20 | margin-bottom: 0;
21 | }
22 |
23 | .fork-me {
24 | top: 0;
25 | right: 0;
26 | border: 0;
27 | z-index: 5;
28 | position: absolute;
29 | }
30 |
31 | .spinner {
32 | display: none;
33 | }
34 |
35 | .logo-container {
36 | top: 15px;
37 | left: 15px;
38 | z-index: 5;
39 | position: absolute;
40 | }
41 |
42 | .input-subtext {
43 | color: inherit;
44 | font-size: 10px;
45 | font-weight: 300;
46 | display: inline-block;
47 | border-bottom: 1px dotted #999;
48 | }
49 |
50 | .advanced-options-container {
51 | display: none;
52 | }
53 |
54 | ::-webkit-input-placeholder {
55 | text-transform: none;
56 | }
57 |
58 | ::-moz-placeholder {
59 | text-transform: none;
60 | }
61 |
62 | :-moz-placeholder {
63 | text-transform: none;
64 | }
65 |
66 | -ms-input-placeholder {
67 | text-transform: none;
68 | }
69 |
70 | @media (max-width: 767px) {
71 | .text-center-mobile {
72 | text-align: center;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/public/css/flexslider.css:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery FlexSlider v2.3.0
3 | * http://www.woothemes.com/flexslider/
4 | *
5 | * Copyright 2012 WooThemes
6 | * Free to use under the GPLv2 license.
7 | * http://www.gnu.org/licenses/gpl-2.0.html
8 | *
9 | * Contributing author: Ville Ristimäki (@villeristi)
10 | *
11 | */
12 | /* ====================================================================================================================
13 | * FONT-FACE
14 | * ====================================================================================================================*/
15 |
16 | /* ====================================================================================================================
17 | * RESETS
18 | * ====================================================================================================================*/
19 | .flex-container a:hover,
20 | .flex-slider a:hover,
21 | .flex-container a:focus,
22 | .flex-slider a:focus {
23 | outline: none;
24 | }
25 | .slides,
26 | .flex-control-nav,
27 | .flex-direction-nav {
28 | margin: 0;
29 | padding: 0;
30 | list-style: none;
31 | }
32 | .flex-pauseplay span {
33 | text-transform: capitalize;
34 | }
35 | /* ====================================================================================================================
36 | * BASE STYLES
37 | * ====================================================================================================================*/
38 | .flexslider {
39 | margin: 0;
40 | padding: 0;
41 | }
42 | .flexslider .slides > li {
43 | display: none;
44 | -webkit-backface-visibility: hidden;
45 | }
46 | .flexslider .slides img {
47 | width: 100%;
48 | display: block;
49 | }
50 | .flexslider .slides:after {
51 | content: "\0020";
52 | display: block;
53 | clear: both;
54 | visibility: hidden;
55 | line-height: 0;
56 | height: 0;
57 | }
58 | html[xmlns] .flexslider .slides {
59 | display: block;
60 | }
61 | * html .flexslider .slides {
62 | height: 1%;
63 | }
64 | .no-js .flexslider .slides > li:first-child {
65 | display: block;
66 | }
67 | /* ====================================================================================================================
68 | * DEFAULT THEME
69 | * ====================================================================================================================*/
70 | .flexslider {
71 | margin: 0 0 60px;
72 | background: #fff;
73 | border: 4px solid #fff;
74 | position: relative;
75 | zoom: 1;
76 | -webkit-border-radius: 4px;
77 | -moz-border-radius: 4px;
78 | border-radius: 4px;
79 | -webkit-box-shadow: '' 0 1px 4px rgba(0, 0, 0, 0.2);
80 | -moz-box-shadow: '' 0 1px 4px rgba(0, 0, 0, 0.2);
81 | -o-box-shadow: '' 0 1px 4px rgba(0, 0, 0, 0.2);
82 | box-shadow: '' 0 1px 4px rgba(0, 0, 0, 0.2);
83 | }
84 | .flexslider .slides {
85 | zoom: 1;
86 | }
87 | .flex-viewport {
88 | max-height: 2000px;
89 | -webkit-transition: all 1s ease;
90 | -moz-transition: all 1s ease;
91 | -ms-transition: all 1s ease;
92 | -o-transition: all 1s ease;
93 | transition: all 1s ease;
94 | }
95 | .loading .flex-viewport {
96 | max-height: 300px;
97 | }
98 | .carousel li {
99 | margin-right: 5px;
100 | }
101 | .flex-direction-nav {
102 | *height: 0;
103 | }
104 | .flex-direction-nav a {
105 | text-decoration: none;
106 | display: block;
107 | width: 40px;
108 | height: 40px;
109 | margin: -20px 0 0;
110 | position: absolute;
111 | top: 50%;
112 | z-index: 10;
113 | overflow: hidden;
114 | opacity: 0;
115 | cursor: pointer;
116 | color: rgba(0, 0, 0, 0.8);
117 | text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.3);
118 | -webkit-transition: all 0.3s ease-in-out;
119 | -moz-transition: all 0.3s ease-in-out;
120 | -ms-transition: all 0.3s ease-in-out;
121 | -o-transition: all 0.3s ease-in-out;
122 | transition: all 0.3s ease-in-out;
123 | }
124 | .flex-direction-nav a:before {
125 | font-family: "flexslider-icon";
126 | font-size: 40px;
127 | display: inline-block;
128 | content: '\f001';
129 | }
130 | .flex-direction-nav a.flex-next:before {
131 | content: '\f002';
132 | }
133 | .flex-direction-nav .flex-prev {
134 | left: -50px;
135 | }
136 | .flex-direction-nav .flex-next {
137 | right: -50px;
138 | text-align: right;
139 | }
140 | .flexslider:hover .flex-direction-nav .flex-prev {
141 | opacity: 0.7;
142 | left: 10px;
143 | }
144 | .flexslider:hover .flex-direction-nav .flex-prev:hover {
145 | opacity: 1;
146 | }
147 | .flexslider:hover .flex-direction-nav .flex-next {
148 | opacity: 0.7;
149 | right: 10px;
150 | }
151 | .flexslider:hover .flex-direction-nav .flex-next:hover {
152 | opacity: 1;
153 | }
154 | .flex-direction-nav .flex-disabled {
155 | opacity: 0!important;
156 | filter: alpha(opacity=0);
157 | cursor: default;
158 | }
159 | .flex-pauseplay a {
160 | display: block;
161 | width: 20px;
162 | height: 20px;
163 | position: absolute;
164 | bottom: 5px;
165 | left: 10px;
166 | opacity: 0.8;
167 | z-index: 10;
168 | overflow: hidden;
169 | cursor: pointer;
170 | color: #000;
171 | }
172 | .flex-pauseplay a:before {
173 | font-family: "flexslider-icon";
174 | font-size: 20px;
175 | display: inline-block;
176 | content: '\f004';
177 | }
178 | .flex-pauseplay a:hover {
179 | opacity: 1;
180 | }
181 | .flex-pauseplay a .flex-play:before {
182 | content: '\f003';
183 | }
184 | .flex-control-nav {
185 | width: 100%;
186 | position: absolute;
187 | bottom: -40px;
188 | text-align: center;
189 | }
190 | .flex-control-nav li {
191 | margin: 0 6px;
192 | display: inline-block;
193 | zoom: 1;
194 | *display: inline;
195 | }
196 | .flex-control-paging li a {
197 | width: 11px;
198 | height: 11px;
199 | display: block;
200 | background: #666;
201 | background: rgba(0, 0, 0, 0.5);
202 | cursor: pointer;
203 | text-indent: -9999px;
204 | -webkit-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
205 | -moz-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
206 | -o-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
207 | box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
208 | -webkit-border-radius: 20px;
209 | -moz-border-radius: 20px;
210 | border-radius: 20px;
211 | }
212 | .flex-control-paging li a:hover {
213 | background: #333;
214 | background: rgba(0, 0, 0, 0.7);
215 | }
216 | .flex-control-paging li a.flex-active {
217 | background: #000;
218 | background: rgba(0, 0, 0, 0.9);
219 | cursor: default;
220 | }
221 | .flex-control-thumbs {
222 | margin: 5px 0 0;
223 | position: static;
224 | overflow: hidden;
225 | }
226 | .flex-control-thumbs li {
227 | width: 25%;
228 | float: left;
229 | margin: 0;
230 | }
231 | .flex-control-thumbs img {
232 | width: 100%;
233 | display: block;
234 | opacity: .7;
235 | cursor: pointer;
236 | -webkit-transition: all 1s ease;
237 | -moz-transition: all 1s ease;
238 | -ms-transition: all 1s ease;
239 | -o-transition: all 1s ease;
240 | transition: all 1s ease;
241 | }
242 | .flex-control-thumbs img:hover {
243 | opacity: 1;
244 | }
245 | .flex-control-thumbs .flex-active {
246 | opacity: 1;
247 | cursor: default;
248 | }
249 | /* ====================================================================================================================
250 | * RESPONSIVE
251 | * ====================================================================================================================*/
252 | @media screen and (max-width: 860px) {
253 | .flex-direction-nav .flex-prev {
254 | opacity: 1;
255 | left: 10px;
256 | }
257 | .flex-direction-nav .flex-next {
258 | opacity: 1;
259 | right: 10px;
260 | }
261 | }
262 |
--------------------------------------------------------------------------------
/public/css/lightbox.min.css:
--------------------------------------------------------------------------------
1 | body:after{content:url(../img/lightbox/close.png) url(../img/lightbox/loading.gif) url(../img/lightbox/prev.png) url(../img/lightbox/next.png);display:none}.lightboxOverlay{position:absolute;top:0;left:0;z-index:9999;background-color:#000;filter:alpha(Opacity=80);opacity:.8;display:none}.lightbox{position:absolute;left:0;width:100%;z-index:10000;text-align:center;line-height:0;font-weight:400}.lightbox .lb-image{display:block;height:auto;max-width:inherit;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px}.lightbox a img{border:none}.lb-outerContainer{position:relative;background-color:#fff;*zoom:1;width:250px;height:250px;margin:0 auto;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;-o-border-radius:4px;border-radius:4px}.lb-outerContainer:after{content:"";display:table;clear:both}.lb-container{padding:4px}.lb-loader{position:absolute;top:43%;left:0;height:25%;width:100%;text-align:center;line-height:0}.lb-cancel{display:block;width:32px;height:32px;margin:0 auto;background:url(../img/lightbox/loading.gif) no-repeat}.lb-nav{position:absolute;top:0;left:0;height:100%;width:100%;z-index:10}.lb-container>.nav{left:0}.lb-nav a{outline:0;background-image:url(data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==)}.lb-next,.lb-prev{height:100%;cursor:pointer;display:block}.lb-nav a.lb-prev{width:34%;left:0;float:left;background:url(../img/lightbox/prev.png) left 48% no-repeat;filter:alpha(Opacity=0);opacity:0;-webkit-transition:opacity .6s;-moz-transition:opacity .6s;-o-transition:opacity .6s;transition:opacity .6s}.lb-nav a.lb-prev:hover{filter:alpha(Opacity=100);opacity:1}.lb-nav a.lb-next{width:64%;right:0;float:right;background:url(../img/lightbox/next.png) right 48% no-repeat;filter:alpha(Opacity=0);opacity:0;-webkit-transition:opacity .6s;-moz-transition:opacity .6s;-o-transition:opacity .6s;transition:opacity .6s}.lb-nav a.lb-next:hover{filter:alpha(Opacity=100);opacity:1}.lb-dataContainer{margin:0 auto;padding-top:5px;*zoom:1;width:100%;-moz-border-radius-bottomleft:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px}.lb-dataContainer:after{content:"";display:table;clear:both}.lb-data{padding:0 4px;color:#ccc}.lb-data .lb-details{width:85%;float:left;text-align:left;line-height:1.1em}.lb-data .lb-caption{font-size:13px;font-weight:700;line-height:1em}.lb-data .lb-number{display:block;clear:left;padding-bottom:1em;font-size:12px;color:#999}.lb-data .lb-close{display:block;float:right;width:30px;height:30px;background:url(../img/lightbox/close.png) top right no-repeat;text-align:right;outline:0;filter:alpha(Opacity=70);opacity:.7;-webkit-transition:opacity .2s;-moz-transition:opacity .2s;-o-transition:opacity .2s;transition:opacity .2s}.lb-data .lb-close:hover{cursor:pointer;filter:alpha(Opacity=100);opacity:1}
--------------------------------------------------------------------------------
/public/css/themify-icons.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'themify';
3 | src:url('../fonts/themify.eot?');
4 | src:url('../fonts/themify.eot?#iefix-fvbane') format('embedded-opentype'),
5 | url('../fonts/themify.woff') format('woff'),
6 | url('../fonts/themify.ttf') format('truetype'),
7 | url('../fonts/themify.svg') format('svg');
8 | font-weight: normal;
9 | font-style: normal;
10 | }
11 |
12 | [class^="ti-"], [class*=" ti-"] {
13 | font-family: 'themify';
14 | speak: none;
15 | font-style: normal;
16 | font-weight: normal;
17 | font-variant: normal;
18 | text-transform: none;
19 | line-height: 1;
20 |
21 | /* Better Font Rendering =========== */
22 | -webkit-font-smoothing: antialiased;
23 | -moz-osx-font-smoothing: grayscale;
24 | }
25 |
26 | .ti-wand:before {
27 | content: "\e600";
28 | }
29 | .ti-volume:before {
30 | content: "\e601";
31 | }
32 | .ti-user:before {
33 | content: "\e602";
34 | }
35 | .ti-unlock:before {
36 | content: "\e603";
37 | }
38 | .ti-unlink:before {
39 | content: "\e604";
40 | }
41 | .ti-trash:before {
42 | content: "\e605";
43 | }
44 | .ti-thought:before {
45 | content: "\e606";
46 | }
47 | .ti-target:before {
48 | content: "\e607";
49 | }
50 | .ti-tag:before {
51 | content: "\e608";
52 | }
53 | .ti-tablet:before {
54 | content: "\e609";
55 | }
56 | .ti-star:before {
57 | content: "\e60a";
58 | }
59 | .ti-spray:before {
60 | content: "\e60b";
61 | }
62 | .ti-signal:before {
63 | content: "\e60c";
64 | }
65 | .ti-shopping-cart:before {
66 | content: "\e60d";
67 | }
68 | .ti-shopping-cart-full:before {
69 | content: "\e60e";
70 | }
71 | .ti-settings:before {
72 | content: "\e60f";
73 | }
74 | .ti-search:before {
75 | content: "\e610";
76 | }
77 | .ti-zoom-in:before {
78 | content: "\e611";
79 | }
80 | .ti-zoom-out:before {
81 | content: "\e612";
82 | }
83 | .ti-cut:before {
84 | content: "\e613";
85 | }
86 | .ti-ruler:before {
87 | content: "\e614";
88 | }
89 | .ti-ruler-pencil:before {
90 | content: "\e615";
91 | }
92 | .ti-ruler-alt:before {
93 | content: "\e616";
94 | }
95 | .ti-bookmark:before {
96 | content: "\e617";
97 | }
98 | .ti-bookmark-alt:before {
99 | content: "\e618";
100 | }
101 | .ti-reload:before {
102 | content: "\e619";
103 | }
104 | .ti-plus:before {
105 | content: "\e61a";
106 | }
107 | .ti-pin:before {
108 | content: "\e61b";
109 | }
110 | .ti-pencil:before {
111 | content: "\e61c";
112 | }
113 | .ti-pencil-alt:before {
114 | content: "\e61d";
115 | }
116 | .ti-paint-roller:before {
117 | content: "\e61e";
118 | }
119 | .ti-paint-bucket:before {
120 | content: "\e61f";
121 | }
122 | .ti-na:before {
123 | content: "\e620";
124 | }
125 | .ti-mobile:before {
126 | content: "\e621";
127 | }
128 | .ti-minus:before {
129 | content: "\e622";
130 | }
131 | .ti-medall:before {
132 | content: "\e623";
133 | }
134 | .ti-medall-alt:before {
135 | content: "\e624";
136 | }
137 | .ti-marker:before {
138 | content: "\e625";
139 | }
140 | .ti-marker-alt:before {
141 | content: "\e626";
142 | }
143 | .ti-arrow-up:before {
144 | content: "\e627";
145 | }
146 | .ti-arrow-right:before {
147 | content: "\e628";
148 | }
149 | .ti-arrow-left:before {
150 | content: "\e629";
151 | }
152 | .ti-arrow-down:before {
153 | content: "\e62a";
154 | }
155 | .ti-lock:before {
156 | content: "\e62b";
157 | }
158 | .ti-location-arrow:before {
159 | content: "\e62c";
160 | }
161 | .ti-link:before {
162 | content: "\e62d";
163 | }
164 | .ti-layout:before {
165 | content: "\e62e";
166 | }
167 | .ti-layers:before {
168 | content: "\e62f";
169 | }
170 | .ti-layers-alt:before {
171 | content: "\e630";
172 | }
173 | .ti-key:before {
174 | content: "\e631";
175 | }
176 | .ti-import:before {
177 | content: "\e632";
178 | }
179 | .ti-image:before {
180 | content: "\e633";
181 | }
182 | .ti-heart:before {
183 | content: "\e634";
184 | }
185 | .ti-heart-broken:before {
186 | content: "\e635";
187 | }
188 | .ti-hand-stop:before {
189 | content: "\e636";
190 | }
191 | .ti-hand-open:before {
192 | content: "\e637";
193 | }
194 | .ti-hand-drag:before {
195 | content: "\e638";
196 | }
197 | .ti-folder:before {
198 | content: "\e639";
199 | }
200 | .ti-flag:before {
201 | content: "\e63a";
202 | }
203 | .ti-flag-alt:before {
204 | content: "\e63b";
205 | }
206 | .ti-flag-alt-2:before {
207 | content: "\e63c";
208 | }
209 | .ti-eye:before {
210 | content: "\e63d";
211 | }
212 | .ti-export:before {
213 | content: "\e63e";
214 | }
215 | .ti-exchange-vertical:before {
216 | content: "\e63f";
217 | }
218 | .ti-desktop:before {
219 | content: "\e640";
220 | }
221 | .ti-cup:before {
222 | content: "\e641";
223 | }
224 | .ti-crown:before {
225 | content: "\e642";
226 | }
227 | .ti-comments:before {
228 | content: "\e643";
229 | }
230 | .ti-comment:before {
231 | content: "\e644";
232 | }
233 | .ti-comment-alt:before {
234 | content: "\e645";
235 | }
236 | .ti-close:before {
237 | content: "\e646";
238 | }
239 | .ti-clip:before {
240 | content: "\e647";
241 | }
242 | .ti-angle-up:before {
243 | content: "\e648";
244 | }
245 | .ti-angle-right:before {
246 | content: "\e649";
247 | }
248 | .ti-angle-left:before {
249 | content: "\e64a";
250 | }
251 | .ti-angle-down:before {
252 | content: "\e64b";
253 | }
254 | .ti-check:before {
255 | content: "\e64c";
256 | }
257 | .ti-check-box:before {
258 | content: "\e64d";
259 | }
260 | .ti-camera:before {
261 | content: "\e64e";
262 | }
263 | .ti-announcement:before {
264 | content: "\e64f";
265 | }
266 | .ti-brush:before {
267 | content: "\e650";
268 | }
269 | .ti-briefcase:before {
270 | content: "\e651";
271 | }
272 | .ti-bolt:before {
273 | content: "\e652";
274 | }
275 | .ti-bolt-alt:before {
276 | content: "\e653";
277 | }
278 | .ti-blackboard:before {
279 | content: "\e654";
280 | }
281 | .ti-bag:before {
282 | content: "\e655";
283 | }
284 | .ti-move:before {
285 | content: "\e656";
286 | }
287 | .ti-arrows-vertical:before {
288 | content: "\e657";
289 | }
290 | .ti-arrows-horizontal:before {
291 | content: "\e658";
292 | }
293 | .ti-fullscreen:before {
294 | content: "\e659";
295 | }
296 | .ti-arrow-top-right:before {
297 | content: "\e65a";
298 | }
299 | .ti-arrow-top-left:before {
300 | content: "\e65b";
301 | }
302 | .ti-arrow-circle-up:before {
303 | content: "\e65c";
304 | }
305 | .ti-arrow-circle-right:before {
306 | content: "\e65d";
307 | }
308 | .ti-arrow-circle-left:before {
309 | content: "\e65e";
310 | }
311 | .ti-arrow-circle-down:before {
312 | content: "\e65f";
313 | }
314 | .ti-angle-double-up:before {
315 | content: "\e660";
316 | }
317 | .ti-angle-double-right:before {
318 | content: "\e661";
319 | }
320 | .ti-angle-double-left:before {
321 | content: "\e662";
322 | }
323 | .ti-angle-double-down:before {
324 | content: "\e663";
325 | }
326 | .ti-zip:before {
327 | content: "\e664";
328 | }
329 | .ti-world:before {
330 | content: "\e665";
331 | }
332 | .ti-wheelchair:before {
333 | content: "\e666";
334 | }
335 | .ti-view-list:before {
336 | content: "\e667";
337 | }
338 | .ti-view-list-alt:before {
339 | content: "\e668";
340 | }
341 | .ti-view-grid:before {
342 | content: "\e669";
343 | }
344 | .ti-uppercase:before {
345 | content: "\e66a";
346 | }
347 | .ti-upload:before {
348 | content: "\e66b";
349 | }
350 | .ti-underline:before {
351 | content: "\e66c";
352 | }
353 | .ti-truck:before {
354 | content: "\e66d";
355 | }
356 | .ti-timer:before {
357 | content: "\e66e";
358 | }
359 | .ti-ticket:before {
360 | content: "\e66f";
361 | }
362 | .ti-thumb-up:before {
363 | content: "\e670";
364 | }
365 | .ti-thumb-down:before {
366 | content: "\e671";
367 | }
368 | .ti-text:before {
369 | content: "\e672";
370 | }
371 | .ti-stats-up:before {
372 | content: "\e673";
373 | }
374 | .ti-stats-down:before {
375 | content: "\e674";
376 | }
377 | .ti-split-v:before {
378 | content: "\e675";
379 | }
380 | .ti-split-h:before {
381 | content: "\e676";
382 | }
383 | .ti-smallcap:before {
384 | content: "\e677";
385 | }
386 | .ti-shine:before {
387 | content: "\e678";
388 | }
389 | .ti-shift-right:before {
390 | content: "\e679";
391 | }
392 | .ti-shift-left:before {
393 | content: "\e67a";
394 | }
395 | .ti-shield:before {
396 | content: "\e67b";
397 | }
398 | .ti-notepad:before {
399 | content: "\e67c";
400 | }
401 | .ti-server:before {
402 | content: "\e67d";
403 | }
404 | .ti-quote-right:before {
405 | content: "\e67e";
406 | }
407 | .ti-quote-left:before {
408 | content: "\e67f";
409 | }
410 | .ti-pulse:before {
411 | content: "\e680";
412 | }
413 | .ti-printer:before {
414 | content: "\e681";
415 | }
416 | .ti-power-off:before {
417 | content: "\e682";
418 | }
419 | .ti-plug:before {
420 | content: "\e683";
421 | }
422 | .ti-pie-chart:before {
423 | content: "\e684";
424 | }
425 | .ti-paragraph:before {
426 | content: "\e685";
427 | }
428 | .ti-panel:before {
429 | content: "\e686";
430 | }
431 | .ti-package:before {
432 | content: "\e687";
433 | }
434 | .ti-music:before {
435 | content: "\e688";
436 | }
437 | .ti-music-alt:before {
438 | content: "\e689";
439 | }
440 | .ti-mouse:before {
441 | content: "\e68a";
442 | }
443 | .ti-mouse-alt:before {
444 | content: "\e68b";
445 | }
446 | .ti-money:before {
447 | content: "\e68c";
448 | }
449 | .ti-microphone:before {
450 | content: "\e68d";
451 | }
452 | .ti-menu:before {
453 | content: "\e68e";
454 | }
455 | .ti-menu-alt:before {
456 | content: "\e68f";
457 | }
458 | .ti-map:before {
459 | content: "\e690";
460 | }
461 | .ti-map-alt:before {
462 | content: "\e691";
463 | }
464 | .ti-loop:before {
465 | content: "\e692";
466 | }
467 | .ti-location-pin:before {
468 | content: "\e693";
469 | }
470 | .ti-list:before {
471 | content: "\e694";
472 | }
473 | .ti-light-bulb:before {
474 | content: "\e695";
475 | }
476 | .ti-Italic:before {
477 | content: "\e696";
478 | }
479 | .ti-info:before {
480 | content: "\e697";
481 | }
482 | .ti-infinite:before {
483 | content: "\e698";
484 | }
485 | .ti-id-badge:before {
486 | content: "\e699";
487 | }
488 | .ti-hummer:before {
489 | content: "\e69a";
490 | }
491 | .ti-home:before {
492 | content: "\e69b";
493 | }
494 | .ti-help:before {
495 | content: "\e69c";
496 | }
497 | .ti-headphone:before {
498 | content: "\e69d";
499 | }
500 | .ti-harddrives:before {
501 | content: "\e69e";
502 | }
503 | .ti-harddrive:before {
504 | content: "\e69f";
505 | }
506 | .ti-gift:before {
507 | content: "\e6a0";
508 | }
509 | .ti-game:before {
510 | content: "\e6a1";
511 | }
512 | .ti-filter:before {
513 | content: "\e6a2";
514 | }
515 | .ti-files:before {
516 | content: "\e6a3";
517 | }
518 | .ti-file:before {
519 | content: "\e6a4";
520 | }
521 | .ti-eraser:before {
522 | content: "\e6a5";
523 | }
524 | .ti-envelope:before {
525 | content: "\e6a6";
526 | }
527 | .ti-download:before {
528 | content: "\e6a7";
529 | }
530 | .ti-direction:before {
531 | content: "\e6a8";
532 | }
533 | .ti-direction-alt:before {
534 | content: "\e6a9";
535 | }
536 | .ti-dashboard:before {
537 | content: "\e6aa";
538 | }
539 | .ti-control-stop:before {
540 | content: "\e6ab";
541 | }
542 | .ti-control-shuffle:before {
543 | content: "\e6ac";
544 | }
545 | .ti-control-play:before {
546 | content: "\e6ad";
547 | }
548 | .ti-control-pause:before {
549 | content: "\e6ae";
550 | }
551 | .ti-control-forward:before {
552 | content: "\e6af";
553 | }
554 | .ti-control-backward:before {
555 | content: "\e6b0";
556 | }
557 | .ti-cloud:before {
558 | content: "\e6b1";
559 | }
560 | .ti-cloud-up:before {
561 | content: "\e6b2";
562 | }
563 | .ti-cloud-down:before {
564 | content: "\e6b3";
565 | }
566 | .ti-clipboard:before {
567 | content: "\e6b4";
568 | }
569 | .ti-car:before {
570 | content: "\e6b5";
571 | }
572 | .ti-calendar:before {
573 | content: "\e6b6";
574 | }
575 | .ti-book:before {
576 | content: "\e6b7";
577 | }
578 | .ti-bell:before {
579 | content: "\e6b8";
580 | }
581 | .ti-basketball:before {
582 | content: "\e6b9";
583 | }
584 | .ti-bar-chart:before {
585 | content: "\e6ba";
586 | }
587 | .ti-bar-chart-alt:before {
588 | content: "\e6bb";
589 | }
590 | .ti-back-right:before {
591 | content: "\e6bc";
592 | }
593 | .ti-back-left:before {
594 | content: "\e6bd";
595 | }
596 | .ti-arrows-corner:before {
597 | content: "\e6be";
598 | }
599 | .ti-archive:before {
600 | content: "\e6bf";
601 | }
602 | .ti-anchor:before {
603 | content: "\e6c0";
604 | }
605 | .ti-align-right:before {
606 | content: "\e6c1";
607 | }
608 | .ti-align-left:before {
609 | content: "\e6c2";
610 | }
611 | .ti-align-justify:before {
612 | content: "\e6c3";
613 | }
614 | .ti-align-center:before {
615 | content: "\e6c4";
616 | }
617 | .ti-alert:before {
618 | content: "\e6c5";
619 | }
620 | .ti-alarm-clock:before {
621 | content: "\e6c6";
622 | }
623 | .ti-agenda:before {
624 | content: "\e6c7";
625 | }
626 | .ti-write:before {
627 | content: "\e6c8";
628 | }
629 | .ti-window:before {
630 | content: "\e6c9";
631 | }
632 | .ti-widgetized:before {
633 | content: "\e6ca";
634 | }
635 | .ti-widget:before {
636 | content: "\e6cb";
637 | }
638 | .ti-widget-alt:before {
639 | content: "\e6cc";
640 | }
641 | .ti-wallet:before {
642 | content: "\e6cd";
643 | }
644 | .ti-video-clapper:before {
645 | content: "\e6ce";
646 | }
647 | .ti-video-camera:before {
648 | content: "\e6cf";
649 | }
650 | .ti-vector:before {
651 | content: "\e6d0";
652 | }
653 | .ti-themify-logo:before {
654 | content: "\e6d1";
655 | }
656 | .ti-themify-favicon:before {
657 | content: "\e6d2";
658 | }
659 | .ti-themify-favicon-alt:before {
660 | content: "\e6d3";
661 | }
662 | .ti-support:before {
663 | content: "\e6d4";
664 | }
665 | .ti-stamp:before {
666 | content: "\e6d5";
667 | }
668 | .ti-split-v-alt:before {
669 | content: "\e6d6";
670 | }
671 | .ti-slice:before {
672 | content: "\e6d7";
673 | }
674 | .ti-shortcode:before {
675 | content: "\e6d8";
676 | }
677 | .ti-shift-right-alt:before {
678 | content: "\e6d9";
679 | }
680 | .ti-shift-left-alt:before {
681 | content: "\e6da";
682 | }
683 | .ti-ruler-alt-2:before {
684 | content: "\e6db";
685 | }
686 | .ti-receipt:before {
687 | content: "\e6dc";
688 | }
689 | .ti-pin2:before {
690 | content: "\e6dd";
691 | }
692 | .ti-pin-alt:before {
693 | content: "\e6de";
694 | }
695 | .ti-pencil-alt2:before {
696 | content: "\e6df";
697 | }
698 | .ti-palette:before {
699 | content: "\e6e0";
700 | }
701 | .ti-more:before {
702 | content: "\e6e1";
703 | }
704 | .ti-more-alt:before {
705 | content: "\e6e2";
706 | }
707 | .ti-microphone-alt:before {
708 | content: "\e6e3";
709 | }
710 | .ti-magnet:before {
711 | content: "\e6e4";
712 | }
713 | .ti-line-double:before {
714 | content: "\e6e5";
715 | }
716 | .ti-line-dotted:before {
717 | content: "\e6e6";
718 | }
719 | .ti-line-dashed:before {
720 | content: "\e6e7";
721 | }
722 | .ti-layout-width-full:before {
723 | content: "\e6e8";
724 | }
725 | .ti-layout-width-default:before {
726 | content: "\e6e9";
727 | }
728 | .ti-layout-width-default-alt:before {
729 | content: "\e6ea";
730 | }
731 | .ti-layout-tab:before {
732 | content: "\e6eb";
733 | }
734 | .ti-layout-tab-window:before {
735 | content: "\e6ec";
736 | }
737 | .ti-layout-tab-v:before {
738 | content: "\e6ed";
739 | }
740 | .ti-layout-tab-min:before {
741 | content: "\e6ee";
742 | }
743 | .ti-layout-slider:before {
744 | content: "\e6ef";
745 | }
746 | .ti-layout-slider-alt:before {
747 | content: "\e6f0";
748 | }
749 | .ti-layout-sidebar-right:before {
750 | content: "\e6f1";
751 | }
752 | .ti-layout-sidebar-none:before {
753 | content: "\e6f2";
754 | }
755 | .ti-layout-sidebar-left:before {
756 | content: "\e6f3";
757 | }
758 | .ti-layout-placeholder:before {
759 | content: "\e6f4";
760 | }
761 | .ti-layout-menu:before {
762 | content: "\e6f5";
763 | }
764 | .ti-layout-menu-v:before {
765 | content: "\e6f6";
766 | }
767 | .ti-layout-menu-separated:before {
768 | content: "\e6f7";
769 | }
770 | .ti-layout-menu-full:before {
771 | content: "\e6f8";
772 | }
773 | .ti-layout-media-right-alt:before {
774 | content: "\e6f9";
775 | }
776 | .ti-layout-media-right:before {
777 | content: "\e6fa";
778 | }
779 | .ti-layout-media-overlay:before {
780 | content: "\e6fb";
781 | }
782 | .ti-layout-media-overlay-alt:before {
783 | content: "\e6fc";
784 | }
785 | .ti-layout-media-overlay-alt-2:before {
786 | content: "\e6fd";
787 | }
788 | .ti-layout-media-left-alt:before {
789 | content: "\e6fe";
790 | }
791 | .ti-layout-media-left:before {
792 | content: "\e6ff";
793 | }
794 | .ti-layout-media-center-alt:before {
795 | content: "\e700";
796 | }
797 | .ti-layout-media-center:before {
798 | content: "\e701";
799 | }
800 | .ti-layout-list-thumb:before {
801 | content: "\e702";
802 | }
803 | .ti-layout-list-thumb-alt:before {
804 | content: "\e703";
805 | }
806 | .ti-layout-list-post:before {
807 | content: "\e704";
808 | }
809 | .ti-layout-list-large-image:before {
810 | content: "\e705";
811 | }
812 | .ti-layout-line-solid:before {
813 | content: "\e706";
814 | }
815 | .ti-layout-grid4:before {
816 | content: "\e707";
817 | }
818 | .ti-layout-grid3:before {
819 | content: "\e708";
820 | }
821 | .ti-layout-grid2:before {
822 | content: "\e709";
823 | }
824 | .ti-layout-grid2-thumb:before {
825 | content: "\e70a";
826 | }
827 | .ti-layout-cta-right:before {
828 | content: "\e70b";
829 | }
830 | .ti-layout-cta-left:before {
831 | content: "\e70c";
832 | }
833 | .ti-layout-cta-center:before {
834 | content: "\e70d";
835 | }
836 | .ti-layout-cta-btn-right:before {
837 | content: "\e70e";
838 | }
839 | .ti-layout-cta-btn-left:before {
840 | content: "\e70f";
841 | }
842 | .ti-layout-column4:before {
843 | content: "\e710";
844 | }
845 | .ti-layout-column3:before {
846 | content: "\e711";
847 | }
848 | .ti-layout-column2:before {
849 | content: "\e712";
850 | }
851 | .ti-layout-accordion-separated:before {
852 | content: "\e713";
853 | }
854 | .ti-layout-accordion-merged:before {
855 | content: "\e714";
856 | }
857 | .ti-layout-accordion-list:before {
858 | content: "\e715";
859 | }
860 | .ti-ink-pen:before {
861 | content: "\e716";
862 | }
863 | .ti-info-alt:before {
864 | content: "\e717";
865 | }
866 | .ti-help-alt:before {
867 | content: "\e718";
868 | }
869 | .ti-headphone-alt:before {
870 | content: "\e719";
871 | }
872 | .ti-hand-point-up:before {
873 | content: "\e71a";
874 | }
875 | .ti-hand-point-right:before {
876 | content: "\e71b";
877 | }
878 | .ti-hand-point-left:before {
879 | content: "\e71c";
880 | }
881 | .ti-hand-point-down:before {
882 | content: "\e71d";
883 | }
884 | .ti-gallery:before {
885 | content: "\e71e";
886 | }
887 | .ti-face-smile:before {
888 | content: "\e71f";
889 | }
890 | .ti-face-sad:before {
891 | content: "\e720";
892 | }
893 | .ti-credit-card:before {
894 | content: "\e721";
895 | }
896 | .ti-control-skip-forward:before {
897 | content: "\e722";
898 | }
899 | .ti-control-skip-backward:before {
900 | content: "\e723";
901 | }
902 | .ti-control-record:before {
903 | content: "\e724";
904 | }
905 | .ti-control-eject:before {
906 | content: "\e725";
907 | }
908 | .ti-comments-smiley:before {
909 | content: "\e726";
910 | }
911 | .ti-brush-alt:before {
912 | content: "\e727";
913 | }
914 | .ti-youtube:before {
915 | content: "\e728";
916 | }
917 | .ti-vimeo:before {
918 | content: "\e729";
919 | }
920 | .ti-twitter:before {
921 | content: "\e72a";
922 | }
923 | .ti-time:before {
924 | content: "\e72b";
925 | }
926 | .ti-tumblr:before {
927 | content: "\e72c";
928 | }
929 | .ti-skype:before {
930 | content: "\e72d";
931 | }
932 | .ti-share:before {
933 | content: "\e72e";
934 | }
935 | .ti-share-alt:before {
936 | content: "\e72f";
937 | }
938 | .ti-rocket:before {
939 | content: "\e730";
940 | }
941 | .ti-pinterest:before {
942 | content: "\e731";
943 | }
944 | .ti-new-window:before {
945 | content: "\e732";
946 | }
947 | .ti-microsoft:before {
948 | content: "\e733";
949 | }
950 | .ti-list-ol:before {
951 | content: "\e734";
952 | }
953 | .ti-linkedin:before {
954 | content: "\e735";
955 | }
956 | .ti-layout-sidebar-2:before {
957 | content: "\e736";
958 | }
959 | .ti-layout-grid4-alt:before {
960 | content: "\e737";
961 | }
962 | .ti-layout-grid3-alt:before {
963 | content: "\e738";
964 | }
965 | .ti-layout-grid2-alt:before {
966 | content: "\e739";
967 | }
968 | .ti-layout-column4-alt:before {
969 | content: "\e73a";
970 | }
971 | .ti-layout-column3-alt:before {
972 | content: "\e73b";
973 | }
974 | .ti-layout-column2-alt:before {
975 | content: "\e73c";
976 | }
977 | .ti-instagram:before {
978 | content: "\e73d";
979 | }
980 | .ti-google:before {
981 | content: "\e73e";
982 | }
983 | .ti-github:before {
984 | content: "\e73f";
985 | }
986 | .ti-flickr:before {
987 | content: "\e740";
988 | }
989 | .ti-facebook:before {
990 | content: "\e741";
991 | }
992 | .ti-dropbox:before {
993 | content: "\e742";
994 | }
995 | .ti-dribbble:before {
996 | content: "\e743";
997 | }
998 | .ti-apple:before {
999 | content: "\e744";
1000 | }
1001 | .ti-android:before {
1002 | content: "\e745";
1003 | }
1004 | .ti-save:before {
1005 | content: "\e746";
1006 | }
1007 | .ti-save-alt:before {
1008 | content: "\e747";
1009 | }
1010 | .ti-yahoo:before {
1011 | content: "\e748";
1012 | }
1013 | .ti-wordpress:before {
1014 | content: "\e749";
1015 | }
1016 | .ti-vimeo-alt:before {
1017 | content: "\e74a";
1018 | }
1019 | .ti-twitter-alt:before {
1020 | content: "\e74b";
1021 | }
1022 | .ti-tumblr-alt:before {
1023 | content: "\e74c";
1024 | }
1025 | .ti-trello:before {
1026 | content: "\e74d";
1027 | }
1028 | .ti-stack-overflow:before {
1029 | content: "\e74e";
1030 | }
1031 | .ti-soundcloud:before {
1032 | content: "\e74f";
1033 | }
1034 | .ti-sharethis:before {
1035 | content: "\e750";
1036 | }
1037 | .ti-sharethis-alt:before {
1038 | content: "\e751";
1039 | }
1040 | .ti-reddit:before {
1041 | content: "\e752";
1042 | }
1043 | .ti-pinterest-alt:before {
1044 | content: "\e753";
1045 | }
1046 | .ti-microsoft-alt:before {
1047 | content: "\e754";
1048 | }
1049 | .ti-linux:before {
1050 | content: "\e755";
1051 | }
1052 | .ti-jsfiddle:before {
1053 | content: "\e756";
1054 | }
1055 | .ti-joomla:before {
1056 | content: "\e757";
1057 | }
1058 | .ti-html5:before {
1059 | content: "\e758";
1060 | }
1061 | .ti-flickr-alt:before {
1062 | content: "\e759";
1063 | }
1064 | .ti-email:before {
1065 | content: "\e75a";
1066 | }
1067 | .ti-drupal:before {
1068 | content: "\e75b";
1069 | }
1070 | .ti-dropbox-alt:before {
1071 | content: "\e75c";
1072 | }
1073 | .ti-css3:before {
1074 | content: "\e75d";
1075 | }
1076 | .ti-rss:before {
1077 | content: "\e75e";
1078 | }
1079 | .ti-rss-alt:before {
1080 | content: "\e75f";
1081 | }
1082 |
--------------------------------------------------------------------------------
/public/fonts/themify.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/fonts/themify.eot
--------------------------------------------------------------------------------
/public/fonts/themify.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/fonts/themify.ttf
--------------------------------------------------------------------------------
/public/fonts/themify.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/fonts/themify.woff
--------------------------------------------------------------------------------
/public/img/bootstrap-colorpicker/alpha-horizontal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/img/bootstrap-colorpicker/alpha-horizontal.png
--------------------------------------------------------------------------------
/public/img/bootstrap-colorpicker/alpha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/img/bootstrap-colorpicker/alpha.png
--------------------------------------------------------------------------------
/public/img/bootstrap-colorpicker/hue-horizontal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/img/bootstrap-colorpicker/hue-horizontal.png
--------------------------------------------------------------------------------
/public/img/bootstrap-colorpicker/hue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/img/bootstrap-colorpicker/hue.png
--------------------------------------------------------------------------------
/public/img/bootstrap-colorpicker/saturation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/img/bootstrap-colorpicker/saturation.png
--------------------------------------------------------------------------------
/public/img/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/img/cover.jpg
--------------------------------------------------------------------------------
/public/img/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/img/favicon.png
--------------------------------------------------------------------------------
/public/img/fork.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/img/fork.png
--------------------------------------------------------------------------------
/public/img/lightbox/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/img/lightbox/close.png
--------------------------------------------------------------------------------
/public/img/lightbox/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/img/lightbox/loading.gif
--------------------------------------------------------------------------------
/public/img/lightbox/next.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/img/lightbox/next.png
--------------------------------------------------------------------------------
/public/img/lightbox/prev.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/img/lightbox/prev.png
--------------------------------------------------------------------------------
/public/img/logo-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/img/logo-dark.png
--------------------------------------------------------------------------------
/public/img/logo-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/img/logo-light.png
--------------------------------------------------------------------------------
/public/img/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/img/preview.png
--------------------------------------------------------------------------------
/public/img/screenshots/install.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eladnava/applicationize/d73f5ffc1ee2da0403dda215be8c072c43ddfd1e/public/img/screenshots/install.png
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Applicationize - Convert Web Apps to Desktop Apps
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
49 |
50 |
51 |
52 |
53 |
Applicationize
54 | Seamlessly convert web apps into desktop apps
55 |
56 |
57 |
58 |
59 |
60 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | We convert your favorite web apps into
73 | desktop apps with their own dedicated launcher icon
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
A preview of Facebook Messenger running as an applicationized app on Mac OS X.
89 |
90 |
91 |
92 |
Here's how it works
93 |
94 | Applicationize generates a Google Chrome extension that embeds your favorite web app and places a custom shortcut icon in your app launcher when you install it.
95 |
96 |
97 | Don't worry if that's all nonsense to you — it's dead simple to applicationize a web app: simply enter its URL, download a customized Google Chrome extension, install, and enjoy.
98 |
99 |
Applicationize Me
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
Stay Organized
115 |
116 | Tabs are meant for websites, not web apps. Avoid clutter by applicationizing your frequently-used web apps.
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
Enhance Focus
125 |
126 | Avoid being distracted by time-wasting tabs in Google Chrome when you want to get things done.
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
Boost Productivity
135 |
136 | Access your web apps quickly and easily from your dock or taskbar, without having to open them in Chrome.
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
Go on, try it.
152 |
153 | Simply enter a URL address, download a customized Google Chrome extension, install, and enjoy. What are you waiting for?
154 |
155 |
Applicationize Me
156 |
157 |
158 |
159 |
160 |
161 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
211 |
212 |
213 |
--------------------------------------------------------------------------------
/public/js/applicationizer.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function () {
2 | "use strict";
3 |
4 | // Color picker for customizing app frame color
5 | $('.colorpicker').colorpicker({ format: 'hex', align: 'left' });
6 |
7 | // Handle advanced options toggle click
8 | $('.advanced-options-toggle').click(function (e) {
9 | // Cancel default browser navigation
10 | e.preventDefault();
11 |
12 | // Make sure we're not currently generating an extension
13 | if (!$(this).find('.submit').is(':disabled')) {
14 | // Toggle the advanced options container's visibility
15 | $('.advanced-options-container').toggle();
16 | }
17 | });
18 |
19 | // Handle applicationize form submit
20 | $('.applicationize-form').submit(function (e) {
21 | // Get input URL
22 | var url = $(this).find('input[name="url"]').val();
23 | var frameColor = $(this).find('input[name="frameColor"]').val();
24 |
25 | // Try parsing the URL
26 | var parser = document.createElement('a');
27 | parser.href = url;
28 |
29 | // Verify host & protocol
30 | if (!url || url.substring(0, 4) !== 'http' || !parser.host) {
31 | alert('Please provide a valid web app URL.\r\nExample: https://www.messenger.com/');
32 | return e.preventDefault();
33 | }
34 |
35 | // Verify valid frame color (if provided)
36 | if (frameColor && !/^#[0-9A-F]{6}$/i.test(frameColor)) {
37 | alert('Please provide a valid frame color hex value.');
38 | return e.preventDefault();
39 | }
40 |
41 | // Grab spinner and submit elements
42 | var submit = $(this).find('.submit');
43 | var spinner = $(this).find('.spinner');
44 |
45 | // Hide submit button and show spinner
46 | submit.hide();
47 | spinner.show();
48 |
49 | // Wait a few seconds (ugly hack since we don't know when the file has been downloaded)
50 | setTimeout(function () {
51 | // Flip the visibility back to normal
52 | spinner.hide();
53 | submit.show();
54 | }, 2500);
55 | });
56 | });
--------------------------------------------------------------------------------
/public/js/bootstrap-colorpicker.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap Colorpicker v2.3.3
3 | * http://mjolnic.github.io/bootstrap-colorpicker/
4 | */
5 | !function(a){"use strict";"object"==typeof exports?module.exports=a(window.jQuery):"function"==typeof define&&define.amd?define(["jquery"],a):window.jQuery&&!window.jQuery.fn.colorpicker&&a(window.jQuery)}(function(a){"use strict";var b=function(b,c){this.value={h:0,s:0,b:0,a:1},this.origFormat=null,c&&a.extend(this.colors,c),b&&(void 0!==b.toLowerCase?(b+="",this.setColor(b)):void 0!==b.h&&(this.value=b))};b.prototype={constructor:b,colors:{aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32",transparent:"transparent"},_sanitizeNumber:function(a){return"number"==typeof a?a:isNaN(a)||null===a||""===a||void 0===a?1:""===a?0:void 0!==a.toLowerCase?(a.match(/^\./)&&(a="0"+a),Math.ceil(100*parseFloat(a))/100):1},isTransparent:function(a){return a?(a=a.toLowerCase().trim(),"transparent"===a||a.match(/#?00000000/)||a.match(/(rgba|hsla)\(0,0,0,0?\.?0\)/)):!1},rgbaIsTransparent:function(a){return 0===a.r&&0===a.g&&0===a.b&&0===a.a},setColor:function(a){a=a.toLowerCase().trim(),a&&(this.isTransparent(a)?this.value={h:0,s:0,b:0,a:0}:this.value=this.stringToHSB(a)||{h:0,s:0,b:0,a:1})},stringToHSB:function(b){b=b.toLowerCase();var c;"undefined"!=typeof this.colors[b]&&(b=this.colors[b],c="alias");var d=this,e=!1;return a.each(this.stringParsers,function(a,f){var g=f.re.exec(b),h=g&&f.parse.apply(d,[g]),i=c||f.format||"rgba";return h?(e=i.match(/hsla?/)?d.RGBtoHSB.apply(d,d.HSLtoRGB.apply(d,h)):d.RGBtoHSB.apply(d,h),d.origFormat=i,!1):!0}),e},setHue:function(a){this.value.h=1-a},setSaturation:function(a){this.value.s=a},setBrightness:function(a){this.value.b=1-a},setAlpha:function(a){this.value.a=Math.round(parseInt(100*(1-a),10)/100*100)/100},toRGB:function(a,b,c,d){a||(a=this.value.h,b=this.value.s,c=this.value.b),a*=360;var e,f,g,h,i;return a=a%360/60,i=c*b,h=i*(1-Math.abs(a%2-1)),e=f=g=c-i,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],{r:Math.round(255*e),g:Math.round(255*f),b:Math.round(255*g),a:d||this.value.a}},toHex:function(a,b,c,d){var e=this.toRGB(a,b,c,d);return this.rgbaIsTransparent(e)?"transparent":"#"+(1<<24|parseInt(e.r)<<16|parseInt(e.g)<<8|parseInt(e.b)).toString(16).substr(1)},toHSL:function(a,b,c,d){a=a||this.value.h,b=b||this.value.s,c=c||this.value.b,d=d||this.value.a;var e=a,f=(2-b)*c,g=b*c;return g/=f>0&&1>=f?f:2-f,f/=2,g>1&&(g=1),{h:isNaN(e)?0:e,s:isNaN(g)?0:g,l:isNaN(f)?0:f,a:isNaN(d)?0:d}},toAlias:function(a,b,c,d){var e=this.toHex(a,b,c,d);for(var f in this.colors)if(this.colors[f]===e)return f;return!1},RGBtoHSB:function(a,b,c,d){a/=255,b/=255,c/=255;var e,f,g,h;return g=Math.max(a,b,c),h=g-Math.min(a,b,c),e=0===h?null:g===a?(b-c)/h:g===b?(c-a)/h+2:(a-b)/h+4,e=(e+360)%6*60/360,f=0===h?0:h/g,{h:this._sanitizeNumber(e),s:f,b:g,a:this._sanitizeNumber(d)}},HueToRGB:function(a,b,c){return 0>c?c+=1:c>1&&(c-=1),1>6*c?a+(b-a)*c*6:1>2*c?b:2>3*c?a+(b-a)*(2/3-c)*6:a},HSLtoRGB:function(a,b,c,d){0>b&&(b=0);var e;e=.5>=c?c*(1+b):c+b-c*b;var f=2*c-e,g=a+1/3,h=a,i=a-1/3,j=Math.round(255*this.HueToRGB(f,e,g)),k=Math.round(255*this.HueToRGB(f,e,h)),l=Math.round(255*this.HueToRGB(f,e,i));return[j,k,l,this._sanitizeNumber(d)]},toString:function(a){a=a||"rgba";var b=!1;switch(a){case"rgb":return b=this.toRGB(),this.rgbaIsTransparent(b)?"transparent":"rgb("+b.r+","+b.g+","+b.b+")";case"rgba":return b=this.toRGB(),"rgba("+b.r+","+b.g+","+b.b+","+b.a+")";case"hsl":return b=this.toHSL(),"hsl("+Math.round(360*b.h)+","+Math.round(100*b.s)+"%,"+Math.round(100*b.l)+"%)";case"hsla":return b=this.toHSL(),"hsla("+Math.round(360*b.h)+","+Math.round(100*b.s)+"%,"+Math.round(100*b.l)+"%,"+b.a+")";case"hex":return this.toHex();case"alias":return this.toAlias()||this.toHex();default:return b}},stringParsers:[{re:/rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*?\)/,format:"rgb",parse:function(a){return[a[1],a[2],a[3],1]}},{re:/rgb\(\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*?\)/,format:"rgb",parse:function(a){return[2.55*a[1],2.55*a[2],2.55*a[3],1]}},{re:/rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d*(?:\.\d+)?)\s*)?\)/,format:"rgba",parse:function(a){return[a[1],a[2],a[3],a[4]]}},{re:/rgba\(\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*(?:,\s*(\d*(?:\.\d+)?)\s*)?\)/,format:"rgba",parse:function(a){return[2.55*a[1],2.55*a[2],2.55*a[3],a[4]]}},{re:/hsl\(\s*(\d*(?:\.\d+)?)\s*,\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*?\)/,format:"hsl",parse:function(a){return[a[1]/360,a[2]/100,a[3]/100,a[4]]}},{re:/hsla\(\s*(\d*(?:\.\d+)?)\s*,\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*(?:,\s*(\d*(?:\.\d+)?)\s*)?\)/,format:"hsla",parse:function(a){return[a[1]/360,a[2]/100,a[3]/100,a[4]]}},{re:/#?([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,format:"hex",parse:function(a){return[parseInt(a[1],16),parseInt(a[2],16),parseInt(a[3],16),1]}},{re:/#?([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/,format:"hex",parse:function(a){return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16),1]}}],colorNameToHex:function(a){return"undefined"!=typeof this.colors[a.toLowerCase()]?this.colors[a.toLowerCase()]:!1}};var c={horizontal:!1,inline:!1,color:!1,format:!1,input:"input",container:!1,component:".add-on, .input-group-addon",sliders:{saturation:{maxLeft:100,maxTop:100,callLeft:"setSaturation",callTop:"setBrightness"},hue:{maxLeft:0,maxTop:100,callLeft:!1,callTop:"setHue"},alpha:{maxLeft:0,maxTop:100,callLeft:!1,callTop:"setAlpha"}},slidersHorz:{saturation:{maxLeft:100,maxTop:100,callLeft:"setSaturation",callTop:"setBrightness"},hue:{maxLeft:100,maxTop:0,callLeft:"setHue",callTop:!1},alpha:{maxLeft:100,maxTop:0,callLeft:"setAlpha",callTop:!1}},template:'',align:"right",customClass:null,colorSelectors:null},d=function(d,e){if(this.element=a(d).addClass("colorpicker-element"),this.options=a.extend(!0,{},c,this.element.data(),e),this.component=this.options.component,this.component=this.component!==!1?this.element.find(this.component):!1,this.component&&0===this.component.length&&(this.component=!1),this.container=this.options.container===!0?this.element:this.options.container,this.container=this.container!==!1?a(this.container):!1,this.input=this.element.is("input")?this.element:this.options.input?this.element.find(this.options.input):!1,this.input&&0===this.input.length&&(this.input=!1),this.color=new b(this.options.color!==!1?this.options.color:this.getValue(),this.options.colorSelectors),this.format=this.options.format!==!1?this.options.format:this.color.origFormat,this.options.color!==!1&&(this.updateInput(this.color),this.updateData(this.color)),this.picker=a(this.options.template),this.options.customClass&&this.picker.addClass(this.options.customClass),this.options.inline?this.picker.addClass("colorpicker-inline colorpicker-visible"):this.picker.addClass("colorpicker-hidden"),this.options.horizontal&&this.picker.addClass("colorpicker-horizontal"),"rgba"!==this.format&&"hsla"!==this.format&&this.options.format!==!1||this.picker.addClass("colorpicker-with-alpha"),"right"===this.options.align&&this.picker.addClass("colorpicker-right"),this.options.inline===!0&&this.picker.addClass("colorpicker-no-arrow"),this.options.colorSelectors){var f=this;a.each(this.options.colorSelectors,function(b,c){var d=a(" ").css("background-color",c).data("class",b);d.click(function(){f.setValue(a(this).css("background-color"))}),f.picker.find(".colorpicker-selectors").append(d)}),this.picker.find(".colorpicker-selectors").show()}this.picker.on("mousedown.colorpicker touchstart.colorpicker",a.proxy(this.mousedown,this)),this.picker.appendTo(this.container?this.container:a("body")),this.input!==!1&&(this.input.on({"keyup.colorpicker":a.proxy(this.keyup,this)}),this.input.on({"change.colorpicker":a.proxy(this.change,this)}),this.component===!1&&this.element.on({"focus.colorpicker":a.proxy(this.show,this)}),this.options.inline===!1&&this.element.on({"focusout.colorpicker":a.proxy(this.hide,this)})),this.component!==!1&&this.component.on({"click.colorpicker":a.proxy(this.show,this)}),this.input===!1&&this.component===!1&&this.element.on({"click.colorpicker":a.proxy(this.show,this)}),this.input!==!1&&this.component!==!1&&"color"===this.input.attr("type")&&this.input.on({"click.colorpicker":a.proxy(this.show,this),"focus.colorpicker":a.proxy(this.show,this)}),this.update(),a(a.proxy(function(){this.element.trigger("create")},this))};d.Color=b,d.prototype={constructor:d,destroy:function(){this.picker.remove(),this.element.removeData("colorpicker","color").off(".colorpicker"),this.input!==!1&&this.input.off(".colorpicker"),this.component!==!1&&this.component.off(".colorpicker"),this.element.removeClass("colorpicker-element"),this.element.trigger({type:"destroy"})},reposition:function(){if(this.options.inline!==!1||this.options.container)return!1;var a=this.container&&this.container[0]!==document.body?"position":"offset",b=this.component||this.element,c=b[a]();"right"===this.options.align&&(c.left-=this.picker.outerWidth()-b.outerWidth()),this.picker.css({top:c.top+b.outerHeight(),left:c.left})},show:function(b){return this.isDisabled()?!1:(this.picker.addClass("colorpicker-visible").removeClass("colorpicker-hidden"),this.reposition(),a(window).on("resize.colorpicker",a.proxy(this.reposition,this)),!b||this.hasInput()&&"color"!==this.input.attr("type")||b.stopPropagation&&b.preventDefault&&(b.stopPropagation(),b.preventDefault()),!this.component&&this.input||this.options.inline!==!1||a(window.document).on({"mousedown.colorpicker":a.proxy(this.hide,this)}),void this.element.trigger({type:"showPicker",color:this.color}))},hide:function(){this.picker.addClass("colorpicker-hidden").removeClass("colorpicker-visible"),a(window).off("resize.colorpicker",this.reposition),a(document).off({"mousedown.colorpicker":this.hide}),this.update(),this.element.trigger({type:"hidePicker",color:this.color})},updateData:function(a){return a=a||this.color.toString(this.format),this.element.data("color",a),a},updateInput:function(a){if(a=a||this.color.toString(this.format),this.input!==!1){if(this.options.colorSelectors){var c=new b(a,this.options.colorSelectors),d=c.toAlias();"undefined"!=typeof this.options.colorSelectors[d]&&(a=d)}this.input.prop("value",a)}return a},updatePicker:function(a){void 0!==a&&(this.color=new b(a,this.options.colorSelectors));var c=this.options.horizontal===!1?this.options.sliders:this.options.slidersHorz,d=this.picker.find("i");return 0!==d.length?(this.options.horizontal===!1?(c=this.options.sliders,d.eq(1).css("top",c.hue.maxTop*(1-this.color.value.h)).end().eq(2).css("top",c.alpha.maxTop*(1-this.color.value.a))):(c=this.options.slidersHorz,d.eq(1).css("left",c.hue.maxLeft*(1-this.color.value.h)).end().eq(2).css("left",c.alpha.maxLeft*(1-this.color.value.a))),d.eq(0).css({top:c.saturation.maxTop-this.color.value.b*c.saturation.maxTop,left:this.color.value.s*c.saturation.maxLeft}),this.picker.find(".colorpicker-saturation").css("backgroundColor",this.color.toHex(this.color.value.h,1,1,1)),this.picker.find(".colorpicker-alpha").css("backgroundColor",this.color.toHex()),this.picker.find(".colorpicker-color, .colorpicker-color div").css("backgroundColor",this.color.toString(this.format)),a):void 0},updateComponent:function(a){if(a=a||this.color.toString(this.format),this.component!==!1){var b=this.component.find("i").eq(0);b.length>0?b.css({backgroundColor:a}):this.component.css({backgroundColor:a})}return a},update:function(a){var b;return this.getValue(!1)===!1&&a!==!0||(b=this.updateComponent(),this.updateInput(b),this.updateData(b),this.updatePicker()),b},setValue:function(a){this.color=new b(a,this.options.colorSelectors),this.update(!0),this.element.trigger({type:"changeColor",color:this.color,value:a})},getValue:function(a){a=void 0===a?"#000000":a;var b;return b=this.hasInput()?this.input.val():this.element.data("color"),void 0!==b&&""!==b&&null!==b||(b=a),b},hasInput:function(){return this.input!==!1},isDisabled:function(){return this.hasInput()?this.input.prop("disabled")===!0:!1},disable:function(){return this.hasInput()?(this.input.prop("disabled",!0),this.element.trigger({type:"disable",color:this.color,value:this.getValue()}),!0):!1},enable:function(){return this.hasInput()?(this.input.prop("disabled",!1),this.element.trigger({type:"enable",color:this.color,value:this.getValue()}),!0):!1},currentSlider:null,mousePointer:{left:0,top:0},mousedown:function(b){!b.pageX&&!b.pageY&&b.originalEvent&&b.originalEvent.touches&&(b.pageX=b.originalEvent.touches[0].pageX,b.pageY=b.originalEvent.touches[0].pageY),b.stopPropagation(),b.preventDefault();var c=a(b.target),d=c.closest("div"),e=this.options.horizontal?this.options.slidersHorz:this.options.sliders;if(!d.is(".colorpicker")){if(d.is(".colorpicker-saturation"))this.currentSlider=a.extend({},e.saturation);else if(d.is(".colorpicker-hue"))this.currentSlider=a.extend({},e.hue);else{if(!d.is(".colorpicker-alpha"))return!1;this.currentSlider=a.extend({},e.alpha)}var f=d.offset();this.currentSlider.guide=d.find("i")[0].style,this.currentSlider.left=b.pageX-f.left,this.currentSlider.top=b.pageY-f.top,this.mousePointer={left:b.pageX,top:b.pageY},a(document).on({"mousemove.colorpicker":a.proxy(this.mousemove,this),"touchmove.colorpicker":a.proxy(this.mousemove,this),"mouseup.colorpicker":a.proxy(this.mouseup,this),"touchend.colorpicker":a.proxy(this.mouseup,this)}).trigger("mousemove")}return!1},mousemove:function(a){!a.pageX&&!a.pageY&&a.originalEvent&&a.originalEvent.touches&&(a.pageX=a.originalEvent.touches[0].pageX,a.pageY=a.originalEvent.touches[0].pageY),a.stopPropagation(),a.preventDefault();var b=Math.max(0,Math.min(this.currentSlider.maxLeft,this.currentSlider.left+((a.pageX||this.mousePointer.left)-this.mousePointer.left))),c=Math.max(0,Math.min(this.currentSlider.maxTop,this.currentSlider.top+((a.pageY||this.mousePointer.top)-this.mousePointer.top)));return this.currentSlider.guide.left=b+"px",this.currentSlider.guide.top=c+"px",this.currentSlider.callLeft&&this.color[this.currentSlider.callLeft].call(this.color,b/this.currentSlider.maxLeft),this.currentSlider.callTop&&this.color[this.currentSlider.callTop].call(this.color,c/this.currentSlider.maxTop),"setAlpha"===this.currentSlider.callTop&&this.options.format===!1&&(1!==this.color.value.a?(this.format="rgba",this.color.origFormat="rgba"):(this.format="hex",this.color.origFormat="hex")),this.update(!0),this.element.trigger({type:"changeColor",color:this.color}),!1},mouseup:function(b){return b.stopPropagation(),b.preventDefault(),a(document).off({"mousemove.colorpicker":this.mousemove,"touchmove.colorpicker":this.mousemove,"mouseup.colorpicker":this.mouseup,"touchend.colorpicker":this.mouseup}),!1},change:function(a){this.keyup(a)},keyup:function(a){38===a.keyCode?(this.color.value.a<1&&(this.color.value.a=Math.round(100*(this.color.value.a+.01))/100),this.update(!0)):40===a.keyCode?(this.color.value.a>0&&(this.color.value.a=Math.round(100*(this.color.value.a-.01))/100),this.update(!0)):(this.color=new b(this.input.val(),this.options.colorSelectors),this.color.origFormat&&this.options.format===!1&&(this.format=this.color.origFormat),this.getValue(!1)!==!1&&(this.updateData(),this.updateComponent(),this.updatePicker())),this.element.trigger({type:"changeColor",color:this.color,value:this.input.val()})}},a.colorpicker=d,a.fn.colorpicker=function(b){var c=arguments,e=null,f=this.each(function(){var f=a(this),g=f.data("colorpicker"),h="object"==typeof b?b:{};g||"string"==typeof b?"string"==typeof b&&(e=g[b].apply(g,Array.prototype.slice.call(c,1))):f.data("colorpicker",new d(this,h))});return"getValue"===b?e:f},a.fn.colorpicker.constructor=d});
--------------------------------------------------------------------------------
/public/js/flexslider.min.js:
--------------------------------------------------------------------------------
1 | !function($){$.flexslider=function(e,t){var a=$(e);a.vars=$.extend({},$.flexslider.defaults,t);var n=a.vars.namespace,i=window.navigator&&window.navigator.msPointerEnabled&&window.MSGesture,s=("ontouchstart"in window||i||window.DocumentTouch&&document instanceof DocumentTouch)&&a.vars.touch,r="click touchend MSPointerUp keyup",o="",l,c="vertical"===a.vars.direction,d=a.vars.reverse,u=a.vars.itemWidth>0,v="fade"===a.vars.animation,p=""!==a.vars.asNavFor,m={},f=!0;$.data(e,"flexslider",a),m={init:function(){a.animating=!1,a.currentSlide=parseInt(a.vars.startAt?a.vars.startAt:0,10),isNaN(a.currentSlide)&&(a.currentSlide=0),a.animatingTo=a.currentSlide,a.atEnd=0===a.currentSlide||a.currentSlide===a.last,a.containerSelector=a.vars.selector.substr(0,a.vars.selector.search(" ")),a.slides=$(a.vars.selector,a),a.container=$(a.containerSelector,a),a.count=a.slides.length,a.syncExists=$(a.vars.sync).length>0,"slide"===a.vars.animation&&(a.vars.animation="swing"),a.prop=c?"top":"marginLeft",a.args={},a.manualPause=!1,a.stopped=!1,a.started=!1,a.startTimeout=null,a.transitions=!a.vars.video&&!v&&a.vars.useCSS&&function(){var e=document.createElement("div"),t=["perspectiveProperty","WebkitPerspective","MozPerspective","OPerspective","msPerspective"];for(var n in t)if(void 0!==e.style[t[n]])return a.pfx=t[n].replace("Perspective","").toLowerCase(),a.prop="-"+a.pfx+"-transform",!0;return!1}(),a.ensureAnimationEnd="",""!==a.vars.controlsContainer&&(a.controlsContainer=$(a.vars.controlsContainer).length>0&&$(a.vars.controlsContainer)),""!==a.vars.manualControls&&(a.manualControls=$(a.vars.manualControls).length>0&&$(a.vars.manualControls)),a.vars.randomize&&(a.slides.sort(function(){return Math.round(Math.random())-.5}),a.container.empty().append(a.slides)),a.doMath(),a.setup("init"),a.vars.controlNav&&m.controlNav.setup(),a.vars.directionNav&&m.directionNav.setup(),a.vars.keyboard&&(1===$(a.containerSelector).length||a.vars.multipleKeyboard)&&$(document).bind("keyup",function(e){var t=e.keyCode;if(!a.animating&&(39===t||37===t)){var n=39===t?a.getTarget("next"):37===t?a.getTarget("prev"):!1;a.flexAnimate(n,a.vars.pauseOnAction)}}),a.vars.mousewheel&&a.bind("mousewheel",function(e,t,n,i){e.preventDefault();var s=a.getTarget(0>t?"next":"prev");a.flexAnimate(s,a.vars.pauseOnAction)}),a.vars.pausePlay&&m.pausePlay.setup(),a.vars.slideshow&&a.vars.pauseInvisible&&m.pauseInvisible.init(),a.vars.slideshow&&(a.vars.pauseOnHover&&a.hover(function(){a.manualPlay||a.manualPause||a.pause()},function(){a.manualPause||a.manualPlay||a.stopped||a.play()}),a.vars.pauseInvisible&&m.pauseInvisible.isHidden()||(a.vars.initDelay>0?a.startTimeout=setTimeout(a.play,a.vars.initDelay):a.play())),p&&m.asNav.setup(),s&&a.vars.touch&&m.touch(),(!v||v&&a.vars.smoothHeight)&&$(window).bind("resize orientationchange focus",m.resize),a.find("img").attr("draggable","false"),setTimeout(function(){a.vars.start(a)},200)},asNav:{setup:function(){a.asNav=!0,a.animatingTo=Math.floor(a.currentSlide/a.move),a.currentItem=a.currentSlide,a.slides.removeClass(n+"active-slide").eq(a.currentItem).addClass(n+"active-slide"),i?(e._slider=a,a.slides.each(function(){var e=this;e._gesture=new MSGesture,e._gesture.target=e,e.addEventListener("MSPointerDown",function(e){e.preventDefault(),e.currentTarget._gesture&&e.currentTarget._gesture.addPointer(e.pointerId)},!1),e.addEventListener("MSGestureTap",function(e){e.preventDefault();var t=$(this),n=t.index();$(a.vars.asNavFor).data("flexslider").animating||t.hasClass("active")||(a.direction=a.currentItem=s&&t.hasClass(n+"active-slide")?a.flexAnimate(a.getTarget("prev"),!0):$(a.vars.asNavFor).data("flexslider").animating||t.hasClass(n+"active-slide")||(a.direction=a.currentItem'),a.pagingCount>1)for(var l=0;l ':""+t+" ","thumbnails"===a.vars.controlNav&&!0===a.vars.thumbCaptions){var c=s.attr("data-thumbcaption");""!=c&&void 0!=c&&(i+=''+c+" ")}a.controlNavScaffold.append(""+i+" "),t++}a.controlsContainer?$(a.controlsContainer).append(a.controlNavScaffold):a.append(a.controlNavScaffold),m.controlNav.set(),m.controlNav.active(),a.controlNavScaffold.delegate("a, img",r,function(e){if(e.preventDefault(),""===o||o===e.type){var t=$(this),i=a.controlNav.index(t);t.hasClass(n+"active")||(a.direction=i>a.currentSlide?"next":"prev",a.flexAnimate(i,a.vars.pauseOnAction))}""===o&&(o=e.type),m.setToClearWatchedEvent()})},setupManual:function(){a.controlNav=a.manualControls,m.controlNav.active(),a.controlNav.bind(r,function(e){if(e.preventDefault(),""===o||o===e.type){var t=$(this),i=a.controlNav.index(t);t.hasClass(n+"active")||(a.direction=i>a.currentSlide?"next":"prev",a.flexAnimate(i,a.vars.pauseOnAction))}""===o&&(o=e.type),m.setToClearWatchedEvent()})},set:function(){var e="thumbnails"===a.vars.controlNav?"img":"a";a.controlNav=$("."+n+"control-nav li "+e,a.controlsContainer?a.controlsContainer:a)},active:function(){a.controlNav.removeClass(n+"active").eq(a.animatingTo).addClass(n+"active")},update:function(e,t){a.pagingCount>1&&"add"===e?a.controlNavScaffold.append($(""+a.count+" ")):1===a.pagingCount?a.controlNavScaffold.find("li").remove():a.controlNav.eq(t).closest("li").remove(),m.controlNav.set(),a.pagingCount>1&&a.pagingCount!==a.controlNav.length?a.update(t,e):m.controlNav.active()}},directionNav:{setup:function(){var e=$('");a.controlsContainer?($(a.controlsContainer).append(e),a.directionNav=$("."+n+"direction-nav li a",a.controlsContainer)):(a.append(e),a.directionNav=$("."+n+"direction-nav li a",a)),m.directionNav.update(),a.directionNav.bind(r,function(e){e.preventDefault();var t;(""===o||o===e.type)&&(t=a.getTarget($(this).hasClass(n+"next")?"next":"prev"),a.flexAnimate(t,a.vars.pauseOnAction)),""===o&&(o=e.type),m.setToClearWatchedEvent()})},update:function(){var e=n+"disabled";1===a.pagingCount?a.directionNav.addClass(e).attr("tabindex","-1"):a.vars.animationLoop?a.directionNav.removeClass(e).removeAttr("tabindex"):0===a.animatingTo?a.directionNav.removeClass(e).filter("."+n+"prev").addClass(e).attr("tabindex","-1"):a.animatingTo===a.last?a.directionNav.removeClass(e).filter("."+n+"next").addClass(e).attr("tabindex","-1"):a.directionNav.removeClass(e).removeAttr("tabindex")}},pausePlay:{setup:function(){var e=$('');a.controlsContainer?(a.controlsContainer.append(e),a.pausePlay=$("."+n+"pauseplay a",a.controlsContainer)):(a.append(e),a.pausePlay=$("."+n+"pauseplay a",a)),m.pausePlay.update(a.vars.slideshow?n+"pause":n+"play"),a.pausePlay.bind(r,function(e){e.preventDefault(),(""===o||o===e.type)&&($(this).hasClass(n+"pause")?(a.manualPause=!0,a.manualPlay=!1,a.pause()):(a.manualPause=!1,a.manualPlay=!0,a.play())),""===o&&(o=e.type),m.setToClearWatchedEvent()})},update:function(e){"play"===e?a.pausePlay.removeClass(n+"pause").addClass(n+"play").html(a.vars.playText):a.pausePlay.removeClass(n+"play").addClass(n+"pause").html(a.vars.pauseText)}},touch:function(){function t(t){a.animating?t.preventDefault():(window.navigator.msPointerEnabled||1===t.touches.length)&&(a.pause(),g=c?a.h:a.w,S=Number(new Date),x=t.touches[0].pageX,b=t.touches[0].pageY,f=u&&d&&a.animatingTo===a.last?0:u&&d?a.limit-(a.itemW+a.vars.itemMargin)*a.move*a.animatingTo:u&&a.currentSlide===a.last?a.limit:u?(a.itemW+a.vars.itemMargin)*a.move*a.currentSlide:d?(a.last-a.currentSlide+a.cloneOffset)*g:(a.currentSlide+a.cloneOffset)*g,p=c?b:x,m=c?x:b,e.addEventListener("touchmove",n,!1),e.addEventListener("touchend",s,!1))}function n(e){x=e.touches[0].pageX,b=e.touches[0].pageY,h=c?p-b:p-x,y=c?Math.abs(h)t)&&(e.preventDefault(),!v&&a.transitions&&(a.vars.animationLoop||(h/=0===a.currentSlide&&0>h||a.currentSlide===a.last&&h>0?Math.abs(h)/g+2:1),a.setProps(f+h,"setTouch")))}function s(t){if(e.removeEventListener("touchmove",n,!1),a.animatingTo===a.currentSlide&&!y&&null!==h){var i=d?-h:h,r=a.getTarget(i>0?"next":"prev");a.canAdvance(r)&&(Number(new Date)-S<550&&Math.abs(i)>50||Math.abs(i)>g/2)?a.flexAnimate(r,a.vars.pauseOnAction):v||a.flexAnimate(a.currentSlide,a.vars.pauseOnAction,!0)}e.removeEventListener("touchend",s,!1),p=null,m=null,h=null,f=null}function r(t){t.stopPropagation(),a.animating?t.preventDefault():(a.pause(),e._gesture.addPointer(t.pointerId),w=0,g=c?a.h:a.w,S=Number(new Date),f=u&&d&&a.animatingTo===a.last?0:u&&d?a.limit-(a.itemW+a.vars.itemMargin)*a.move*a.animatingTo:u&&a.currentSlide===a.last?a.limit:u?(a.itemW+a.vars.itemMargin)*a.move*a.currentSlide:d?(a.last-a.currentSlide+a.cloneOffset)*g:(a.currentSlide+a.cloneOffset)*g)}function o(t){t.stopPropagation();var a=t.target._slider;if(a){var n=-t.translationX,i=-t.translationY;return w+=c?i:n,h=w,y=c?Math.abs(w)500)&&(t.preventDefault(),!v&&a.transitions&&(a.vars.animationLoop||(h=w/(0===a.currentSlide&&0>w||a.currentSlide===a.last&&w>0?Math.abs(w)/g+2:1)),a.setProps(f+h,"setTouch"))))}}function l(e){e.stopPropagation();var t=e.target._slider;if(t){if(t.animatingTo===t.currentSlide&&!y&&null!==h){var a=d?-h:h,n=t.getTarget(a>0?"next":"prev");t.canAdvance(n)&&(Number(new Date)-S<550&&Math.abs(a)>50||Math.abs(a)>g/2)?t.flexAnimate(n,t.vars.pauseOnAction):v||t.flexAnimate(t.currentSlide,t.vars.pauseOnAction,!0)}p=null,m=null,h=null,f=null,w=0}}var p,m,f,g,h,S,y=!1,x=0,b=0,w=0;i?(e.style.msTouchAction="none",e._gesture=new MSGesture,e._gesture.target=e,e.addEventListener("MSPointerDown",r,!1),e._slider=a,e.addEventListener("MSGestureChange",o,!1),e.addEventListener("MSGestureEnd",l,!1)):e.addEventListener("touchstart",t,!1)},resize:function(){!a.animating&&a.is(":visible")&&(u||a.doMath(),v?m.smoothHeight():u?(a.slides.width(a.computedW),a.update(a.pagingCount),a.setProps()):c?(a.viewport.height(a.h),a.setProps(a.h,"setTotal")):(a.vars.smoothHeight&&m.smoothHeight(),a.newSlides.width(a.computedW),a.setProps(a.computedW,"setTotal")))},smoothHeight:function(e){if(!c||v){var t=v?a:a.viewport;e?t.animate({height:a.slides.eq(a.animatingTo).height()},e):t.height(a.slides.eq(a.animatingTo).height())}},sync:function(e){var t=$(a.vars.sync).data("flexslider"),n=a.animatingTo;switch(e){case"animate":t.flexAnimate(n,a.vars.pauseOnAction,!1,!0);break;case"play":t.playing||t.asNav||t.play();break;case"pause":t.pause()}},uniqueID:function(e){return e.filter("[id]").add(e.find("[id]")).each(function(){var e=$(this);e.attr("id",e.attr("id")+"_clone")}),e},pauseInvisible:{visProp:null,init:function(){var e=m.pauseInvisible.getHiddenProp();if(e){var t=e.replace(/[H|h]idden/,"")+"visibilitychange";document.addEventListener(t,function(){m.pauseInvisible.isHidden()?a.startTimeout?clearTimeout(a.startTimeout):a.pause():a.started?a.play():a.vars.initDelay>0?setTimeout(a.play,a.vars.initDelay):a.play()})}},isHidden:function(){var e=m.pauseInvisible.getHiddenProp();return e?document[e]:!1},getHiddenProp:function(){var e=["webkit","moz","ms","o"];if("hidden"in document)return"hidden";for(var t=0;ta.currentSlide?"next":"prev"),p&&1===a.pagingCount&&(a.direction=a.currentItema.limit&&1!==a.visible?a.limit:S):h=0===a.currentSlide&&e===a.count-1&&a.vars.animationLoop&&"next"!==a.direction?d?(a.count+a.cloneOffset)*f:0:a.currentSlide===a.last&&0===e&&a.vars.animationLoop&&"prev"!==a.direction?d?0:(a.count+1)*f:d?(a.count-1-e+a.cloneOffset)*f:(e+a.cloneOffset)*f,a.setProps(h,"",a.vars.animationSpeed),a.transitions?(a.vars.animationLoop&&a.atEnd||(a.animating=!1,a.currentSlide=a.animatingTo),a.container.unbind("webkitTransitionEnd transitionend"),a.container.bind("webkitTransitionEnd transitionend",function(){clearTimeout(a.ensureAnimationEnd),a.wrapup(f)}),clearTimeout(a.ensureAnimationEnd),a.ensureAnimationEnd=setTimeout(function(){a.wrapup(f)},a.vars.animationSpeed+100)):a.container.animate(a.args,a.vars.animationSpeed,a.vars.easing,function(){a.wrapup(f)})}a.vars.smoothHeight&&m.smoothHeight(a.vars.animationSpeed)}},a.wrapup=function(e){v||u||(0===a.currentSlide&&a.animatingTo===a.last&&a.vars.animationLoop?a.setProps(e,"jumpEnd"):a.currentSlide===a.last&&0===a.animatingTo&&a.vars.animationLoop&&a.setProps(e,"jumpStart")),a.animating=!1,a.currentSlide=a.animatingTo,a.vars.after(a)},a.animateSlides=function(){!a.animating&&f&&a.flexAnimate(a.getTarget("next"))},a.pause=function(){clearInterval(a.animatedSlides),a.animatedSlides=null,a.playing=!1,a.vars.pausePlay&&m.pausePlay.update("play"),a.syncExists&&m.sync("pause")},a.play=function(){a.playing&&clearInterval(a.animatedSlides),a.animatedSlides=a.animatedSlides||setInterval(a.animateSlides,a.vars.slideshowSpeed),a.started=a.playing=!0,a.vars.pausePlay&&m.pausePlay.update("pause"),a.syncExists&&m.sync("play")},a.stop=function(){a.pause(),a.stopped=!0},a.canAdvance=function(e,t){var n=p?a.pagingCount-1:a.last;return t?!0:p&&a.currentItem===a.count-1&&0===e&&"prev"===a.direction?!0:p&&0===a.currentItem&&e===a.pagingCount-1&&"next"!==a.direction?!1:e!==a.currentSlide||p?a.vars.animationLoop?!0:a.atEnd&&0===a.currentSlide&&e===n&&"next"!==a.direction?!1:a.atEnd&&a.currentSlide===n&&0===e&&"next"===a.direction?!1:!0:!1},a.getTarget=function(e){return a.direction=e,"next"===e?a.currentSlide===a.last?0:a.currentSlide+1:0===a.currentSlide?a.last:a.currentSlide-1},a.setProps=function(e,t,n){var i=function(){var n=e?e:(a.itemW+a.vars.itemMargin)*a.move*a.animatingTo,i=function(){if(u)return"setTouch"===t?e:d&&a.animatingTo===a.last?0:d?a.limit-(a.itemW+a.vars.itemMargin)*a.move*a.animatingTo:a.animatingTo===a.last?a.limit:n;switch(t){case"setTotal":return d?(a.count-1-a.currentSlide+a.cloneOffset)*e:(a.currentSlide+a.cloneOffset)*e;case"setTouch":return d?e:e;case"jumpEnd":return d?e:a.count*e;case"jumpStart":return d?a.count*e:e;default:return e}}();return-1*i+"px"}();a.transitions&&(i=c?"translate3d(0,"+i+",0)":"translate3d("+i+",0,0)",n=void 0!==n?n/1e3+"s":"0s",a.container.css("-"+a.pfx+"-transition-duration",n),a.container.css("transition-duration",n)),a.args[a.prop]=i,(a.transitions||void 0===n)&&a.container.css(a.args),a.container.css("transform",i)},a.setup=function(e){if(v)a.slides.css({width:"100%","float":"left",marginRight:"-100%",position:"relative"}),"init"===e&&(s?a.slides.css({opacity:0,display:"block",webkitTransition:"opacity "+a.vars.animationSpeed/1e3+"s ease",zIndex:1}).eq(a.currentSlide).css({opacity:1,zIndex:2}):0==a.vars.fadeFirstSlide?a.slides.css({opacity:0,display:"block",zIndex:1}).eq(a.currentSlide).css({zIndex:2}).css({opacity:1}):a.slides.css({opacity:0,display:"block",zIndex:1}).eq(a.currentSlide).css({zIndex:2}).animate({opacity:1},a.vars.animationSpeed,a.vars.easing)),a.vars.smoothHeight&&m.smoothHeight();else{var t,i;"init"===e&&(a.viewport=$('
').css({overflow:"hidden",position:"relative"}).appendTo(a).append(a.container),a.cloneCount=0,a.cloneOffset=0,d&&(i=$.makeArray(a.slides).reverse(),a.slides=$(i),a.container.empty().append(a.slides))),a.vars.animationLoop&&!u&&(a.cloneCount=2,a.cloneOffset=1,"init"!==e&&a.container.find(".clone").remove(),a.container.append(m.uniqueID(a.slides.first().clone().addClass("clone")).attr("aria-hidden","true")).prepend(m.uniqueID(a.slides.last().clone().addClass("clone")).attr("aria-hidden","true"))),a.newSlides=$(a.vars.selector,a),t=d?a.count-1-a.currentSlide+a.cloneOffset:a.currentSlide+a.cloneOffset,c&&!u?(a.container.height(200*(a.count+a.cloneCount)+"%").css("position","absolute").width("100%"),setTimeout(function(){a.newSlides.css({display:"block"}),a.doMath(),a.viewport.height(a.h),a.setProps(t*a.h,"init")},"init"===e?100:0)):(a.container.width(200*(a.count+a.cloneCount)+"%"),a.setProps(t*a.computedW,"init"),setTimeout(function(){a.doMath(),a.newSlides.css({width:a.computedW,"float":"left",display:"block"}),a.vars.smoothHeight&&m.smoothHeight()},"init"===e?100:0))}u||a.slides.removeClass(n+"active-slide").eq(a.currentSlide).addClass(n+"active-slide"),a.vars.init(a)},a.doMath=function(){var e=a.slides.first(),t=a.vars.itemMargin,n=a.vars.minItems,i=a.vars.maxItems;a.w=void 0===a.viewport?a.width():a.viewport.width(),a.h=e.height(),a.boxPadding=e.outerWidth()-e.width(),u?(a.itemT=a.vars.itemWidth+t,a.minW=n?n*a.itemT:a.w,a.maxW=i?i*a.itemT-t:a.w,a.itemW=a.minW>a.w?(a.w-t*(n-1))/n:a.maxWa.w?a.w:a.vars.itemWidth,a.visible=Math.floor(a.w/a.itemW),a.move=a.vars.move>0&&a.vars.movea.w?a.itemW*(a.count-1)+t*(a.count-1):(a.itemW+t)*a.count-a.w-t):(a.itemW=a.w,a.pagingCount=a.count,a.last=a.count-1),a.computedW=a.itemW-a.boxPadding},a.update=function(e,t){a.doMath(),u||(ea.controlNav.length?m.controlNav.update("add"):("remove"===t&&!u||a.pagingCounta.last&&(a.currentSlide-=1,a.animatingTo-=1),m.controlNav.update("remove",a.last))),a.vars.directionNav&&m.directionNav.update()},a.addSlide=function(e,t){var n=$(e);a.count+=1,a.last=a.count-1,c&&d?void 0!==t?a.slides.eq(a.count-t).after(n):a.container.prepend(n):void 0!==t?a.slides.eq(t).before(n):a.container.append(n),a.update(t,"add"),a.slides=$(a.vars.selector+":not(.clone)",a),a.setup(),a.vars.added(a)},a.removeSlide=function(e){var t=isNaN(e)?a.slides.index($(e)):e;a.count-=1,a.last=a.count-1,isNaN(e)?$(e,a.slides).remove():c&&d?a.slides.eq(a.last).remove():a.slides.eq(e).remove(),a.doMath(),a.update(t,"remove"),a.slides=$(a.vars.selector+":not(.clone)",a),a.setup(),a.vars.removed(a)},m.init()},$(window).blur(function(e){focused=!1}).focus(function(e){focused=!0}),$.flexslider.defaults={namespace:"flex-",selector:".slides > li",animation:"fade",easing:"swing",direction:"horizontal",reverse:!1,animationLoop:!0,smoothHeight:!1,startAt:0,slideshow:!0,slideshowSpeed:7e3,animationSpeed:600,initDelay:0,randomize:!1,fadeFirstSlide:!0,thumbCaptions:!1,pauseOnAction:!0,pauseOnHover:!1,pauseInvisible:!0,useCSS:!0,touch:!0,video:!1,controlNav:!0,directionNav:!0,prevText:"Previous",nextText:"Next",keyboard:!0,multipleKeyboard:!1,mousewheel:!1,pausePlay:!1,pauseText:"Pause",playText:"Play",controlsContainer:"",manualControls:"",sync:"",asNavFor:"",itemWidth:0,itemMargin:0,minItems:1,maxItems:0,move:0,allowOneSlide:!0,start:function(){},before:function(){},after:function(){},end:function(){},added:function(){},removed:function(){},init:function(){}},$.fn.flexslider=function(e){if(void 0===e&&(e={}),"object"==typeof e)return this.each(function(){var t=$(this),a=e.selector?e.selector:".slides > li",n=t.find(a);1===n.length&&e.allowOneSlide===!0||0===n.length?(n.fadeIn(400),e.start&&e.start(t)):void 0===t.data("flexslider")&&new $.flexslider(this,e)});var t=$(this).data("flexslider");switch(e){case"play":t.play();break;case"pause":t.pause();break;case"stop":t.stop();break;case"next":t.flexAnimate(t.getTarget("next"),!0);break;case"prev":case"previous":t.flexAnimate(t.getTarget("prev"),!0);break;default:"number"==typeof e&&t.flexAnimate(e,!0)}}}(jQuery);
--------------------------------------------------------------------------------
/public/js/lightbox.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Lightbox v2.7.1
3 | * by Lokesh Dhakar - http://lokeshdhakar.com/projects/lightbox2/
4 | *
5 | * @license http://creativecommons.org/licenses/by/2.5/
6 | * - Free for use in both personal and commercial projects
7 | * - Attribution requires leaving author name, author link, and the license info intact
8 | */
9 | (function(){var a=jQuery,b=function(){function a(){this.fadeDuration=500,this.fitImagesInViewport=!0,this.resizeDuration=700,this.positionFromTop=50,this.showImageNumberLabel=!0,this.alwaysShowNavOnTouchDevices=!1,this.wrapAround=!1}return a.prototype.albumLabel=function(a,b){return"Image "+a+" of "+b},a}(),c=function(){function b(a){this.options=a,this.album=[],this.currentImageIndex=void 0,this.init()}return b.prototype.init=function(){this.enable(),this.build()},b.prototype.enable=function(){var b=this;a("body").on("click","a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]",function(c){return b.start(a(c.currentTarget)),!1})},b.prototype.build=function(){var b=this;a("
").appendTo(a("body")),this.$lightbox=a("#lightbox"),this.$overlay=a("#lightboxOverlay"),this.$outerContainer=this.$lightbox.find(".lb-outerContainer"),this.$container=this.$lightbox.find(".lb-container"),this.containerTopPadding=parseInt(this.$container.css("padding-top"),10),this.containerRightPadding=parseInt(this.$container.css("padding-right"),10),this.containerBottomPadding=parseInt(this.$container.css("padding-bottom"),10),this.containerLeftPadding=parseInt(this.$container.css("padding-left"),10),this.$overlay.hide().on("click",function(){return b.end(),!1}),this.$lightbox.hide().on("click",function(c){return"lightbox"===a(c.target).attr("id")&&b.end(),!1}),this.$outerContainer.on("click",function(c){return"lightbox"===a(c.target).attr("id")&&b.end(),!1}),this.$lightbox.find(".lb-prev").on("click",function(){return b.changeImage(0===b.currentImageIndex?b.album.length-1:b.currentImageIndex-1),!1}),this.$lightbox.find(".lb-next").on("click",function(){return b.changeImage(b.currentImageIndex===b.album.length-1?0:b.currentImageIndex+1),!1}),this.$lightbox.find(".lb-loader, .lb-close").on("click",function(){return b.end(),!1})},b.prototype.start=function(b){function c(a){d.album.push({link:a.attr("href"),title:a.attr("data-title")||a.attr("title")})}var d=this,e=a(window);e.on("resize",a.proxy(this.sizeOverlay,this)),a("select, object, embed").css({visibility:"hidden"}),this.sizeOverlay(),this.album=[];var f,g=0,h=b.attr("data-lightbox");if(h){f=a(b.prop("tagName")+'[data-lightbox="'+h+'"]');for(var i=0;ij||e.height>i)&&(e.width/j>e.height/i?(h=j,g=parseInt(e.height/(e.width/h),10),d.width(h),d.height(g)):(g=i,h=parseInt(e.width/(e.height/g),10),d.width(h),d.height(g)))),c.sizeContainer(d.width(),d.height())},e.src=this.album[b].link,this.currentImageIndex=b},b.prototype.sizeOverlay=function(){this.$overlay.width(a(window).width()).height(a(document).height())},b.prototype.sizeContainer=function(a,b){function c(){d.$lightbox.find(".lb-dataContainer").width(g),d.$lightbox.find(".lb-prevLink").height(h),d.$lightbox.find(".lb-nextLink").height(h),d.showImage()}var d=this,e=this.$outerContainer.outerWidth(),f=this.$outerContainer.outerHeight(),g=a+this.containerLeftPadding+this.containerRightPadding,h=b+this.containerTopPadding+this.containerBottomPadding;e!==g||f!==h?this.$outerContainer.animate({width:g,height:h},this.options.resizeDuration,"swing",function(){c()}):c()},b.prototype.showImage=function(){this.$lightbox.find(".lb-loader").hide(),this.$lightbox.find(".lb-image").fadeIn("slow"),this.updateNav(),this.updateDetails(),this.preloadNeighboringImages(),this.enableKeyboardNav()},b.prototype.updateNav=function(){var a=!1;try{document.createEvent("TouchEvent"),a=this.options.alwaysShowNavOnTouchDevices?!0:!1}catch(b){}this.$lightbox.find(".lb-nav").show(),this.album.length>1&&(this.options.wrapAround?(a&&this.$lightbox.find(".lb-prev, .lb-next").css("opacity","1"),this.$lightbox.find(".lb-prev, .lb-next").show()):(this.currentImageIndex>0&&(this.$lightbox.find(".lb-prev").show(),a&&this.$lightbox.find(".lb-prev").css("opacity","1")),this.currentImageIndex1&&this.options.showImageNumberLabel?this.$lightbox.find(".lb-number").text(this.options.albumLabel(this.currentImageIndex+1,this.album.length)).fadeIn("fast"):this.$lightbox.find(".lb-number").hide(),this.$outerContainer.removeClass("animating"),this.$lightbox.find(".lb-dataContainer").fadeIn(this.options.resizeDuration,function(){return b.sizeOverlay()})},b.prototype.preloadNeighboringImages=function(){if(this.album.length>this.currentImageIndex+1){var a=new Image;a.src=this.album[this.currentImageIndex+1].link}if(this.currentImageIndex>0){var b=new Image;b.src=this.album[this.currentImageIndex-1].link}},b.prototype.enableKeyboardNav=function(){a(document).on("keyup.keyboard",a.proxy(this.keyboardAction,this))},b.prototype.disableKeyboardNav=function(){a(document).off(".keyboard")},b.prototype.keyboardAction=function(a){var b=27,c=37,d=39,e=a.keyCode,f=String.fromCharCode(e).toLowerCase();e===b||f.match(/x|o|c/)?this.end():"p"===f||e===c?0!==this.currentImageIndex?this.changeImage(this.currentImageIndex-1):this.options.wrapAround&&this.album.length>1&&this.changeImage(this.album.length-1):("n"===f||e===d)&&(this.currentImageIndex!==this.album.length-1?this.changeImage(this.currentImageIndex+1):this.options.wrapAround&&this.album.length>1&&this.changeImage(0))},b.prototype.end=function(){this.disableKeyboardNav(),a(window).off("resize",this.sizeOverlay),this.$lightbox.fadeOut(this.options.fadeDuration),this.$overlay.fadeOut(this.options.fadeDuration),a("select, object, embed").css({visibility:"visible"})},b}();a(function(){{var a=new b;new c(a)}})}).call(this);
10 |
--------------------------------------------------------------------------------
/public/js/masonry.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Masonry PACKAGED v3.2.2
3 | * Cascading grid layout library
4 | * http://masonry.desandro.com
5 | * MIT License
6 | * by David DeSandro
7 | */
8 |
9 | !function(a){function b(){}function c(a){function c(b){b.prototype.option||(b.prototype.option=function(b){a.isPlainObject(b)&&(this.options=a.extend(!0,this.options,b))})}function e(b,c){a.fn[b]=function(e){if("string"==typeof e){for(var g=d.call(arguments,1),h=0,i=this.length;i>h;h++){var j=this[h],k=a.data(j,b);if(k)if(a.isFunction(k[e])&&"_"!==e.charAt(0)){var l=k[e].apply(k,g);if(void 0!==l)return l}else f("no such method '"+e+"' for "+b+" instance");else f("cannot call methods on "+b+" prior to initialization; attempted to call '"+e+"'")}return this}return this.each(function(){var d=a.data(this,b);d?(d.option(e),d._init()):(d=new c(this,e),a.data(this,b,d))})}}if(a){var f="undefined"==typeof console?b:function(a){console.error(a)};return a.bridget=function(a,b){c(b),e(a,b)},a.bridget}}var d=Array.prototype.slice;"function"==typeof define&&define.amd?define("jquery-bridget/jquery.bridget",["jquery"],c):c("object"==typeof exports?require("jquery"):a.jQuery)}(window),function(a){function b(b){var c=a.event;return c.target=c.target||c.srcElement||b,c}var c=document.documentElement,d=function(){};c.addEventListener?d=function(a,b,c){a.addEventListener(b,c,!1)}:c.attachEvent&&(d=function(a,c,d){a[c+d]=d.handleEvent?function(){var c=b(a);d.handleEvent.call(d,c)}:function(){var c=b(a);d.call(a,c)},a.attachEvent("on"+c,a[c+d])});var e=function(){};c.removeEventListener?e=function(a,b,c){a.removeEventListener(b,c,!1)}:c.detachEvent&&(e=function(a,b,c){a.detachEvent("on"+b,a[b+c]);try{delete a[b+c]}catch(d){a[b+c]=void 0}});var f={bind:d,unbind:e};"function"==typeof define&&define.amd?define("eventie/eventie",f):"object"==typeof exports?module.exports=f:a.eventie=f}(this),function(a){function b(a){"function"==typeof a&&(b.isReady?a():g.push(a))}function c(a){var c="readystatechange"===a.type&&"complete"!==f.readyState;b.isReady||c||d()}function d(){b.isReady=!0;for(var a=0,c=g.length;c>a;a++){var d=g[a];d()}}function e(e){return"complete"===f.readyState?d():(e.bind(f,"DOMContentLoaded",c),e.bind(f,"readystatechange",c),e.bind(a,"load",c)),b}var f=a.document,g=[];b.isReady=!1,"function"==typeof define&&define.amd?define("doc-ready/doc-ready",["eventie/eventie"],e):"object"==typeof exports?module.exports=e(require("eventie")):a.docReady=e(a.eventie)}(window),function(){function a(){}function b(a,b){for(var c=a.length;c--;)if(a[c].listener===b)return c;return-1}function c(a){return function(){return this[a].apply(this,arguments)}}var d=a.prototype,e=this,f=e.EventEmitter;d.getListeners=function(a){var b,c,d=this._getEvents();if(a instanceof RegExp){b={};for(c in d)d.hasOwnProperty(c)&&a.test(c)&&(b[c]=d[c])}else b=d[a]||(d[a]=[]);return b},d.flattenListeners=function(a){var b,c=[];for(b=0;be;e++)if(b=c[e]+a,"string"==typeof d[b])return b}}var c="Webkit Moz ms Ms O".split(" "),d=document.documentElement.style;"function"==typeof define&&define.amd?define("get-style-property/get-style-property",[],function(){return b}):"object"==typeof exports?module.exports=b:a.getStyleProperty=b}(window),function(a){function b(a){var b=parseFloat(a),c=-1===a.indexOf("%")&&!isNaN(b);return c&&b}function c(){}function d(){for(var a={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},b=0,c=g.length;c>b;b++){var d=g[b];a[d]=0}return a}function e(c){function e(){if(!m){m=!0;var d=a.getComputedStyle;if(j=function(){var a=d?function(a){return d(a,null)}:function(a){return a.currentStyle};return function(b){var c=a(b);return c||f("Style returned "+c+". Are you running this code in a hidden iframe on Firefox? See http://bit.ly/getsizebug1"),c}}(),k=c("boxSizing")){var e=document.createElement("div");e.style.width="200px",e.style.padding="1px 2px 3px 4px",e.style.borderStyle="solid",e.style.borderWidth="1px 2px 3px 4px",e.style[k]="border-box";var g=document.body||document.documentElement;g.appendChild(e);var h=j(e);l=200===b(h.width),g.removeChild(e)}}}function h(a){if(e(),"string"==typeof a&&(a=document.querySelector(a)),a&&"object"==typeof a&&a.nodeType){var c=j(a);if("none"===c.display)return d();var f={};f.width=a.offsetWidth,f.height=a.offsetHeight;for(var h=f.isBorderBox=!(!k||!c[k]||"border-box"!==c[k]),m=0,n=g.length;n>m;m++){var o=g[m],p=c[o];p=i(a,p);var q=parseFloat(p);f[o]=isNaN(q)?0:q}var r=f.paddingLeft+f.paddingRight,s=f.paddingTop+f.paddingBottom,t=f.marginLeft+f.marginRight,u=f.marginTop+f.marginBottom,v=f.borderLeftWidth+f.borderRightWidth,w=f.borderTopWidth+f.borderBottomWidth,x=h&&l,y=b(c.width);y!==!1&&(f.width=y+(x?0:r+v));var z=b(c.height);return z!==!1&&(f.height=z+(x?0:s+w)),f.innerWidth=f.width-(r+v),f.innerHeight=f.height-(s+w),f.outerWidth=f.width+t,f.outerHeight=f.height+u,f}}function i(b,c){if(a.getComputedStyle||-1===c.indexOf("%"))return c;var d=b.style,e=d.left,f=b.runtimeStyle,g=f&&f.left;return g&&(f.left=b.currentStyle.left),d.left=c,c=d.pixelLeft,d.left=e,g&&(f.left=g),c}var j,k,l,m=!1;return h}var f="undefined"==typeof console?c:function(a){console.error(a)},g=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"];"function"==typeof define&&define.amd?define("get-size/get-size",["get-style-property/get-style-property"],e):"object"==typeof exports?module.exports=e(require("desandro-get-style-property")):a.getSize=e(a.getStyleProperty)}(window),function(a){function b(a,b){return a[g](b)}function c(a){if(!a.parentNode){var b=document.createDocumentFragment();b.appendChild(a)}}function d(a,b){c(a);for(var d=a.parentNode.querySelectorAll(b),e=0,f=d.length;f>e;e++)if(d[e]===a)return!0;return!1}function e(a,d){return c(a),b(a,d)}var f,g=function(){if(a.matchesSelector)return"matchesSelector";for(var b=["webkit","moz","ms","o"],c=0,d=b.length;d>c;c++){var e=b[c],f=e+"MatchesSelector";if(a[f])return f}}();if(g){var h=document.createElement("div"),i=b(h,"div");f=i?b:e}else f=d;"function"==typeof define&&define.amd?define("matches-selector/matches-selector",[],function(){return f}):"object"==typeof exports?module.exports=f:window.matchesSelector=f}(Element.prototype),function(a){function b(a,b){for(var c in b)a[c]=b[c];return a}function c(a){for(var b in a)return!1;return b=null,!0}function d(a){return a.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()})}function e(a,e,f){function h(a,b){a&&(this.element=a,this.layout=b,this.position={x:0,y:0},this._create())}var i=f("transition"),j=f("transform"),k=i&&j,l=!!f("perspective"),m={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"otransitionend",transition:"transitionend"}[i],n=["transform","transition","transitionDuration","transitionProperty"],o=function(){for(var a={},b=0,c=n.length;c>b;b++){var d=n[b],e=f(d);e&&e!==d&&(a[d]=e)}return a}();b(h.prototype,a.prototype),h.prototype._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},h.prototype.handleEvent=function(a){var b="on"+a.type;this[b]&&this[b](a)},h.prototype.getSize=function(){this.size=e(this.element)},h.prototype.css=function(a){var b=this.element.style;for(var c in a){var d=o[c]||c;b[d]=a[c]}},h.prototype.getPosition=function(){var a=g(this.element),b=this.layout.options,c=b.isOriginLeft,d=b.isOriginTop,e=parseInt(a[c?"left":"right"],10),f=parseInt(a[d?"top":"bottom"],10);e=isNaN(e)?0:e,f=isNaN(f)?0:f;var h=this.layout.size;e-=c?h.paddingLeft:h.paddingRight,f-=d?h.paddingTop:h.paddingBottom,this.position.x=e,this.position.y=f},h.prototype.layoutPosition=function(){var a=this.layout.size,b=this.layout.options,c={};b.isOriginLeft?(c.left=this.position.x+a.paddingLeft+"px",c.right=""):(c.right=this.position.x+a.paddingRight+"px",c.left=""),b.isOriginTop?(c.top=this.position.y+a.paddingTop+"px",c.bottom=""):(c.bottom=this.position.y+a.paddingBottom+"px",c.top=""),this.css(c),this.emitEvent("layout",[this])};var p=l?function(a,b){return"translate3d("+a+"px, "+b+"px, 0)"}:function(a,b){return"translate("+a+"px, "+b+"px)"};h.prototype._transitionTo=function(a,b){this.getPosition();var c=this.position.x,d=this.position.y,e=parseInt(a,10),f=parseInt(b,10),g=e===this.position.x&&f===this.position.y;if(this.setPosition(a,b),g&&!this.isTransitioning)return void this.layoutPosition();var h=a-c,i=b-d,j={},k=this.layout.options;h=k.isOriginLeft?h:-h,i=k.isOriginTop?i:-i,j.transform=p(h,i),this.transition({to:j,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},h.prototype.goTo=function(a,b){this.setPosition(a,b),this.layoutPosition()},h.prototype.moveTo=k?h.prototype._transitionTo:h.prototype.goTo,h.prototype.setPosition=function(a,b){this.position.x=parseInt(a,10),this.position.y=parseInt(b,10)},h.prototype._nonTransition=function(a){this.css(a.to),a.isCleaning&&this._removeStyles(a.to);for(var b in a.onTransitionEnd)a.onTransitionEnd[b].call(this)},h.prototype._transition=function(a){if(!parseFloat(this.layout.options.transitionDuration))return void this._nonTransition(a);var b=this._transn;for(var c in a.onTransitionEnd)b.onEnd[c]=a.onTransitionEnd[c];for(c in a.to)b.ingProperties[c]=!0,a.isCleaning&&(b.clean[c]=!0);if(a.from){this.css(a.from);var d=this.element.offsetHeight;d=null}this.enableTransition(a.to),this.css(a.to),this.isTransitioning=!0};var q=j&&d(j)+",opacity";h.prototype.enableTransition=function(){this.isTransitioning||(this.css({transitionProperty:q,transitionDuration:this.layout.options.transitionDuration}),this.element.addEventListener(m,this,!1))},h.prototype.transition=h.prototype[i?"_transition":"_nonTransition"],h.prototype.onwebkitTransitionEnd=function(a){this.ontransitionend(a)},h.prototype.onotransitionend=function(a){this.ontransitionend(a)};var r={"-webkit-transform":"transform","-moz-transform":"transform","-o-transform":"transform"};h.prototype.ontransitionend=function(a){if(a.target===this.element){var b=this._transn,d=r[a.propertyName]||a.propertyName;if(delete b.ingProperties[d],c(b.ingProperties)&&this.disableTransition(),d in b.clean&&(this.element.style[a.propertyName]="",delete b.clean[d]),d in b.onEnd){var e=b.onEnd[d];e.call(this),delete b.onEnd[d]}this.emitEvent("transitionEnd",[this])}},h.prototype.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(m,this,!1),this.isTransitioning=!1},h.prototype._removeStyles=function(a){var b={};for(var c in a)b[c]="";this.css(b)};var s={transitionProperty:"",transitionDuration:""};return h.prototype.removeTransitionStyles=function(){this.css(s)},h.prototype.removeElem=function(){this.element.parentNode.removeChild(this.element),this.emitEvent("remove",[this])},h.prototype.remove=function(){if(!i||!parseFloat(this.layout.options.transitionDuration))return void this.removeElem();var a=this;this.on("transitionEnd",function(){return a.removeElem(),!0}),this.hide()},h.prototype.reveal=function(){delete this.isHidden,this.css({display:""});var a=this.layout.options;this.transition({from:a.hiddenStyle,to:a.visibleStyle,isCleaning:!0})},h.prototype.hide=function(){this.isHidden=!0,this.css({display:""});var a=this.layout.options;this.transition({from:a.visibleStyle,to:a.hiddenStyle,isCleaning:!0,onTransitionEnd:{opacity:function(){this.isHidden&&this.css({display:"none"})}}})},h.prototype.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},h}var f=a.getComputedStyle,g=f?function(a){return f(a,null)}:function(a){return a.currentStyle};"function"==typeof define&&define.amd?define("outlayer/item",["eventEmitter/EventEmitter","get-size/get-size","get-style-property/get-style-property"],e):"object"==typeof exports?module.exports=e(require("wolfy87-eventemitter"),require("get-size"),require("desandro-get-style-property")):(a.Outlayer={},a.Outlayer.Item=e(a.EventEmitter,a.getSize,a.getStyleProperty))}(window),function(a){function b(a,b){for(var c in b)a[c]=b[c];return a}function c(a){return"[object Array]"===l.call(a)}function d(a){var b=[];if(c(a))b=a;else if(a&&"number"==typeof a.length)for(var d=0,e=a.length;e>d;d++)b.push(a[d]);else b.push(a);return b}function e(a,b){var c=n(b,a);-1!==c&&b.splice(c,1)}function f(a){return a.replace(/(.)([A-Z])/g,function(a,b,c){return b+"-"+c}).toLowerCase()}function g(c,g,l,n,o,p){function q(a,c){if("string"==typeof a&&(a=h.querySelector(a)),!a||!m(a))return void(i&&i.error("Bad "+this.constructor.namespace+" element: "+a));this.element=a,this.options=b({},this.constructor.defaults),this.option(c);var d=++r;this.element.outlayerGUID=d,s[d]=this,this._create(),this.options.isInitLayout&&this.layout()}var r=0,s={};return q.namespace="outlayer",q.Item=p,q.defaults={containerStyle:{position:"relative"},isInitLayout:!0,isOriginLeft:!0,isOriginTop:!0,isResizeBound:!0,isResizingContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}},b(q.prototype,l.prototype),q.prototype.option=function(a){b(this.options,a)},q.prototype._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),b(this.element.style,this.options.containerStyle),this.options.isResizeBound&&this.bindResize()},q.prototype.reloadItems=function(){this.items=this._itemize(this.element.children)},q.prototype._itemize=function(a){for(var b=this._filterFindItemElements(a),c=this.constructor.Item,d=[],e=0,f=b.length;f>e;e++){var g=b[e],h=new c(g,this);d.push(h)}return d},q.prototype._filterFindItemElements=function(a){a=d(a);for(var b=this.options.itemSelector,c=[],e=0,f=a.length;f>e;e++){var g=a[e];if(m(g))if(b){o(g,b)&&c.push(g);for(var h=g.querySelectorAll(b),i=0,j=h.length;j>i;i++)c.push(h[i])}else c.push(g)}return c},q.prototype.getItemElements=function(){for(var a=[],b=0,c=this.items.length;c>b;b++)a.push(this.items[b].element);return a},q.prototype.layout=function(){this._resetLayout(),this._manageStamps();var a=void 0!==this.options.isLayoutInstant?this.options.isLayoutInstant:!this._isLayoutInited;this.layoutItems(this.items,a),this._isLayoutInited=!0},q.prototype._init=q.prototype.layout,q.prototype._resetLayout=function(){this.getSize()},q.prototype.getSize=function(){this.size=n(this.element)},q.prototype._getMeasurement=function(a,b){var c,d=this.options[a];d?("string"==typeof d?c=this.element.querySelector(d):m(d)&&(c=d),this[a]=c?n(c)[b]:d):this[a]=0},q.prototype.layoutItems=function(a,b){a=this._getItemsForLayout(a),this._layoutItems(a,b),this._postLayout()},q.prototype._getItemsForLayout=function(a){for(var b=[],c=0,d=a.length;d>c;c++){var e=a[c];e.isIgnored||b.push(e)}return b},q.prototype._layoutItems=function(a,b){function c(){d.emitEvent("layoutComplete",[d,a])}var d=this;if(!a||!a.length)return void c();this._itemsOn(a,"layout",c);for(var e=[],f=0,g=a.length;g>f;f++){var h=a[f],i=this._getItemLayoutPosition(h);i.item=h,i.isInstant=b||h.isLayoutInstant,e.push(i)}this._processLayoutQueue(e)},q.prototype._getItemLayoutPosition=function(){return{x:0,y:0}},q.prototype._processLayoutQueue=function(a){for(var b=0,c=a.length;c>b;b++){var d=a[b];this._positionItem(d.item,d.x,d.y,d.isInstant)}},q.prototype._positionItem=function(a,b,c,d){d?a.goTo(b,c):a.moveTo(b,c)},q.prototype._postLayout=function(){this.resizeContainer()},q.prototype.resizeContainer=function(){if(this.options.isResizingContainer){var a=this._getContainerSize();a&&(this._setContainerMeasure(a.width,!0),this._setContainerMeasure(a.height,!1))}},q.prototype._getContainerSize=k,q.prototype._setContainerMeasure=function(a,b){if(void 0!==a){var c=this.size;c.isBorderBox&&(a+=b?c.paddingLeft+c.paddingRight+c.borderLeftWidth+c.borderRightWidth:c.paddingBottom+c.paddingTop+c.borderTopWidth+c.borderBottomWidth),a=Math.max(a,0),this.element.style[b?"width":"height"]=a+"px"}},q.prototype._itemsOn=function(a,b,c){function d(){return e++,e===f&&c.call(g),!0}for(var e=0,f=a.length,g=this,h=0,i=a.length;i>h;h++){var j=a[h];j.on(b,d)}},q.prototype.ignore=function(a){var b=this.getItem(a);b&&(b.isIgnored=!0)},q.prototype.unignore=function(a){var b=this.getItem(a);b&&delete b.isIgnored},q.prototype.stamp=function(a){if(a=this._find(a)){this.stamps=this.stamps.concat(a);for(var b=0,c=a.length;c>b;b++){var d=a[b];this.ignore(d)}}},q.prototype.unstamp=function(a){if(a=this._find(a))for(var b=0,c=a.length;c>b;b++){var d=a[b];e(d,this.stamps),this.unignore(d)}},q.prototype._find=function(a){return a?("string"==typeof a&&(a=this.element.querySelectorAll(a)),a=d(a)):void 0},q.prototype._manageStamps=function(){if(this.stamps&&this.stamps.length){this._getBoundingRect();for(var a=0,b=this.stamps.length;b>a;a++){var c=this.stamps[a];this._manageStamp(c)}}},q.prototype._getBoundingRect=function(){var a=this.element.getBoundingClientRect(),b=this.size;this._boundingRect={left:a.left+b.paddingLeft+b.borderLeftWidth,top:a.top+b.paddingTop+b.borderTopWidth,right:a.right-(b.paddingRight+b.borderRightWidth),bottom:a.bottom-(b.paddingBottom+b.borderBottomWidth)}},q.prototype._manageStamp=k,q.prototype._getElementOffset=function(a){var b=a.getBoundingClientRect(),c=this._boundingRect,d=n(a),e={left:b.left-c.left-d.marginLeft,top:b.top-c.top-d.marginTop,right:c.right-b.right-d.marginRight,bottom:c.bottom-b.bottom-d.marginBottom};return e},q.prototype.handleEvent=function(a){var b="on"+a.type;this[b]&&this[b](a)},q.prototype.bindResize=function(){this.isResizeBound||(c.bind(a,"resize",this),this.isResizeBound=!0)},q.prototype.unbindResize=function(){this.isResizeBound&&c.unbind(a,"resize",this),this.isResizeBound=!1},q.prototype.onresize=function(){function a(){b.resize(),delete b.resizeTimeout}this.resizeTimeout&&clearTimeout(this.resizeTimeout);var b=this;this.resizeTimeout=setTimeout(a,100)},q.prototype.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},q.prototype.needsResizeLayout=function(){var a=n(this.element),b=this.size&&a;return b&&a.innerWidth!==this.size.innerWidth},q.prototype.addItems=function(a){var b=this._itemize(a);return b.length&&(this.items=this.items.concat(b)),b},q.prototype.appended=function(a){var b=this.addItems(a);b.length&&(this.layoutItems(b,!0),this.reveal(b))},q.prototype.prepended=function(a){var b=this._itemize(a);if(b.length){var c=this.items.slice(0);this.items=b.concat(c),this._resetLayout(),this._manageStamps(),this.layoutItems(b,!0),this.reveal(b),this.layoutItems(c)}},q.prototype.reveal=function(a){var b=a&&a.length;if(b)for(var c=0;b>c;c++){var d=a[c];d.reveal()}},q.prototype.hide=function(a){var b=a&&a.length;if(b)for(var c=0;b>c;c++){var d=a[c];d.hide()}},q.prototype.getItem=function(a){for(var b=0,c=this.items.length;c>b;b++){var d=this.items[b];if(d.element===a)return d}},q.prototype.getItems=function(a){if(a&&a.length){for(var b=[],c=0,d=a.length;d>c;c++){var e=a[c],f=this.getItem(e);f&&b.push(f)}return b}},q.prototype.remove=function(a){a=d(a);var b=this.getItems(a);if(b&&b.length){this._itemsOn(b,"remove",function(){this.emitEvent("removeComplete",[this,b])});for(var c=0,f=b.length;f>c;c++){var g=b[c];g.remove(),e(g,this.items)}}},q.prototype.destroy=function(){var a=this.element.style;a.height="",a.position="",a.width="";for(var b=0,c=this.items.length;c>b;b++){var d=this.items[b];d.destroy()}this.unbindResize();var e=this.element.outlayerGUID;delete s[e],delete this.element.outlayerGUID,j&&j.removeData(this.element,this.constructor.namespace)},q.data=function(a){var b=a&&a.outlayerGUID;return b&&s[b]},q.create=function(a,c){function d(){q.apply(this,arguments)}return Object.create?d.prototype=Object.create(q.prototype):b(d.prototype,q.prototype),d.prototype.constructor=d,d.defaults=b({},q.defaults),b(d.defaults,c),d.prototype.settings={},d.namespace=a,d.data=q.data,d.Item=function(){p.apply(this,arguments)},d.Item.prototype=new p,g(function(){for(var b=f(a),c=h.querySelectorAll(".js-"+b),e="data-"+b+"-options",g=0,k=c.length;k>g;g++){var l,m=c[g],n=m.getAttribute(e);try{l=n&&JSON.parse(n)}catch(o){i&&i.error("Error parsing "+e+" on "+m.nodeName.toLowerCase()+(m.id?"#"+m.id:"")+": "+o);continue}var p=new d(m,l);j&&j.data(m,a,p)}}),j&&j.bridget&&j.bridget(a,d),d},q.Item=p,q}var h=a.document,i=a.console,j=a.jQuery,k=function(){},l=Object.prototype.toString,m="function"==typeof HTMLElement||"object"==typeof HTMLElement?function(a){return a instanceof HTMLElement}:function(a){return a&&"object"==typeof a&&1===a.nodeType&&"string"==typeof a.nodeName},n=Array.prototype.indexOf?function(a,b){return a.indexOf(b)}:function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1};"function"==typeof define&&define.amd?define("outlayer/outlayer",["eventie/eventie","doc-ready/doc-ready","eventEmitter/EventEmitter","get-size/get-size","matches-selector/matches-selector","./item"],g):"object"==typeof exports?module.exports=g(require("eventie"),require("doc-ready"),require("wolfy87-eventemitter"),require("get-size"),require("desandro-matches-selector"),require("./item")):a.Outlayer=g(a.eventie,a.docReady,a.EventEmitter,a.getSize,a.matchesSelector,a.Outlayer.Item)}(window),function(a){function b(a,b){var d=a.create("masonry");return d.prototype._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns();var a=this.cols;for(this.colYs=[];a--;)this.colYs.push(0);this.maxY=0},d.prototype.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var a=this.items[0],c=a&&a.element;this.columnWidth=c&&b(c).outerWidth||this.containerWidth}this.columnWidth+=this.gutter,this.cols=Math.floor((this.containerWidth+this.gutter)/this.columnWidth),this.cols=Math.max(this.cols,1)},d.prototype.getContainerWidth=function(){var a=this.options.isFitWidth?this.element.parentNode:this.element,c=b(a);this.containerWidth=c&&c.innerWidth},d.prototype._getItemLayoutPosition=function(a){a.getSize();var b=a.size.outerWidth%this.columnWidth,d=b&&1>b?"round":"ceil",e=Math[d](a.size.outerWidth/this.columnWidth);e=Math.min(e,this.cols);for(var f=this._getColGroup(e),g=Math.min.apply(Math,f),h=c(f,g),i={x:this.columnWidth*h,y:g},j=g+a.size.outerHeight,k=this.cols+1-f.length,l=0;k>l;l++)this.colYs[h+l]=j;return i},d.prototype._getColGroup=function(a){if(2>a)return this.colYs;for(var b=[],c=this.cols+1-a,d=0;c>d;d++){var e=this.colYs.slice(d,d+a);b[d]=Math.max.apply(Math,e)}return b},d.prototype._manageStamp=function(a){var c=b(a),d=this._getElementOffset(a),e=this.options.isOriginLeft?d.left:d.right,f=e+c.outerWidth,g=Math.floor(e/this.columnWidth);g=Math.max(0,g);var h=Math.floor(f/this.columnWidth);h-=f%this.columnWidth?0:1,h=Math.min(this.cols-1,h);for(var i=(this.options.isOriginTop?d.top:d.bottom)+c.outerHeight,j=g;h>=j;j++)this.colYs[j]=Math.max(i,this.colYs[j])},d.prototype._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var a={height:this.maxY};return this.options.isFitWidth&&(a.width=this._getContainerFitWidth()),a},d.prototype._getContainerFitWidth=function(){for(var a=0,b=this.cols;--b&&0===this.colYs[b];)a++;return(this.cols-a)*this.columnWidth-this.gutter},d.prototype.needsResizeLayout=function(){var a=this.containerWidth;return this.getContainerWidth(),a!==this.containerWidth},d}var c=Array.prototype.indexOf?function(a,b){return a.indexOf(b)}:function(a,b){for(var c=0,d=a.length;d>c;c++){var e=a[c];if(e===b)return c}return-1};"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size"],b):"object"==typeof exports?module.exports=b(require("outlayer"),require("get-size")):a.Masonry=b(a.Outlayer,a.getSize)}(window);
--------------------------------------------------------------------------------
/public/js/parallax.js:
--------------------------------------------------------------------------------
1 | function mr_parallax(){"use strict";function a(a){for(var b=0;bB||-B>D)&&(E.scrollBy(0,D),D=0),u++,u>C&&(u=0,s=!1,t=!0,v=0,w=0,x=0,D=0)),l(d)}function e(a,b,c,d){var e=j();e?b+q-r>a.elemTop&&b-ra.elemTop&&bv?-y:v,v=v>y?y:v,s=!0,u=z}function i(a){var b={};return a&&"[object Function]"===b.toString.call(a)}function j(){return"undefined"==typeof window.mr_variant?!1:!0}var k,l=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame,m=["transform","msTransform","webkitTransform","mozTransform","oTransform"],n=a(m),o="translate3d(0,",p="px,0)",q=Math.max(document.documentElement.clientHeight,window.innerHeight||0),r=0,s=!1,t=!0,u=0,v=0,w=0,x=0,y=2,z=4,A=300,B=1,C=30,D=0,E=window,F=(j(),!1),G=this;jQuery(document).ready(function(){G.documentReady()}),jQuery(window).load(function(){G.windowLoad()}),this.getScrollingState=function(){return u>0?!0:!1},this.documentReady=function(a){return q=Math.max(document.documentElement.clientHeight,window.innerHeight||0),jQuery("body").hasClass("parallax-2d")&&(o="translate(0,",p="px)"),/Android|iPad|iPhone|iPod|BlackBerry|Windows Phone/i.test(navigator.userAgent||navigator.vendor||window.opera)?jQuery(".parallax").removeClass("parallax"):l&&(G.profileParallaxElements(),G.setupParallax()),i(a)?void a():void 0},this.windowLoad=function(){q=Math.max(document.documentElement.clientHeight,window.innerHeight||0),r=b(),window.mr_parallax.profileParallaxElements()},this.setupParallax=function(){j()&&(E=jQuery(".viu").get(0),"undefined"!=typeof E&&(E.scrollBy=function(a,b){this.scrollTop+=b,this.scrollLeft+=a})),"undefined"!=typeof E&&(E.addEventListener("scroll",g,!1),window.addWheelListener(E,h,!1),window.addEventListener("resize",function(){q=Math.max(document.documentElement.clientHeight,window.innerHeight||0),r=b(),G.profileParallaxElements()},!1),d())},this.profileParallaxElements=function(){k=[],r=b();var a=j(),c=".parallax > .background-image-holder, .parallax ul.slides > li > .background-image-holder";a&&(c=".viu .parallax > .background-image-holder, .viu .parallax ul.slides > li > .background-image-holder"),jQuery(c).each(function(b){var c=jQuery(this).closest(".parallax"),d=a?c.position().top:c.offset().top;k.push({section:c.get(0),outerHeight:c.outerHeight(),elemTop:d,elemBottom:d+c.outerHeight(),isFirstSection:c.is(":nth-of-type(1)")?!0:!1,imageHolder:jQuery(this).get(0)}),a?a&&(c.is(":nth-of-type(1)")?G.mr_setTranslate3DTransform(jQuery(this).get(0),0===f()?0:f()/2):G.mr_setTranslate3DTransform(jQuery(this).get(0),(f()-d-r)/2)):c.is(":nth-of-type(1)")?G.mr_setTranslate3DTransform(jQuery(this).get(0),0===f()?0:f()/2):G.mr_setTranslate3DTransform(jQuery(this).get(0),(f()+q-d)/2)})},this.mr_setTranslate3DTransform=function(a,b){a.style[n]=o+b+p}}window.mr_parallax=new mr_parallax,function(a,b){function c(b,c,g,h){b[d](f+c,"wheel"==e?g:function(b){!b&&(b=a.event);var c={originalEvent:b,target:b.target||b.srcElement,type:"wheel",deltaMode:"MozMousePixelScroll"==b.type?0:1,deltaX:0,deltaZ:0,notRealWheel:1,preventDefault:function(){b.preventDefault?b.preventDefault():b.returnValue=!1}};return"mousewheel"==e?(c.deltaY=-1/40*b.wheelDelta,b.wheelDeltaX&&(c.deltaX=-1/40*b.wheelDeltaX)):c.deltaY=b.detail/3,g(c)},h||!1)}var d,e,f="";a.addEventListener?d="addEventListener":(d="attachEvent",f="on"),e="onwheel"in b.createElement("div")?"wheel":"undefined"!=typeof b.onmousewheel?"mousewheel":"DOMMouseScroll",a.addWheelListener=function(a,b,d){c(a,e,b,d),"DOMMouseScroll"==e&&c(a,"MozMousePixelScroll",b,d)}}(window,document);
--------------------------------------------------------------------------------
/public/js/smooth-scroll.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Smooth Scroll - v1.4.10 - 2013-03-02
3 | * https://github.com/kswedberg/jquery-smooth-scroll
4 | * Copyright (c) 2013 Karl Swedberg
5 | * Licensed MIT (https://github.com/kswedberg/jquery-smooth-scroll/blob/master/LICENSE-MIT)
6 | */
7 | !function(l){function t(l){return l.replace(/(:|\.)/g,"\\$1")}var e="1.4.10",o={exclude:[],excludeWithin:[],offset:0,direction:"top",scrollElement:null,scrollTarget:null,beforeScroll:function(){},afterScroll:function(){},easing:"swing",speed:400,autoCoefficent:2},r=function(t){var e=[],o=!1,r=t.dir&&"left"==t.dir?"scrollLeft":"scrollTop";return this.each(function(){if(this!=document&&this!=window){var t=l(this);t[r]()>0?e.push(this):(t[r](1),o=t[r]()>0,o&&e.push(this),t[r](0))}}),e.length||this.each(function(){"BODY"===this.nodeName&&(e=[this])}),"first"===t.el&&e.length>1&&(e=[e[0]]),e};l.fn.extend({scrollable:function(l){var t=r.call(this,{dir:l});return this.pushStack(t)},firstScrollable:function(l){var t=r.call(this,{el:"first",dir:l});return this.pushStack(t)},smoothScroll:function(e){e=e||{};var o=l.extend({},l.fn.smoothScroll.defaults,e),r=l.smoothScroll.filterPath(location.pathname);return this.unbind("click.smoothscroll").bind("click.smoothscroll",function(e){var n=this,s=l(this),c=o.exclude,i=o.excludeWithin,a=0,f=0,h=!0,u={},d=location.hostname===n.hostname||!n.hostname,m=o.scrollTarget||(l.smoothScroll.filterPath(n.pathname)||r)===r,p=t(n.hash);if(o.scrollTarget||d&&m&&p){for(;h&&c.length>a;)s.is(t(c[a++]))&&(h=!1);for(;h&&i.length>f;)s.closest(i[f++]).length&&(h=!1)}else h=!1;h&&(e.preventDefault(),l.extend(u,o,{scrollTarget:o.scrollTarget||p,link:n}),l.smoothScroll(u))}),this}}),l.smoothScroll=function(t,e){var o,r,n,s,c=0,i="offset",a="scrollTop",f={},h={};"number"==typeof t?(o=l.fn.smoothScroll.defaults,n=t):(o=l.extend({},l.fn.smoothScroll.defaults,t||{}),o.scrollElement&&(i="position","static"==o.scrollElement.css("position")&&o.scrollElement.css("position","relative"))),o=l.extend({link:null},o),a="left"==o.direction?"scrollLeft":a,o.scrollElement?(r=o.scrollElement,c=r[a]()):r=l("html, body").firstScrollable(),o.beforeScroll.call(r,o),n="number"==typeof t?t:e||l(o.scrollTarget)[i]()&&l(o.scrollTarget)[i]()[o.direction]||0,f[a]=n+c+o.offset,s=o.speed,"auto"===s&&(s=f[a]||r.scrollTop(),s/=o.autoCoefficent),h={duration:s,easing:o.easing,complete:function(){o.afterScroll.call(o.link,o)}},o.step&&(h.step=o.step),r.length?r.stop().animate(f,h):o.afterScroll.call(o.link,o)},l.smoothScroll.version=e,l.smoothScroll.filterPath=function(l){return l.replace(/^\//,"").replace(/(index|default).[a-zA-Z]{3,4}$/,"").replace(/\/$/,"")},l.fn.smoothScroll.defaults=o}(jQuery);
--------------------------------------------------------------------------------
/public/now.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Applicationize - Applicationizer
9 |
10 |
11 |
12 |
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 |
42 |
43 |
44 |
45 |
46 |
Applicationize
47 | Seamlessly convert web apps into desktop apps
48 |
49 |
50 |
51 |
52 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
1. Generate Extension
62 |
63 | Enter the address of the web app you want to applicationize.
64 |
65 |
146 |
147 |
148 |
2. Install Extension
149 |
150 | Install the Chrome Extension to start using the applicationized web app.
151 |
152 |
153 |
154 |
155 | Copy and paste this into a new tab
156 |
157 |
158 |
159 |
160 |
161 | a. Toggle the Developer Mode setting to On in the top right corner
162 |
163 |
164 |
165 |
166 | b. Unzip the .zip archive to extract the .crx extension file
167 |
168 |
169 |
170 |
171 | c. Drag and drop the .crx file to the Extensions page to install it
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
All done, enjoy!
189 |
190 | Your applicationized web app is now available via your app launcher.
191 |
192 | We recommend pinning it to your application dock or system taskbar!
193 |
194 |
Tweet About This
195 |
196 |
197 |
198 |
199 |
200 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
251 |
252 |
253 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 | var koa = require('koa');
3 | var http = require('http');
4 | var https = require('https');
5 | var route = require('koa-route');
6 | var static = require('koa-static');
7 | var body = require('koa-better-body');
8 |
9 | // Koa middleware
10 | var error = require('./lib/middleware/error');
11 | var redirect = require('./lib/middleware/redirect');
12 |
13 | // Create koa app
14 | var app = koa();
15 |
16 | // Koa middleware
17 | app.use(error());
18 | app.use(body());
19 | app.use(redirect());
20 | app.use(static('./public'));
21 |
22 | // HTML file aliases
23 | app.use(route.get('/now', require('./lib/routes/now')));
24 |
25 | // API routes
26 | app.use(route.post('/applicationize', require('./lib/routes/applicationize')));
27 |
28 | // Define configurable port
29 | var port = process.env.PORT || 8080;
30 | var securePort = process.env.SECURE_PORT || 8443;
31 |
32 | // Listen for connections
33 | http.createServer(app.callback()).listen(port);
34 |
35 | // HTTPS support
36 | https.createServer({
37 | key: fs.readFileSync('ssl/server.key'),
38 | cert: fs.readFileSync('ssl/server.crt')
39 | }, app.callback()).listen(securePort);
40 |
41 | // Log port
42 | console.log('Server listening on port ' + port);
--------------------------------------------------------------------------------