Photo Gallery by Envira – Responsive Image Gallery for WordPress - Version 1.5.0.2

Version Description

  • Added: ImageGallery and ImageObject Schema Markup to Galleries
  • Added: Option to insert Gallery Title as heading when using the Add Gallery button in a Visual Editor
  • Added: More detailed on screen progress bars when uploading multiple images
  • Added: envira_isotopes and envira_isotopes_config JS arrays for developers
  • Updated: Isotope to 3.0.0
  • Updated: ImagesLoaded to 4.1.0
  • Updated: Standardised edit screen titles and descriptions
  • Fix: Better rendering of Isotope layouts using imagesLoaded
  • Fix: Image uploader on Gallery Add/Edit screen not displaying on some tablet and mobile devices
  • Fix: Checkmark icon wrongly displaying on modal close when editing images.
  • Fix: Display text in warning when Envira Lite and Envira Gallery are both activated.
  • Fix: Ensure that third party notification plugins dont remove the Envira Gallery logo and header from Enviras screens
  • Fix: Various resets for images and captions to prevent themes overriding default behaviour
  • Fix: Minified admin CSS for faster load times
  • Fix: When editing an image, store any checkbox values if checked, instead of assuming 1 or 0 for better Addon compatibility.
Download this release

Release Info

Developer n7studios
Plugin Icon 128x128 Photo Gallery by Envira – Responsive Image Gallery for WordPress
Version 1.5.0.2
Comparing to
See all releases

Code changes from version 1.5.0.1 to 1.5.0.2

assets/css/admin.css CHANGED
@@ -1 +1,523 @@
1
- body.post-type-envira #wpcontent,body.post-type-envira_album #wpcontent{padding-left:0}body.post-type-envira .update-nag,body.post-type-envira_album .update-nag{margin-left:20px;margin-bottom:20px}body.post-type-envira .subheading,body.post-type-envira_album .subheading{background-color:#fff;height:45px;margin-left:-20px}@media (max-width: 767px){body.post-type-envira .subheading,body.post-type-envira_album .subheading{height:auto;padding-bottom:20px}}body.post-type-envira .subheading h1,body.post-type-envira_album .subheading h1{font-size:20px;font-weight:400;line-height:45px;margin:0 0 0 20px;padding-left:20px}body.post-type-envira div.wrap,body.post-type-envira_album div.wrap{margin:0}body.post-type-envira div.wrap>h1,body.post-type-envira div.wrap>h2,body.post-type-envira_album div.wrap>h1,body.post-type-envira_album div.wrap>h2{margin:0 0 20px 0;padding:15px 20px 10px 20px;background:#fff;font-weight:600;font-size:20px}body.post-type-envira div.wrap>h1 a.page-title-action:hover,body.post-type-envira div.wrap>h2 a.page-title-action:hover,body.post-type-envira_album div.wrap>h1 a.page-title-action:hover,body.post-type-envira_album div.wrap>h2 a.page-title-action:hover{background:#95dc5e;border-color:#95dc5e;color:#fff}body.post-type-envira div.wrap>h1 span.subtitle,body.post-type-envira div.wrap>h2 span.subtitle,body.post-type-envira_album div.wrap>h1 span.subtitle,body.post-type-envira_album div.wrap>h2 span.subtitle{float:right}body.post-type-envira div.wrap .envira-tab,body.post-type-envira_album div.wrap .envira-tab{display:none}body.post-type-envira div.wrap .envira-tab.envira-active,body.post-type-envira_album div.wrap .envira-tab.envira-active{display:block}body.post-type-envira div.wrap div.envira-code,body.post-type-envira_album div.wrap div.envira-code{position:relative;margin:0 0 10px 0}body.post-type-envira div.wrap div.envira-code:after,body.post-type-envira_album div.wrap div.envira-code:after{content:"";display:table;clear:both}body.post-type-envira div.wrap div.envira-code code,body.post-type-envira_album div.wrap div.envira-code code{display:block;font-size:11px;padding:5px 20px 5px 5px}body.post-type-envira div.wrap div.envira-code a.envira-clipboard,body.post-type-envira_album div.wrap div.envira-code a.envira-clipboard{position:absolute;top:5px;right:5px;color:#23282d}body.post-type-envira div.wrap div.envira-code a.envira-clipboard span,body.post-type-envira_album div.wrap div.envira-code a.envira-clipboard span{display:block;text-indent:-9999px}body.post-type-envira .button,body.post-type-envira_album .button{-webkit-border-radius:2px;-moz-border-radius:2px;-o-border-radius:2px;border-radius:2px;padding:0 16px 1px;height:33px;line-height:30px;text-decoration:none;text-shadow:none;font-weight:600;-webkit-box-shadow:none;box-shadow:none}body.post-type-envira .button.button-small,body.post-type-envira_album .button.button-small{padding:0 8px 1px;line-height:22px;height:24px}@media (max-width: 767px){body.post-type-envira .button,body.post-type-envira_album .button{margin-top:10px}}body.post-type-envira .button.show-settings,body.post-type-envira_album .button.show-settings{height:auto}body.post-type-envira .button.button-primary,body.post-type-envira_album .button.button-primary{background:#7cc048;border-color:#7cc048;-webkit-box-shadow:none;box-shadow:none;color:#fff}body.post-type-envira .button.button-primary:hover,body.post-type-envira_album .button.button-primary:hover{background:#95dc5e;border-color:#95dc5e;color:#fff}body.post-type-envira .button.button-danger,body.post-type-envira_album .button.button-danger{background:#e02626;border-color:#e02626;-webkit-box-shadow:none;box-shadow:none;color:#fff}body.post-type-envira .button.button-danger:hover,body.post-type-envira_album .button.button-danger:hover{background:#f85959;border-color:#f85959;color:#fff}body.post-type-envira div#TB_window div.wrap,body.post-type-envira_album div#TB_window div.wrap{margin:10px 20px 0 2px}#envira-header{background-color:#7cc048;height:120px}#envira-header h1.envira-logo{margin:0;line-height:120px;margin-left:20px}#envira-header h1.envira-logo img{max-width:339px;height:auto}@media (max-width: 767px){#envira-header h1.envira-logo img{width:90%}}.envira-notice{position:relative;padding:20px;-webkit-border-radius:2px;-moz-border-radius:2px;-o-border-radius:2px;border-radius:2px;-webkit-box-shadow:none;box-shadow:none}.envira-notice p.envira-intro{border:none;margin:0 0 10px 0 !important;padding:0 0 10px 0 !important}.envira-notice .notice-dismiss{top:10px;right:10px;color:#fff}.envira-notice .notice-dismiss:before{color:#fff;width:26px;height:26px;font-size:22px}.envira-notice.updated{background:#7cc048;color:#fff;border:none}.envira-notice.warning{background:#fcf8e3;border:1px solid #faebcc}.envira-notice.warning .notice-dismiss{color:#000}.envira-notice.warning .notice-dismiss:before{color:#000}.envira-notice.error{border-top:1px solid #dc3232;border-right:1px solid #dc3232;border-bottom:1px solid #dc3232}body.post-type-envira.edit-php div.wrap,body.post-type-envira.post-new-php div.wrap,body.post-type-envira.post-php div.wrap,body.post-type-envira_album.edit-php div.wrap,body.post-type-envira_album.post-new-php div.wrap,body.post-type-envira_album.post-php div.wrap{margin:0}body.post-type-envira.edit-php div.wrap>div.error,body.post-type-envira.edit-php div.wrap>div.notice,body.post-type-envira.edit-php div.wrap>div.updated,body.post-type-envira.post-new-php div.wrap>div.error,body.post-type-envira.post-new-php div.wrap>div.notice,body.post-type-envira.post-new-php div.wrap>div.updated,body.post-type-envira.post-php div.wrap>div.error,body.post-type-envira.post-php div.wrap>div.notice,body.post-type-envira.post-php div.wrap>div.updated,body.post-type-envira_album.edit-php div.wrap>div.error,body.post-type-envira_album.edit-php div.wrap>div.notice,body.post-type-envira_album.edit-php div.wrap>div.updated,body.post-type-envira_album.post-new-php div.wrap>div.error,body.post-type-envira_album.post-new-php div.wrap>div.notice,body.post-type-envira_album.post-new-php div.wrap>div.updated,body.post-type-envira_album.post-php div.wrap>div.error,body.post-type-envira_album.post-php div.wrap>div.notice,body.post-type-envira_album.post-php div.wrap>div.updated{margin-left:20px;margin-right:20px}body.post-type-envira.edit-tags-php div.wrap,body.post-type-envira.taxonomy-envira-tag div.wrap{margin:0}body.post-type-envira.edit-tags-php div.wrap>div.error,body.post-type-envira.edit-tags-php div.wrap>div.notice,body.post-type-envira.edit-tags-php div.wrap>div.updated,body.post-type-envira.taxonomy-envira-tag div.wrap>div.error,body.post-type-envira.taxonomy-envira-tag div.wrap>div.notice,body.post-type-envira.taxonomy-envira-tag div.wrap>div.updated{margin-left:20px;margin-right:20px}body.post-type-envira.edit-tags-php div.wrap form.search-form,body.post-type-envira.edit-tags-php div.wrap form#edittag,body.post-type-envira.edit-tags-php div.wrap #col-container,body.post-type-envira.taxonomy-envira-tag div.wrap form.search-form,body.post-type-envira.taxonomy-envira-tag div.wrap form#edittag,body.post-type-envira.taxonomy-envira-tag div.wrap #col-container{margin:0 20px}body.post-type-envira.edit-tags-php div.wrap .button,body.post-type-envira.taxonomy-envira-tag div.wrap .button{height:28px;line-height:26px}body.post-type-envira div.wrap{margin:0 20px}@media screen and (max-width: 640px){body.post-type-envira div.wrap h1,body.post-type-envira_album div.wrap h1{padding-bottom:40px}body.post-type-envira div.wrap h1 span.subtitle,body.post-type-envira_album div.wrap h1 span.subtitle{clear:both;width:100%;padding:0}}@media screen and (max-width: 340px){body.post-type-envira div.wrap h1,body.post-type-envira_album div.wrap h1{text-align:center}body.post-type-envira div.wrap h1 a.page-title-action,body.post-type-envira_album div.wrap h1 a.page-title-action{display:block;text-align:center;margin:10px 0 0 0}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* ==========================================================================
2
+ admin.css loads on all Envira Administration Screens:
3
+ - WP_List_Tables
4
+ - Add New
5
+ - Albums
6
+ - Settings
7
+ - NextGEN Import
8
+
9
+ Any styles that will be used by all of the above (or are useful to be included
10
+ for future use) should be added to this file:
11
+ - Header and Logo
12
+ - WordPress Red Button
13
+ ========================================================================== */
14
+ /* ==========================================================================
15
+ Imports
16
+ ========================================================================== */
17
+ /* ==========================================================================
18
+ Variables SCSS
19
+ ========================================================================== */
20
+ /* ==========================================================================
21
+ Mixins
22
+ ========================================================================== */
23
+ /**
24
+ * Media Query
25
+ */
26
+ /**
27
+ * Border-Radius
28
+ */
29
+ body.post-type-envira,
30
+ body.post-type-envira_album {
31
+ /**
32
+ * Subheading
33
+ */
34
+ /**
35
+ * Wrapper
36
+ */
37
+ /* ==========================================================================
38
+ Button Styles
39
+ ========================================================================== */
40
+ /* ==========================================================================
41
+ Thickbox (used for choosing a Default Gallery/Album)
42
+ ========================================================================== */ }
43
+ body.post-type-envira #wpcontent,
44
+ body.post-type-envira_album #wpcontent {
45
+ padding-left: 0; }
46
+ body.post-type-envira .update-nag,
47
+ body.post-type-envira_album .update-nag {
48
+ margin-left: 20px;
49
+ margin-bottom: 20px; }
50
+ body.post-type-envira .subheading,
51
+ body.post-type-envira_album .subheading {
52
+ background-color: #ffffff;
53
+ height: 45px;
54
+ margin-left: -20px; }
55
+ @media (min-width: 600px) and (max-width: 767px) {
56
+ body.post-type-envira .subheading,
57
+ body.post-type-envira_album .subheading {
58
+ height: auto;
59
+ padding-bottom: 20px; } }
60
+ body.post-type-envira .subheading h1,
61
+ body.post-type-envira_album .subheading h1 {
62
+ font-size: 20px;
63
+ font-weight: 400;
64
+ line-height: 45px;
65
+ margin: 0 0 0 20px;
66
+ padding-left: 20px; }
67
+ body.post-type-envira div.wrap,
68
+ body.post-type-envira_album div.wrap {
69
+ margin: 0;
70
+ /**
71
+ * Screen Title
72
+ * - h1 used from WordPress 4.3+
73
+ * - h2 used in WordPress 4.2-
74
+ */
75
+ /**
76
+ * Tab Panels
77
+ * - By default, they're hidden and the .envira-active class displays them
78
+ */
79
+ /**
80
+ * Code Snippets
81
+ */ }
82
+ body.post-type-envira div.wrap > h1,
83
+ body.post-type-envira div.wrap > h2,
84
+ body.post-type-envira_album div.wrap > h1,
85
+ body.post-type-envira_album div.wrap > h2 {
86
+ margin: 0 0 20px 0;
87
+ padding: 15px 20px 10px 20px;
88
+ background: #ffffff;
89
+ font-weight: 600;
90
+ font-size: 20px;
91
+ /**
92
+ * Page Title Action (i.e. Add New)
93
+ */
94
+ /**
95
+ * Subtitle (search results title)
96
+ */ }
97
+ body.post-type-envira div.wrap > h1 a.page-title-action:hover,
98
+ body.post-type-envira div.wrap > h2 a.page-title-action:hover,
99
+ body.post-type-envira_album div.wrap > h1 a.page-title-action:hover,
100
+ body.post-type-envira_album div.wrap > h2 a.page-title-action:hover {
101
+ background: #95dc5e;
102
+ border-color: #95dc5e;
103
+ color: #ffffff; }
104
+ body.post-type-envira div.wrap > h1 span.subtitle,
105
+ body.post-type-envira div.wrap > h2 span.subtitle,
106
+ body.post-type-envira_album div.wrap > h1 span.subtitle,
107
+ body.post-type-envira_album div.wrap > h2 span.subtitle {
108
+ float: right; }
109
+ body.post-type-envira div.wrap .envira-tab,
110
+ body.post-type-envira_album div.wrap .envira-tab {
111
+ display: none;
112
+ /**
113
+ * Active Tab
114
+ */ }
115
+ body.post-type-envira div.wrap .envira-tab.envira-active,
116
+ body.post-type-envira_album div.wrap .envira-tab.envira-active {
117
+ display: block; }
118
+ body.post-type-envira div.wrap div.envira-code,
119
+ body.post-type-envira_album div.wrap div.envira-code {
120
+ position: relative;
121
+ margin: 0 0 10px 0;
122
+ /**
123
+ * Clearfix
124
+ */
125
+ /**
126
+ * Copy to Clipboard
127
+ */ }
128
+ body.post-type-envira div.wrap div.envira-code:after,
129
+ body.post-type-envira_album div.wrap div.envira-code:after {
130
+ content: "";
131
+ display: table;
132
+ clear: both; }
133
+ body.post-type-envira div.wrap div.envira-code code,
134
+ body.post-type-envira_album div.wrap div.envira-code code {
135
+ display: block;
136
+ font-size: 11px;
137
+ padding: 5px 20px 5px 5px; }
138
+ body.post-type-envira div.wrap div.envira-code a.envira-clipboard,
139
+ body.post-type-envira_album div.wrap div.envira-code a.envira-clipboard {
140
+ position: absolute;
141
+ top: 5px;
142
+ right: 5px;
143
+ color: #23282d; }
144
+ body.post-type-envira div.wrap div.envira-code a.envira-clipboard span,
145
+ body.post-type-envira_album div.wrap div.envira-code a.envira-clipboard span {
146
+ display: block;
147
+ text-indent: -9999px; }
148
+ body.post-type-envira .button,
149
+ body.post-type-envira_album .button {
150
+ -webkit-border-radius: 2px;
151
+ -moz-border-radius: 2px;
152
+ -o-border-radius: 2px;
153
+ border-radius: 2px;
154
+ padding: 0 16px 1px;
155
+ height: 33px;
156
+ line-height: 30px;
157
+ text-decoration: none;
158
+ text-shadow: none;
159
+ font-weight: 600;
160
+ -webkit-box-shadow: none;
161
+ box-shadow: none;
162
+ /**
163
+ * Screen Options
164
+ * - Don't set a height
165
+ */
166
+ /**
167
+ * Green Button
168
+ * - Replaces WordPress' default primary button style
169
+ */
170
+ /**
171
+ * Red Button
172
+ */ }
173
+ body.post-type-envira .button.button-small,
174
+ body.post-type-envira_album .button.button-small {
175
+ padding: 0 8px 1px;
176
+ line-height: 22px;
177
+ height: 24px; }
178
+ @media (min-width: 600px) and (max-width: 767px) {
179
+ body.post-type-envira .button,
180
+ body.post-type-envira_album .button {
181
+ margin-top: 10px; } }
182
+ body.post-type-envira .button.show-settings,
183
+ body.post-type-envira_album .button.show-settings {
184
+ height: auto; }
185
+ body.post-type-envira .button.button-primary,
186
+ body.post-type-envira_album .button.button-primary {
187
+ background: #7cc048;
188
+ border-color: #7cc048;
189
+ -webkit-box-shadow: none;
190
+ box-shadow: none;
191
+ color: #ffffff; }
192
+ body.post-type-envira .button.button-primary:hover,
193
+ body.post-type-envira_album .button.button-primary:hover {
194
+ background: #95dc5e;
195
+ border-color: #95dc5e;
196
+ color: #ffffff; }
197
+ body.post-type-envira .button.button-danger,
198
+ body.post-type-envira_album .button.button-danger {
199
+ background: #e02626;
200
+ border-color: #e02626;
201
+ -webkit-box-shadow: none;
202
+ box-shadow: none;
203
+ color: #ffffff; }
204
+ body.post-type-envira .button.button-danger:hover,
205
+ body.post-type-envira_album .button.button-danger:hover {
206
+ background: #f85959;
207
+ border-color: #f85959;
208
+ color: #ffffff; }
209
+ body.post-type-envira div#TB_window div.wrap,
210
+ body.post-type-envira_album div#TB_window div.wrap {
211
+ margin: 10px 20px 0 2px; }
212
+
213
+ /* ==========================================================================
214
+ Header
215
+ ========================================================================== */
216
+ #envira-header-temp {
217
+ position: relative; }
218
+
219
+ #envira-header {
220
+ background-color: #7cc048;
221
+ height: 120px; }
222
+ @media (max-width: 599px) {
223
+ #envira-header {
224
+ padding-top: 46px; } }
225
+ #envira-header h1.envira-logo {
226
+ margin: 0;
227
+ line-height: 120px;
228
+ margin-left: 20px; }
229
+ #envira-header h1.envira-logo img {
230
+ /**
231
+ * Image width and height (image is 2x so this ensures it displays correctly)
232
+ */
233
+ max-width: 339px;
234
+ height: auto;
235
+ width: 90%;
236
+ /**
237
+ * Responsive - ensure the logo doesn't exceed the header dimensions
238
+ */ }
239
+ @media (min-width: 600px) and (max-width: 767px) {
240
+ #envira-header h1.envira-logo img {
241
+ width: 90%; } }
242
+
243
+ @media (max-width: 599px) {
244
+ #wpbody {
245
+ padding-top: 0; } }
246
+
247
+ /* ==========================================================================
248
+ Inline Notices
249
+ - These are Envira-specific notices with custom styling for e.g. Instagram oAuth,
250
+ upgrade / upsells.
251
+ ========================================================================== */
252
+ .envira-notice {
253
+ position: relative;
254
+ margin: 0 0 20px 0;
255
+ padding: 20px;
256
+ -webkit-border-radius: 2px;
257
+ -moz-border-radius: 2px;
258
+ -o-border-radius: 2px;
259
+ border-radius: 2px;
260
+ /**
261
+ * Heading
262
+ */
263
+ /**
264
+ * Close Button
265
+ */
266
+ /**
267
+ * Success
268
+ */
269
+ /**
270
+ * Warning
271
+ */
272
+ /**
273
+ * Error
274
+ */ }
275
+ .envira-notice p.envira-intro {
276
+ border: none !important;
277
+ margin: 0 0 20px 0 !important;
278
+ padding: 0 !important; }
279
+ .envira-notice .notice-dismiss {
280
+ top: 10px;
281
+ right: 10px;
282
+ color: #ffffff; }
283
+ .envira-notice .notice-dismiss:before {
284
+ color: #ffffff;
285
+ width: 26px;
286
+ height: 26px;
287
+ font-size: 22px; }
288
+ .envira-notice.success {
289
+ background: #7cc048;
290
+ color: #ffffff;
291
+ border: none;
292
+ /**
293
+ * Button background color needs to be adjusted so it displays over the green background
294
+ * of the success message
295
+ */ }
296
+ .envira-notice.success .button.button-primary {
297
+ background-color: #95dc5e;
298
+ border-color: #95dc5e; }
299
+ .envira-notice.warning {
300
+ background: #fcf8e3;
301
+ border: 1px solid #faebcc; }
302
+ .envira-notice.warning .notice-dismiss {
303
+ color: #000000; }
304
+ .envira-notice.warning .notice-dismiss:before {
305
+ color: #000000; }
306
+ .envira-notice.error {
307
+ border-top: 1px solid #dc3232;
308
+ border-right: 1px solid #dc3232;
309
+ border-bottom: 1px solid #dc3232; }
310
+
311
+ /* ==========================================================================
312
+ Table, Add, Edit Screens
313
+ ========================================================================== */
314
+ body.post-type-envira.edit-php div.wrap,
315
+ body.post-type-envira.post-new-php div.wrap,
316
+ body.post-type-envira.post-php div.wrap,
317
+ body.post-type-envira_album.edit-php div.wrap,
318
+ body.post-type-envira_album.post-new-php div.wrap,
319
+ body.post-type-envira_album.post-php div.wrap {
320
+ /**
321
+ * Remove the margin on the wrapper
322
+ */
323
+ margin: 0;
324
+ /**
325
+ * Add margin to notices
326
+ */ }
327
+ body.post-type-envira.edit-php div.wrap > div.error,
328
+ body.post-type-envira.edit-php div.wrap > div.notice,
329
+ body.post-type-envira.edit-php div.wrap > div.updated,
330
+ body.post-type-envira.post-new-php div.wrap > div.error,
331
+ body.post-type-envira.post-new-php div.wrap > div.notice,
332
+ body.post-type-envira.post-new-php div.wrap > div.updated,
333
+ body.post-type-envira.post-php div.wrap > div.error,
334
+ body.post-type-envira.post-php div.wrap > div.notice,
335
+ body.post-type-envira.post-php div.wrap > div.updated,
336
+ body.post-type-envira_album.edit-php div.wrap > div.error,
337
+ body.post-type-envira_album.edit-php div.wrap > div.notice,
338
+ body.post-type-envira_album.edit-php div.wrap > div.updated,
339
+ body.post-type-envira_album.post-new-php div.wrap > div.error,
340
+ body.post-type-envira_album.post-new-php div.wrap > div.notice,
341
+ body.post-type-envira_album.post-new-php div.wrap > div.updated,
342
+ body.post-type-envira_album.post-php div.wrap > div.error,
343
+ body.post-type-envira_album.post-php div.wrap > div.notice,
344
+ body.post-type-envira_album.post-php div.wrap > div.updated {
345
+ margin-left: 20px;
346
+ margin-right: 20px; }
347
+
348
+ /* ==========================================================================
349
+ Taxonomy Screens
350
+ ========================================================================== */
351
+ body.post-type-envira.edit-tags-php div.wrap,
352
+ body.post-type-envira.taxonomy-envira-tag div.wrap {
353
+ margin: 0;
354
+ /**
355
+ * Add margin to notices
356
+ */
357
+ /**
358
+ * Reduce our global custom button sizes so they align with inputs
359
+ */ }
360
+ body.post-type-envira.edit-tags-php div.wrap > div.error,
361
+ body.post-type-envira.edit-tags-php div.wrap > div.notice,
362
+ body.post-type-envira.edit-tags-php div.wrap > div.updated,
363
+ body.post-type-envira.taxonomy-envira-tag div.wrap > div.error,
364
+ body.post-type-envira.taxonomy-envira-tag div.wrap > div.notice,
365
+ body.post-type-envira.taxonomy-envira-tag div.wrap > div.updated {
366
+ margin-left: 20px;
367
+ margin-right: 20px; }
368
+ body.post-type-envira.edit-tags-php div.wrap form.search-form,
369
+ body.post-type-envira.edit-tags-php div.wrap form#edittag,
370
+ body.post-type-envira.edit-tags-php div.wrap #col-container,
371
+ body.post-type-envira.taxonomy-envira-tag div.wrap form.search-form,
372
+ body.post-type-envira.taxonomy-envira-tag div.wrap form#edittag,
373
+ body.post-type-envira.taxonomy-envira-tag div.wrap #col-container {
374
+ /**
375
+ * Re-establish the left and right margins, so there's spacing between the Admin Menu
376
+ * and the content
377
+ */
378
+ margin: 0 20px; }
379
+ body.post-type-envira.edit-tags-php div.wrap .button,
380
+ body.post-type-envira.taxonomy-envira-tag div.wrap .button {
381
+ height: 28px;
382
+ line-height: 26px; }
383
+
384
+ /* ==========================================================================
385
+ Third Party Screens
386
+ ========================================================================== */
387
+ body.post-type-envira div.wrap {
388
+ /**
389
+ * Re-establish the left and right margins, so there's spacing between the Admin Menu
390
+ * and the content for any third party plugins which add sections / pages within Envira
391
+ */
392
+ margin: 0 20px; }
393
+
394
+ /* ==========================================================================
395
+ Gallery / Album Selection Media Modal
396
+ ========================================================================== */
397
+ .media-modal .media-modal-content .media-frame-content .attachments-browser.envira-gallery-editor {
398
+ /**
399
+ * Error
400
+ * - Position below the search bar
401
+ */
402
+ /**
403
+ * Grid
404
+ */
405
+ /**
406
+ * Sidebar
407
+ */ }
408
+ .media-modal .media-modal-content .media-frame-content .attachments-browser.envira-gallery-editor div.envira-gallery-error {
409
+ position: absolute;
410
+ top: 50px;
411
+ left: 0;
412
+ right: 300px; }
413
+ .media-modal .media-modal-content .media-frame-content .attachments-browser.envira-gallery-editor ul.attachments li.attachment {
414
+ width: 20%; }
415
+ .media-modal .media-modal-content .media-frame-content .attachments-browser.envira-gallery-editor ul.attachments li.attachment div.attachment-preview div.thumbnail {
416
+ /**
417
+ * Thumbnail Image
418
+ */
419
+ /**
420
+ * Title
421
+ */
422
+ /**
423
+ * Shortcode
424
+ */ }
425
+ .media-modal .media-modal-content .media-frame-content .attachments-browser.envira-gallery-editor ul.attachments li.attachment div.attachment-preview div.thumbnail img {
426
+ position: absolute;
427
+ z-index: 1;
428
+ top: 0;
429
+ left: 0;
430
+ width: 100%;
431
+ height: 100%;
432
+ opacity: 0.2; }
433
+ .media-modal .media-modal-content .media-frame-content .attachments-browser.envira-gallery-editor ul.attachments li.attachment div.attachment-preview div.thumbnail strong {
434
+ position: absolute;
435
+ z-index: 2;
436
+ height: 50%;
437
+ top: 0;
438
+ left: 0;
439
+ right: 0;
440
+ padding: 10px;
441
+ text-align: center;
442
+ overflow: hidden;
443
+ -webkit-box-sizing: border-box;
444
+ -moz-box-sizing: border-box;
445
+ box-sizing: border-box;
446
+ vertical-align: bottom;
447
+ background: rgba(0, 0, 0, 0.07);
448
+ text-shadow: 1px 1px #ddd; }
449
+ .media-modal .media-modal-content .media-frame-content .attachments-browser.envira-gallery-editor ul.attachments li.attachment div.attachment-preview div.thumbnail strong span {
450
+ display: block;
451
+ position: absolute;
452
+ bottom: 10px;
453
+ left: 0;
454
+ right: 0;
455
+ padding: 0 10px;
456
+ text-align: center; }
457
+ .media-modal .media-modal-content .media-frame-content .attachments-browser.envira-gallery-editor ul.attachments li.attachment div.attachment-preview div.thumbnail code {
458
+ position: absolute;
459
+ z-index: 2;
460
+ height: 50%;
461
+ bottom: 0;
462
+ left: 0;
463
+ right: 0;
464
+ padding: 10px;
465
+ text-align: center;
466
+ -webkit-box-sizing: border-box;
467
+ -moz-box-sizing: border-box;
468
+ box-sizing: border-box;
469
+ vertical-align: middle;
470
+ text-shadow: 1px 1px #ddd; }
471
+ .media-modal .media-modal-content .media-frame-content .attachments-browser.envira-gallery-editor div.media-sidebar div.settings .name {
472
+ text-align: left; }
473
+
474
+ /* ==========================================================================
475
+ Responsive
476
+ ========================================================================== */
477
+ @media screen and (max-width: 640px) {
478
+ body.post-type-envira,
479
+ body.post-type-envira_album {
480
+ /**
481
+ * Wrapper
482
+ */ }
483
+ body.post-type-envira div.wrap,
484
+ body.post-type-envira_album div.wrap {
485
+ /**
486
+ * Screen Title
487
+ */ }
488
+ body.post-type-envira div.wrap h1,
489
+ body.post-type-envira_album div.wrap h1 {
490
+ /**
491
+ * Allow space for the "Search results for..." text to display, when searching
492
+ */
493
+ padding-bottom: 40px;
494
+ /**
495
+ * Subtitle (search results title)
496
+ */ }
497
+ body.post-type-envira div.wrap h1 span.subtitle,
498
+ body.post-type-envira_album div.wrap h1 span.subtitle {
499
+ clear: both;
500
+ width: 100%;
501
+ padding: 0; } }
502
+ @media screen and (max-width: 340px) {
503
+ body.post-type-envira,
504
+ body.post-type-envira_album {
505
+ /**
506
+ * Wrapper
507
+ */ }
508
+ body.post-type-envira div.wrap,
509
+ body.post-type-envira_album div.wrap {
510
+ /**
511
+ * Screen Title
512
+ */ }
513
+ body.post-type-envira div.wrap h1,
514
+ body.post-type-envira_album div.wrap h1 {
515
+ text-align: center;
516
+ /**
517
+ * Page Title Action (i.e. Add New)
518
+ */ }
519
+ body.post-type-envira div.wrap h1 a.page-title-action,
520
+ body.post-type-envira_album div.wrap h1 a.page-title-action {
521
+ display: block;
522
+ text-align: center;
523
+ margin: 10px 0 0 0; } }
assets/css/editor.css CHANGED
@@ -1 +1 @@
1
- .envira-gallery-choose-gallery,.envira-albums-choose-album{padding-left:.4em}.envira-gallery-choose-gallery span.envira-media-icon,.envira-albums-choose-album span.envira-media-icon{background:url(images/menu-icon.png) transparent no-repeat scroll 0 0;width:16px;height:16px;display:inline-block;vertical-align:text-top}.media-modal .media-modal-content .media-frame-content .attachments-browser.envira-gallery-editor div.envira-gallery-error{position:absolute;top:50px;left:0;right:300px}.media-modal .media-modal-content .media-frame-content .attachments-browser.envira-gallery-editor ul.attachments li.attachment{width:20%}.media-modal .media-modal-content .media-frame-content .attachments-browser.envira-gallery-editor ul.attachments li.attachment div.attachment-preview div.thumbnail img{position:absolute;z-index:1;top:0;left:0;width:100%;height:100%;opacity:0.2}.media-modal .media-modal-content .media-frame-content .attachments-browser.envira-gallery-editor ul.attachments li.attachment div.attachment-preview div.thumbnail strong{position:absolute;z-index:2;height:50%;top:0;left:0;right:0;padding:10px;text-align:center;overflow:hidden;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;vertical-align:bottom;background:rgba(0,0,0,0.07);text-shadow:1px 1px #ddd}.media-modal .media-modal-content .media-frame-content .attachments-browser.envira-gallery-editor ul.attachments li.attachment div.attachment-preview div.thumbnail strong span{display:block;position:absolute;bottom:10px;left:0;right:0;padding:0 10px;text-align:center}.media-modal .media-modal-content .media-frame-content .attachments-browser.envira-gallery-editor ul.attachments li.attachment div.attachment-preview div.thumbnail code{position:absolute;z-index:2;height:50%;bottom:0;left:0;right:0;padding:10px;text-align:center;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;vertical-align:middle;text-shadow:1px 1px #ddd}@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2 / 1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx){#envira-media-modal-button .envira-media-icon[style]{background-image:url(images/menu-icon@2x.png) !important;background-size:16px 16px !important}}
1
+ .envira-gallery-choose-gallery,.envira-albums-choose-album{padding-left:.4em}.envira-gallery-choose-gallery span.envira-media-icon,.envira-albums-choose-album span.envira-media-icon{background:url(images/menu-icon.png) transparent no-repeat scroll 0 0;width:16px;height:16px;display:inline-block;vertical-align:text-top}@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2 / 1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx){#envira-media-modal-button .envira-media-icon[style]{background-image:url(images/menu-icon@2x.png) !important;background-size:16px 16px !important}}
assets/css/images/icons/comments.svg ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="0 0 76 76" style="enable-background:new 0 0 76 76;" xml:space="preserve">
5
+ <g id="_x37_7_Essential_Icons_11_">
6
+ <path id="Message" d="M74,4.992H2c-1.1,0-2,0.9-2,2v48c0,1.1,0.9,2,2,2h16v12c0,1.8,2.1,2.7,3.4,1.4l13.6-13.4h39c1.1,0,2-0.9,2-2
7
+ v-48C76,5.892,75.1,4.992,74,4.992z M72,52.992H34.2c-0.5,0-1,0.2-1.4,0.6L22,64.192v-9.2c0-1.1-0.9-2-2-2H4v-44h68V52.992z"/>
8
+ </g>
9
+ <g>
10
+ </g>
11
+ <g>
12
+ </g>
13
+ <g>
14
+ </g>
15
+ <g>
16
+ </g>
17
+ <g>
18
+ </g>
19
+ <g>
20
+ </g>
21
+ <g>
22
+ </g>
23
+ <g>
24
+ </g>
25
+ <g>
26
+ </g>
27
+ <g>
28
+ </g>
29
+ <g>
30
+ </g>
31
+ <g>
32
+ </g>
33
+ <g>
34
+ </g>
35
+ <g>
36
+ </g>
37
+ <g>
38
+ </g>
39
+ </svg>
assets/css/metabox.css CHANGED
@@ -1 +1,1241 @@
1
- body.post-type-envira #message,body.post-type-envira_album #message{margin:5px 20px 15px 20px}form#post.envira-gallery{margin:0 20px}form#post.envira-gallery #poststuff p.envira-intro{margin:0;padding:0 0 30px 0;border-bottom:1px solid #ddd;font-size:16px;font-weight:700}form#post.envira-gallery #poststuff p.envira-intro small{margin:5px 0 0 0;display:block;font-weight:400}form#post.envira-gallery #poststuff p.envira-intro small a{text-decoration:none;font-weight:600}form#post.envira-gallery #poststuff div.envira-video-help{position:relative;z-index:1;width:100%;margin:20px 0 0 0}form#post.envira-gallery #poststuff div.envira-video-help iframe{position:relative;z-index:1;width:100%;height:auto;min-height:300px}form#post.envira-gallery #poststuff div.envira-video-help a.envira-video-close{position:absolute;z-index:2;top:-12px;right:-12px;width:24px;height:24px;line-height:24px;-webkit-border-radius:50%;-moz-border-radius:50%;-o-border-radius:50%;border-radius:50%;background:#f5f5f5;color:#000;text-align:center;text-decoration:none}form#post.envira-gallery #poststuff ul.envira-gallery-images-output{width:100%}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li{position:relative;display:inline-block;width:150px;margin:0 20px 20px 0;padding:0;list-style:none;vertical-align:top;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;background:#f7f7f7}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li img{display:block;width:150px;height:150px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.placeholder-image{display:block;width:148px;height:149px;background:url(images/icons/leaf.svg) center no-repeat;background-size:64px 64px;border-left:1px solid #dfdfdf;border-top:1px solid #dfdfdf;border-right:1px solid #dfdfdf}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta{width:148px;overflow:hidden;text-align:center;border-left:1px solid #dfdfdf;border-bottom:1px solid #dfdfdf;border-right:1px solid #dfdfdf}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta div.title{font-size:12px;font-weight:700;width:138px;height:18px;line-height:18px;margin:8px 5px;overflow:hidden}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta div.title a.hint{position:absolute;display:inline-block;bottom:10px;right:10px;width:16px;height:16px;background:#f7f7f7}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta div.title a.hint.hidden{display:none}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta div.additional{display:none;margin:5px 0 0 0;font-weight:400}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.check{display:none;position:absolute;right:5px;top:5px;width:24px;height:24px;background-color:#eee;-webkit-box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,0,0,0.15);box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,0,0,0.15)}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.check div.media-modal-icon{display:none;width:15px;height:15px;margin:5px 0 0 5px;background-position:-21px 0}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.dashicons{position:absolute;display:block;top:5px;left:5px;width:25px;height:25px;line-height:25px;font-size:18px;outline:none;z-index:20;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.dashicons.envira-gallery-modify-image{background:#0085ba;color:#fff}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.dashicons.envira-gallery-remove-image{left:35px;background:#e02626;color:#fff}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.selected{width:148px;border:2px solid #7cc048 !important}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.selected a.check{display:block;background-color:#7cc048;-webkit-box-shadow:0 0 0 1px #fff,0 0 0 2px #7cc048;box-shadow:0 0 0 1px #fff,0 0 0 2px #7cc048}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.selected a.check div.media-modal-icon{display:block}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.selected div.meta{width:146px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.ui-sortable-helper li{position:absolute;top:0;left:0}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li{position:relative;z-index:2;display:block;width:100%;margin:0 0 10px 0;padding:10px 15px;background:#fff;border:1px solid #ddd;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li img{display:inline-block;width:75px;margin-left:45px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li div.meta{position:absolute;z-index:1;left:0;display:inline-block;width:100%;padding:0 80px 0 150px;border:none;font-weight:700;text-align:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li div.meta div.title{display:block;width:100%;height:auto;font-size:16px;margin:0;padding:0}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li div.meta div.title a.hint{display:none}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li div.meta div.additional{display:block}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li a.check{display:block;position:absolute;left:15px;top:35px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li a.envira-gallery-remove-image{left:auto;top:10px;right:10px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li a.envira-gallery-modify-image{left:auto;top:10px;right:40px}form#post.envira-gallery #poststuff #envira-gallery{margin:60px 0 20px 0}form#post.envira-gallery #poststuff #envira-gallery .handlediv,form#post.envira-gallery #poststuff #envira-albums .handlediv{display:none}form#post.envira-gallery #poststuff #envira-gallery .hndle,form#post.envira-gallery #poststuff #envira-albums .hndle{display:none}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper{margin:-56px 0 0 -1px;padding:0;border-bottom:none}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab{display:inline-block;width:49%;margin:0;padding:15px 0;text-align:center;font-size:16px;border-color:#e5e5e5;background:#f5f5f5}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab.nav-tab-native-envira-gallery span,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab.nav-tab-native-envira-gallery span{display:inline-block;background:url(images/icons/leaf.svg) 0 5px no-repeat;background-size:14px 14px;text-indent:20px}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab.nav-tab-external-gallery,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab.nav-tab-external-gallery{margin-right:-1px}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab:hover,form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab.envira-active,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab:hover,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab.envira-active{background:#fff;border-bottom:1px solid #fff}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab:focus,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab:last-child,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab:last-child{float:right}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab input[type=radio],form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab input[type=radio]{display:none}form#post.envira-gallery #poststuff #envira-gallery .inside,form#post.envira-gallery #poststuff #envira-albums .inside{margin:0;padding:0}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui{display:none}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop{display:block}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop .drag-drop-inside,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop .drag-drop-inside{width:520px;margin-top:50px}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop .drag-drop-inside p.drag-drop-buttons,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop .drag-drop-inside p.drag-drop-buttons{text-align:left}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop .drag-drop-inside .envira-progress-bar,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop .drag-drop-inside .envira-progress-bar{display:none;width:100%;position:relative;height:10px;width:100%;margin:10px auto;border-radius:10px;background:#dfdfdf;background:rgba(0,0,0,0.1)}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop .drag-drop-inside .envira-progress-bar div,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop .drag-drop-inside .envira-progress-bar div{height:10px;min-width:20px;width:0;background:#aaa;background:rgba(0,0,0,0.2);border-radius:10px;-webkit-transition:width 300ms;-moz-transition:width 300ms;-ms-transition:width 300ms;-o-transition:width 300ms;transition:width 300ms}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui a.envira-media-library.button,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui a.envira-media-library.button{display:block;position:absolute;margin:0 auto;left:280px;right:0;width:230px;top:115px;text-align:center}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui p.upload-flash-bypass,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui p.upload-flash-bypass{display:none}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab{padding:20px}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav{text-align:center}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li{display:inline-block;margin:0 20px 0 0;vertical-align:top}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li:last-child,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li:last-child{margin:0}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li label,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li label{float:left;width:110px}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li label input,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li label input{display:none}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li label div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li label div.icon{width:110px;height:110px;margin:0 0 10px 0;border:1px solid #ddd;background-size:64px 64px;background-position:center;background-repeat:no-repeat}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li label div.title,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li label div.title{font-weight:700}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li:hover label div.icon,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li.envira-active label div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li:hover label div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li.envira-active label div.icon{background-color:#f7fcf3;border-color:#7cc048}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li#envira-gallery-type-fc label div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li#envira-gallery-type-fc label div.icon{background-image:url(../images/types/fc.png)}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li#envira-gallery-type-instagram label div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li#envira-gallery-type-instagram label div.icon{background-image:url(../images/types/instagram.png)}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native{position:relative}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native ul#envira-album-drag-drop-area{z-index:2;min-height:200px;margin:0;padding:20px;border:4px dashed #b4b9be;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native ul#envira-album-drag-drop-area li{cursor:move}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native p.drag-drop-info{position:absolute;top:80px;z-index:1;margin:0 auto;left:0;right:0;text-align:center;color:#a0a5aa;font-size:20px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native p.drag-drop-info span{display:block}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native p.drag-drop-info span.click{font-size:18px}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native p.drag-drop-info small{display:block;margin:5px 0;font-size:14px}form#post.envira-gallery #poststuff #envira-gallery-settings,form#post.envira-gallery #poststuff #envira-albums-settings{background:#f7f7f7}form#post.envira-gallery #poststuff #envira-gallery-settings:after,form#post.envira-gallery #poststuff #envira-albums-settings:after{content:"";display:table;clear:both}form#post.envira-gallery #poststuff #envira-gallery-settings .handlediv,form#post.envira-gallery #poststuff #envira-albums-settings .handlediv{display:none}form#post.envira-gallery #poststuff #envira-gallery-settings .hndle,form#post.envira-gallery #poststuff #envira-albums-settings .hndle{display:none}form#post.envira-gallery #poststuff #envira-gallery-settings .inside,form#post.envira-gallery #poststuff #envira-albums-settings .inside{margin:0;padding:0}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav{width:160px;margin:0;padding:0;border-right:1px solid #ddd}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li{float:left;width:100%;margin:0;padding:0}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a{float:left;width:120px;margin:0 20px;padding:20px 0 20px 25px;text-decoration:none;color:#999;border-bottom:1px solid #ddd;background-position:left center;background-repeat:no-repeat;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;transition:none;-webkit-transition:none}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a:hover,form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a.envira-active,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a:hover,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a.envira-active{width:161px;margin:-1px 0 0 0;padding:20px 20px 20px 45px;text-decoration:none;color:#444;border-top:1px solid #ddd;border-bottom:1px solid #ddd;border-right:1px solid #fff;background-color:#fff;background-position:20px center}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a:focus,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li:last-child a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li:last-child a{border-bottom:none}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li:last-child a:hover,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li:last-child a:hover{border-bottom:none}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-images a,form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-galleries a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-images a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-galleries a{background-image:url(images/icons/leaf.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-config a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-config a{background-image:url(images/icons/configuration.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-lightbox a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-lightbox a{background-image:url(images/icons/lightbox.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-mobile a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-mobile a{background-image:url(images/icons/mobile.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-downloads a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-downloads a{background-image:url(images/icons/downloads.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-exif a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-exif a{background-image:url(images/icons/exif.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-pagination a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-pagination a{background-image:url(images/icons/pagination.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-pinterest a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-pinterest a{background-image:url(images/icons/pinterest.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-proofing a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-proofing a{background-image:url(images/icons/proofing.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-printing a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-printing a{background-image:url(images/icons/printing.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-slideshow a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-slideshow a{background-image:url(images/icons/slideshow.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-social a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-social a{background-image:url(images/icons/social.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-tags a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-tags a{background-image:url(images/icons/tags.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-videos a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-videos a{background-image:url(images/icons/video.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-watermarking a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-watermarking a{background-image:url(images/icons/watermark.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-woocommerce a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-woocommerce a{background-image:url(images/icons/woocommerce.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-misc a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-misc a{background-image:url(images/icons/misc.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs{margin:0 0 0 160px;padding:20px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;background:#fff;border-left:1px solid #ddd}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs h2,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs h2{clear:none}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table{clear:none;margin:0 0 40px 0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table.no-margin,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table.no-margin{margin:0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table th,form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table td,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table th,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table td{padding-top:30px;padding-bottom:30px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table label.full-width,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table label.full-width{display:block;margin:0 0 5px 0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table label.full-width:first-child,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table label.full-width:first-child{margin-top:5px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table textarea,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table textarea{width:100%}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table input[type=checkbox],form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table input[type=checkbox]{margin-bottom:2px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table p.description,form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table span.description,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table p.description,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table span.description{font-size:13px;font-style:italic;color:#666}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav{width:100%}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav.envira-tab-options,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav.envira-tab-options{margin:20px 0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons{position:absolute;color:#999}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons.dashicons-grid-view,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons.dashicons-grid-view{right:20px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons.dashicons-list-view,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons.dashicons-list-view{right:50px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons.selected,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons.selected{color:#23282d}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons span,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons span{display:inline-block;text-indent:-9999px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav.envira-select-options,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav.envira-select-options{display:none}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images ul#envira-gallery-output li,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images ul#envira-gallery-output li{cursor:move}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav{width:100%}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options{height:40px;margin:20px 0;position:relative}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options a.envira-galleries-add,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options a.envira-galleries-add{display:none;position:absolute;top:0;left:0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options input#envira-albums-gallery-search,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options input#envira-albums-gallery-search{position:absolute;top:0;right:0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav.envira-select-options,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav.envira-select-options{display:none}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li{cursor:move}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li a.envira-gallery-remove-image,form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li a.envira-gallery-modify-image,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li a.envira-gallery-remove-image,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li a.envira-gallery-modify-image{display:none}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs:after,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs:after{content:"";display:table;clear:both}form#post.envira-gallery #poststuff #envira-gallery-preview:after{content:"";display:table;clear:both}form#post.envira-gallery #poststuff #envira-gallery-preview button.handlediv{display:none}form#post.envira-gallery #poststuff #envira-gallery-preview h2.hndle{display:none}form#post.envira-gallery #poststuff #envira-gallery-preview .inside{margin:0;padding:20px}.media-modal .edit-attachment-frame .edit-media-header button.right{border-right:1px solid #ddd}.media-modal .uploader-inline a.envira-media-library.button{display:none}.media-modal .attachment.details{-webkit-box-shadow:inset 0 0 0 3px #fff,inset 0 0 0 7px #7cc048;box-shadow:inset 0 0 0 3px #fff,inset 0 0 0 7px #7cc048}.media-modal .attachment.details .check{background-color:#7cc048;-webkit-box-shadow:0 0 0 1px #fff,0 0 0 2px #7cc048;box-shadow:0 0 0 1px #fff,0 0 0 2px #7cc048}.media-modal ul.attachments.envira-albums-gallery-cover-image{padding:10px}.media-modal ul.attachments.envira-bulk-edit li.attachment{cursor:default}.media-modal ul.attachments.envira-bulk-edit li.attachment .attachment-preview{cursor:default}.media-modal .attachment-details .attachment-info{padding:16px}.media-modal .attachment-details .attachment-info .settings{margin:0;padding:0;border:none}.media-modal .attachment-details .attachment-info .settings .setting{margin:0 0 20px 0;padding:0 0 20px 0;border-bottom:1px solid #ddd}.media-modal .attachment-details .attachment-info .settings .setting input[type="text"],.media-modal .attachment-details .attachment-info .settings .setting textarea{display:block;width:100%;min-width:100%;margin:0}.media-modal .attachment-details .attachment-info .settings .setting input[type="checkbox"]{float:left;margin:7px 3px 0 0}.media-modal .attachment-details .attachment-info .settings .setting select{margin:0}.media-modal .attachment-details .attachment-info .settings .setting span.name{display:block;width:100%;min-width:100%;margin:0;padding:0;text-align:left;font-weight:700;font-size:14px}.media-modal .attachment-details .attachment-info .settings .setting span.description{text-align:left;font-style:normal;font-size:13px;font-style:italic;color:#666}.media-modal .attachment-details .attachment-info .settings .setting div.description{clear:both;float:left;margin:5px 0 0 0;text-align:left;font-size:13px;font-style:italic;color:#666}.media-modal .attachment-details .attachment-info div.actions a.button{display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.25), (min-resolution: 120dpi){.wp-core-ui a.check .media-modal-icon{background-image:url(../../../../../wp-includes/images/uploader-icons-2x.png) !important;-webkit-background-size:134px 15px;background-size:134px 15px}}@media screen and (max-width: 1100px){form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area{border-color:#d5d5d5}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop .drag-drop-inside,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop .drag-drop-inside{width:100%;margin-top:20px}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop .drag-drop-inside p.drag-drop-buttons,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop .drag-drop-inside p.drag-drop-buttons{text-align:center}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui a.envira-media-library.button,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui a.envira-media-library.button{left:0;right:0;width:235px;top:145px}}@media screen and (max-width: 768px){form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav{width:60px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a{width:60px;height:60px;margin:0;padding:0;text-indent:-9999px;background-position:center}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a:hover,form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a.envira-active,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a:hover,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a.envira-active{width:60px;height:60px;margin:0;padding:0;text-indent:-9999px;background-position:center}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs{margin:0 0 0 60px}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* ==========================================================================
2
+ metabox.css loads on any Envira Gallery and Album Create/Edit Screen
3
+
4
+ Any styles that will be used by the main Gallery / Album editor screen should be
5
+ added to this file
6
+ ========================================================================== */
7
+ /* ==========================================================================
8
+ Imports
9
+ ========================================================================== */
10
+ /* ==========================================================================
11
+ Variables SCSS
12
+ ========================================================================== */
13
+ /* ==========================================================================
14
+ Mixins
15
+ ========================================================================== */
16
+ /**
17
+ * Media Query
18
+ */
19
+ /**
20
+ * Border-Radius
21
+ */
22
+ /* ==========================================================================
23
+ Messages
24
+ ========================================================================== */
25
+ body.post-type-envira,
26
+ body.post-type-envira_album {
27
+ /**
28
+ * Add left and right margins to ensure the message notification horizontally lines up
29
+ * with the metaboxes
30
+ */ }
31
+ body.post-type-envira #message,
32
+ body.post-type-envira_album #message {
33
+ margin: 5px 20px 15px 20px; }
34
+
35
+ /* ==========================================================================
36
+ Form
37
+ - The envira-gallery class is assigned to the Gallery and Album Add/Edit screens form.
38
+ ========================================================================== */
39
+ form#post.envira-gallery {
40
+ /**
41
+ * Re-establish the left and right margins, so there's spacing between the Admin Menu
42
+ * and the content
43
+ */
44
+ margin: 0 20px;
45
+ /**
46
+ * Defined so we override WordPress' default styles
47
+ */ }
48
+ form#post.envira-gallery #poststuff {
49
+ /* ==========================================================================
50
+ Envira Gallery Shared Styles for Types and Settings
51
+ ========================================================================== */
52
+ /**
53
+ * Intro Text
54
+ */
55
+ /**
56
+ * Help Video
57
+ * - Can be placed inside p.envira-intro by JS, or outside p.envira-intro when
58
+ * viewing the Images tab for a Dynamic or Default Gallery
59
+ */
60
+ /**
61
+ * Image Grid
62
+ * - Used on the Images tab for Default Galleries, as well as the Preview Metabox
63
+ */
64
+ /* ==========================================================================
65
+ Envira Gallery Type
66
+ Envira Album Type
67
+ ========================================================================== */
68
+ /* ==========================================================================
69
+ Envira Albums Drag & Drop Area
70
+ ========================================================================== */
71
+ /* ==========================================================================
72
+ Envira Gallery Settings
73
+ Envira Albums Settings
74
+ ========================================================================== */
75
+ /* ==========================================================================
76
+ Envira Gallery Preview Metabox
77
+ ========================================================================== */ }
78
+ form#post.envira-gallery #poststuff p.envira-intro {
79
+ margin: 0;
80
+ padding: 0 0 30px 0;
81
+ border-bottom: 1px solid #ddd;
82
+ font-size: 16px;
83
+ font-weight: 700; }
84
+ form#post.envira-gallery #poststuff p.envira-intro small {
85
+ margin: 5px 0 0 0;
86
+ display: block;
87
+ font-weight: 400; }
88
+ form#post.envira-gallery #poststuff p.envira-intro small a {
89
+ text-decoration: none;
90
+ font-weight: 600; }
91
+ form#post.envira-gallery #poststuff div.envira-video-help {
92
+ position: relative;
93
+ z-index: 1;
94
+ width: 100%;
95
+ margin: 20px 0 0 0; }
96
+ form#post.envira-gallery #poststuff div.envira-video-help iframe {
97
+ position: relative;
98
+ z-index: 1;
99
+ width: 100%;
100
+ height: auto;
101
+ min-height: 300px; }
102
+ form#post.envira-gallery #poststuff div.envira-video-help a.envira-video-close {
103
+ position: absolute;
104
+ z-index: 2;
105
+ top: -12px;
106
+ right: -12px;
107
+ width: 24px;
108
+ height: 24px;
109
+ line-height: 24px;
110
+ -webkit-border-radius: 50%;
111
+ -moz-border-radius: 50%;
112
+ -o-border-radius: 50%;
113
+ border-radius: 50%;
114
+ background: #f5f5f5;
115
+ color: #000;
116
+ text-align: center;
117
+ text-decoration: none; }
118
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output {
119
+ width: 100%;
120
+ /**
121
+ * List View
122
+ */ }
123
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li {
124
+ position: relative;
125
+ display: inline-block;
126
+ width: 150px;
127
+ margin: 0 20px 20px 0;
128
+ padding: 0;
129
+ list-style: none;
130
+ vertical-align: top;
131
+ -moz-background-clip: padding;
132
+ -webkit-background-clip: padding-box;
133
+ background-clip: padding-box;
134
+ background: #f7f7f7;
135
+ /**
136
+ * If, for some reason, the image doesn't exist or fails to load,
137
+ * the placeholder logo is displayed
138
+ */
139
+ /**
140
+ * Metadata
141
+ */
142
+ /**
143
+ * Tick Icon
144
+ */
145
+ /**
146
+ * Edit / Delete Buttons
147
+ */
148
+ /**
149
+ * Selected state
150
+ */
151
+ /**
152
+ * Multiple selection sorting - stacks images when the user has selected more than one image + dragged them
153
+ */ }
154
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li img {
155
+ display: block;
156
+ width: 150px;
157
+ height: 150px; }
158
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.placeholder-image {
159
+ display: block;
160
+ width: 148px;
161
+ height: 149px;
162
+ background: url(images/icons/leaf.svg) center no-repeat;
163
+ background-size: 64px 64px;
164
+ border-left: 1px solid #dfdfdf;
165
+ border-top: 1px solid #dfdfdf;
166
+ border-right: 1px solid #dfdfdf; }
167
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta {
168
+ width: 148px;
169
+ overflow: hidden;
170
+ text-align: center;
171
+ border-left: 1px solid #dfdfdf;
172
+ border-bottom: 1px solid #dfdfdf;
173
+ border-right: 1px solid #dfdfdf;
174
+ /**
175
+ * Title
176
+ */
177
+ /**
178
+ * Additional metadata
179
+ */ }
180
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta div.title {
181
+ font-size: 12px;
182
+ font-weight: 700;
183
+ width: 138px;
184
+ height: 18px;
185
+ line-height: 18px;
186
+ margin: 8px 5px;
187
+ overflow: hidden;
188
+ /**
189
+ * Hint
190
+ * - Displays the full title on hover
191
+ */ }
192
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta div.title a.hint {
193
+ position: absolute;
194
+ display: inline-block;
195
+ bottom: 10px;
196
+ right: 10px;
197
+ width: 16px;
198
+ height: 16px;
199
+ background: #f7f7f7; }
200
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta div.title a.hint.hidden {
201
+ display: none; }
202
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta div.additional {
203
+ display: none;
204
+ margin: 5px 0 0 0;
205
+ font-weight: 400; }
206
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.check {
207
+ display: none;
208
+ position: absolute;
209
+ right: 5px;
210
+ top: 5px;
211
+ width: 24px;
212
+ height: 24px;
213
+ background-color: #eee;
214
+ -webkit-box-shadow: 0 0 0 1px #fff, 0 0 0 2px rgba(0, 0, 0, 0.15);
215
+ box-shadow: 0 0 0 1px #fff, 0 0 0 2px rgba(0, 0, 0, 0.15); }
216
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.check div.media-modal-icon {
217
+ display: none;
218
+ width: 15px;
219
+ height: 15px;
220
+ margin: 5px 0 0 5px;
221
+ background-position: -21px 0; }
222
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.dashicons {
223
+ position: absolute;
224
+ display: block;
225
+ top: 5px;
226
+ left: 5px;
227
+ width: 25px;
228
+ height: 25px;
229
+ line-height: 25px;
230
+ font-size: 18px;
231
+ /* Controls the icon size */
232
+ outline: none;
233
+ z-index: 20;
234
+ border-radius: 2px;
235
+ -moz-border-radius: 2px;
236
+ -webkit-border-radius: 2px; }
237
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.dashicons.envira-gallery-modify-image {
238
+ background: #0085ba;
239
+ color: #ffffff; }
240
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.dashicons.envira-gallery-remove-image {
241
+ left: 35px;
242
+ background: #e02626;
243
+ color: #ffffff; }
244
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.selected {
245
+ width: 148px;
246
+ border: 2px solid #7cc048 !important; }
247
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.selected a.check {
248
+ display: block;
249
+ background-color: #7cc048;
250
+ -webkit-box-shadow: 0 0 0 1px #fff, 0 0 0 2px #7cc048;
251
+ box-shadow: 0 0 0 1px #fff, 0 0 0 2px #7cc048; }
252
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.selected a.check div.media-modal-icon {
253
+ display: block; }
254
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.selected div.meta {
255
+ width: 146px; }
256
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.ui-sortable-helper li {
257
+ position: absolute;
258
+ top: 0;
259
+ left: 0; }
260
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li {
261
+ position: relative;
262
+ z-index: 2;
263
+ display: block;
264
+ width: 100%;
265
+ margin: 0 0 10px 0;
266
+ padding: 10px 15px;
267
+ background: #fff;
268
+ border: 1px solid #ddd;
269
+ -webkit-box-sizing: border-box;
270
+ -moz-box-sizing: border-box;
271
+ box-sizing: border-box;
272
+ border-radius: 2px;
273
+ -moz-border-radius: 2px;
274
+ -webkit-border-radius: 2px;
275
+ /**
276
+ * Metadata
277
+ */
278
+ /**
279
+ * Checkbox
280
+ * - Always display
281
+ */ }
282
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li img {
283
+ display: inline-block;
284
+ width: 75px;
285
+ margin-left: 45px; }
286
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li div.meta {
287
+ position: absolute;
288
+ z-index: 1;
289
+ left: 0;
290
+ display: inline-block;
291
+ width: 100%;
292
+ padding: 0 80px 0 150px;
293
+ border: none;
294
+ font-weight: 700;
295
+ text-align: left;
296
+ -webkit-box-sizing: border-box;
297
+ -moz-box-sizing: border-box;
298
+ box-sizing: border-box;
299
+ /**
300
+ * Title
301
+ */
302
+ /**
303
+ * Additional metadata
304
+ * - Displayed in list view
305
+ */ }
306
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li div.meta div.title {
307
+ display: block;
308
+ width: 100%;
309
+ height: auto;
310
+ font-size: 16px;
311
+ margin: 0;
312
+ padding: 0; }
313
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li div.meta div.title a.hint {
314
+ display: none; }
315
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li div.meta div.additional {
316
+ display: block; }
317
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li a.check {
318
+ display: block;
319
+ position: absolute;
320
+ left: 15px;
321
+ top: 35px; }
322
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li a.envira-gallery-remove-image {
323
+ left: auto;
324
+ top: 10px;
325
+ right: 10px; }
326
+ form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li a.envira-gallery-modify-image {
327
+ left: auto;
328
+ top: 10px;
329
+ right: 40px; }
330
+ form#post.envira-gallery #poststuff #envira-gallery {
331
+ margin: 60px 0 20px 0; }
332
+ form#post.envira-gallery #poststuff #envira-gallery,
333
+ form#post.envira-gallery #poststuff #envira-albums {
334
+ /**
335
+ * Hide the title bar of the metabox, so we have a seamless style
336
+ */
337
+ /**
338
+ * Tabs
339
+ * - Move up vertically so they sit above the metabox
340
+ */
341
+ /**
342
+ * Tab Settings
343
+ */ }
344
+ form#post.envira-gallery #poststuff #envira-gallery .handlediv,
345
+ form#post.envira-gallery #poststuff #envira-albums .handlediv {
346
+ display: none; }
347
+ form#post.envira-gallery #poststuff #envira-gallery .hndle,
348
+ form#post.envira-gallery #poststuff #envira-albums .hndle {
349
+ display: none; }
350
+ form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper,
351
+ form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper {
352
+ margin: -56px 0 0 -1px;
353
+ /* The height of the tab */
354
+ padding: 0;
355
+ border-bottom: none;
356
+ /**
357
+ * Increase tab sizes and style
358
+ */ }
359
+ form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab,
360
+ form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab {
361
+ display: inline-block;
362
+ width: 49%;
363
+ margin: 0;
364
+ padding: 15px 0;
365
+ text-align: center;
366
+ font-size: 16px;
367
+ border-color: #e5e5e5;
368
+ /* Matches the metabox border for a seamless UI */
369
+ background: #f5f5f5;
370
+ /**
371
+ * Envira Gallery Icon
372
+ */
373
+ /**
374
+ * External Gallery Tab
375
+ */
376
+ /**
377
+ * Hover and Active States
378
+ */
379
+ /**
380
+ * Focus State
381
+ * - Remove WordPress' blue focus box from tabs
382
+ */
383
+ /**
384
+ * Hides the radio input on a label
385
+ * The radio input will be selected when the label is clicked
386
+ */ }
387
+ form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab.nav-tab-native-envira-gallery span,
388
+ form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab.nav-tab-native-envira-gallery span {
389
+ display: inline-block;
390
+ background: url(images/icons/leaf.svg) 0 5px no-repeat;
391
+ background-size: 14px 14px;
392
+ text-indent: 20px; }
393
+ form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab.nav-tab-external-gallery,
394
+ form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab.nav-tab-external-gallery {
395
+ margin-right: -1px; }
396
+ form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab:hover, form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab.envira-active,
397
+ form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab:hover,
398
+ form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab.envira-active {
399
+ background: #ffffff;
400
+ border-bottom: 1px solid #ffffff; }
401
+ form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab:focus,
402
+ form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab:focus {
403
+ -webkit-box-shadow: none;
404
+ -moz-box-shadow: none;
405
+ box-shadow: none; }
406
+ form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab:last-child,
407
+ form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab:last-child {
408
+ float: right; }
409
+ form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab input[type=radio],
410
+ form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab input[type=radio] {
411
+ display: none; }
412
+ form#post.envira-gallery #poststuff #envira-gallery .inside,
413
+ form#post.envira-gallery #poststuff #envira-albums .inside {
414
+ margin: 0;
415
+ padding: 0;
416
+ /**
417
+ * Native Envira Gallery Uploader / Select Files
418
+ * - Styles the pluploader instance to look the way we want it
419
+ * - Also see responsive styles at the end of this file
420
+ */ }
421
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui,
422
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui {
423
+ /* Reserves the space needed for the drag-drop-area, which is loaded using JS */
424
+ height: 210px;
425
+ /**
426
+ * A drag-drop-area div is always output, whether we're on a touch
427
+ * device or not. WordPress will only style this div if its parent
428
+ * has the .drag-drop class (i.e. touch devices won't get any CSS styling)
429
+ *
430
+ * The below CSS ensures that the drag drop area looks consistent
431
+ * regardless of device used, and then adjusts the layout if drag-drop is supported.
432
+ */
433
+ /**
434
+ * Select Files from Other Sources Button
435
+ */
436
+ /**
437
+ * When the uploader supports drag and drop, a .drag-drop
438
+ * class is appended to #drag-drop-area by WordPress
439
+ *
440
+ * We use this to show certain descriptions
441
+ */
442
+ /**
443
+ * Upload Progress Bar
444
+ */ }
445
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area,
446
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area {
447
+ display: none;
448
+ border: 4px dashed #b4b9be;
449
+ height: 200px; }
450
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside,
451
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside {
452
+ margin: 0 auto 0 auto; }
453
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p,
454
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p {
455
+ display: block;
456
+ text-align: center;
457
+ color: #a0a5aa;
458
+ position: absolute;
459
+ top: 50%;
460
+ left: 50%;
461
+ margin: -10px 0 0 -10px;
462
+ /**
463
+ * "Drop Files here"
464
+ */ }
465
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p.drag-drop-info,
466
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p.drag-drop-info {
467
+ display: none;
468
+ font-size: 20px; }
469
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p.drag-drop-buttons,
470
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p.drag-drop-buttons {
471
+ text-align: center;
472
+ position: relative;
473
+ top: 20px;
474
+ left: 0;
475
+ margin: 0; }
476
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui a.envira-media-library.button,
477
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui a.envira-media-library.button {
478
+ display: none;
479
+ position: absolute;
480
+ margin: 0 auto;
481
+ left: 280px;
482
+ right: 0;
483
+ width: 230px;
484
+ top: 115px;
485
+ text-align: center; }
486
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside,
487
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside {
488
+ width: 520px;
489
+ margin: 50px auto 0 auto; }
490
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p,
491
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p {
492
+ position: relative;
493
+ top: 0;
494
+ left: 0;
495
+ margin: 0; }
496
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-info,
497
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-info {
498
+ display: block; }
499
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-buttons,
500
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-buttons {
501
+ margin: 10px 0 0 0;
502
+ text-align: left; }
503
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar,
504
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar {
505
+ display: none;
506
+ width: 100%;
507
+ position: relative;
508
+ height: 10px;
509
+ width: 100%;
510
+ margin: 10px auto;
511
+ border-radius: 10px;
512
+ background: #dfdfdf;
513
+ background: rgba(0, 0, 0, 0.1); }
514
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-inner,
515
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-inner {
516
+ height: 10px;
517
+ min-width: 20px;
518
+ width: 0;
519
+ background: #aaa;
520
+ background: rgba(0, 0, 0, 0.2);
521
+ border-radius: 10px;
522
+ -webkit-transition: width 300ms;
523
+ -moz-transition: width 300ms;
524
+ -ms-transition: width 300ms;
525
+ -o-transition: width 300ms;
526
+ transition: width 300ms; }
527
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-status,
528
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-status {
529
+ clear: both;
530
+ position: absolute;
531
+ right: 0;
532
+ width: 50%;
533
+ height: 30px;
534
+ margin: 12px 0 0 0;
535
+ text-align: right; }
536
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-status .done,
537
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-status .done {
538
+ display: none; }
539
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui p.upload-flash-bypass,
540
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui p.upload-flash-bypass {
541
+ display: none; }
542
+ form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab,
543
+ form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab {
544
+ padding: 20px;
545
+ /**
546
+ * External Gallery Types
547
+ */ }
548
+ form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav,
549
+ form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav {
550
+ text-align: center; }
551
+ form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li,
552
+ form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li {
553
+ display: inline-block;
554
+ margin: 0 20px 0 0;
555
+ vertical-align: top;
556
+ /**
557
+ * Hover State
558
+ * Selected State
559
+ */
560
+ /**
561
+ * Featured Content
562
+ */
563
+ /**
564
+ * Instagram
565
+ */ }
566
+ form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li:last-child,
567
+ form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li:last-child {
568
+ margin: 0; }
569
+ form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li label,
570
+ form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li label {
571
+ float: left;
572
+ width: 110px; }
573
+ form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li label input,
574
+ form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li label input {
575
+ display: none; }
576
+ form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li label div.icon,
577
+ form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li label div.icon {
578
+ width: 110px;
579
+ height: 110px;
580
+ margin: 0 0 10px 0;
581
+ border: 1px solid #ddd;
582
+ background-size: 64px 64px;
583
+ background-position: center;
584
+ background-repeat: no-repeat; }
585
+ form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li label div.title,
586
+ form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li label div.title {
587
+ font-weight: 700; }
588
+ form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li:hover label div.icon, form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li.envira-active label div.icon,
589
+ form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li:hover label div.icon,
590
+ form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li.envira-active label div.icon {
591
+ background-color: #f7fcf3;
592
+ border-color: #7cc048; }
593
+ form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li#envira-gallery-type-fc label div.icon,
594
+ form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li#envira-gallery-type-fc label div.icon {
595
+ background-image: url(../images/types/fc.png); }
596
+ form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab ul#envira-gallery-types-nav li#envira-gallery-type-instagram label div.icon,
597
+ form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab ul#envira-gallery-types-nav li#envira-gallery-type-instagram label div.icon {
598
+ background-image: url(../images/types/instagram.png); }
599
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native {
600
+ position: relative;
601
+ /**
602
+ * Galleries (Drop Target)
603
+ */
604
+ /**
605
+ * Drag & Drop Instructions
606
+ */ }
607
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native ul#envira-album-drag-drop-area {
608
+ z-index: 2;
609
+ min-height: 200px;
610
+ margin: 0;
611
+ padding: 20px;
612
+ border: 4px dashed #b4b9be;
613
+ -webkit-box-sizing: border-box;
614
+ -moz-box-sizing: border-box;
615
+ box-sizing: border-box; }
616
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native ul#envira-album-drag-drop-area li {
617
+ cursor: move; }
618
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native p.drag-drop-info {
619
+ position: absolute;
620
+ top: 80px;
621
+ z-index: 1;
622
+ margin: 0 auto;
623
+ left: 0;
624
+ right: 0;
625
+ text-align: center;
626
+ color: #a0a5aa;
627
+ font-size: 20px;
628
+ -webkit-box-sizing: border-box;
629
+ -moz-box-sizing: border-box;
630
+ box-sizing: border-box; }
631
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native p.drag-drop-info span {
632
+ display: block; }
633
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native p.drag-drop-info span.click {
634
+ font-size: 18px; }
635
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native p.drag-drop-info small {
636
+ display: block;
637
+ margin: 5px 0;
638
+ font-size: 14px; }
639
+ form#post.envira-gallery #poststuff #envira-gallery-settings,
640
+ form#post.envira-gallery #poststuff #envira-albums-settings {
641
+ background: #f7f7f7;
642
+ /* The background for tabs, full height */
643
+ /**
644
+ * Clearfix
645
+ */
646
+ /**
647
+ * Hide the title bar of the metabox, so we have a seamless style
648
+ */
649
+ /**
650
+ * Tabs
651
+ */
652
+ /**
653
+ * Settings
654
+ */ }
655
+ form#post.envira-gallery #poststuff #envira-gallery-settings:after,
656
+ form#post.envira-gallery #poststuff #envira-albums-settings:after {
657
+ content: "";
658
+ display: table;
659
+ clear: both; }
660
+ form#post.envira-gallery #poststuff #envira-gallery-settings .handlediv,
661
+ form#post.envira-gallery #poststuff #envira-albums-settings .handlediv {
662
+ display: none; }
663
+ form#post.envira-gallery #poststuff #envira-gallery-settings .hndle,
664
+ form#post.envira-gallery #poststuff #envira-albums-settings .hndle {
665
+ display: none; }
666
+ form#post.envira-gallery #poststuff #envira-gallery-settings .inside,
667
+ form#post.envira-gallery #poststuff #envira-albums-settings .inside {
668
+ margin: 0;
669
+ padding: 0; }
670
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav,
671
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav {
672
+ width: 160px;
673
+ margin: 0;
674
+ padding: 0;
675
+ border-right: 1px solid #ddd; }
676
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li,
677
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li {
678
+ float: left;
679
+ width: 100%;
680
+ margin: 0;
681
+ padding: 0;
682
+ /**
683
+ * Last Item
684
+ */
685
+ /**
686
+ * Tab Icons
687
+ */ }
688
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a,
689
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a {
690
+ float: left;
691
+ width: 120px;
692
+ margin: 0 20px;
693
+ padding: 20px 0 20px 25px;
694
+ text-decoration: none;
695
+ color: #999;
696
+ border-bottom: 1px solid #ddd;
697
+ background-position: left center;
698
+ background-repeat: no-repeat;
699
+ -webkit-box-sizing: border-box;
700
+ -moz-box-sizing: border-box;
701
+ box-sizing: border-box;
702
+ transition: none;
703
+ -webkit-transition: none;
704
+ /**
705
+ * Hover and Active States
706
+ */
707
+ /**
708
+ * Focus State
709
+ * - Remove WordPress' blue focus box from tabs
710
+ */ }
711
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a:hover, form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a.envira-active,
712
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a:hover,
713
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a.envira-active {
714
+ width: 161px;
715
+ margin: -1px 0 0 0;
716
+ padding: 20px 20px 20px 45px;
717
+ text-decoration: none;
718
+ color: #444;
719
+ border-top: 1px solid #ddd;
720
+ border-bottom: 1px solid #ddd;
721
+ border-right: 1px solid #ffffff;
722
+ background-color: #ffffff;
723
+ background-position: 20px center; }
724
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a:focus,
725
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a:focus {
726
+ -webkit-box-shadow: none;
727
+ -moz-box-shadow: none;
728
+ box-shadow: none; }
729
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li:last-child a,
730
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li:last-child a {
731
+ border-bottom: none; }
732
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li:last-child a:hover,
733
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li:last-child a:hover {
734
+ border-bottom: none; }
735
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-images a, form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-galleries a,
736
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-images a,
737
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-galleries a {
738
+ background-image: url(images/icons/leaf.svg);
739
+ background-size: 16px 16px; }
740
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-config a,
741
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-config a {
742
+ background-image: url(images/icons/configuration.svg);
743
+ background-size: 16px 16px; }
744
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-lightbox a,
745
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-lightbox a {
746
+ background-image: url(images/icons/lightbox.svg);
747
+ background-size: 16px 16px; }
748
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-mobile a,
749
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-mobile a {
750
+ background-image: url(images/icons/mobile.svg);
751
+ background-size: 16px 16px; }
752
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-breadcrumbs a,
753
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-breadcrumbs a {
754
+ background-image: url(images/icons/breadcrumbs.svg);
755
+ background-size: 16px 16px; }
756
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-comments a,
757
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-comments a {
758
+ background-image: url(images/icons/comments.svg);
759
+ background-size: 16px 16px; }
760
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-downloads a,
761
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-downloads a {
762
+ background-image: url(images/icons/downloads.svg);
763
+ background-size: 16px 16px; }
764
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-exif a,
765
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-exif a {
766
+ background-image: url(images/icons/exif.svg);
767
+ background-size: 16px 16px; }
768
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-pagination a,
769
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-pagination a {
770
+ background-image: url(images/icons/pagination.svg);
771
+ background-size: 16px 16px; }
772
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-pinterest a,
773
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-pinterest a {
774
+ background-image: url(images/icons/pinterest.svg);
775
+ background-size: 16px 16px; }
776
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-proofing a,
777
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-proofing a {
778
+ background-image: url(images/icons/proofing.svg);
779
+ background-size: 16px 16px; }
780
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-printing a,
781
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-printing a {
782
+ background-image: url(images/icons/printing.svg);
783
+ background-size: 16px 16px; }
784
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-slideshow a,
785
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-slideshow a {
786
+ background-image: url(images/icons/slideshow.svg);
787
+ background-size: 16px 16px; }
788
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-social a,
789
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-social a {
790
+ background-image: url(images/icons/social.svg);
791
+ background-size: 16px 16px; }
792
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-tags a,
793
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-tags a {
794
+ background-image: url(images/icons/tags.svg);
795
+ background-size: 16px 16px; }
796
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-videos a,
797
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-videos a {
798
+ background-image: url(images/icons/video.svg);
799
+ background-size: 16px 16px; }
800
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-watermarking a,
801
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-watermarking a {
802
+ background-image: url(images/icons/watermark.svg);
803
+ background-size: 16px 16px; }
804
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-woocommerce a,
805
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-woocommerce a {
806
+ background-image: url(images/icons/woocommerce.svg);
807
+ background-size: 16px 16px; }
808
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-misc a,
809
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-misc a {
810
+ background-image: url(images/icons/misc.svg);
811
+ background-size: 16px 16px; }
812
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs,
813
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs {
814
+ margin: 0 0 0 160px;
815
+ /* Must match #ul#envira-tabs-nav width */
816
+ padding: 20px;
817
+ -webkit-box-sizing: border-box;
818
+ -moz-box-sizing: border-box;
819
+ box-sizing: border-box;
820
+ background: #ffffff;
821
+ border-left: 1px solid #ddd;
822
+ /**
823
+ * Headings
824
+ */
825
+ /**
826
+ * All Tabs
827
+ */
828
+ /**
829
+ * Tab: Images
830
+ */
831
+ /**
832
+ * Tab: Galleries
833
+ * - Used on Albums
834
+ */
835
+ /**
836
+ * Clearfix
837
+ */ }
838
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs h2,
839
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs h2 {
840
+ clear: none; }
841
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table,
842
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table {
843
+ clear: none;
844
+ margin: 0 0 40px 0;
845
+ /**
846
+ * Row padding
847
+ */
848
+ /**
849
+ * Sub Headings
850
+ * - Used to denote an Addon's settings within a settings tab e.g. the Mobile tab
851
+ */
852
+ /**
853
+ * Full width labels (used for checkboxes that we don't want to be inline)
854
+ */
855
+ /**
856
+ * Full width textareas
857
+ */
858
+ /**
859
+ * Checkbox alignment
860
+ */
861
+ /**
862
+ * Descriptions
863
+ */ }
864
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table.no-margin,
865
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table.no-margin {
866
+ margin: 0; }
867
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table th, form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table td,
868
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table th,
869
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table td {
870
+ padding-top: 20px;
871
+ padding-bottom: 20px; }
872
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table tr.sub-heading th,
873
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table tr.sub-heading th {
874
+ margin: 0;
875
+ padding: 20px 0 0 0;
876
+ font-style: italic;
877
+ font-weight: 400;
878
+ font-size: 16px; }
879
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table label.full-width,
880
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table label.full-width {
881
+ display: block;
882
+ margin: 0 0 5px 0; }
883
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table label.full-width:first-child,
884
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table label.full-width:first-child {
885
+ margin-top: 5px; }
886
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table textarea,
887
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table textarea {
888
+ width: 100%; }
889
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table input[type=checkbox],
890
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table input[type=checkbox] {
891
+ margin-bottom: 2px; }
892
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table p.description,
893
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table span.description,
894
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table p.description,
895
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table span.description {
896
+ font-size: 13px;
897
+ font-style: italic;
898
+ color: #666; }
899
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images,
900
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images {
901
+ /**
902
+ * Inline Navigation
903
+ * - Select All
904
+ * - List View / Grid View
905
+ * - Edit / Delete Selected Items
906
+ */
907
+ /**
908
+ * Images
909
+ * - Show move cursor
910
+ */ }
911
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav,
912
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav {
913
+ width: 100%;
914
+ /**
915
+ * Edit / Delete Selected
916
+ * - Hidden by default, shown by JS when image(s) are selected
917
+ */ }
918
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav.envira-tab-options,
919
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav.envira-tab-options {
920
+ margin: 20px 0; }
921
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons,
922
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons {
923
+ position: absolute;
924
+ color: #999; }
925
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons.dashicons-grid-view,
926
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons.dashicons-grid-view {
927
+ right: 20px; }
928
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons.dashicons-list-view,
929
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons.dashicons-list-view {
930
+ right: 50px; }
931
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons.selected,
932
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons.selected {
933
+ color: #23282d; }
934
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons span,
935
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons span {
936
+ display: inline-block;
937
+ text-indent: -9999px; }
938
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav.envira-select-options,
939
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav.envira-select-options {
940
+ display: none; }
941
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images ul#envira-gallery-output li,
942
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images ul#envira-gallery-output li {
943
+ cursor: move; }
944
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries,
945
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries {
946
+ /**
947
+ * Inline Navigation
948
+ * - Search
949
+ */
950
+ /**
951
+ * Images
952
+ * - Show move cursor
953
+ * - Hide Edit & Delete icons, as these are only displayed when the gallery is assigned to the Album
954
+ */ }
955
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav,
956
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav {
957
+ width: 100%;
958
+ /**
959
+ * Bulk Action Buttons
960
+ * - Hidden by default, shown by JS when galleries(s) are selected
961
+ */ }
962
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options,
963
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options {
964
+ height: 40px;
965
+ margin: 20px 0;
966
+ position: relative;
967
+ /**
968
+ * Add Galleries to Album Button
969
+ */
970
+ /**
971
+ * Search
972
+ */ }
973
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options a.envira-galleries-add,
974
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options a.envira-galleries-add {
975
+ display: none;
976
+ /* Displayed via JS when Galleries selected */
977
+ position: absolute;
978
+ top: 0;
979
+ left: 0; }
980
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options input#envira-albums-gallery-search,
981
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options input#envira-albums-gallery-search {
982
+ position: absolute;
983
+ top: 0;
984
+ right: 0; }
985
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav.envira-select-options,
986
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav.envira-select-options {
987
+ display: none; }
988
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li,
989
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li {
990
+ cursor: move; }
991
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li a.envira-gallery-remove-image,
992
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li a.envira-gallery-modify-image,
993
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li a.envira-gallery-remove-image,
994
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li a.envira-gallery-modify-image {
995
+ display: none; }
996
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs:after,
997
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs:after {
998
+ content: "";
999
+ display: table;
1000
+ clear: both; }
1001
+ form#post.envira-gallery #poststuff #envira-gallery-preview {
1002
+ /**
1003
+ * Clearfix
1004
+ */
1005
+ /**
1006
+ * Hide the title bar of the metabox, so we have a seamless style
1007
+ */ }
1008
+ form#post.envira-gallery #poststuff #envira-gallery-preview:after {
1009
+ content: "";
1010
+ display: table;
1011
+ clear: both; }
1012
+ form#post.envira-gallery #poststuff #envira-gallery-preview button.handlediv {
1013
+ display: none; }
1014
+ form#post.envira-gallery #poststuff #envira-gallery-preview h2.hndle {
1015
+ display: none; }
1016
+ form#post.envira-gallery #poststuff #envira-gallery-preview .inside {
1017
+ margin: 0;
1018
+ padding: 20px; }
1019
+
1020
+ /* ==========================================================================
1021
+ Media Modal (Insert Images and Edit Metadata)
1022
+ ========================================================================== */
1023
+ .media-modal {
1024
+ /**
1025
+ * Header Buttons
1026
+ */
1027
+ /**
1028
+ * Upload
1029
+ */
1030
+ /**
1031
+ * Insert
1032
+ */
1033
+ /**
1034
+ * Attachments
1035
+ * - Ensures that images fill each <li> attachment block, providing compatibility from WordPress 4.0 upwards
1036
+ * - Removed as breaks 4.4, 4.5
1037
+ ul.attachments {
1038
+ li.attachment {
1039
+ width: 20%;
1040
+
1041
+ img {
1042
+ width: 100%;
1043
+ height: 100%;
1044
+ }
1045
+ }
1046
+ }
1047
+ */
1048
+ /**
1049
+ * Albums: Select Gallery Cover Image
1050
+ * - Add some top spacing so that a selected cover image that's on the first line of the results
1051
+ * doesn't have its checkmark cut off
1052
+ */
1053
+ /**
1054
+ * Bulk Edit Attachments
1055
+ * - Restore cursor to default, so the user doesn't think they can click an image
1056
+ */
1057
+ /**
1058
+ * Edit
1059
+ */ }
1060
+ .media-modal .edit-attachment-frame .edit-media-header button.right {
1061
+ border-right: 1px solid #ddd; }
1062
+ .media-modal .uploader-inline {
1063
+ /**
1064
+ * Don't display the 'Select Files from Other Sources' button that we add to plupload
1065
+ * when we're in a modal.
1066
+ */ }
1067
+ .media-modal .uploader-inline a.envira-media-library.button {
1068
+ display: none; }
1069
+ .media-modal .attachment.details {
1070
+ -webkit-box-shadow: inset 0 0 0 3px #fff, inset 0 0 0 7px #7cc048;
1071
+ box-shadow: inset 0 0 0 3px #fff, inset 0 0 0 7px #7cc048; }
1072
+ .media-modal .attachment.details .check {
1073
+ background-color: #7cc048;
1074
+ -webkit-box-shadow: 0 0 0 1px #fff, 0 0 0 2px #7cc048;
1075
+ box-shadow: 0 0 0 1px #fff, 0 0 0 2px #7cc048; }
1076
+ .media-modal ul.attachments.envira-albums-gallery-cover-image {
1077
+ padding: 10px; }
1078
+ .media-modal ul.attachments.envira-bulk-edit li.attachment {
1079
+ cursor: default; }
1080
+ .media-modal ul.attachments.envira-bulk-edit li.attachment .attachment-preview {
1081
+ cursor: default; }
1082
+ .media-modal .attachment-details .attachment-info {
1083
+ padding: 16px;
1084
+ /**
1085
+ * Settings
1086
+ * - Contains one or more setting elements (Title, Alt etc)
1087
+ */
1088
+ /**
1089
+ * Actions
1090
+ * - Save Button
1091
+ * - Spinner
1092
+ */ }
1093
+ .media-modal .attachment-details .attachment-info .settings {
1094
+ margin: 0;
1095
+ padding: 0;
1096
+ border: none;
1097
+ /**
1098
+ * Individual Setting (Title, Alt etc)
1099
+ */ }
1100
+ .media-modal .attachment-details .attachment-info .settings .setting {
1101
+ margin: 0 0 20px 0;
1102
+ padding: 0 0 20px 0;
1103
+ border-bottom: 1px solid #ddd;
1104
+ /**
1105
+ * Input
1106
+ */ }
1107
+ .media-modal .attachment-details .attachment-info .settings .setting input[type="text"],
1108
+ .media-modal .attachment-details .attachment-info .settings .setting textarea {
1109
+ display: block;
1110
+ width: 100%;
1111
+ min-width: 100%;
1112
+ margin: 0; }
1113
+ .media-modal .attachment-details .attachment-info .settings .setting input[type="checkbox"] {
1114
+ float: left;
1115
+ margin: 7px 3px 0 0; }
1116
+ .media-modal .attachment-details .attachment-info .settings .setting select {
1117
+ margin: 0; }
1118
+ .media-modal .attachment-details .attachment-info .settings .setting span {
1119
+ /**
1120
+ * Title
1121
+ */
1122
+ /**
1123
+ * Description
1124
+ */ }
1125
+ .media-modal .attachment-details .attachment-info .settings .setting span.name {
1126
+ display: block;
1127
+ width: 100%;
1128
+ min-width: 100%;
1129
+ margin: 0;
1130
+ padding: 0;
1131
+ text-align: left;
1132
+ font-weight: 700;
1133
+ font-size: 14px; }
1134
+ .media-modal .attachment-details .attachment-info .settings .setting span.description {
1135
+ text-align: left;
1136
+ font-style: normal;
1137
+ font-size: 13px;
1138
+ font-style: italic;
1139
+ color: #666; }
1140
+ .media-modal .attachment-details .attachment-info .settings .setting div.description {
1141
+ clear: both;
1142
+ float: left;
1143
+ margin: 5px 0 0 0;
1144
+ text-align: left;
1145
+ font-size: 13px;
1146
+ font-style: italic;
1147
+ color: #666; }
1148
+ .media-modal .attachment-details .attachment-info div.actions {
1149
+ /**
1150
+ * Ensure button renders at correct height
1151
+ */ }
1152
+ .media-modal .attachment-details .attachment-info div.actions a.button {
1153
+ display: inline-block; }
1154
+
1155
+ /* ==========================================================================
1156
+ Retina
1157
+ ========================================================================== */
1158
+ @media (-webkit-min-device-pixel-ratio: 1.25), (min-resolution: 120dpi) {
1159
+ /**
1160
+ * WP media-views.css doesn't use .wp-core-ui for the x2 icons, therefore they never get applied
1161
+ */
1162
+ .wp-core-ui a.check .media-modal-icon {
1163
+ background-image: url(../../../../../wp-includes/images/uploader-icons-2x.png) !important;
1164
+ -webkit-background-size: 134px 15px;
1165
+ background-size: 134px 15px; } }
1166
+ /* ==========================================================================
1167
+ Responsive
1168
+ ========================================================================== */
1169
+ @media screen and (max-width: 1100px) {
1170
+ /* ==========================================================================
1171
+ Form
1172
+ - The envira-gallery class is assigned to the Gallery and Album Add/Edit screens form.
1173
+ ========================================================================== */
1174
+ form#post.envira-gallery #poststuff #envira-gallery,
1175
+ form#post.envira-gallery #poststuff #envira-albums {
1176
+ /**
1177
+ * Tab Settings
1178
+ */ }
1179
+ form#post.envira-gallery #poststuff #envira-gallery .inside,
1180
+ form#post.envira-gallery #poststuff #envira-albums .inside {
1181
+ /**
1182
+ * Native Envira Gallery
1183
+ */ }
1184
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area,
1185
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area {
1186
+ border-color: #d5d5d5; }
1187
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside,
1188
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside {
1189
+ width: 100%;
1190
+ margin-top: 20px; }
1191
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-buttons,
1192
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-buttons {
1193
+ text-align: center; }
1194
+ form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui a.envira-media-library.button,
1195
+ form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui a.envira-media-library.button {
1196
+ left: 0;
1197
+ right: 0;
1198
+ width: 235px;
1199
+ top: 145px; } }
1200
+ @media screen and (max-width: 768px) {
1201
+ /* ==========================================================================
1202
+ Form
1203
+ - The envira-gallery class is assigned to the Gallery and Album Add/Edit screens form.
1204
+ ========================================================================== */
1205
+ form#post.envira-gallery #poststuff {
1206
+ /* ==========================================================================
1207
+ Envira Gallery Settings
1208
+ Envira Albums Settings
1209
+ ========================================================================== */ }
1210
+ form#post.envira-gallery #poststuff #envira-gallery-settings,
1211
+ form#post.envira-gallery #poststuff #envira-albums-settings {
1212
+ /**
1213
+ * Tabs
1214
+ */
1215
+ /**
1216
+ * Settings
1217
+ */ }
1218
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav,
1219
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav {
1220
+ width: 60px; }
1221
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a,
1222
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a {
1223
+ width: 60px;
1224
+ height: 60px;
1225
+ margin: 0;
1226
+ padding: 0;
1227
+ text-indent: -9999px;
1228
+ background-position: center; }
1229
+ form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a:hover, form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a.envira-active,
1230
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a:hover,
1231
+ form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a.envira-active {
1232
+ width: 60px;
1233
+ height: 60px;
1234
+ margin: 0;
1235
+ padding: 0;
1236
+ text-indent: -9999px;
1237
+ background-position: center; }
1238
+ form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs,
1239
+ form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs {
1240
+ margin: 0 0 0 60px;
1241
+ /* Must match #ul#envira-tabs-nav width */ } }
assets/css/settings.css CHANGED
@@ -1 +1 @@
1
- .envira-tab label{margin-top:7px;display:block}.nav-tab{float:left}#envira-gallery-settings{padding:20px 0}#envira-gallery-settings #envira-gallery-refresh-submit{margin-left:10px}#envira-gallery-settings .envira-hideme{display:none}#envira-gallery-settings .envira-clear{clear:both}#envira-gallery-settings .envira-clear:after{clear:both;content:'.';display:block;height:0;line-height:0;overflow:auto;visibility:hidden;zoom:1}#envira-gallery-settings .envira-gallery{margin:15px 0 20px}#envira-gallery-settings .envira-tab{display:none}#envira-gallery-settings .envira-tab.envira-active{display:block}#envira-gallery-settings .envira-tab th{width:170px;padding-right:40px}@media (max-width: 767px){#envira-gallery-settings .envira-tab th{width:auto}}#envira-gallery-settings .envira-tab input[type="text"],#envira-gallery-settings .envira-tab input[type="number"],#envira-gallery-settings .envira-tab input[type="password"],#envira-gallery-settings .envira-tab select,#envira-gallery-settings .envira-tab textarea{width:350px;padding-right:0;font-size:13px}@media (max-width: 767px){#envira-gallery-settings .envira-tab input[type="text"],#envira-gallery-settings .envira-tab input[type="number"],#envira-gallery-settings .envira-tab input[type="password"],#envira-gallery-settings .envira-tab select,#envira-gallery-settings .envira-tab textarea{width:100%}}#envira-gallery-settings .envira-tab input[type="text"],#envira-gallery-settings .envira-tab input[type="number"],#envira-gallery-settings .envira-tab input[type="password"]{height:32px}@media (max-width: 767px){#envira-gallery-settings .envira-tab input[type="text"],#envira-gallery-settings .envira-tab input[type="number"],#envira-gallery-settings .envira-tab input[type="password"]{height:auto}}#envira-gallery-settings .envira-tab #envira-gallery-settings-submit{margin:40px 0 0 0px}#envira-gallery-settings #envira-gallery-refresh-submit{vertical-align:baseline}#envira-tabs .form-table th,#envira-tabs .form-table td{padding-top:40px;padding-bottom:40px}@media (min-width: 768px) and (max-width: 991px){#envira-tabs .form-table th{padding-top:40px;padding-bottom:10px;padding-right:0px !important}}@media (max-width: 767px){#envira-tabs .form-table th{padding-top:40px;padding-bottom:10px;padding-right:0px !important}}@media (min-width: 768px) and (max-width: 991px){#envira-tabs .form-table tr#envira-settings-key-box th{padding-top:20px}}@media (max-width: 767px){#envira-tabs .form-table tr#envira-settings-key-box th{padding-top:20px}}@media (min-width: 768px) and (max-width: 991px){#envira-tabs .form-table td{padding-top:0;padding-right:0px}}@media (max-width: 767px){#envira-tabs .form-table td{padding-top:0;padding-right:0px}}#envira-tabs .form-table tr{border-bottom:1px solid #ddd}#envira-tabs .form-table tr.no-bottom-border{border-bottom:0}#envira-tabs .description{color:#666;font-size:13px;margin-top:10px}#envira-tabs-nav{border-bottom:0 !important;background-color:#fff;height:50px;padding-left:20px;margin:0 0 0 -20px;display:table;width:100%}@media (max-width: 767px){#envira-tabs-nav{height:auto;background-color:transparent;margin:5px 0 0 0;padding:0 10px;display:table}}#envira-tabs-nav a{float:left;border-left:1px solid #f1f1f1;border-right:1px solid #f1f1f1;border-top:0;color:#6b6e72;background:none;line-height:50px;font-size:13px;padding:0 15px;margin:0}@media (max-width: 767px){#envira-tabs-nav a{-webkit-border-radius:5px;-moz-border-radius:5px;-o-border-radius:5px;border-radius:5px;background-color:#f7f7f7;padding:0px 20px;margin:5px 5px 0px 0;border:1px solid #ddd;line-height:35px;min-height:30px}}#envira-tabs-nav .envira-active{background-color:#f1f1f1;border-left:0;border-right:0;border-top:0;color:#000}@media (max-width: 767px){#envira-tabs-nav .envira-active{background-color:#6b6e72;color:#fff}}@media (max-width: 767px){#envira-tabs-nav a:hover{background-color:#6b6e72;color:#fff}}@media only screen and (max-width: 770px){#envira-gallery-settings #envira-gallery-settings-submit{margin:40px 0 0 0}}
1
+ .envira-tab label{margin-top:7px;display:block}.nav-tab{float:left}#envira-gallery-settings{padding:20px 0}#envira-gallery-settings #envira-gallery-refresh-submit{margin-left:10px}#envira-gallery-settings .envira-hideme{display:none}#envira-gallery-settings .envira-clear{clear:both}#envira-gallery-settings .envira-clear:after{clear:both;content:'.';display:block;height:0;line-height:0;overflow:auto;visibility:hidden;zoom:1}#envira-gallery-settings .envira-gallery{margin:15px 0 20px}#envira-gallery-settings .envira-tab{display:none}#envira-gallery-settings .envira-tab.envira-active{display:block}#envira-gallery-settings .envira-tab th{width:170px;padding-right:40px}@media (min-width: 600px) and (max-width: 767px){#envira-gallery-settings .envira-tab th{width:auto}}#envira-gallery-settings .envira-tab input[type="text"],#envira-gallery-settings .envira-tab input[type="number"],#envira-gallery-settings .envira-tab input[type="password"],#envira-gallery-settings .envira-tab select,#envira-gallery-settings .envira-tab textarea{width:350px;padding-right:0;font-size:13px}@media (min-width: 600px) and (max-width: 767px){#envira-gallery-settings .envira-tab input[type="text"],#envira-gallery-settings .envira-tab input[type="number"],#envira-gallery-settings .envira-tab input[type="password"],#envira-gallery-settings .envira-tab select,#envira-gallery-settings .envira-tab textarea{width:100%}}#envira-gallery-settings .envira-tab input[type="text"],#envira-gallery-settings .envira-tab input[type="number"],#envira-gallery-settings .envira-tab input[type="password"]{height:32px}@media (min-width: 600px) and (max-width: 767px){#envira-gallery-settings .envira-tab input[type="text"],#envira-gallery-settings .envira-tab input[type="number"],#envira-gallery-settings .envira-tab input[type="password"]{height:auto}}#envira-gallery-settings .envira-tab a.envira-clipboard{width:33px;padding:0}#envira-gallery-settings .envira-tab #envira-gallery-settings-submit{margin:40px 0 0 0px}#envira-gallery-settings #envira-gallery-refresh-submit{vertical-align:baseline}#envira-tabs .form-table th,#envira-tabs .form-table td{padding-top:40px;padding-bottom:40px}@media (min-width: 768px) and (max-width: 991px){#envira-tabs .form-table th{padding-top:40px;padding-bottom:10px;padding-right:0px !important}}@media (min-width: 600px) and (max-width: 767px){#envira-tabs .form-table th{padding-top:40px;padding-bottom:10px;padding-right:0px !important}}@media (min-width: 768px) and (max-width: 991px){#envira-tabs .form-table tr#envira-settings-key-box th{padding-top:20px}}@media (min-width: 600px) and (max-width: 767px){#envira-tabs .form-table tr#envira-settings-key-box th{padding-top:20px}}@media (min-width: 768px) and (max-width: 991px){#envira-tabs .form-table td{padding-top:0;padding-right:0px}}@media (min-width: 600px) and (max-width: 767px){#envira-tabs .form-table td{padding-top:0;padding-right:0px}}#envira-tabs .form-table tr{border-bottom:1px solid #ddd}#envira-tabs .form-table tr.no-bottom-border{border-bottom:0}#envira-tabs .description{color:#666;font-size:13px;margin-top:10px}#envira-tabs-nav{border-bottom:0 !important;background-color:#fff;height:50px;padding-left:20px;margin:0 0 0 -20px;display:table;width:100%}@media (min-width: 600px) and (max-width: 767px){#envira-tabs-nav{height:auto;background-color:transparent;margin:5px 0 0 0;padding:0 10px;display:table}}#envira-tabs-nav a{float:left;border-left:1px solid #f1f1f1;border-right:1px solid #f1f1f1;border-top:0;color:#6b6e72;background:none;line-height:50px;font-size:13px;padding:0 15px;margin:0}@media (min-width: 600px) and (max-width: 767px){#envira-tabs-nav a{-webkit-border-radius:5px;-moz-border-radius:5px;-o-border-radius:5px;border-radius:5px;background-color:#f7f7f7;padding:0px 20px;margin:5px 5px 0px 0;border:1px solid #ddd;line-height:35px;min-height:30px}}#envira-tabs-nav .envira-active{background-color:#f1f1f1;border-left:0;border-right:0;border-top:0;color:#000}@media (min-width: 600px) and (max-width: 767px){#envira-tabs-nav .envira-active{background-color:#6b6e72;color:#fff}}@media (min-width: 600px) and (max-width: 767px){#envira-tabs-nav a:hover{background-color:#6b6e72;color:#fff}}@media only screen and (max-width: 770px){#envira-gallery-settings #envira-gallery-settings-submit{margin:40px 0 0 0}}
assets/js/admin.js CHANGED
@@ -7,7 +7,10 @@
7
  */
8
  jQuery( document ).ready( function( $ ) {
9
 
10
- /**
 
 
 
11
  * Copy to Clipboard
12
  */
13
  if ( typeof Clipboard !== 'undefined' ) {
@@ -17,7 +20,7 @@ jQuery( document ).ready( function( $ ) {
17
  } );
18
  }
19
 
20
- /**
21
  * Dismissable Notices
22
  * - Sends an AJAX request to mark the notice as dismissed
23
  */
@@ -32,12 +35,12 @@ jQuery( document ).ready( function( $ ) {
32
  $.post(
33
  envira_gallery_admin.ajax,
34
  {
35
- action: 'envira_gallery_ajax_dismiss_notice',
36
- nonce: envira_gallery_admin.dismiss_notice_nonce,
37
- notice: $( this ).parent().data( 'notice' )
38
  },
39
  function( response ) {
40
- },
41
  'json'
42
  );
43
  }
7
  */
8
  jQuery( document ).ready( function( $ ) {
9
 
10
+ $("#screen-meta-links").prependTo("#envira-header-temp");
11
+ $("#screen-meta").prependTo("#envira-header-temp");
12
+
13
+ /**
14
  * Copy to Clipboard
15
  */
16
  if ( typeof Clipboard !== 'undefined' ) {
20
  } );
21
  }
22
 
23
+ /**
24
  * Dismissable Notices
25
  * - Sends an AJAX request to mark the notice as dismissed
26
  */
35
  $.post(
36
  envira_gallery_admin.ajax,
37
  {
38
+ action: 'envira_gallery_ajax_dismiss_notice',
39
+ nonce: envira_gallery_admin.dismiss_notice_nonce,
40
+ notice: $( this ).parent().data( 'notice' )
41
  },
42
  function( response ) {
43
+ },
44
  'json'
45
  );
46
  }
assets/js/conditional-fields.js CHANGED
@@ -38,6 +38,7 @@ jQuery( document ).ready( function( $ ) {
38
 
39
  // Setup conditionals on each DOM element
40
  this.each(function() {
 
41
  // Check for conditional elements
42
  if ( typeof $( this ).data( settings.data ) === 'undefined' ) {
43
  return true;
38
 
39
  // Setup conditionals on each DOM element
40
  this.each(function() {
41
+
42
  // Check for conditional elements
43
  if ( typeof $( this ).data( settings.data ) === 'undefined' ) {
44
  return true;
assets/js/editor.js CHANGED
@@ -1,463 +1,44 @@
1
- /**
2
- * Controller: Modal Window
3
- * - Used by most Envira Backbone views to display information e.g. bulk edit, edit single image etc.
4
- */
5
- if ( typeof EnviraGalleryModalWindow == 'undefined' ) {
6
-
7
- var EnviraGalleryModalWindow = new wp.media.view.Modal( {
8
- controller: {
9
- trigger: function() {
10
- }
11
- }
12
- } );
13
-
14
- }
15
-
16
- /**
17
- * View: Error
18
- * - Renders a WordPress style error message when something goes wrong.
19
- *
20
- * @since 1.4.3.0
21
- */
22
- wp.media.view.EnviraGalleryError = wp.Backbone.View.extend( {
23
-
24
- // The outer tag and class name to use. The item is wrapped in this
25
- tagName : 'div',
26
- className : 'notice error envira-gallery-error',
27
-
28
- render: function() {
29
-
30
- // Load the template to render
31
- // See includes/admin/media-views.php
32
- this.template = wp.media.template( 'envira-gallery-error' );
33
-
34
- // Define the HTML for the template
35
- this.$el.html( this.template( this.model ) );
36
-
37
- // Return the template
38
- return this;
39
-
40
- }
41
-
42
- } );
43
-
44
- /**
45
- * View: Single Item (Gallery or Album)
46
- * - Renders an <li> element within the "Choose your Gallery / Album" view
47
- *
48
- * @since 1.5.0
49
- */
50
- var EnviraGallerySelectionItemView = wp.Backbone.View.extend( {
51
-
52
- /**
53
- * The Tag Name and Tag's Class(es)
54
- */
55
- tagName: 'li',
56
- className: 'attachment',
57
-
58
- /**
59
- * Template
60
- * - The template to load inside the above tagName element
61
- */
62
- template: wp.template( 'envira-selection-item' ),
63
-
64
- /**
65
- * Initialize
66
- *
67
- * @param object model EnviraGalleryImage Backbone Model
68
- */
69
- initialize: function( args ) {
70
-
71
- // Assign the model to this view
72
- this.model = args.model;
73
-
74
- },
75
-
76
- /**
77
- * Render
78
- * - Binds the model to the view, so we populate the view's fields and data
79
- */
80
- render: function() {
81
-
82
- // Get HTML
83
- this.$el.html( this.template( this.model.attributes ) );
84
- return this;
85
-
86
- }
87
-
88
- } );
89
-
90
- /**
91
- * Gallery Selection View
92
- */
93
- var EnviraGallerySelectionView = wp.Backbone.View.extend( {
94
-
95
- /**
96
- * The Tag Name and Tag's Class(es)
97
- */
98
- tagName: 'div',
99
- className: 'media-frame mode-select wp-core-ui hide-router hide-menu',
100
-
101
- /**
102
- * Template
103
- * - The template to load inside the above tagName element
104
- */
105
- template: wp.template( 'envira-selection' ),
106
-
107
- /**
108
- * Events
109
- * - Functions to call when specific events occur
110
- */
111
- events: {
112
- // Clicked a gallery
113
- 'click .attachment': 'click',
114
-
115
- // Used the search input
116
- 'keyup': 'search',
117
- 'search': 'search',
118
-
119
- // Insert Button
120
- 'click button.media-button-insert': 'insert',
121
- },
122
-
123
- /**
124
- * Initialize
125
- */
126
- initialize: function( args ) {
127
-
128
- // Whether we're inserting galleries or albums
129
- this.action = args.action;
130
-
131
- // Define a collection, which will store the Galleries
132
- this.selection = new Backbone.Collection(); // The galleries / albums the user has selected
133
- this.collection = new Backbone.Collection(); // The available galleries / albums
134
-
135
- // Define some other flags.
136
- this.is_loading = false;
137
- this.search_timeout = false;
138
-
139
- // Define loading and loaded events
140
- this.on( 'loading', this.loading, this );
141
- this.on( 'loaded', this.loaded, this );
142
-
143
- // Get Galleries
144
- this.getItems( false, '' );
145
-
146
- },
147
-
148
- /**
149
- * Called when a Gallery is clicked
150
- *
151
- * @param object event Event
152
- */
153
- click: function( event ) {
154
-
155
- // Get the target element, whether it's a directory and its ID
156
- var target = jQuery( event.currentTarget ),
157
- id = jQuery( 'div.attachment-preview', target ).attr( 'data-id' );
158
-
159
- // Add or remove item from the selection, depending on its current state
160
- if ( target.hasClass( 'selected' ) ) {
161
- // Remove
162
- this.removeFromSelection( target, id );
163
- } else {
164
- // Add
165
- this.addToSelection( target, id );
166
- }
167
-
168
- },
169
-
170
- /**
171
- * Called when the search event is fired (the user types into the search field)
172
- *
173
- * @param object event Event
174
- */
175
- search: function( event ) {
176
-
177
- // If we're already loading something, bail
178
- if ( this.is_loading ) {
179
- return;
180
- }
181
-
182
- // Clear any existing timeout
183
- clearTimeout( this.search_timeout );
184
-
185
- // Check if a search term exists, and is at least 3 characters
186
- var search = event.target.value;
187
-
188
- // If search is empty, return the entire folder's contents
189
- if ( search.length == 0 ) {
190
- this.getItems( false, '' );
191
- return;
192
- }
193
-
194
- // If search isn't empty but less than 3 characters, don't do anything
195
- if ( search.length < 3 ) {
196
- return;
197
- }
198
-
199
- // Set a small timeout before we perform the search. If the user keeps typing,
200
- // this ensures we don't return the wrong results too early.
201
- var that = this;
202
- this.search_timeout = setTimeout( function() {
203
- that.getItems( true, search );
204
- }, 1000 );
205
-
206
- },
207
-
208
- /**
209
- * Gets galleries by sending an AJAX request
210
- *
211
- * @param bool is_search Is a search request
212
- * @param string search_terms Search Terms
213
- */
214
- getItems: function( is_search, search_terms ) {
215
-
216
- // If we're already loading something, bail
217
- if ( this.is_loading ) {
218
- return;
219
- }
220
-
221
- // Clear the existing collection
222
- this.clearSelection();
223
- this.$el.find( 'ul.attachments' ).empty();
224
- this.$el.find( 'div.envira-gallery-error' ).remove();
225
-
226
- // Update the loading flag
227
- this.trigger( 'loading' );
228
-
229
- // Determine whether we're going to retrieve Galleries or Albums.
230
- var action = '';
231
- switch ( this.action ) {
232
- case 'gallery':
233
- action = 'envira_gallery_editor_get_galleries';
234
- break;
235
- case 'album':
236
- action = 'envira_albums_editor_get_albums';
237
- break;
238
- }
239
-
240
- // Perform AJAX request to get Galleries or Albums.
241
- wp.media.ajax( action, {
242
- context: this,
243
- data: {
244
- nonce: envira_gallery_editor.get_galleries_nonce,
245
- search: is_search,
246
- search_terms: search_terms,
247
- },
248
- success: function( items ) {
249
-
250
- // Define a collection
251
- var collection = new Backbone.Collection( items );
252
-
253
- // Reset the collection
254
- this.collection.reset();
255
-
256
- // Add the collection's models (items) to this class' collection
257
- this.collection.add( collection.models );
258
-
259
- // Render each item in the collection
260
- this.collection.each( function( model ) {
261
-
262
- // Init with model
263
- var child_view = new EnviraGallerySelectionItemView( {
264
- model: model
265
- } );
266
-
267
- // Render view within our main view
268
- this.$el.find( 'ul.attachments' ).append( child_view.render().el );
269
-
270
- }, this );
271
-
272
- // Tell wp.media we've finished loading items
273
- this.trigger( 'loaded' );
274
-
275
- },
276
- error: function( error_message ) {
277
-
278
- // Tell wp.media we've finished loading items, and send the error message
279
- // for output
280
- this.trigger( 'loaded', error_message );
281
-
282
- }
283
- } );
284
-
285
- },
286
-
287
- /**
288
- * Render
289
- * - Binds the collection to the view, so we populate the view's attachments grid
290
- */
291
- render: function() {
292
-
293
- // Get HTML
294
- this.$el.html( this.template() );
295
-
296
- // Return
297
- return this;
298
-
299
- },
300
-
301
- /**
302
- * Renders an error using
303
- * wp.media.view.EnviraGalleryError
304
- */
305
- renderError: function( error ) {
306
-
307
- // Define model
308
- var model = {};
309
- model.error = error;
310
-
311
- // Define view
312
- var view = new wp.media.view.EnviraGalleryError( {
313
- model: model
314
- } );
315
-
316
- // Return rendered view
317
- return view.render().el;
318
-
319
- },
320
-
321
- /**
322
- * Tells the view we're loading by displaying a spinner
323
- */
324
- loading: function() {
325
-
326
- // Set a flag so we know we're loading data
327
- this.is_loading = true;
328
-
329
- // Show the spinner
330
- this.$el.find( '.spinner' ).css( 'visibility', 'visible' );
331
-
332
- },
333
-
334
- /**
335
- * Hides the loading spinner
336
- */
337
- loaded: function( response ) {
338
-
339
- // Set a flag so we know we're not loading anything now
340
- this.is_loading = false;
341
-
342
- // Hide the spinner
343
- this.$el.find( '.spinner' ).css( 'visibility', 'hidden' );
344
-
345
- // Display the error message, if it's provided
346
- if ( typeof response !== 'undefined' ) {
347
- this.$el.find( 'ul.attachments' ).before( this.renderError( response ) );
348
- }
349
-
350
- },
351
-
352
- /**
353
- * Adds the given target to the selection
354
- *
355
- * @param object target Selected Element
356
- * @param string id Unique Identifier (i.e. third party API item's UID)
357
- */
358
- addToSelection: function( target, id ) {
359
-
360
- // Trigger the loading event
361
- this.trigger( 'loading' );
362
-
363
- // Iterate through the current collection of models until we find the model
364
- // that has a path matching the given path
365
- this.collection.each( function( model ) {
366
- // If this model matches the model the user selected, add it to the selection
367
- if ( model.get( 'id' ) == id ) {
368
- this.selection.add( model );
369
- }
370
- }, this );
371
-
372
- // Mark the item as selected in the media view
373
- target.addClass( 'selected details' );
374
-
375
- // If the selection is not empty, enable the Insert button
376
- if ( this.selection.length > 0 ) {
377
- this.$el.find( 'button.media-button-insert' ).attr( 'disabled', false );
378
- }
379
-
380
- // Trigger the loaded event
381
- this.trigger( 'loaded' );
382
-
383
- },
384
-
385
- /**
386
- * Removes the given target from the selection
387
- *
388
- * @param object target Deselected Element
389
- * @param string id Unique Identifier (i.e. third party API item's UID)
390
- */
391
- removeFromSelection: function( target, id ) {
392
-
393
- // Trigger the loading event
394
- this.trigger( 'loading' );
395
-
396
- // Iterate through the current collection of selected models until we find the model
397
- // that has a path matching the given path
398
- this.selection.each( function( model ) {
399
- // remove this model from the collection of selected models
400
- this.selection.remove([{ cid: model.cid }]);
401
- }, this );
402
-
403
- // Mark the item as deselected in the media view
404
- target.removeClass( 'selected details' );
405
-
406
- // If the selection is empty, disable the Insert button
407
- if ( this.selection.length == 0 ) {
408
- this.$el.find( 'button.media-button-insert' ).attr( 'disabled', 'disabled' );
409
- }
410
-
411
- // Trigger the loaded event
412
- this.trigger( 'loaded' );
413
-
414
- },
415
-
416
- /**
417
- * Clears all selected items
418
- */
419
- clearSelection: function() {
420
-
421
- // Iterate through each item, removing the selected state from the UI
422
- this.selection.each( function( model ) {
423
- this.$el.find( 'div[data-id="' + model.get( 'id' ) + '"]' ).parent().removeClass( 'selected details' );
424
- }, this );
425
-
426
- // Disable the Insert button
427
- this.$el.find( 'button.media-button-insert' ).attr( 'disabled', 'disabled' );
428
-
429
- // Clear the selected models
430
- this.selection.reset();
431
-
432
- },
433
-
434
- /**
435
- * Inserts one or more Galleries or Albums into the Editor
436
- */
437
- insert: function() {
438
-
439
- // Tell the View we're loading
440
- this.trigger( 'loading' );
441
-
442
- // For each selected item, insert a shortcode into the editor
443
- this.selection.forEach( function( item ) {
444
- wp.media.editor.insert( '[envira-' + this.action + ' id="' + item.id + '"]' );
445
- }, this );
446
-
447
- // Trigger the loaded event
448
- this.trigger( 'loaded' );
449
-
450
- // Close the modal
451
- EnviraGalleryModalWindow.close();
452
-
453
- }
454
-
455
- } );
456
-
457
  jQuery( document ).ready( function( $ ) {
458
 
459
  // Open the "Add Gallery" / "Add Album" modal
460
- $( document ).on( 'click', 'a.envira-gallery-choose-gallery, a.envira-albums-choose-album', function( e ) {
461
 
462
  // Prevent default action
463
  e.preventDefault();
@@ -467,7 +48,10 @@ jQuery( document ).ready( function( $ ) {
467
 
468
  // Define the modal's view
469
  EnviraGalleryModalWindow.content( new EnviraGallerySelectionView( {
470
- action: action
 
 
 
471
  } ) );
472
 
473
  // Open the modal window
1
+ /* ==========================================================
2
+ * editor.js
3
+ * http://enviragallery.com/
4
+ *
5
+ * This file can be used by 3rd party plugins to integrate
6
+ * with their custom field systems. It allows the selection
7
+ * process to be standardized so that 3rd party plugins can
8
+ * trigger modal selection windows and receive the corresponding
9
+ * selected data objects.
10
+ *
11
+ * Using this file requires two actions for the 3rd party plugin.
12
+ *
13
+ * 1. This file should be enqueued on the page where the field resides.
14
+ *
15
+ * 2. You must add the class ".envira-gallery-modal-trigger" to the
16
+ * option/dropdown/button that will trigger the modal.
17
+ *
18
+ * 3. You must add the data-action="gallery" or data-action="album" attribute
19
+ * to the option/dropdown/button that will trigger the modal.
20
+ *
21
+ * 4. Attaching to a global event that is fired once the data for the
22
+ * selection has been retrieved. You should listen on the document
23
+ * object for the "enviraGalleryModalData" event, like this:
24
+ *
25
+ * jQuery( document ).on( 'enviraGalleryModalData', function( e ) {
26
+ * console.log( e.action ); // 'gallery' or 'album'
27
+ * console.log( e.multiple ); // Whether the user could select multiple Galleries / Albums (true|false)
28
+ * console.log( e.items ); // An array of Galleries or Albums
29
+ * console.log( e.insert_options ); // An object of the Insert Options the user chose
30
+ * } );
31
+ *
32
+ * This will give you access to the entire array of galleries or albums that
33
+ * the user has selected, including ID, title and slug.
34
+ *
35
+ * Please note that Envira Gallery 1.5.0 and Envira Albums 1.3.0 introduced
36
+ * support for selecting multiple Galleries / Albums in the Backbone modal.
37
+ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  jQuery( document ).ready( function( $ ) {
39
 
40
  // Open the "Add Gallery" / "Add Album" modal
41
+ $( document ).on( 'click', 'a.envira-gallery-choose-gallery, a.envira-albums-choose-album, .envira-gallery-modal-trigger', function( e ) {
42
 
43
  // Prevent default action
44
  e.preventDefault();
48
 
49
  // Define the modal's view
50
  EnviraGalleryModalWindow.content( new EnviraGallerySelectionView( {
51
+ action: action, // gallery|album
52
+ multiple: true, // Allow multiple Galleries / Albums to be selected
53
+ modal_title: envira_gallery_editor.modal_title,
54
+ insert_button_label:envira_gallery_editor.insert_button_label
55
  } ) );
56
 
57
  // Open the modal window
assets/js/envira.js CHANGED
@@ -1,13 +1,31 @@
1
  /**
2
  * envira.js is a placeholder, which CodeKit attaches the following JS files to, before compiling as min/envira-min.js:
3
- * - lib/fancybox.js
 
4
  * - lib/imagesloaded.js
5
  * - lib/isotope.js
6
- * - lib/mousewheel.js
7
- * - lib/touchsupport.js
8
- * - lib/touchswipe.js
 
9
  *
10
  * To load more JS resources:
11
  * - Add them to the lib subfolder
12
  * - Add the to the imports directive of this file in CodeKit
13
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  /**
2
  * envira.js is a placeholder, which CodeKit attaches the following JS files to, before compiling as min/envira-min.js:
3
+ * - lib/touchswipe.js
4
+ * - lib/mousewheel.js
5
  * - lib/imagesloaded.js
6
  * - lib/isotope.js
7
+ * - lib/fancybox.js
8
+ * - lib/fancybox-buttons.js
9
+ * - lib/fancybox-media.js
10
+ * - lib/fancybox-thumbs.js
11
  *
12
  * To load more JS resources:
13
  * - Add them to the lib subfolder
14
  * - Add the to the imports directive of this file in CodeKit
15
+ */
16
+
17
+ /**
18
+ * If a lightbox caption's link is an anchor, close the lightbox
19
+ */
20
+ jQuery( document ).ready( function( $ ) {
21
+
22
+ $( 'body' ).on( 'click', 'div.envirabox-title a[href*="#"]:not([href="#"])', function( e ) {
23
+
24
+ if ( location.pathname.replace( /^\//, '' ) == this.pathname.replace( /^\//, '' ) && location.hostname == this.hostname ) {
25
+ $.envirabox.close();
26
+ return false;
27
+ }
28
+
29
+ } );
30
+
31
+ } );
assets/js/gallery-select.js ADDED
@@ -0,0 +1,634 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* ==========================================================
2
+ * gallery-select.js
3
+ *
4
+ * Defines a Backbone Modal for Gallery or Album selection.
5
+ *
6
+ * To use:
7
+ * EnviraGalleryModalWindow.content( new EnviraGallerySelectionView( {
8
+ * action: 'gallery', // gallery|album
9
+ * multiple: true, // Support multiple Gallery / Album selection
10
+ * sidebar_view: 'envira-selection-sidebar' // WordPress media view to render into the sidebar
11
+ * modal_title: 'Insert Gallery', // Title for the Backbone Modal
12
+ * insert_button_label: 'Insert', // Label for the Insert Button
13
+ * onInsert: function() {}, // Callback function when the 'Insert' button in the modal is pressed.
14
+ * // You'll have access to this.selection, containing the chosen Galleries / Albums.
15
+ * } ).open();
16
+ *
17
+ * Only the 'action' and 'multiple' arguments are required; defaults will be appled for the other arguments if they're not specified.
18
+ *
19
+ * You can also attach a global event once the user has chosen Galleries / Albums, clicked the Insert button and the item(s)
20
+ * have been inserted:
21
+ * jQuery( document ).on( 'enviraGalleryModalData', function( e ) {
22
+ * console.log( e.action ); // 'gallery' or 'album'
23
+ * console.log( e.multiple ); // Whether the user could select multiple Galleries / Albums (true|false)
24
+ * console.log( e.items ); // An array of Galleries or Albums
25
+ * console.log( e.insert_options ); // An object of the Insert Options the user chose
26
+ * } );
27
+ */
28
+
29
+ /**
30
+ * Controller: Modal Window
31
+ * - Used by most Envira Backbone views to display information e.g. bulk edit, edit single image etc.
32
+ */
33
+ if ( typeof EnviraGalleryModalWindow == 'undefined' ) {
34
+
35
+ var EnviraGalleryModalWindow = new wp.media.view.Modal( {
36
+ controller: {
37
+ trigger: function() {
38
+ }
39
+ }
40
+ } );
41
+
42
+ }
43
+
44
+ /**
45
+ * View: Error
46
+ * - Renders a WordPress style error message when something goes wrong.
47
+ *
48
+ * @since 1.4.3.0
49
+ */
50
+ wp.media.view.EnviraGalleryError = wp.Backbone.View.extend( {
51
+
52
+ // The outer tag and class name to use. The item is wrapped in this
53
+ tagName : 'div',
54
+ className : 'notice error envira-gallery-error',
55
+
56
+ render: function() {
57
+
58
+ // Load the template to render
59
+ // See includes/admin/media-views.php
60
+ this.template = wp.media.template( 'envira-gallery-error' );
61
+
62
+ // Define the HTML for the template
63
+ this.$el.html( this.template( this.model ) );
64
+
65
+ // Return the template
66
+ return this;
67
+
68
+ }
69
+
70
+ } );
71
+
72
+ /**
73
+ * View: Single Item (Gallery or Album)
74
+ * - Renders an <li> element within the "Choose your Gallery / Album" view
75
+ *
76
+ * @since 1.5.0
77
+ */
78
+ var EnviraGallerySelectionItemView = wp.Backbone.View.extend( {
79
+
80
+ /**
81
+ * The Tag Name and Tag's Class(es)
82
+ */
83
+ tagName: 'li',
84
+ className: 'attachment',
85
+
86
+ /**
87
+ * Template
88
+ * - The template to load inside the above tagName element
89
+ */
90
+ template: wp.template( 'envira-selection-item' ),
91
+
92
+ /**
93
+ * Initialize
94
+ *
95
+ * @param object model EnviraGalleryImage Backbone Model
96
+ */
97
+ initialize: function( args ) {
98
+
99
+ // Assign the model to this view
100
+ this.model = args.model;
101
+
102
+ },
103
+
104
+ /**
105
+ * Render
106
+ * - Binds the model to the view, so we populate the view's fields and data
107
+ */
108
+ render: function() {
109
+
110
+ // Get HTML
111
+ this.$el.html( this.template( this.model.attributes ) );
112
+ return this;
113
+
114
+ }
115
+
116
+ } );
117
+
118
+ /**
119
+ * View: Sidebar
120
+ * - Renders the Helpful Tips when selecting a Gallery or Album for insertion into a Post.
121
+ *
122
+ * @since 1.5.0.3
123
+ */
124
+ var EnviraGallerySelectionSidebarView = wp.Backbone.View.extend( {
125
+
126
+ /**
127
+ * The Tag Name and Tag's Class(es)
128
+ */
129
+ tagName: 'div',
130
+ className: 'sidebar',
131
+
132
+ /**
133
+ * Initialize
134
+ *
135
+ * @param string view View to render
136
+ */
137
+ initialize: function( view ) {
138
+
139
+ // Define the sidebar view to render
140
+ // This must be a WordPress media view using e.g. <script type="text/html" id="tmpl-my-sidebar-view-name">
141
+ this.view = ( ( typeof view == 'undefined' ) ? 'envira-selection-sidebar' : view );
142
+
143
+ },
144
+
145
+ /**
146
+ * Render the view
147
+ */
148
+ render: function() {
149
+
150
+ // Get HTML
151
+ this.$el.html( wp.template( this.view ) );
152
+ return this;
153
+
154
+ }
155
+
156
+ } );
157
+
158
+ /**
159
+ * Gallery Selection View
160
+ */
161
+ var EnviraGallerySelectionView = wp.Backbone.View.extend( {
162
+
163
+ /**
164
+ * The Tag Name and Tag's Class(es)
165
+ */
166
+ tagName: 'div',
167
+ className: 'media-frame mode-select wp-core-ui hide-router hide-menu',
168
+
169
+ /**
170
+ * Template
171
+ * - The template to load inside the above tagName element
172
+ */
173
+ template: wp.template( 'envira-selection' ),
174
+
175
+ /**
176
+ * Events
177
+ * - Functions to call when specific events occur
178
+ */
179
+ events: {
180
+ // Clicked a gallery
181
+ 'click .attachment': 'click',
182
+
183
+ // Used the search input
184
+ 'keyup': 'search',
185
+ 'search': 'search',
186
+
187
+ // Display Options
188
+ 'change select': 'updateInsertOption',
189
+
190
+ // Insert Button
191
+ 'click button.media-button-insert': 'insert',
192
+ },
193
+
194
+ /**
195
+ * Initialize
196
+ *
197
+ * @param object args:
198
+ * - action: gallery|album (required)
199
+ * - multiple: true|false (required)
200
+ * - sidebar_view: A custom WordPress media view to render into the sidebar (optional)
201
+ * - modal_title: The modal title (optional)
202
+ * - insert_button_label: The 'Insert' button label (optional)
203
+ * - prepend_ids: Optional array of Galleries or Albums to always prepend to the resultset
204
+ * - onInsert: function() {} (optional)
205
+ */
206
+ initialize: function( args ) {
207
+
208
+ // Whether we're inserting galleries or albums
209
+ this.action = args.action;
210
+
211
+ // Whether multiple galleries or albums can be selected
212
+ this.multiple = args.multiple;
213
+
214
+ // Define the sidebar view to render into this Modal
215
+ // This must be a WordPress media view using e.g. <script type="text/html" id="tmpl-my-sidebar-view-name">
216
+ this.sidebar_view = ( ( typeof args.sidebar_view == 'undefined' ) ? 'envira-selection-sidebar' : args.sidebar_view );
217
+
218
+ // Store the onInsert function provided by the calling class
219
+ this.onInsert = args.onInsert;
220
+
221
+ // Whether we're prepending galleries / albums to the collection
222
+ this.prepend_ids = ( ( typeof args.prepend_ids == 'undefined' ) ? false : args.prepend_ids );
223
+
224
+ // Whether we're preselecting galleries / albums
225
+ this.select_ids = ( ( typeof args.select_ids == 'undefined' ) ? false : args.select_ids );
226
+
227
+ // Define a collection, which will store the Galleries
228
+ this.selection = new Backbone.Collection(); // The galleries / albums the user has selected
229
+ this.collection = new Backbone.Collection(); // The available galleries / albums
230
+
231
+ // Define a model to store Insert Options
232
+ this.insert_options = new Backbone.Model( {
233
+ 'modal_title': ( ( typeof args.modal_title == 'undefined' ) ? envira_gallery_select.modal_title : args.modal_title ),
234
+ 'title': 0,
235
+ 'insert_button_label': ( ( typeof args.modal_title == 'undefined' ) ? envira_gallery_select.insert_button_label : args.insert_button_label )
236
+ } );
237
+
238
+ // Define some other flags.
239
+ this.is_loading = false;
240
+ this.search_timeout = false;
241
+
242
+ // Define loading and loaded events
243
+ this.on( 'loading', this.loading, this );
244
+ this.on( 'loaded', this.loaded, this );
245
+
246
+ // Get Galleries
247
+ this.getItems( false, '' );
248
+
249
+ },
250
+
251
+ /**
252
+ * Called when a Gallery is clicked
253
+ *
254
+ * @param object event Event
255
+ */
256
+ click: function( event ) {
257
+
258
+ // Get the target element, whether it's a directory and its ID
259
+ var target = jQuery( event.currentTarget ),
260
+ id = jQuery( 'div.attachment-preview', target ).attr( 'data-id' );
261
+
262
+ // Add or remove item from the selection, depending on its current state
263
+ if ( target.hasClass( 'selected' ) ) {
264
+ // Remove
265
+ this.removeFromSelection( target, id );
266
+ } else {
267
+ // If multiple selection isn't supported, clear the selection first
268
+ if ( ! this.multiple ) {
269
+ this.clearSelection();
270
+ }
271
+
272
+ // Add
273
+ this.addToSelection( target, id );
274
+ }
275
+
276
+ },
277
+
278
+ /**
279
+ * Called when the search event is fired (the user types into the search field)
280
+ *
281
+ * @param object event Event
282
+ */
283
+ search: function( event ) {
284
+
285
+ // If we're already loading something, bail
286
+ if ( this.is_loading ) {
287
+ return;
288
+ }
289
+
290
+ // Clear any existing timeout
291
+ clearTimeout( this.search_timeout );
292
+
293
+ // Check if a search term exists, and is at least 3 characters
294
+ var search = event.target.value;
295
+
296
+ // If search is empty, return the entire folder's contents
297
+ if ( search.length == 0 ) {
298
+ this.getItems( false, '' );
299
+ return;
300
+ }
301
+
302
+ // If search isn't empty but less than 3 characters, don't do anything
303
+ if ( search.length < 3 ) {
304
+ return;
305
+ }
306
+
307
+ // Set a small timeout before we perform the search. If the user keeps typing,
308
+ // this ensures we don't return the wrong results too early.
309
+ var that = this;
310
+ this.search_timeout = setTimeout( function() {
311
+ that.getItems( true, search );
312
+ }, 1000 );
313
+
314
+ },
315
+
316
+ /**
317
+ * Gets galleries by sending an AJAX request
318
+ *
319
+ * @param bool is_search Is a search request
320
+ * @param string search_terms Search Terms
321
+ */
322
+ getItems: function( is_search, search_terms ) {
323
+
324
+ // If we're already loading something, bail
325
+ if ( this.is_loading ) {
326
+ return;
327
+ }
328
+
329
+ // Clear the existing collection
330
+ this.clearSelection();
331
+ this.$el.find( 'ul.attachments' ).empty();
332
+ this.$el.find( 'div.envira-gallery-error' ).remove();
333
+
334
+ // Update the loading flag
335
+ this.trigger( 'loading' );
336
+
337
+ // Determine whether we're going to retrieve Galleries or Albums.
338
+ var action = '';
339
+ switch ( this.action ) {
340
+ case 'gallery':
341
+ action = 'envira_gallery_editor_get_galleries';
342
+ break;
343
+ case 'album':
344
+ action = 'envira_albums_editor_get_albums';
345
+ break;
346
+ }
347
+
348
+ // Perform AJAX request to get Galleries or Albums.
349
+ wp.media.ajax( action, {
350
+ context: this,
351
+ data: {
352
+ nonce: envira_gallery_select.get_galleries_nonce,
353
+ search: is_search,
354
+ search_terms: search_terms,
355
+ prepend_ids: this.prepend_ids
356
+ },
357
+ success: function( items ) {
358
+
359
+ // Define a collection
360
+ var collection = new Backbone.Collection( items );
361
+
362
+ // Reset the collection
363
+ this.collection.reset();
364
+
365
+ // Add the collection's models (items) to this class' collection
366
+ this.collection.add( collection.models );
367
+
368
+ // Render each item in the collection
369
+ this.collection.each( function( model ) {
370
+
371
+ // Init with model
372
+ var child_view = new EnviraGallerySelectionItemView( {
373
+ model: model
374
+ } );
375
+
376
+ // Render view within our main view
377
+ this.$el.find( 'ul.attachments' ).append( child_view.render().el );
378
+
379
+ // If we're selecting specific item IDs, check now if this item should be selected
380
+ if ( this.select_ids !== false ) {
381
+ var select_model = jQuery.inArray( parseInt( model.get( 'id' ) ), this.select_ids );
382
+ if ( select_model > -1 ) {
383
+ // Select this item
384
+ this.addToSelection( jQuery( child_view.render().el ), model.get( 'id' ) );
385
+ }
386
+ }
387
+
388
+ }, this );
389
+
390
+ // Tell wp.media we've finished loading items
391
+ this.trigger( 'loaded' );
392
+
393
+ },
394
+ error: function( error_message ) {
395
+
396
+ // Tell wp.media we've finished loading items, and send the error message
397
+ // for output
398
+ this.trigger( 'loaded', error_message );
399
+
400
+ }
401
+ } );
402
+
403
+ },
404
+
405
+ /**
406
+ * Updates an Insert Option (displayed in the sidebar) when changed.
407
+ */
408
+ updateInsertOption: function( event ) {
409
+
410
+ // Check if the target has a name. If not, it's not a model value we want to store
411
+ if ( event.target.name == '' ) {
412
+ return;
413
+ }
414
+
415
+ // Update the model's value, depending on the input type
416
+ if ( event.target.type == 'checkbox' ) {
417
+ value = ( event.target.checked ? 1 : 0 );
418
+ } else {
419
+ value = event.target.value;
420
+ }
421
+
422
+ // Update the model
423
+ this.insert_options.set( event.target.name, value );
424
+
425
+ },
426
+
427
+ /**
428
+ * Render
429
+ * - Binds the collection to the view, so we populate the view's attachments grid
430
+ */
431
+ render: function() {
432
+
433
+ // Get HTML
434
+ this.$el.html( this.template( this.insert_options.attributes ) );
435
+
436
+ // Render the Sidebar View
437
+ var sidebar = new EnviraGallerySelectionSidebarView( this.sidebar_view );
438
+ this.$el.find( 'div.media-sidebar' ).append( sidebar.render().el );
439
+
440
+ // Return
441
+ return this;
442
+
443
+ },
444
+
445
+ /**
446
+ * Renders an error using
447
+ * wp.media.view.EnviraGalleryError
448
+ */
449
+ renderError: function( error ) {
450
+
451
+ // Define model
452
+ var model = {};
453
+ model.error = error;
454
+
455
+ // Define view
456
+ var view = new wp.media.view.EnviraGalleryError( {
457
+ model: model
458
+ } );
459
+
460
+ // Return rendered view
461
+ return view.render().el;
462
+
463
+ },
464
+
465
+ /**
466
+ * Tells the view we're loading by displaying a spinner
467
+ */
468
+ loading: function() {
469
+
470
+ // Set a flag so we know we're loading data
471
+ this.is_loading = true;
472
+
473
+ // Show the spinner
474
+ this.$el.find( '.spinner' ).css( 'visibility', 'visible' );
475
+
476
+ },
477
+
478
+ /**
479
+ * Hides the loading spinner
480
+ */
481
+ loaded: function( response ) {
482
+
483
+ // Set a flag so we know we're not loading anything now
484
+ this.is_loading = false;
485
+
486
+ // Hide the spinner
487
+ this.$el.find( '.spinner' ).css( 'visibility', 'hidden' );
488
+
489
+ // Display the error message, if it's provided
490
+ if ( typeof response !== 'undefined' ) {
491
+ this.$el.find( 'ul.attachments' ).before( this.renderError( response ) );
492
+ }
493
+
494
+ },
495
+
496
+ /**
497
+ * Adds the given target to the selection
498
+ *
499
+ * @param object target Selected Element
500
+ * @param string id Unique Identifier (i.e. third party API item's UID)
501
+ */
502
+ addToSelection: function( target, id ) {
503
+
504
+ // Trigger the loading event
505
+ this.trigger( 'loading' );
506
+
507
+ // Iterate through the current collection of models until we find the model
508
+ // that matches the ID we have
509
+ this.collection.each( function( model ) {
510
+ // If this model matches the model the user selected, add it to the selection
511
+ if ( model.get( 'id' ) == id ) {
512
+ this.selection.add( model );
513
+ }
514
+ }, this );
515
+
516
+ // Mark the item as selected in the media view
517
+ target.addClass( 'selected details' );
518
+
519
+ // If the selection is not empty, enable the Insert button
520
+ if ( this.selection.length > 0 ) {
521
+ this.$el.find( 'button.media-button-insert' ).attr( 'disabled', false );
522
+ }
523
+
524
+ // Trigger the loaded event
525
+ this.trigger( 'loaded' );
526
+
527
+ },
528
+
529
+ /**
530
+ * Removes the given target from the selection
531
+ *
532
+ * @param object target Deselected Element
533
+ * @param string id Unique Identifier (i.e. third party API item's UID)
534
+ */
535
+ removeFromSelection: function( target, id ) {
536
+
537
+ // Trigger the loading event
538
+ this.trigger( 'loading' );
539
+
540
+ // Iterate through the current collection of selected models until we find the model
541
+ // that has a path matching the given path
542
+ this.selection.each( function( model ) {
543
+ // remove this model from the collection of selected models
544
+ this.selection.remove([{ cid: model.cid }]);
545
+ }, this );
546
+
547
+ // Mark the item as deselected in the media view
548
+ target.removeClass( 'selected details' );
549
+
550
+ // If the selection is empty, disable the Insert button
551
+ if ( this.selection.length == 0 ) {
552
+ this.$el.find( 'button.media-button-insert' ).attr( 'disabled', 'disabled' );
553
+ }
554
+
555
+ // Trigger the loaded event
556
+ this.trigger( 'loaded' );
557
+
558
+ },
559
+
560
+ /**
561
+ * Clears all selected items
562
+ */
563
+ clearSelection: function() {
564
+
565
+ // Iterate through each item, removing the selected state from the UI
566
+ this.selection.each( function( model ) {
567
+ this.$el.find( 'div[data-id="' + model.get( 'id' ) + '"]' ).parent().removeClass( 'selected details' );
568
+ }, this );
569
+
570
+ // Disable the Insert button
571
+ this.$el.find( 'button.media-button-insert' ).attr( 'disabled', 'disabled' );
572
+
573
+ // Clear the selected models
574
+ this.selection.reset();
575
+
576
+ },
577
+
578
+ /**
579
+ * Inserts one or more Galleries or Albums into the Editor
580
+ */
581
+ insert: function() {
582
+
583
+ // Tell the View we're loading
584
+ this.trigger( 'loading' );
585
+
586
+ // Run the onInsert() function from the calling class
587
+ // If no function given, run the default action, which is to insert
588
+ // into the Visual Editor
589
+ if ( typeof this.onInsert === 'undefined' ) {
590
+ // For each selected item, insert a shortcode into the editor
591
+ var items = [];
592
+ this.selection.forEach( function( item ) {
593
+
594
+ // Build array of items, and reset shortcode
595
+ items.push( item.attributes );
596
+ var shortcode = '';
597
+
598
+ // Prepend Title to Shortcode
599
+ if ( this.insert_options.get( 'title' ) != 0 ) {
600
+ shortcode = '<' + this.insert_options.get( 'title' ) + '>' + item.get( 'title' ) + '</' + this.insert_options.get( 'title' ) + '>';
601
+ }
602
+
603
+ // Shortcode
604
+ shortcode += '[envira-' + this.action + ' id="' + item.id + '"]';
605
+
606
+ // Insert into Editor
607
+ wp.media.editor.insert( shortcode );
608
+
609
+ }, this );
610
+
611
+ // Trigger the enviraGalleryModalData event, comprising of the chosen Galleries.
612
+ jQuery( document ).trigger( {
613
+ type: 'enviraGalleryModalData',
614
+ items: items, // array of galleries or albums
615
+ insert_options: this.insert_options,// Backbone Model comprising of Insert Options the user chose on screen
616
+ action: this.action // gallery or album
617
+ } );
618
+
619
+ var result = true;
620
+ } else {
621
+ var result = this.onInsert();
622
+ }
623
+
624
+ // Trigger the loaded event
625
+ this.trigger( 'loaded' );
626
+
627
+ // If the result was successful, close the modal window
628
+ if ( result ) {
629
+ EnviraGalleryModalWindow.close();
630
+ }
631
+
632
+ }
633
+
634
+ } );
assets/js/lib/imagesloaded.js CHANGED
@@ -1,592 +1,148 @@
1
- /**
2
- * imagesLoaded PACKAGED v3.1.8
3
  * JavaScript is all like "You images are done yet or what?"
4
  * MIT License
5
  */
6
 
7
-
8
  /**
9
- * EventEmitter v4.2.6 - git.io/ee
10
- * Oliver Caldwell
11
- * MIT license
12
  */
13
 
14
- (function () {
15
-
16
-
17
- /**
18
- * Class for managing events.
19
- * Can be extended to provide event functionality in other classes.
20
- *
21
- * @class EventEmitter Manages event registering and emitting.
22
- */
23
- function EventEmitter() {}
24
-
25
- // Shortcuts to improve speed and size
26
- var proto = EventEmitter.prototype;
27
- var exports = this;
28
- var originalGlobalValue = exports.EventEmitter;
29
-
30
- /**
31
- * Finds the index of the listener for the event in it's storage array.
32
- *
33
- * @param {Function[]} listeners Array of listeners to search through.
34
- * @param {Function} listener Method to look for.
35
- * @return {Number} Index of the specified listener, -1 if not found
36
- * @api private
37
- */
38
- function indexOfListener(listeners, listener) {
39
- var i = listeners.length;
40
- while (i--) {
41
- if (listeners[i].listener === listener) {
42
- return i;
43
- }
44
- }
45
-
46
- return -1;
47
- }
48
-
49
- /**
50
- * Alias a method while keeping the context correct, to allow for overwriting of target method.
51
- *
52
- * @param {String} name The name of the target method.
53
- * @return {Function} The aliased method
54
- * @api private
55
- */
56
- function alias(name) {
57
- return function aliasClosure() {
58
- return this[name].apply(this, arguments);
59
- };
60
- }
61
-
62
- /**
63
- * Returns the listener array for the specified event.
64
- * Will initialise the event object and listener arrays if required.
65
- * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
66
- * Each property in the object response is an array of listener functions.
67
- *
68
- * @param {String|RegExp} evt Name of the event to return the listeners from.
69
- * @return {Function[]|Object} All listener functions for the event.
70
- */
71
- proto.getListeners = function getListeners(evt) {
72
- var events = this._getEvents();
73
- var response;
74
- var key;
75
-
76
- // Return a concatenated array of all matching events if
77
- // the selector is a regular expression.
78
- if (typeof evt === 'object') {
79
- response = {};
80
- for (key in events) {
81
- if (events.hasOwnProperty(key) && evt.test(key)) {
82
- response[key] = events[key];
83
- }
84
- }
85
- }
86
- else {
87
- response = events[evt] || (events[evt] = []);
88
- }
89
-
90
- return response;
91
- };
92
-
93
- /**
94
- * Takes a list of listener objects and flattens it into a list of listener functions.
95
- *
96
- * @param {Object[]} listeners Raw listener objects.
97
- * @return {Function[]} Just the listener functions.
98
- */
99
- proto.flattenListeners = function flattenListeners(listeners) {
100
- var flatListeners = [];
101
- var i;
102
-
103
- for (i = 0; i < listeners.length; i += 1) {
104
- flatListeners.push(listeners[i].listener);
105
- }
106
-
107
- return flatListeners;
108
- };
109
-
110
- /**
111
- * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.
112
- *
113
- * @param {String|RegExp} evt Name of the event to return the listeners from.
114
- * @return {Object} All listener functions for an event in an object.
115
- */
116
- proto.getListenersAsObject = function getListenersAsObject(evt) {
117
- var listeners = this.getListeners(evt);
118
- var response;
119
-
120
- if (listeners instanceof Array) {
121
- response = {};
122
- response[evt] = listeners;
123
- }
124
-
125
- return response || listeners;
126
- };
127
-
128
- /**
129
- * Adds a listener function to the specified event.
130
- * The listener will not be added if it is a duplicate.
131
- * If the listener returns true then it will be removed after it is called.
132
- * If you pass a regular expression as the event name then the listener will be added to all events that match it.
133
- *
134
- * @param {String|RegExp} evt Name of the event to attach the listener to.
135
- * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
136
- * @return {Object} Current instance of EventEmitter for chaining.
137
- */
138
- proto.addListener = function addListener(evt, listener) {
139
- var listeners = this.getListenersAsObject(evt);
140
- var listenerIsWrapped = typeof listener === 'object';
141
- var key;
142
-
143
- for (key in listeners) {
144
- if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
145
- listeners[key].push(listenerIsWrapped ? listener : {
146
- listener: listener,
147
- once: false
148
- });
149
- }
150
- }
151
-
152
- return this;
153
- };
154
-
155
- /**
156
- * Alias of addListener
157
- */
158
- proto.on = alias('addListener');
159
-
160
- /**
161
- * Semi-alias of addListener. It will add a listener that will be
162
- * automatically removed after it's first execution.
163
- *
164
- * @param {String|RegExp} evt Name of the event to attach the listener to.
165
- * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
166
- * @return {Object} Current instance of EventEmitter for chaining.
167
- */
168
- proto.addOnceListener = function addOnceListener(evt, listener) {
169
- return this.addListener(evt, {
170
- listener: listener,
171
- once: true
172
- });
173
- };
174
-
175
- /**
176
- * Alias of addOnceListener.
177
- */
178
- proto.once = alias('addOnceListener');
179
-
180
- /**
181
- * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.
182
- * You need to tell it what event names should be matched by a regex.
183
- *
184
- * @param {String} evt Name of the event to create.
185
- * @return {Object} Current instance of EventEmitter for chaining.
186
- */
187
- proto.defineEvent = function defineEvent(evt) {
188
- this.getListeners(evt);
189
- return this;
190
- };
191
-
192
- /**
193
- * Uses defineEvent to define multiple events.
194
- *
195
- * @param {String[]} evts An array of event names to define.
196
- * @return {Object} Current instance of EventEmitter for chaining.
197
- */
198
- proto.defineEvents = function defineEvents(evts) {
199
- for (var i = 0; i < evts.length; i += 1) {
200
- this.defineEvent(evts[i]);
201
- }
202
- return this;
203
- };
204
-
205
- /**
206
- * Removes a listener function from the specified event.
207
- * When passed a regular expression as the event name, it will remove the listener from all events that match it.
208
- *
209
- * @param {String|RegExp} evt Name of the event to remove the listener from.
210
- * @param {Function} listener Method to remove from the event.
211
- * @return {Object} Current instance of EventEmitter for chaining.
212
- */
213
- proto.removeListener = function removeListener(evt, listener) {
214
- var listeners = this.getListenersAsObject(evt);
215
- var index;
216
- var key;
217
-
218
- for (key in listeners) {
219
- if (listeners.hasOwnProperty(key)) {
220
- index = indexOfListener(listeners[key], listener);
221
-
222
- if (index !== -1) {
223
- listeners[key].splice(index, 1);
224
- }
225
- }
226
- }
227
-
228
- return this;
229
- };
230
-
231
- /**
232
- * Alias of removeListener
233
- */
234
- proto.off = alias('removeListener');
235
-
236
- /**
237
- * Adds listeners in bulk using the manipulateListeners method.
238
- * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
239
- * You can also pass it a regular expression to add the array of listeners to all events that match it.
240
- * Yeah, this function does quite a bit. That's probably a bad thing.
241
- *
242
- * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
243
- * @param {Function[]} [listeners] An optional array of listener functions to add.
244
- * @return {Object} Current instance of EventEmitter for chaining.
245
- */
246
- proto.addListeners = function addListeners(evt, listeners) {
247
- // Pass through to manipulateListeners
248
- return this.manipulateListeners(false, evt, listeners);
249
- };
250
-
251
- /**
252
- * Removes listeners in bulk using the manipulateListeners method.
253
- * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
254
- * You can also pass it an event name and an array of listeners to be removed.
255
- * You can also pass it a regular expression to remove the listeners from all events that match it.
256
- *
257
- * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
258
- * @param {Function[]} [listeners] An optional array of listener functions to remove.
259
- * @return {Object} Current instance of EventEmitter for chaining.
260
- */
261
- proto.removeListeners = function removeListeners(evt, listeners) {
262
- // Pass through to manipulateListeners
263
- return this.manipulateListeners(true, evt, listeners);
264
- };
265
-
266
- /**
267
- * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.
268
- * The first argument will determine if the listeners are removed (true) or added (false).
269
- * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
270
- * You can also pass it an event name and an array of listeners to be added/removed.
271
- * You can also pass it a regular expression to manipulate the listeners of all events that match it.
272
- *
273
- * @param {Boolean} remove True if you want to remove listeners, false if you want to add.
274
- * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.
275
- * @param {Function[]} [listeners] An optional array of listener functions to add/remove.
276
- * @return {Object} Current instance of EventEmitter for chaining.
277
- */
278
- proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
279
- var i;
280
- var value;
281
- var single = remove ? this.removeListener : this.addListener;
282
- var multiple = remove ? this.removeListeners : this.addListeners;
283
-
284
- // If evt is an object then pass each of it's properties to this method
285
- if (typeof evt === 'object' && !(evt instanceof RegExp)) {
286
- for (i in evt) {
287
- if (evt.hasOwnProperty(i) && (value = evt[i])) {
288
- // Pass the single listener straight through to the singular method
289
- if (typeof value === 'function') {
290
- single.call(this, i, value);
291
- }
292
- else {
293
- // Otherwise pass back to the multiple function
294
- multiple.call(this, i, value);
295
- }
296
- }
297
- }
298
- }
299
- else {
300
- // So evt must be a string
301
- // And listeners must be an array of listeners
302
- // Loop over it and pass each one to the multiple method
303
- i = listeners.length;
304
- while (i--) {
305
- single.call(this, evt, listeners[i]);
306
- }
307
- }
308
-
309
- return this;
310
- };
311
-
312
- /**
313
- * Removes all listeners from a specified event.
314
- * If you do not specify an event then all listeners will be removed.
315
- * That means every event will be emptied.
316
- * You can also pass a regex to remove all events that match it.
317
- *
318
- * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
319
- * @return {Object} Current instance of EventEmitter for chaining.
320
- */
321
- proto.removeEvent = function removeEvent(evt) {
322
- var type = typeof evt;
323
- var events = this._getEvents();
324
- var key;
325
-
326
- // Remove different things depending on the state of evt
327
- if (type === 'string') {
328
- // Remove all listeners for the specified event
329
- delete events[evt];
330
- }
331
- else if (type === 'object') {
332
- // Remove all events matching the regex.
333
- for (key in events) {
334
- if (events.hasOwnProperty(key) && evt.test(key)) {
335
- delete events[key];
336
- }
337
- }
338
- }
339
- else {
340
- // Remove all listeners in all events
341
- delete this._events;
342
- }
343
-
344
- return this;
345
- };
346
-
347
- /**
348
- * Alias of removeEvent.
349
- *
350
- * Added to mirror the node API.
351
- */
352
- proto.removeAllListeners = alias('removeEvent');
353
-
354
- /**
355
- * Emits an event of your choice.
356
- * When emitted, every listener attached to that event will be executed.
357
- * If you pass the optional argument array then those arguments will be passed to every listener upon execution.
358
- * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
359
- * So they will not arrive within the array on the other side, they will be separate.
360
- * You can also pass a regular expression to emit to all events that match it.
361
- *
362
- * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
363
- * @param {Array} [args] Optional array of arguments to be passed to each listener.
364
- * @return {Object} Current instance of EventEmitter for chaining.
365
- */
366
- proto.emitEvent = function emitEvent(evt, args) {
367
- var listeners = this.getListenersAsObject(evt);
368
- var listener;
369
- var i;
370
- var key;
371
- var response;
372
-
373
- for (key in listeners) {
374
- if (listeners.hasOwnProperty(key)) {
375
- i = listeners[key].length;
376
-
377
- while (i--) {
378
- // If the listener returns true then it shall be removed from the event
379
- // The function is executed either with a basic call or an apply if there is an args array
380
- listener = listeners[key][i];
381
-
382
- if (listener.once === true) {
383
- this.removeListener(evt, listener.listener);
384
- }
385
-
386
- response = listener.listener.apply(this, args || []);
387
-
388
- if (response === this._getOnceReturnValue()) {
389
- this.removeListener(evt, listener.listener);
390
- }
391
- }
392
- }
393
- }
394
-
395
- return this;
396
- };
397
-
398
- /**
399
- * Alias of emitEvent
400
- */
401
- proto.trigger = alias('emitEvent');
402
-
403
- /**
404
- * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.
405
- * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
406
- *
407
- * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
408
- * @param {...*} Optional additional arguments to be passed to each listener.
409
- * @return {Object} Current instance of EventEmitter for chaining.
410
- */
411
- proto.emit = function emit(evt) {
412
- var args = Array.prototype.slice.call(arguments, 1);
413
- return this.emitEvent(evt, args);
414
- };
415
-
416
- /**
417
- * Sets the current value to check against when executing listeners. If a
418
- * listeners return value matches the one set here then it will be removed
419
- * after execution. This value defaults to true.
420
- *
421
- * @param {*} value The new value to check for when executing listeners.
422
- * @return {Object} Current instance of EventEmitter for chaining.
423
- */
424
- proto.setOnceReturnValue = function setOnceReturnValue(value) {
425
- this._onceReturnValue = value;
426
- return this;
427
- };
428
-
429
- /**
430
- * Fetches the current value to check against when executing listeners. If
431
- * the listeners return value matches this one then it should be removed
432
- * automatically. It will return true by default.
433
- *
434
- * @return {*|Boolean} The current value to check for or the default, true.
435
- * @api private
436
- */
437
- proto._getOnceReturnValue = function _getOnceReturnValue() {
438
- if (this.hasOwnProperty('_onceReturnValue')) {
439
- return this._onceReturnValue;
440
- }
441
- else {
442
- return true;
443
- }
444
- };
445
-
446
- /**
447
- * Fetches the events object and creates one if required.
448
- *
449
- * @return {Object} The events storage object.
450
- * @api private
451
- */
452
- proto._getEvents = function _getEvents() {
453
- return this._events || (this._events = {});
454
- };
455
-
456
- /**
457
- * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.
458
- *
459
- * @return {Function} Non conflicting EventEmitter class.
460
- */
461
- EventEmitter.noConflict = function noConflict() {
462
- exports.EventEmitter = originalGlobalValue;
463
- return EventEmitter;
464
- };
465
-
466
- // Expose the class either via AMD, CommonJS or the global object
467
- if (typeof define === 'function' && define.amd) {
468
- define('eventEmitter/EventEmitter',[],function () {
469
- return EventEmitter;
470
- });
471
- }
472
- else if (typeof module === 'object' && module.exports){
473
- module.exports = EventEmitter;
474
- }
475
- else {
476
- this.EventEmitter = EventEmitter;
477
- }
478
- }.call(this));
479
 
480
- /**
481
- * eventie v1.0.4
482
- * event binding helper
483
- * eventie.bind( elem, 'click', myFn )
484
- * eventie.unbind( elem, 'click', myFn )
485
- */
 
 
 
 
 
 
 
486
 
487
- /*jshint browser: true, undef: true, unused: true */
488
- /*global define: false */
489
 
490
- ( function( window ) {
491
 
492
 
 
493
 
494
- var docElem = document.documentElement;
495
 
496
- var bind = function() {};
 
 
 
 
 
 
 
 
 
 
 
497
 
498
- function getIEEvent( obj ) {
499
- var event = window.event;
500
- // add event.target
501
- event.target = event.target || event.srcElement || obj;
502
- return event;
503
- }
504
 
505
- if ( docElem.addEventListener ) {
506
- bind = function( obj, type, fn ) {
507
- obj.addEventListener( type, fn, false );
508
- };
509
- } else if ( docElem.attachEvent ) {
510
- bind = function( obj, type, fn ) {
511
- obj[ type + fn ] = fn.handleEvent ?
512
- function() {
513
- var event = getIEEvent( obj );
514
- fn.handleEvent.call( fn, event );
515
- } :
516
- function() {
517
- var event = getIEEvent( obj );
518
- fn.call( obj, event );
519
- };
520
- obj.attachEvent( "on" + type, obj[ type + fn ] );
521
- };
522
- }
 
 
 
 
 
 
 
 
523
 
524
- var unbind = function() {};
 
525
 
526
- if ( docElem.removeEventListener ) {
527
- unbind = function( obj, type, fn ) {
528
- obj.removeEventListener( type, fn, false );
529
- };
530
- } else if ( docElem.detachEvent ) {
531
- unbind = function( obj, type, fn ) {
532
- obj.detachEvent( "on" + type, obj[ type + fn ] );
533
- try {
534
- delete obj[ type + fn ];
535
- } catch ( err ) {
536
- // can't delete window object properties
537
- obj[ type + fn ] = undefined;
 
 
 
 
 
 
 
538
  }
539
- };
540
- }
 
 
 
 
541
 
542
- var eventie = {
543
- bind: bind,
544
- unbind: unbind
545
  };
546
 
547
- // transport
548
- if ( typeof define === 'function' && define.amd ) {
549
- // AMD
550
- define( 'eventie/eventie',eventie );
551
- } else {
552
- // browser global
553
- window.eventie = eventie;
554
- }
555
 
556
- })( this );
557
 
558
- /**
559
- * imagesLoaded v3.1.8
560
  * JavaScript is all like "You images are done yet or what?"
561
  * MIT License
562
  */
563
 
564
- ( function( window, factory ) {
565
  // universal module definition
566
 
567
  /*global define: false, module: false, require: false */
568
 
569
- if ( typeof define === 'function' && define.amd ) {
570
  // AMD
571
  define( [
572
- 'eventEmitter/EventEmitter',
573
- 'eventie/eventie'
574
- ], function( EventEmitter, eventie ) {
575
- return factory( window, EventEmitter, eventie );
576
  });
577
- } else if ( typeof exports === 'object' ) {
578
  // CommonJS
579
  module.exports = factory(
580
  window,
581
- require('wolfy87-eventemitter'),
582
- require('eventie')
583
  );
584
  } else {
585
  // browser global
586
  window.imagesLoaded = factory(
587
  window,
588
- window.EventEmitter,
589
- window.eventie
590
  );
591
  }
592
 
@@ -594,13 +150,12 @@ if ( typeof define === 'function' && define.amd ) {
594
 
595
  // -------------------------- factory -------------------------- //
596
 
597
- function factory( window, EventEmitter, eventie ) {
598
 
599
 
600
 
601
  var $ = window.jQuery;
602
  var console = window.console;
603
- var hasConsole = typeof console !== 'undefined';
604
 
605
  // -------------------------- helpers -------------------------- //
606
 
@@ -612,20 +167,15 @@ function extend( a, b ) {
612
  return a;
613
  }
614
 
615
- var objToString = Object.prototype.toString;
616
- function isArray( obj ) {
617
- return objToString.call( obj ) === '[object Array]';
618
- }
619
-
620
  // turn element or nodeList into an array
621
  function makeArray( obj ) {
622
  var ary = [];
623
- if ( isArray( obj ) ) {
624
  // use object if already an array
625
  ary = obj;
626
- } else if ( typeof obj.length === 'number' ) {
627
  // convert nodeList to array
628
- for ( var i=0, len = obj.length; i < len; i++ ) {
629
  ary.push( obj[i] );
630
  }
631
  } else {
@@ -635,258 +185,302 @@ function makeArray( obj ) {
635
  return ary;
636
  }
637
 
638
- // -------------------------- imagesLoaded -------------------------- //
639
-
640
- /**
641
- * @param {Array, Element, NodeList, String} elem
642
- * @param {Object or Function} options - if function, use as callback
643
- * @param {Function} onAlways - callback function
644
- */
645
- function ImagesLoaded( elem, options, onAlways ) {
646
- // coerce ImagesLoaded() without new, to be new ImagesLoaded()
647
- if ( !( this instanceof ImagesLoaded ) ) {
648
- return new ImagesLoaded( elem, options );
649
- }
650
- // use elem as selector string
651
- if ( typeof elem === 'string' ) {
652
- elem = document.querySelectorAll( elem );
653
- }
654
 
655
- this.elements = makeArray( elem );
656
- this.options = extend( {}, this.options );
 
 
 
 
 
 
 
 
 
 
 
 
657
 
658
- if ( typeof options === 'function' ) {
659
- onAlways = options;
660
- } else {
661
- extend( this.options, options );
662
- }
663
 
664
- if ( onAlways ) {
665
- this.on( 'always', onAlways );
666
- }
 
 
667
 
668
- this.getImages();
 
 
669
 
670
- if ( $ ) {
671
- // add jQuery Deferred object
672
- this.jqDeferred = new $.Deferred();
673
- }
674
 
675
- // HACK check async to allow time to bind listeners
676
- var _this = this;
677
- setTimeout( function() {
678
- _this.check();
679
- });
680
  }
681
 
682
- ImagesLoaded.prototype = new EventEmitter();
683
-
684
- ImagesLoaded.prototype.options = {};
685
-
686
- ImagesLoaded.prototype.getImages = function() {
687
- this.images = [];
688
-
689
- // filter & find items if we have an item selector
690
- for ( var i=0, len = this.elements.length; i < len; i++ ) {
691
- var elem = this.elements[i];
692
- // filter siblings
693
- if ( elem.nodeName === 'IMG' ) {
694
- this.addImage( elem );
695
- }
696
- // find children
697
- // no non-element nodes, #143
698
- var nodeType = elem.nodeType;
699
- if ( !nodeType || !( nodeType === 1 || nodeType === 9 || nodeType === 11 ) ) {
700
- continue;
701
- }
702
- var childElems = elem.querySelectorAll('img');
703
- // concat childElems to filterFound array
704
- for ( var j=0, jLen = childElems.length; j < jLen; j++ ) {
705
- var img = childElems[j];
706
- this.addImage( img );
707
- }
708
- }
709
- };
710
 
711
- /**
712
- * @param {Image} img
713
- */
714
- ImagesLoaded.prototype.addImage = function( img ) {
715
- var loadingImage = new LoadingImage( img );
716
- this.images.push( loadingImage );
717
- };
718
 
719
- ImagesLoaded.prototype.check = function() {
720
- var _this = this;
721
- var checkedCount = 0;
722
- var length = this.images.length;
723
- this.hasAnyBroken = false;
724
- // complete if no images
725
- if ( !length ) {
726
- this.complete();
727
- return;
728
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
729
 
730
- function onConfirm( image, message ) {
731
- if ( _this.options.debug && hasConsole ) {
732
- console.log( 'confirm', image, message );
733
- }
734
-
735
- _this.progress( image );
736
- checkedCount++;
737
- if ( checkedCount === length ) {
738
- _this.complete();
739
- }
740
- return true; // bind once
741
  }
 
 
 
 
 
 
 
 
742
 
743
- for ( var i=0; i < length; i++ ) {
744
- var loadingImage = this.images[i];
745
- loadingImage.on( 'confirm', onConfirm );
746
- loadingImage.check();
 
 
 
 
 
 
 
 
 
747
  }
748
- };
 
 
749
 
750
- ImagesLoaded.prototype.progress = function( image ) {
751
- this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
752
- // HACK - Chrome triggers event before object properties have changed. #83
753
- var _this = this;
754
- setTimeout( function() {
755
- _this.emit( 'progress', _this, image );
756
- if ( _this.jqDeferred && _this.jqDeferred.notify ) {
757
- _this.jqDeferred.notify( _this, image );
758
- }
759
- });
760
- };
761
 
762
- ImagesLoaded.prototype.complete = function() {
763
- var eventName = this.hasAnyBroken ? 'fail' : 'done';
764
- this.isComplete = true;
765
- var _this = this;
766
- // HACK - another setTimeout so that confirm happens after progress
767
- setTimeout( function() {
768
- _this.emit( eventName, _this );
769
- _this.emit( 'always', _this );
770
- if ( _this.jqDeferred ) {
771
- var jqMethod = _this.hasAnyBroken ? 'reject' : 'resolve';
772
- _this.jqDeferred[ jqMethod ]( _this );
773
- }
774
- });
775
- };
776
 
777
- // -------------------------- jquery -------------------------- //
 
 
 
 
 
 
 
 
778
 
779
- if ( $ ) {
780
- $.fn.imagesLoaded = function( options, callback ) {
781
- var instance = new ImagesLoaded( this, options, callback );
782
- return instance.jqDeferred.promise( $(this) );
783
- };
784
  }
785
 
 
 
 
 
 
786
 
787
- // -------------------------- -------------------------- //
 
 
 
 
 
 
 
 
 
 
 
788
 
789
- function LoadingImage( img ) {
790
- this.img = img;
791
  }
 
792
 
793
- LoadingImage.prototype = new EventEmitter();
 
 
 
 
 
 
 
 
 
794
 
795
- LoadingImage.prototype.check = function() {
796
- // first check cached any previous images that have same src
797
- var resource = cache[ this.img.src ] || new Resource( this.img.src );
798
- if ( resource.isConfirmed ) {
799
- this.confirm( resource.isLoaded, 'cached was confirmed' );
800
- return;
801
- }
802
 
803
- // If complete is true and browser supports natural sizes,
804
- // try to check for image status manually.
805
- if ( this.img.complete && this.img.naturalWidth !== undefined ) {
806
- // report based on naturalWidth
807
- this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
808
- return;
809
- }
810
 
811
- // If none of the checks above matched, simulate loading on detached element.
812
- var _this = this;
813
- resource.on( 'confirm', function( resrc, message ) {
814
- _this.confirm( resrc.isLoaded, message );
815
- return true;
816
- });
817
 
818
- resource.check();
819
- };
 
 
 
 
 
 
 
820
 
821
- LoadingImage.prototype.confirm = function( isLoaded, message ) {
822
- this.isLoaded = isLoaded;
823
- this.emit( 'confirm', this, message );
824
- };
 
 
 
 
 
825
 
826
- // -------------------------- Resource -------------------------- //
 
 
827
 
828
- // Resource checks each src, only once
829
- // separate class from LoadingImage to prevent memory leaks. See #115
 
 
830
 
831
- var cache = {};
832
 
833
- function Resource( src ) {
834
- this.src = src;
835
- // add to cache
836
- cache[ src ] = this;
 
837
  }
 
838
 
839
- Resource.prototype = new EventEmitter();
 
 
 
840
 
841
- Resource.prototype.check = function() {
842
- // only trigger checking once
843
- if ( this.isChecked ) {
844
- return;
845
- }
846
- // simulate loading on detached element
847
- var proxyImage = new Image();
848
- eventie.bind( proxyImage, 'load', this );
849
- eventie.bind( proxyImage, 'error', this );
850
- proxyImage.src = this.src;
851
- // set flag
852
- this.isChecked = true;
853
- };
854
 
855
- // ----- events ----- //
 
 
 
 
 
856
 
857
- // trigger specified handler for event type
858
- Resource.prototype.handleEvent = function( event ) {
859
- var method = 'on' + event.type;
860
- if ( this[ method ] ) {
861
- this[ method ]( event );
862
- }
863
- };
864
 
865
- Resource.prototype.onload = function( event ) {
866
- this.confirm( true, 'onload' );
867
- this.unbindProxyEvents( event );
868
- };
 
869
 
870
- Resource.prototype.onerror = function( event ) {
871
- this.confirm( false, 'onerror' );
872
- this.unbindProxyEvents( event );
873
- };
 
 
 
 
 
 
 
 
 
 
874
 
875
- // ----- confirm ----- //
 
 
 
876
 
877
- Resource.prototype.confirm = function( isLoaded, message ) {
878
- this.isConfirmed = true;
879
- this.isLoaded = isLoaded;
880
- this.emit( 'confirm', this, message );
881
- };
882
 
883
- Resource.prototype.unbindProxyEvents = function( event ) {
884
- eventie.unbind( event.target, 'load', this );
885
- eventie.unbind( event.target, 'error', this );
 
 
 
 
 
 
 
 
 
 
886
  };
 
 
 
887
 
888
- // ----- ----- //
889
 
890
- return ImagesLoaded;
891
 
892
- });
1
+ /*!
2
+ * imagesLoaded PACKAGED v4.1.0
3
  * JavaScript is all like "You images are done yet or what?"
4
  * MIT License
5
  */
6
 
 
7
  /**
8
+ * EvEmitter v1.0.1
9
+ * Lil' event emitter
10
+ * MIT License
11
  */
12
 
13
+ /* jshint unused: true, undef: true, strict: true */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
+ ( function( global, factory ) {
16
+ // universal module definition
17
+ /* jshint strict: false */ /* globals define, module */
18
+ if ( typeof define == 'function' && define.amd ) {
19
+ // AMD - RequireJS
20
+ define( 'ev-emitter/ev-emitter',factory );
21
+ } else if ( typeof module == 'object' && module.exports ) {
22
+ // CommonJS - Browserify, Webpack
23
+ module.exports = factory();
24
+ } else {
25
+ // Browser globals
26
+ global.EvEmitter = factory();
27
+ }
28
 
29
+ }( this, function() {
 
30
 
 
31
 
32
 
33
+ function EvEmitter() {}
34
 
35
+ var proto = EvEmitter.prototype;
36
 
37
+ proto.on = function( eventName, listener ) {
38
+ if ( !eventName || !listener ) {
39
+ return;
40
+ }
41
+ // set events hash
42
+ var events = this._events = this._events || {};
43
+ // set listeners array
44
+ var listeners = events[ eventName ] = events[ eventName ] || [];
45
+ // only add once
46
+ if ( listeners.indexOf( listener ) == -1 ) {
47
+ listeners.push( listener );
48
+ }
49
 
50
+ return this;
51
+ };
 
 
 
 
52
 
53
+ proto.once = function( eventName, listener ) {
54
+ if ( !eventName || !listener ) {
55
+ return;
56
+ }
57
+ // add event
58
+ this.on( eventName, listener );
59
+ // set once flag
60
+ // set onceEvents hash
61
+ var onceEvents = this._onceEvents = this._onceEvents || {};
62
+ // set onceListeners array
63
+ var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || [];
64
+ // set flag
65
+ onceListeners[ listener ] = true;
66
+
67
+ return this;
68
+ };
69
+
70
+ proto.off = function( eventName, listener ) {
71
+ var listeners = this._events && this._events[ eventName ];
72
+ if ( !listeners || !listeners.length ) {
73
+ return;
74
+ }
75
+ var index = listeners.indexOf( listener );
76
+ if ( index != -1 ) {
77
+ listeners.splice( index, 1 );
78
+ }
79
 
80
+ return this;
81
+ };
82
 
83
+ proto.emitEvent = function( eventName, args ) {
84
+ var listeners = this._events && this._events[ eventName ];
85
+ if ( !listeners || !listeners.length ) {
86
+ return;
87
+ }
88
+ var i = 0;
89
+ var listener = listeners[i];
90
+ args = args || [];
91
+ // once stuff
92
+ var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
93
+
94
+ while ( listener ) {
95
+ var isOnce = onceListeners && onceListeners[ listener ];
96
+ if ( isOnce ) {
97
+ // remove listener
98
+ // remove before trigger to prevent recursion
99
+ this.off( eventName, listener );
100
+ // unset once flag
101
+ delete onceListeners[ listener ];
102
  }
103
+ // trigger listener
104
+ listener.apply( this, args );
105
+ // get next listener
106
+ i += isOnce ? 0 : 1;
107
+ listener = listeners[i];
108
+ }
109
 
110
+ return this;
 
 
111
  };
112
 
113
+ return EvEmitter;
 
 
 
 
 
 
 
114
 
115
+ }));
116
 
117
+ /*!
118
+ * imagesLoaded v4.1.0
119
  * JavaScript is all like "You images are done yet or what?"
120
  * MIT License
121
  */
122
 
123
+ ( function( window, factory ) { 'use strict';
124
  // universal module definition
125
 
126
  /*global define: false, module: false, require: false */
127
 
128
+ if ( typeof define == 'function' && define.amd ) {
129
  // AMD
130
  define( [
131
+ 'ev-emitter/ev-emitter'
132
+ ], function( EvEmitter ) {
133
+ return factory( window, EvEmitter );
 
134
  });
135
+ } else if ( typeof module == 'object' && module.exports ) {
136
  // CommonJS
137
  module.exports = factory(
138
  window,
139
+ require('ev-emitter')
 
140
  );
141
  } else {
142
  // browser global
143
  window.imagesLoaded = factory(
144
  window,
145
+ window.EvEmitter
 
146
  );
147
  }
148
 
150
 
151
  // -------------------------- factory -------------------------- //
152
 
153
+ function factory( window, EvEmitter ) {
154
 
155
 
156
 
157
  var $ = window.jQuery;
158
  var console = window.console;
 
159
 
160
  // -------------------------- helpers -------------------------- //
161
 
167
  return a;
168
  }
169
 
 
 
 
 
 
170
  // turn element or nodeList into an array
171
  function makeArray( obj ) {
172
  var ary = [];
173
+ if ( Array.isArray( obj ) ) {
174
  // use object if already an array
175
  ary = obj;
176
+ } else if ( typeof obj.length == 'number' ) {
177
  // convert nodeList to array
178
+ for ( var i=0; i < obj.length; i++ ) {
179
  ary.push( obj[i] );
180
  }
181
  } else {
185
  return ary;
186
  }
187
 
188
+ // -------------------------- imagesLoaded -------------------------- //
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
 
190
+ /**
191
+ * @param {Array, Element, NodeList, String} elem
192
+ * @param {Object or Function} options - if function, use as callback
193
+ * @param {Function} onAlways - callback function
194
+ */
195
+ function ImagesLoaded( elem, options, onAlways ) {
196
+ // coerce ImagesLoaded() without new, to be new ImagesLoaded()
197
+ if ( !( this instanceof ImagesLoaded ) ) {
198
+ return new ImagesLoaded( elem, options, onAlways );
199
+ }
200
+ // use elem as selector string
201
+ if ( typeof elem == 'string' ) {
202
+ elem = document.querySelectorAll( elem );
203
+ }
204
 
205
+ this.elements = makeArray( elem );
206
+ this.options = extend( {}, this.options );
 
 
 
207
 
208
+ if ( typeof options == 'function' ) {
209
+ onAlways = options;
210
+ } else {
211
+ extend( this.options, options );
212
+ }
213
 
214
+ if ( onAlways ) {
215
+ this.on( 'always', onAlways );
216
+ }
217
 
218
+ this.getImages();
 
 
 
219
 
220
+ if ( $ ) {
221
+ // add jQuery Deferred object
222
+ this.jqDeferred = new $.Deferred();
 
 
223
  }
224
 
225
+ // HACK check async to allow time to bind listeners
226
+ setTimeout( function() {
227
+ this.check();
228
+ }.bind( this ));
229
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
 
231
+ ImagesLoaded.prototype = Object.create( EvEmitter.prototype );
 
 
 
 
 
 
232
 
233
+ ImagesLoaded.prototype.options = {};
234
+
235
+ ImagesLoaded.prototype.getImages = function() {
236
+ this.images = [];
237
+
238
+ // filter & find items if we have an item selector
239
+ this.elements.forEach( this.addElementImages, this );
240
+ };
241
+
242
+ /**
243
+ * @param {Node} element
244
+ */
245
+ ImagesLoaded.prototype.addElementImages = function( elem ) {
246
+ // filter siblings
247
+ if ( elem.nodeName == 'IMG' ) {
248
+ this.addImage( elem );
249
+ }
250
+ // get background image on element
251
+ if ( this.options.background === true ) {
252
+ this.addElementBackgroundImages( elem );
253
+ }
254
+
255
+ // find children
256
+ // no non-element nodes, #143
257
+ var nodeType = elem.nodeType;
258
+ if ( !nodeType || !elementNodeTypes[ nodeType ] ) {
259
+ return;
260
+ }
261
+ var childImgs = elem.querySelectorAll('img');
262
+ // concat childElems to filterFound array
263
+ for ( var i=0; i < childImgs.length; i++ ) {
264
+ var img = childImgs[i];
265
+ this.addImage( img );
266
+ }
267
 
268
+ // get child background images
269
+ if ( typeof this.options.background == 'string' ) {
270
+ var children = elem.querySelectorAll( this.options.background );
271
+ for ( i=0; i < children.length; i++ ) {
272
+ var child = children[i];
273
+ this.addElementBackgroundImages( child );
 
 
 
 
 
274
  }
275
+ }
276
+ };
277
+
278
+ var elementNodeTypes = {
279
+ 1: true,
280
+ 9: true,
281
+ 11: true
282
+ };
283
 
284
+ ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
285
+ var style = getComputedStyle( elem );
286
+ if ( !style ) {
287
+ // Firefox returns null if in a hidden iframe https://bugzil.la/548397
288
+ return;
289
+ }
290
+ // get url inside url("...")
291
+ var reURL = /url\((['"])?(.*?)\1\)/gi;
292
+ var matches = reURL.exec( style.backgroundImage );
293
+ while ( matches !== null ) {
294
+ var url = matches && matches[2];
295
+ if ( url ) {
296
+ this.addBackground( url, elem );
297
  }
298
+ matches = reURL.exec( style.backgroundImage );
299
+ }
300
+ };
301
 
302
+ /**
303
+ * @param {Image} img
304
+ */
305
+ ImagesLoaded.prototype.addImage = function( img ) {
306
+ var loadingImage = new LoadingImage( img );
307
+ this.images.push( loadingImage );
308
+ };
 
 
 
 
309
 
310
+ ImagesLoaded.prototype.addBackground = function( url, elem ) {
311
+ var background = new Background( url, elem );
312
+ this.images.push( background );
313
+ };
 
 
 
 
 
 
 
 
 
 
314
 
315
+ ImagesLoaded.prototype.check = function() {
316
+ var _this = this;
317
+ this.progressedCount = 0;
318
+ this.hasAnyBroken = false;
319
+ // complete if no images
320
+ if ( !this.images.length ) {
321
+ this.complete();
322
+ return;
323
+ }
324
 
325
+ function onProgress( image, elem, message ) {
326
+ // HACK - Chrome triggers event before object properties have changed. #83
327
+ setTimeout( function() {
328
+ _this.progress( image, elem, message );
329
+ });
330
  }
331
 
332
+ this.images.forEach( function( loadingImage ) {
333
+ loadingImage.once( 'progress', onProgress );
334
+ loadingImage.check();
335
+ });
336
+ };
337
 
338
+ ImagesLoaded.prototype.progress = function( image, elem, message ) {
339
+ this.progressedCount++;
340
+ this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
341
+ // progress event
342
+ this.emitEvent( 'progress', [ this, image, elem ] );
343
+ if ( this.jqDeferred && this.jqDeferred.notify ) {
344
+ this.jqDeferred.notify( this, image );
345
+ }
346
+ // check if completed
347
+ if ( this.progressedCount == this.images.length ) {
348
+ this.complete();
349
+ }
350
 
351
+ if ( this.options.debug && console ) {
352
+ console.log( 'progress: ' + message, image, elem );
353
  }
354
+ };
355
 
356
+ ImagesLoaded.prototype.complete = function() {
357
+ var eventName = this.hasAnyBroken ? 'fail' : 'done';
358
+ this.isComplete = true;
359
+ this.emitEvent( eventName, [ this ] );
360
+ this.emitEvent( 'always', [ this ] );
361
+ if ( this.jqDeferred ) {
362
+ var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
363
+ this.jqDeferred[ jqMethod ]( this );
364
+ }
365
+ };
366
 
367
+ // -------------------------- -------------------------- //
 
 
 
 
 
 
368
 
369
+ function LoadingImage( img ) {
370
+ this.img = img;
371
+ }
 
 
 
 
372
 
373
+ LoadingImage.prototype = Object.create( EvEmitter.prototype );
 
 
 
 
 
374
 
375
+ LoadingImage.prototype.check = function() {
376
+ // If complete is true and browser supports natural sizes,
377
+ // try to check for image status manually.
378
+ var isComplete = this.getIsImageComplete();
379
+ if ( isComplete ) {
380
+ // report based on naturalWidth
381
+ this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
382
+ return;
383
+ }
384
 
385
+ // If none of the checks above matched, simulate loading on detached element.
386
+ this.proxyImage = new Image();
387
+ this.proxyImage.addEventListener( 'load', this );
388
+ this.proxyImage.addEventListener( 'error', this );
389
+ // bind to image as well for Firefox. #191
390
+ this.img.addEventListener( 'load', this );
391
+ this.img.addEventListener( 'error', this );
392
+ this.proxyImage.src = this.img.src;
393
+ };
394
 
395
+ LoadingImage.prototype.getIsImageComplete = function() {
396
+ return this.img.complete && this.img.naturalWidth !== undefined;
397
+ };
398
 
399
+ LoadingImage.prototype.confirm = function( isLoaded, message ) {
400
+ this.isLoaded = isLoaded;
401
+ this.emitEvent( 'progress', [ this, this.img, message ] );
402
+ };
403
 
404
+ // ----- events ----- //
405
 
406
+ // trigger specified handler for event type
407
+ LoadingImage.prototype.handleEvent = function( event ) {
408
+ var method = 'on' + event.type;
409
+ if ( this[ method ] ) {
410
+ this[ method ]( event );
411
  }
412
+ };
413
 
414
+ LoadingImage.prototype.onload = function() {
415
+ this.confirm( true, 'onload' );
416
+ this.unbindEvents();
417
+ };
418
 
419
+ LoadingImage.prototype.onerror = function() {
420
+ this.confirm( false, 'onerror' );
421
+ this.unbindEvents();
422
+ };
 
 
 
 
 
 
 
 
 
423
 
424
+ LoadingImage.prototype.unbindEvents = function() {
425
+ this.proxyImage.removeEventListener( 'load', this );
426
+ this.proxyImage.removeEventListener( 'error', this );
427
+ this.img.removeEventListener( 'load', this );
428
+ this.img.removeEventListener( 'error', this );
429
+ };
430
 
431
+ // -------------------------- Background -------------------------- //
 
 
 
 
 
 
432
 
433
+ function Background( url, element ) {
434
+ this.url = url;
435
+ this.element = element;
436
+ this.img = new Image();
437
+ }
438
 
439
+ // inherit LoadingImage prototype
440
+ Background.prototype = Object.create( LoadingImage.prototype );
441
+
442
+ Background.prototype.check = function() {
443
+ this.img.addEventListener( 'load', this );
444
+ this.img.addEventListener( 'error', this );
445
+ this.img.src = this.url;
446
+ // check if image is already complete
447
+ var isComplete = this.getIsImageComplete();
448
+ if ( isComplete ) {
449
+ this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
450
+ this.unbindEvents();
451
+ }
452
+ };
453
 
454
+ Background.prototype.unbindEvents = function() {
455
+ this.img.removeEventListener( 'load', this );
456
+ this.img.removeEventListener( 'error', this );
457
+ };
458
 
459
+ Background.prototype.confirm = function( isLoaded, message ) {
460
+ this.isLoaded = isLoaded;
461
+ this.emitEvent( 'progress', [ this, this.element, message ] );
462
+ };
 
463
 
464
+ // -------------------------- jQuery -------------------------- //
465
+
466
+ ImagesLoaded.makeJQueryPlugin = function( jQuery ) {
467
+ jQuery = jQuery || window.jQuery;
468
+ if ( !jQuery ) {
469
+ return;
470
+ }
471
+ // set local variable
472
+ $ = jQuery;
473
+ // $().imagesLoaded()
474
+ $.fn.imagesLoaded = function( options, callback ) {
475
+ var instance = new ImagesLoaded( this, options, callback );
476
+ return instance.jqDeferred.promise( $(this) );
477
  };
478
+ };
479
+ // try making plugin
480
+ ImagesLoaded.makeJQueryPlugin();
481
 
482
+ // -------------------------- -------------------------- //
483
 
484
+ return ImagesLoaded;
485
 
486
+ });
assets/js/lib/isotope.js CHANGED
@@ -1,777 +1,295 @@
1
  /*!
2
- * Enviratope PACKAGED v2.2.2
3
  *
4
  * Licensed GPLv3 for open source use
5
  * or Enviratope Commercial License for commercial use
6
  *
7
  * http://enviratope.metafizzy.co
8
- * Copyright 2015 Metafizzy
9
  */
10
 
11
  /**
12
  * Bridget makes jQuery widgets
13
- * v1.1.0
14
  * MIT license
15
  */
16
 
17
- ( function( window ) {
18
 
 
 
 
19
 
20
-
21
- // -------------------------- utils -------------------------- //
22
-
23
- var slice = Array.prototype.slice;
24
-
25
- function noop() {}
26
-
27
- // -------------------------- definition -------------------------- //
28
-
29
- function defineBridget( $ ) {
30
-
31
- // bail if no jQuery
32
- if ( !$ ) {
33
- return;
34
- }
35
-
36
- // -------------------------- addOptionMethod -------------------------- //
37
-
38
- /**
39
- * adds option method -> $().plugin('option', {...})
40
- * @param {Function} PluginClass - constructor class
41
- */
42
- function addOptionMethod( PluginClass ) {
43
- // don't overwrite original option method
44
- if ( PluginClass.prototype.option ) {
45
- return;
46
  }
47
 
48
- // option setter
49
- PluginClass.prototype.option = function( opts ) {
50
- // bail out if not an object
51
- if ( !$.isPlainObject( opts ) ){
52
- return;
53
- }
54
- this.options = $.extend( true, this.options, opts );
55
- };
56
- }
57
 
58
- // -------------------------- plugin bridge -------------------------- //
59
 
60
  // helper function for logging errors
61
  // $.error breaks jQuery chaining
62
- var logError = typeof console === 'undefined' ? noop :
 
63
  function( message ) {
64
  console.error( message );
65
  };
66
 
67
- /**
68
- * jQuery plugin bridge, access methods like $elem.plugin('method')
69
- * @param {String} namespace - plugin name
70
- * @param {Function} PluginClass - constructor class
71
- */
72
- function bridge( namespace, PluginClass ) {
73
- // add to jQuery fn namespace
74
- $.fn[ namespace ] = function( options ) {
75
- if ( typeof options === 'string' ) {
76
- // call plugin method when first argument is a string
77
- // get arguments for method
78
- var args = slice.call( arguments, 1 );
79
-
80
- for ( var i=0, len = this.length; i < len; i++ ) {
81
- var elem = this[i];
82
- var instance = $.data( elem, namespace );
83
- if ( !instance ) {
84
- logError( "cannot call methods on " + namespace + " prior to initialization; " +
85
- "attempted to call '" + options + "'" );
86
- continue;
87
- }
88
- if ( !$.isFunction( instance[options] ) || options.charAt(0) === '_' ) {
89
- logError( "no such method '" + options + "' for " + namespace + " instance" );
90
- continue;
91
- }
92
 
93
- // trigger method with arguments
94
- var returnValue = instance[ options ].apply( instance, args );
 
 
 
95
 
96
- // break look and return first value if provided
97
- if ( returnValue !== undefined ) {
98
- return returnValue;
99
- }
 
 
 
100
  }
101
- // return this if no return value
102
- return this;
103
- } else {
104
- return this.each( function() {
105
- var instance = $.data( this, namespace );
106
- if ( instance ) {
107
- // apply options & init
108
- instance.option( options );
109
- instance._init();
110
- } else {
111
- // initialize new instance
112
- instance = new PluginClass( this, options );
113
- $.data( this, namespace, instance );
114
- }
115
- });
116
  }
 
 
 
117
  };
118
 
119
- }
120
-
121
- // -------------------------- bridget -------------------------- //
122
-
123
- /**
124
- * converts a Prototypical class into a proper jQuery plugin
125
- * the class must have a ._init method
126
- * @param {String} namespace - plugin name, used in $().pluginName
127
- * @param {Function} PluginClass - constructor class
128
- */
129
- $.bridget = function( namespace, PluginClass ) {
130
- addOptionMethod( PluginClass );
131
- bridge( namespace, PluginClass );
132
- };
133
-
134
- return $.bridget;
135
-
136
- }
137
-
138
- // transport
139
- if ( typeof define === 'function' && define.amd ) {
140
- // AMD
141
- define( 'jquery-bridget/jquery.bridget',[ 'jquery' ], defineBridget );
142
- } else if ( typeof exports === 'object' ) {
143
- defineBridget( require('jquery') );
144
- } else {
145
- // get jquery from browser global
146
- defineBridget( window.jQuery );
147
- }
148
-
149
- })( window );
150
-
151
- /*!
152
- * eventie v1.0.6
153
- * event binding helper
154
- * eventie.bind( elem, 'click', myFn )
155
- * eventie.unbind( elem, 'click', myFn )
156
- * MIT license
157
- */
158
-
159
- /*jshint browser: true, undef: true, unused: true */
160
- /*global define: false, module: false */
161
-
162
- ( function( window ) {
163
-
164
 
 
 
 
 
 
 
 
 
165
 
166
- var docElem = document.documentElement;
 
 
 
 
167
 
168
- var bind = function() {};
 
 
 
 
169
 
170
- function getIEEvent( obj ) {
171
- var event = window.event;
172
- // add event.target
173
- event.target = event.target || event.srcElement || obj;
174
- return event;
175
- }
176
 
177
- if ( docElem.addEventListener ) {
178
- bind = function( obj, type, fn ) {
179
- obj.addEventListener( type, fn, false );
180
- };
181
- } else if ( docElem.attachEvent ) {
182
- bind = function( obj, type, fn ) {
183
- obj[ type + fn ] = fn.handleEvent ?
184
- function() {
185
- var event = getIEEvent( obj );
186
- fn.handleEvent.call( fn, event );
187
- } :
188
- function() {
189
- var event = getIEEvent( obj );
190
- fn.call( obj, event );
191
- };
192
- obj.attachEvent( "on" + type, obj[ type + fn ] );
193
- };
194
- }
195
 
196
- var unbind = function() {};
197
 
198
- if ( docElem.removeEventListener ) {
199
- unbind = function( obj, type, fn ) {
200
- obj.removeEventListener( type, fn, false );
201
- };
202
- } else if ( docElem.detachEvent ) {
203
- unbind = function( obj, type, fn ) {
204
- obj.detachEvent( "on" + type, obj[ type + fn ] );
205
- try {
206
- delete obj[ type + fn ];
207
- } catch ( err ) {
208
- // can't delete window object properties
209
- obj[ type + fn ] = undefined;
210
- }
211
- };
212
  }
213
 
214
- var eventie = {
215
- bind: bind,
216
- unbind: unbind
217
- };
218
 
219
- // ----- module definition ----- //
220
-
221
- if ( typeof define === 'function' && define.amd ) {
222
- // AMD
223
- define( 'eventie/eventie',eventie );
224
- } else if ( typeof exports === 'object' ) {
225
- // CommonJS
226
- module.exports = eventie;
227
- } else {
228
- // browser global
229
- window.eventie = eventie;
230
  }
231
 
232
- })( window );
233
-
234
- /*!
235
- * EventEmitter v4.2.11 - git.io/ee
236
- * Unlicense - http://unlicense.org/
237
- * Oliver Caldwell - http://oli.me.uk/
238
- * @preserve
239
- */
240
-
241
- ;(function () {
242
- 'use strict';
243
-
244
- /**
245
- * Class for managing events.
246
- * Can be extended to provide event functionality in other classes.
247
- *
248
- * @class EventEmitter Manages event registering and emitting.
249
- */
250
- function EventEmitter() {}
251
-
252
- // Shortcuts to improve speed and size
253
- var proto = EventEmitter.prototype;
254
- var exports = this;
255
- var originalGlobalValue = exports.EventEmitter;
256
-
257
- /**
258
- * Finds the index of the listener for the event in its storage array.
259
- *
260
- * @param {Function[]} listeners Array of listeners to search through.
261
- * @param {Function} listener Method to look for.
262
- * @return {Number} Index of the specified listener, -1 if not found
263
- * @api private
264
- */
265
- function indexOfListener(listeners, listener) {
266
- var i = listeners.length;
267
- while (i--) {
268
- if (listeners[i].listener === listener) {
269
- return i;
270
- }
271
- }
272
-
273
- return -1;
274
- }
275
-
276
- /**
277
- * Alias a method while keeping the context correct, to allow for overwriting of target method.
278
- *
279
- * @param {String} name The name of the target method.
280
- * @return {Function} The aliased method
281
- * @api private
282
- */
283
- function alias(name) {
284
- return function aliasClosure() {
285
- return this[name].apply(this, arguments);
286
- };
287
- }
288
-
289
- /**
290
- * Returns the listener array for the specified event.
291
- * Will initialise the event object and listener arrays if required.
292
- * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
293
- * Each property in the object response is an array of listener functions.
294
- *
295
- * @param {String|RegExp} evt Name of the event to return the listeners from.
296
- * @return {Function[]|Object} All listener functions for the event.
297
- */
298
- proto.getListeners = function getListeners(evt) {
299
- var events = this._getEvents();
300
- var response;
301
- var key;
302
-
303
- // Return a concatenated array of all matching events if
304
- // the selector is a regular expression.
305
- if (evt instanceof RegExp) {
306
- response = {};
307
- for (key in events) {
308
- if (events.hasOwnProperty(key) && evt.test(key)) {
309
- response[key] = events[key];
310
- }
311
- }
312
- }
313
- else {
314
- response = events[evt] || (events[evt] = []);
315
- }
316
-
317
- return response;
318
- };
319
-
320
- /**
321
- * Takes a list of listener objects and flattens it into a list of listener functions.
322
- *
323
- * @param {Object[]} listeners Raw listener objects.
324
- * @return {Function[]} Just the listener functions.
325
- */
326
- proto.flattenListeners = function flattenListeners(listeners) {
327
- var flatListeners = [];
328
- var i;
329
-
330
- for (i = 0; i < listeners.length; i += 1) {
331
- flatListeners.push(listeners[i].listener);
332
- }
333
-
334
- return flatListeners;
335
- };
336
-
337
- /**
338
- * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.
339
- *
340
- * @param {String|RegExp} evt Name of the event to return the listeners from.
341
- * @return {Object} All listener functions for an event in an object.
342
- */
343
- proto.getListenersAsObject = function getListenersAsObject(evt) {
344
- var listeners = this.getListeners(evt);
345
- var response;
346
-
347
- if (listeners instanceof Array) {
348
- response = {};
349
- response[evt] = listeners;
350
- }
351
-
352
- return response || listeners;
353
- };
354
-
355
- /**
356
- * Adds a listener function to the specified event.
357
- * The listener will not be added if it is a duplicate.
358
- * If the listener returns true then it will be removed after it is called.
359
- * If you pass a regular expression as the event name then the listener will be added to all events that match it.
360
- *
361
- * @param {String|RegExp} evt Name of the event to attach the listener to.
362
- * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
363
- * @return {Object} Current instance of EventEmitter for chaining.
364
- */
365
- proto.addListener = function addListener(evt, listener) {
366
- var listeners = this.getListenersAsObject(evt);
367
- var listenerIsWrapped = typeof listener === 'object';
368
- var key;
369
-
370
- for (key in listeners) {
371
- if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
372
- listeners[key].push(listenerIsWrapped ? listener : {
373
- listener: listener,
374
- once: false
375
- });
376
- }
377
- }
378
-
379
- return this;
380
- };
381
-
382
- /**
383
- * Alias of addListener
384
- */
385
- proto.on = alias('addListener');
386
-
387
- /**
388
- * Semi-alias of addListener. It will add a listener that will be
389
- * automatically removed after its first execution.
390
- *
391
- * @param {String|RegExp} evt Name of the event to attach the listener to.
392
- * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
393
- * @return {Object} Current instance of EventEmitter for chaining.
394
- */
395
- proto.addOnceListener = function addOnceListener(evt, listener) {
396
- return this.addListener(evt, {
397
- listener: listener,
398
- once: true
399
- });
400
- };
401
-
402
- /**
403
- * Alias of addOnceListener.
404
- */
405
- proto.once = alias('addOnceListener');
406
-
407
- /**
408
- * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.
409
- * You need to tell it what event names should be matched by a regex.
410
- *
411
- * @param {String} evt Name of the event to create.
412
- * @return {Object} Current instance of EventEmitter for chaining.
413
- */
414
- proto.defineEvent = function defineEvent(evt) {
415
- this.getListeners(evt);
416
- return this;
417
- };
418
-
419
- /**
420
- * Uses defineEvent to define multiple events.
421
- *
422
- * @param {String[]} evts An array of event names to define.
423
- * @return {Object} Current instance of EventEmitter for chaining.
424
- */
425
- proto.defineEvents = function defineEvents(evts) {
426
- for (var i = 0; i < evts.length; i += 1) {
427
- this.defineEvent(evts[i]);
428
- }
429
- return this;
430
- };
431
-
432
- /**
433
- * Removes a listener function from the specified event.
434
- * When passed a regular expression as the event name, it will remove the listener from all events that match it.
435
- *
436
- * @param {String|RegExp} evt Name of the event to remove the listener from.
437
- * @param {Function} listener Method to remove from the event.
438
- * @return {Object} Current instance of EventEmitter for chaining.
439
- */
440
- proto.removeListener = function removeListener(evt, listener) {
441
- var listeners = this.getListenersAsObject(evt);
442
- var index;
443
- var key;
444
-
445
- for (key in listeners) {
446
- if (listeners.hasOwnProperty(key)) {
447
- index = indexOfListener(listeners[key], listener);
448
-
449
- if (index !== -1) {
450
- listeners[key].splice(index, 1);
451
- }
452
- }
453
- }
454
-
455
- return this;
456
- };
457
-
458
- /**
459
- * Alias of removeListener
460
- */
461
- proto.off = alias('removeListener');
462
-
463
- /**
464
- * Adds listeners in bulk using the manipulateListeners method.
465
- * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
466
- * You can also pass it a regular expression to add the array of listeners to all events that match it.
467
- * Yeah, this function does quite a bit. That's probably a bad thing.
468
- *
469
- * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
470
- * @param {Function[]} [listeners] An optional array of listener functions to add.
471
- * @return {Object} Current instance of EventEmitter for chaining.
472
- */
473
- proto.addListeners = function addListeners(evt, listeners) {
474
- // Pass through to manipulateListeners
475
- return this.manipulateListeners(false, evt, listeners);
476
- };
477
-
478
- /**
479
- * Removes listeners in bulk using the manipulateListeners method.
480
- * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
481
- * You can also pass it an event name and an array of listeners to be removed.
482
- * You can also pass it a regular expression to remove the listeners from all events that match it.
483
- *
484
- * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
485
- * @param {Function[]} [listeners] An optional array of listener functions to remove.
486
- * @return {Object} Current instance of EventEmitter for chaining.
487
- */
488
- proto.removeListeners = function removeListeners(evt, listeners) {
489
- // Pass through to manipulateListeners
490
- return this.manipulateListeners(true, evt, listeners);
491
- };
492
-
493
- /**
494
- * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.
495
- * The first argument will determine if the listeners are removed (true) or added (false).
496
- * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
497
- * You can also pass it an event name and an array of listeners to be added/removed.
498
- * You can also pass it a regular expression to manipulate the listeners of all events that match it.
499
- *
500
- * @param {Boolean} remove True if you want to remove listeners, false if you want to add.
501
- * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.
502
- * @param {Function[]} [listeners] An optional array of listener functions to add/remove.
503
- * @return {Object} Current instance of EventEmitter for chaining.
504
- */
505
- proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
506
- var i;
507
- var value;
508
- var single = remove ? this.removeListener : this.addListener;
509
- var multiple = remove ? this.removeListeners : this.addListeners;
510
-
511
- // If evt is an object then pass each of its properties to this method
512
- if (typeof evt === 'object' && !(evt instanceof RegExp)) {
513
- for (i in evt) {
514
- if (evt.hasOwnProperty(i) && (value = evt[i])) {
515
- // Pass the single listener straight through to the singular method
516
- if (typeof value === 'function') {
517
- single.call(this, i, value);
518
- }
519
- else {
520
- // Otherwise pass back to the multiple function
521
- multiple.call(this, i, value);
522
- }
523
- }
524
- }
525
- }
526
- else {
527
- // So evt must be a string
528
- // And listeners must be an array of listeners
529
- // Loop over it and pass each one to the multiple method
530
- i = listeners.length;
531
- while (i--) {
532
- single.call(this, evt, listeners[i]);
533
- }
534
- }
535
-
536
- return this;
537
- };
538
-
539
- /**
540
- * Removes all listeners from a specified event.
541
- * If you do not specify an event then all listeners will be removed.
542
- * That means every event will be emptied.
543
- * You can also pass a regex to remove all events that match it.
544
- *
545
- * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
546
- * @return {Object} Current instance of EventEmitter for chaining.
547
- */
548
- proto.removeEvent = function removeEvent(evt) {
549
- var type = typeof evt;
550
- var events = this._getEvents();
551
- var key;
552
-
553
- // Remove different things depending on the state of evt
554
- if (type === 'string') {
555
- // Remove all listeners for the specified event
556
- delete events[evt];
557
- }
558
- else if (evt instanceof RegExp) {
559
- // Remove all events matching the regex.
560
- for (key in events) {
561
- if (events.hasOwnProperty(key) && evt.test(key)) {
562
- delete events[key];
563
- }
564
- }
565
- }
566
- else {
567
- // Remove all listeners in all events
568
- delete this._events;
569
- }
570
 
571
- return this;
572
- };
573
 
574
- /**
575
- * Alias of removeEvent.
576
- *
577
- * Added to mirror the node API.
578
- */
579
- proto.removeAllListeners = alias('removeEvent');
580
-
581
- /**
582
- * Emits an event of your choice.
583
- * When emitted, every listener attached to that event will be executed.
584
- * If you pass the optional argument array then those arguments will be passed to every listener upon execution.
585
- * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
586
- * So they will not arrive within the array on the other side, they will be separate.
587
- * You can also pass a regular expression to emit to all events that match it.
588
- *
589
- * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
590
- * @param {Array} [args] Optional array of arguments to be passed to each listener.
591
- * @return {Object} Current instance of EventEmitter for chaining.
592
- */
593
- proto.emitEvent = function emitEvent(evt, args) {
594
- var listeners = this.getListenersAsObject(evt);
595
- var listener;
596
- var i;
597
- var key;
598
- var response;
599
-
600
- for (key in listeners) {
601
- if (listeners.hasOwnProperty(key)) {
602
- i = listeners[key].length;
603
-
604
- while (i--) {
605
- // If the listener returns true then it shall be removed from the event
606
- // The function is executed either with a basic call or an apply if there is an args array
607
- listener = listeners[key][i];
608
-
609
- if (listener.once === true) {
610
- this.removeListener(evt, listener.listener);
611
- }
612
-
613
- response = listener.listener.apply(this, args || []);
614
-
615
- if (response === this._getOnceReturnValue()) {
616
- this.removeListener(evt, listener.listener);
617
- }
618
- }
619
- }
620
- }
621
 
622
- return this;
623
- };
624
 
625
- /**
626
- * Alias of emitEvent
627
- */
628
- proto.trigger = alias('emitEvent');
629
-
630
- /**
631
- * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.
632
- * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
633
- *
634
- * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
635
- * @param {...*} Optional additional arguments to be passed to each listener.
636
- * @return {Object} Current instance of EventEmitter for chaining.
637
- */
638
- proto.emit = function emit(evt) {
639
- var args = Array.prototype.slice.call(arguments, 1);
640
- return this.emitEvent(evt, args);
641
- };
642
 
643
- /**
644
- * Sets the current value to check against when executing listeners. If a
645
- * listeners return value matches the one set here then it will be removed
646
- * after execution. This value defaults to true.
647
- *
648
- * @param {*} value The new value to check for when executing listeners.
649
- * @return {Object} Current instance of EventEmitter for chaining.
650
- */
651
- proto.setOnceReturnValue = function setOnceReturnValue(value) {
652
- this._onceReturnValue = value;
653
- return this;
654
- };
655
 
656
- /**
657
- * Fetches the current value to check against when executing listeners. If
658
- * the listeners return value matches this one then it should be removed
659
- * automatically. It will return true by default.
660
- *
661
- * @return {*|Boolean} The current value to check for or the default, true.
662
- * @api private
663
- */
664
- proto._getOnceReturnValue = function _getOnceReturnValue() {
665
- if (this.hasOwnProperty('_onceReturnValue')) {
666
- return this._onceReturnValue;
667
- }
668
- else {
669
- return true;
670
- }
671
- };
672
 
673
- /**
674
- * Fetches the events object and creates one if required.
675
- *
676
- * @return {Object} The events storage object.
677
- * @api private
678
- */
679
- proto._getEvents = function _getEvents() {
680
- return this._events || (this._events = {});
681
- };
682
 
683
- /**
684
- * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.
685
- *
686
- * @return {Function} Non conflicting EventEmitter class.
687
- */
688
- EventEmitter.noConflict = function noConflict() {
689
- exports.EventEmitter = originalGlobalValue;
690
- return EventEmitter;
691
- };
692
 
693
- // Expose the class either via AMD, CommonJS or the global object
694
- if (typeof define === 'function' && define.amd) {
695
- define('eventEmitter/EventEmitter',[],function () {
696
- return EventEmitter;
697
- });
698
- }
699
- else if (typeof module === 'object' && module.exports){
700
- module.exports = EventEmitter;
701
- }
702
- else {
703
- exports.EventEmitter = EventEmitter;
704
- }
705
- }.call(this));
706
 
707
- /*!
708
- * getStyleProperty v1.0.4
709
- * original by kangax
710
- * http://perfectionkills.com/feature-testing-css-properties/
711
- * MIT license
712
- */
713
 
714
- /*jshint browser: true, strict: true, undef: true */
715
- /*global define: false, exports: false, module: false */
716
 
717
- ( function( window ) {
 
 
 
 
 
 
 
 
 
 
 
718
 
 
 
719
 
 
 
 
 
 
 
 
 
 
 
 
 
 
720
 
721
- var prefixes = 'Webkit Moz ms Ms O'.split(' ');
722
- var docElemStyle = document.documentElement.style;
723
 
724
- function getStyleProperty( propName ) {
725
- if ( !propName ) {
 
726
  return;
727
  }
728
-
729
- // test standard property first
730
- if ( typeof docElemStyle[ propName ] === 'string' ) {
731
- return propName;
732
  }
733
 
734
- // capitalize
735
- propName = propName.charAt(0).toUpperCase() + propName.slice(1);
 
 
 
 
 
 
 
 
 
 
 
736
 
737
- // test vendor specific properties
738
- var prefixed;
739
- for ( var i=0, len = prefixes.length; i < len; i++ ) {
740
- prefixed = prefixes[i] + propName;
741
- if ( typeof docElemStyle[ prefixed ] === 'string' ) {
742
- return prefixed;
 
 
743
  }
 
 
 
 
 
744
  }
745
- }
746
 
747
- // transport
748
- if ( typeof define === 'function' && define.amd ) {
749
- // AMD
750
- define( 'get-style-property/get-style-property',[],function() {
751
- return getStyleProperty;
752
- });
753
- } else if ( typeof exports === 'object' ) {
754
- // CommonJS for Component
755
- module.exports = getStyleProperty;
756
- } else {
757
- // browser global
758
- window.getStyleProperty = getStyleProperty;
759
- }
760
 
761
- })( window );
762
 
763
  /*!
764
- * getSize v1.2.2
765
  * measure size of elements
766
  * MIT license
767
  */
768
 
769
  /*jshint browser: true, strict: true, undef: true, unused: true */
770
- /*global define: false, exports: false, require: false, module: false, console: false */
771
 
772
- ( function( window, undefined ) {
 
773
 
 
 
 
 
 
 
 
 
 
 
 
 
774
 
 
 
775
 
776
  // -------------------------- helpers -------------------------- //
777
 
@@ -779,13 +297,13 @@ if ( typeof define === 'function' && define.amd ) {
779
  function getStyleSize( value ) {
780
  var num = parseFloat( value );
781
  // not a percent like '100%', and a number
782
- var isValid = value.indexOf('%') === -1 && !isNaN( num );
783
  return isValid && num;
784
  }
785
 
786
  function noop() {}
787
 
788
- var logError = typeof console === 'undefined' ? noop :
789
  function( message ) {
790
  console.error( message );
791
  };
@@ -807,6 +325,8 @@ var measurements = [
807
  'borderBottomWidth'
808
  ];
809
 
 
 
810
  function getZeroSize() {
811
  var size = {
812
  width: 0,
@@ -816,27 +336,39 @@ function getZeroSize() {
816
  outerWidth: 0,
817
  outerHeight: 0
818
  };
819
- for ( var i=0, len = measurements.length; i < len; i++ ) {
820
  var measurement = measurements[i];
821
  size[ measurement ] = 0;
822
  }
823
  return size;
824
  }
825
 
 
826
 
827
-
828
- function defineGetSize( getStyleProperty ) {
 
 
 
 
 
 
 
 
 
 
 
829
 
830
  // -------------------------- setup -------------------------- //
831
 
832
  var isSetup = false;
833
 
834
- var getStyle, boxSizingProp, isBoxSizeOuter;
835
 
836
  /**
837
- * setup vars and functions
838
- * do it on initial getSize(), rather than on script load
839
- * For Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=548397
840
  */
841
  function setup() {
842
  // setup once
@@ -845,50 +377,25 @@ function setup() {
845
  }
846
  isSetup = true;
847
 
848
- var getComputedStyle = window.getComputedStyle;
849
- getStyle = ( function() {
850
- var getStyleFn = getComputedStyle ?
851
- function( elem ) {
852
- return getComputedStyle( elem, null );
853
- } :
854
- function( elem ) {
855
- return elem.currentStyle;
856
- };
857
-
858
- return function getStyle( elem ) {
859
- var style = getStyleFn( elem );
860
- if ( !style ) {
861
- logError( 'Style returned ' + style +
862
- '. Are you running this code in a hidden iframe on Firefox? ' +
863
- 'See http://bit.ly/getsizebug1' );
864
- }
865
- return style;
866
- };
867
- })();
868
-
869
  // -------------------------- box sizing -------------------------- //
870
 
871
- boxSizingProp = getStyleProperty('boxSizing');
872
-
873
  /**
874
  * WebKit measures the outer-width on style.width on border-box elems
875
- * IE & Firefox measures the inner-width
876
  */
877
- if ( boxSizingProp ) {
878
- var div = document.createElement('div');
879
- div.style.width = '200px';
880
- div.style.padding = '1px 2px 3px 4px';
881
- div.style.borderStyle = 'solid';
882
- div.style.borderWidth = '1px 2px 3px 4px';
883
- div.style[ boxSizingProp ] = 'border-box';
884
-
885
- var body = document.body || document.documentElement;
886
- body.appendChild( div );
887
- var style = getStyle( div );
888
-
889
- isBoxSizeOuter = getStyleSize( style.width ) === 200;
890
- body.removeChild( div );
891
- }
892
 
893
  }
894
 
@@ -898,19 +405,19 @@ function getSize( elem ) {
898
  setup();
899
 
900
  // use querySeletor if elem is string
901
- if ( typeof elem === 'string' ) {
902
  elem = document.querySelector( elem );
903
  }
904
 
905
  // do not proceed on non-objects
906
- if ( !elem || typeof elem !== 'object' || !elem.nodeType ) {
907
  return;
908
  }
909
 
910
  var style = getStyle( elem );
911
 
912
  // if hidden, everything is 0
913
- if ( style.display === 'none' ) {
914
  return getZeroSize();
915
  }
916
 
@@ -918,14 +425,12 @@ function getSize( elem ) {
918
  size.width = elem.offsetWidth;
919
  size.height = elem.offsetHeight;
920
 
921
- var isBorderBox = size.isBorderBox = !!( boxSizingProp &&
922
- style[ boxSizingProp ] && style[ boxSizingProp ] === 'border-box' );
923
 
924
  // get all measurements
925
- for ( var i=0, len = measurements.length; i < len; i++ ) {
926
  var measurement = measurements[i];
927
  var value = style[ measurement ];
928
- value = mungeNonPixel( elem, value );
929
  var num = parseFloat( value );
930
  // any 'auto', 'medium' value will be 0
931
  size[ measurement ] = !isNaN( num ) ? num : 0;
@@ -964,148 +469,38 @@ function getSize( elem ) {
964
  return size;
965
  }
966
 
967
- // IE8 returns percent values, not pixels
968
- // taken from jQuery's curCSS
969
- function mungeNonPixel( elem, value ) {
970
- // IE8 and has percent value
971
- if ( window.getComputedStyle || value.indexOf('%') === -1 ) {
972
- return value;
973
- }
974
- var style = elem.style;
975
- // Remember the original values
976
- var left = style.left;
977
- var rs = elem.runtimeStyle;
978
- var rsLeft = rs && rs.left;
979
-
980
- // Put in the new values to get a computed value out
981
- if ( rsLeft ) {
982
- rs.left = elem.currentStyle.left;
983
- }
984
- style.left = value;
985
- value = style.pixelLeft;
986
-
987
- // Revert the changed values
988
- style.left = left;
989
- if ( rsLeft ) {
990
- rs.left = rsLeft;
991
- }
992
-
993
- return value;
994
- }
995
-
996
  return getSize;
997
 
998
- }
999
-
1000
- // transport
1001
- if ( typeof define === 'function' && define.amd ) {
1002
- // AMD for RequireJS
1003
- define( 'get-size/get-size',[ 'get-style-property/get-style-property' ], defineGetSize );
1004
- } else if ( typeof exports === 'object' ) {
1005
- // CommonJS for Component
1006
- module.exports = defineGetSize( require('desandro-get-style-property') );
1007
- } else {
1008
- // browser global
1009
- window.getSize = defineGetSize( window.getStyleProperty );
1010
- }
1011
-
1012
- })( window );
1013
-
1014
- /*!
1015
- * docReady v1.0.4
1016
- * Cross browser DOMContentLoaded event emitter
1017
- * MIT license
1018
- */
1019
-
1020
- /*jshint browser: true, strict: true, undef: true, unused: true*/
1021
- /*global define: false, require: false, module: false */
1022
-
1023
- ( function( window ) {
1024
-
1025
-
1026
-
1027
- var document = window.document;
1028
- // collection of functions to be triggered on ready
1029
- var queue = [];
1030
-
1031
- function docReady( fn ) {
1032
- // throw out non-functions
1033
- if ( typeof fn !== 'function' ) {
1034
- return;
1035
- }
1036
-
1037
- if ( docReady.isReady ) {
1038
- // ready now, hit it
1039
- fn();
1040
- } else {
1041
- // queue function when ready
1042
- queue.push( fn );
1043
- }
1044
- }
1045
-
1046
- docReady.isReady = false;
1047
-
1048
- // triggered on various doc ready events
1049
- function onReady( event ) {
1050
- // bail if already triggered or IE8 document is not ready just yet
1051
- var isIE8NotReady = event.type === 'readystatechange' && document.readyState !== 'complete';
1052
- if ( docReady.isReady || isIE8NotReady ) {
1053
- return;
1054
- }
1055
-
1056
- trigger();
1057
- }
1058
-
1059
- function trigger() {
1060
- docReady.isReady = true;
1061
- // process queue
1062
- for ( var i=0, len = queue.length; i < len; i++ ) {
1063
- var fn = queue[i];
1064
- fn();
1065
- }
1066
- }
1067
-
1068
- function defineDocReady( eventie ) {
1069
- // trigger ready if page is ready
1070
- if ( document.readyState === 'complete' ) {
1071
- trigger();
1072
- } else {
1073
- // listen for events
1074
- eventie.bind( document, 'DOMContentLoaded', onReady );
1075
- eventie.bind( document, 'readystatechange', onReady );
1076
- eventie.bind( window, 'load', onReady );
1077
- }
1078
-
1079
- return docReady;
1080
- }
1081
-
1082
- // transport
1083
- if ( typeof define === 'function' && define.amd ) {
1084
- // AMD
1085
- define( 'doc-ready/doc-ready',[ 'eventie/eventie' ], defineDocReady );
1086
- } else if ( typeof exports === 'object' ) {
1087
- module.exports = defineDocReady( require('eventie') );
1088
- } else {
1089
- // browser global
1090
- window.docReady = defineDocReady( window.eventie );
1091
- }
1092
-
1093
- })( window );
1094
 
1095
  /**
1096
- * matchesSelector v1.0.3
1097
  * matchesSelector( element, '.selector' )
1098
  * MIT license
1099
  */
1100
 
1101
  /*jshint browser: true, strict: true, undef: true, unused: true */
1102
- /*global define: false, module: false */
1103
 
1104
- ( function( ElemProto ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
1105
 
 
1106
  'use strict';
1107
 
1108
  var matchesMethod = ( function() {
 
1109
  // check for the standard method name first
1110
  if ( ElemProto.matches ) {
1111
  return 'matches';
@@ -1117,7 +512,7 @@ if ( typeof define === 'function' && define.amd ) {
1117
  // check vendor prefixes
1118
  var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
1119
 
1120
- for ( var i=0, len = prefixes.length; i < len; i++ ) {
1121
  var prefix = prefixes[i];
1122
  var method = prefix + 'MatchesSelector';
1123
  if ( ElemProto[ method ] ) {
@@ -1126,117 +521,45 @@ if ( typeof define === 'function' && define.amd ) {
1126
  }
1127
  })();
1128
 
1129
- // ----- match ----- //
1130
-
1131
- function match( elem, selector ) {
1132
  return elem[ matchesMethod ]( selector );
1133
- }
1134
-
1135
- // ----- appendToFragment ----- //
1136
-
1137
- function checkParent( elem ) {
1138
- // not needed if already has parent
1139
- if ( elem.parentNode ) {
1140
- return;
1141
- }
1142
- var fragment = document.createDocumentFragment();
1143
- fragment.appendChild( elem );
1144
- }
1145
-
1146
- // ----- query ----- //
1147
-
1148
- // fall back to using QSA
1149
- // thx @jonathantneal https://gist.github.com/3062955
1150
- function query( elem, selector ) {
1151
- // append to fragment if no parent
1152
- checkParent( elem );
1153
-
1154
- // match elem with all selected elems of parent
1155
- var elems = elem.parentNode.querySelectorAll( selector );
1156
- for ( var i=0, len = elems.length; i < len; i++ ) {
1157
- // return true if match
1158
- if ( elems[i] === elem ) {
1159
- return true;
1160
- }
1161
- }
1162
- // otherwise return false
1163
- return false;
1164
- }
1165
-
1166
- // ----- matchChild ----- //
1167
-
1168
- function matchChild( elem, selector ) {
1169
- checkParent( elem );
1170
- return match( elem, selector );
1171
- }
1172
-
1173
- // ----- matchesSelector ----- //
1174
-
1175
- var matchesSelector;
1176
-
1177
- if ( matchesMethod ) {
1178
- // IE9 supports matchesSelector, but doesn't work on orphaned elems
1179
- // check for that
1180
- var div = document.createElement('div');
1181
- var supportsOrphans = match( div, 'div' );
1182
- matchesSelector = supportsOrphans ? match : matchChild;
1183
- } else {
1184
- matchesSelector = query;
1185
- }
1186
-
1187
- // transport
1188
- if ( typeof define === 'function' && define.amd ) {
1189
- // AMD
1190
- define( 'matches-selector/matches-selector',[],function() {
1191
- return matchesSelector;
1192
- });
1193
- } else if ( typeof exports === 'object' ) {
1194
- module.exports = matchesSelector;
1195
- }
1196
- else {
1197
- // browser global
1198
- window.matchesSelector = matchesSelector;
1199
- }
1200
 
1201
- })( Element.prototype );
1202
 
1203
  /**
1204
- * Fizzy UI utils v1.0.1
1205
  * MIT license
1206
  */
1207
 
1208
  /*jshint browser: true, undef: true, unused: true, strict: true */
1209
 
1210
  ( function( window, factory ) {
1211
- /*global define: false, module: false, require: false */
1212
- 'use strict';
1213
  // universal module definition
 
1214
 
1215
  if ( typeof define == 'function' && define.amd ) {
1216
  // AMD
1217
  define( 'fizzy-ui-utils/utils',[
1218
- 'doc-ready/doc-ready',
1219
- 'matches-selector/matches-selector'
1220
- ], function( docReady, matchesSelector ) {
1221
- return factory( window, docReady, matchesSelector );
1222
  });
1223
- } else if ( typeof exports == 'object' ) {
1224
  // CommonJS
1225
  module.exports = factory(
1226
  window,
1227
- require('doc-ready'),
1228
  require('desandro-matches-selector')
1229
  );
1230
  } else {
1231
  // browser global
1232
  window.fizzyUIUtils = factory(
1233
  window,
1234
- window.docReady,
1235
  window.matchesSelector
1236
  );
1237
  }
1238
 
1239
- }( window, function factory( window, docReady, matchesSelector ) {
1240
 
1241
 
1242
 
@@ -1258,24 +581,17 @@ utils.modulo = function( num, div ) {
1258
  return ( ( num % div ) + div ) % div;
1259
  };
1260
 
1261
- // ----- isArray ----- //
1262
-
1263
- var objToString = Object.prototype.toString;
1264
- utils.isArray = function( obj ) {
1265
- return objToString.call( obj ) == '[object Array]';
1266
- };
1267
-
1268
  // ----- makeArray ----- //
1269
 
1270
  // turn element or nodeList into an array
1271
  utils.makeArray = function( obj ) {
1272
  var ary = [];
1273
- if ( utils.isArray( obj ) ) {
1274
  // use object if already an array
1275
  ary = obj;
1276
  } else if ( obj && typeof obj.length == 'number' ) {
1277
  // convert nodeList to array
1278
- for ( var i=0, len = obj.length; i < len; i++ ) {
1279
  ary.push( obj[i] );
1280
  }
1281
  } else {
@@ -1285,53 +601,15 @@ utils.makeArray = function( obj ) {
1285
  return ary;
1286
  };
1287
 
1288
- // ----- indexOf ----- //
1289
-
1290
- // index of helper cause IE8
1291
- utils.indexOf = Array.prototype.indexOf ? function( ary, obj ) {
1292
- return ary.indexOf( obj );
1293
- } : function( ary, obj ) {
1294
- for ( var i=0, len = ary.length; i < len; i++ ) {
1295
- if ( ary[i] === obj ) {
1296
- return i;
1297
- }
1298
- }
1299
- return -1;
1300
- };
1301
-
1302
  // ----- removeFrom ----- //
1303
 
1304
  utils.removeFrom = function( ary, obj ) {
1305
- var index = utils.indexOf( ary, obj );
1306
  if ( index != -1 ) {
1307
  ary.splice( index, 1 );
1308
  }
1309
  };
1310
 
1311
- // ----- isElement ----- //
1312
-
1313
- // http://stackoverflow.com/a/384380/182183
1314
- utils.isElement = ( typeof HTMLElement == 'function' || typeof HTMLElement == 'object' ) ?
1315
- function isElementDOM2( obj ) {
1316
- return obj instanceof HTMLElement;
1317
- } :
1318
- function isElementQuirky( obj ) {
1319
- return obj && typeof obj == 'object' &&
1320
- obj.nodeType == 1 && typeof obj.nodeName == 'string';
1321
- };
1322
-
1323
- // ----- setText ----- //
1324
-
1325
- utils.setText = ( function() {
1326
- var setTextProperty;
1327
- function setText( elem, text ) {
1328
- // only check setTextProperty once
1329
- setTextProperty = setTextProperty || ( document.documentElement.textContent !== undefined ? 'textContent' : 'innerText' );
1330
- elem[ setTextProperty ] = text;
1331
- }
1332
- return setText;
1333
- })();
1334
-
1335
  // ----- getParent ----- //
1336
 
1337
  utils.getParent = function( elem, selector ) {
@@ -1370,28 +648,28 @@ utils.filterFindElements = function( elems, selector ) {
1370
  elems = utils.makeArray( elems );
1371
  var ffElems = [];
1372
 
1373
- for ( var i=0, len = elems.length; i < len; i++ ) {
1374
- var elem = elems[i];
1375
  // check that elem is an actual element
1376
- if ( !utils.isElement( elem ) ) {
1377
- continue;
 
 
 
 
 
1378
  }
1379
  // filter & find items if we have a selector
1380
- if ( selector ) {
1381
- // filter siblings
1382
- if ( matchesSelector( elem, selector ) ) {
1383
- ffElems.push( elem );
1384
- }
1385
- // find children
1386
- var childElems = elem.querySelectorAll( selector );
1387
- // concat childElems to filterFound array
1388
- for ( var j=0, jLen = childElems.length; j < jLen; j++ ) {
1389
- ffElems.push( childElems[j] );
1390
- }
1391
- } else {
1392
  ffElems.push( elem );
1393
  }
1394
- }
 
 
 
 
 
 
1395
 
1396
  return ffElems;
1397
  };
@@ -1418,6 +696,16 @@ utils.debounceMethod = function( _class, methodName, threshold ) {
1418
  };
1419
  };
1420
 
 
 
 
 
 
 
 
 
 
 
1421
  // ----- htmlInit ----- //
1422
 
1423
  // http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
@@ -1429,39 +717,43 @@ utils.toDashed = function( str ) {
1429
 
1430
  var console = window.console;
1431
  /**
1432
- * allow user to initialize classes via .js-namespace class
1433
  * htmlInit( Widget, 'widgetName' )
1434
- * options are parsed from data-namespace-option attribute
1435
  */
1436
  utils.htmlInit = function( WidgetClass, namespace ) {
1437
- docReady( function() {
1438
  var dashedNamespace = utils.toDashed( namespace );
1439
- var elems = document.querySelectorAll( '.js-' + dashedNamespace );
1440
- var dataAttr = 'data-' + dashedNamespace + '-options';
1441
-
1442
- for ( var i=0, len = elems.length; i < len; i++ ) {
1443
- var elem = elems[i];
1444
- var attr = elem.getAttribute( dataAttr );
 
 
 
 
 
1445
  var options;
1446
  try {
1447
  options = attr && JSON.parse( attr );
1448
  } catch ( error ) {
1449
  // log error, do not initialize
1450
  if ( console ) {
1451
- console.error( 'Error parsing ' + dataAttr + ' on ' +
1452
- elem.nodeName.toLowerCase() + ( elem.id ? '#' + elem.id : '' ) + ': ' +
1453
- error );
1454
  }
1455
- continue;
1456
  }
1457
  // initialize
1458
  var instance = new WidgetClass( elem, options );
1459
  // make available via $().data('layoutname')
1460
- var jQuery = window.jQuery;
1461
  if ( jQuery ) {
1462
  jQuery.data( elem, namespace, instance );
1463
  }
1464
- }
 
1465
  });
1466
  };
1467
 
@@ -1476,56 +768,36 @@ return utils;
1476
  */
1477
 
1478
  ( function( window, factory ) {
1479
- 'use strict';
1480
  // universal module definition
1481
- if ( typeof define === 'function' && define.amd ) {
1482
- // AMD
 
1483
  define( 'outlayer/item',[
1484
- 'eventEmitter/EventEmitter',
1485
- 'get-size/get-size',
1486
- 'get-style-property/get-style-property',
1487
- 'fizzy-ui-utils/utils'
1488
  ],
1489
- function( EventEmitter, getSize, getStyleProperty, utils ) {
1490
- return factory( window, EventEmitter, getSize, getStyleProperty, utils );
1491
- }
1492
  );
1493
- } else if (typeof exports === 'object') {
1494
- // CommonJS
1495
  module.exports = factory(
1496
- window,
1497
- require('wolfy87-eventemitter'),
1498
- require('get-size'),
1499
- require('desandro-get-style-property'),
1500
- require('fizzy-ui-utils')
1501
  );
1502
  } else {
1503
  // browser global
1504
  window.Outlayer = {};
1505
  window.Outlayer.Item = factory(
1506
- window,
1507
- window.EventEmitter,
1508
- window.getSize,
1509
- window.getStyleProperty,
1510
- window.fizzyUIUtils
1511
  );
1512
  }
1513
 
1514
- }( window, function factory( window, EventEmitter, getSize, getStyleProperty, utils ) {
1515
  'use strict';
1516
 
1517
  // ----- helpers ----- //
1518
 
1519
- var getComputedStyle = window.getComputedStyle;
1520
- var getStyle = getComputedStyle ?
1521
- function( elem ) {
1522
- return getComputedStyle( elem, null );
1523
- } :
1524
- function( elem ) {
1525
- return elem.currentStyle;
1526
- };
1527
-
1528
-
1529
  function isEmptyObj( obj ) {
1530
  for ( var prop in obj ) {
1531
  return false;
@@ -1536,38 +808,27 @@ function isEmptyObj( obj ) {
1536
 
1537
  // -------------------------- CSS3 support -------------------------- //
1538
 
1539
- var transitionProperty = getStyleProperty('transition');
1540
- var transformProperty = getStyleProperty('transform');
1541
- var supportsCSS3 = transitionProperty && transformProperty;
1542
- var is3d = !!getStyleProperty('perspective');
 
 
 
1543
 
1544
  var transitionEndEvent = {
1545
  WebkitTransition: 'webkitTransitionEnd',
1546
- MozTransition: 'transitionend',
1547
- OTransition: 'otransitionend',
1548
  transition: 'transitionend'
1549
  }[ transitionProperty ];
1550
 
1551
- // properties that could have vendor prefix
1552
- var prefixableProperties = [
1553
- 'transform',
1554
- 'transition',
1555
- 'transitionDuration',
1556
- 'transitionProperty'
1557
- ];
1558
-
1559
- // cache all vendor properties
1560
- var vendorProperties = ( function() {
1561
- var cache = {};
1562
- for ( var i=0, len = prefixableProperties.length; i < len; i++ ) {
1563
- var prop = prefixableProperties[i];
1564
- var supportedProp = getStyleProperty( prop );
1565
- if ( supportedProp && supportedProp !== prop ) {
1566
- cache[ prop ] = supportedProp;
1567
- }
1568
- }
1569
- return cache;
1570
- })();
1571
 
1572
  // -------------------------- Item -------------------------- //
1573
 
@@ -1587,10 +848,11 @@ function Item( element, layout ) {
1587
  this._create();
1588
  }
1589
 
1590
- // inherit EventEmitter
1591
- utils.extend( Item.prototype, EventEmitter.prototype );
 
1592
 
1593
- Item.prototype._create = function() {
1594
  // transition objects
1595
  this._transn = {
1596
  ingProperties: {},
@@ -1604,14 +866,14 @@ Item.prototype._create = function() {
1604
  };
1605
 
1606
  // trigger specified handler for event type
1607
- Item.prototype.handleEvent = function( event ) {
1608
  var method = 'on' + event.type;
1609
  if ( this[ method ] ) {
1610
  this[ method ]( event );
1611
  }
1612
  };
1613
 
1614
- Item.prototype.getSize = function() {
1615
  this.size = getSize( this.element );
1616
  };
1617
 
@@ -1619,7 +881,7 @@ Item.prototype.getSize = function() {
1619
  * apply CSS styles to element
1620
  * @param {Object} style
1621
  */
1622
- Item.prototype.css = function( style ) {
1623
  var elemStyle = this.element.style;
1624
 
1625
  for ( var prop in style ) {
@@ -1630,11 +892,10 @@ Item.prototype.css = function( style ) {
1630
  };
1631
 
1632
  // measure position, and sets it
1633
- Item.prototype.getPosition = function() {
1634
- var style = getStyle( this.element );
1635
- var layoutOptions = this.layout.options;
1636
- var isOriginLeft = layoutOptions.isOriginLeft;
1637
- var isOriginTop = layoutOptions.isOriginTop;
1638
  var xValue = style[ isOriginLeft ? 'left' : 'right' ];
1639
  var yValue = style[ isOriginTop ? 'top' : 'bottom' ];
1640
  // convert percent to pixels
@@ -1656,15 +917,16 @@ Item.prototype.getPosition = function() {
1656
  };
1657
 
1658
  // set settled position, apply padding
1659
- Item.prototype.layoutPosition = function() {
1660
  var layoutSize = this.layout.size;
1661
- var layoutOptions = this.layout.options;
1662
  var style = {};
 
 
1663
 
1664
  // x
1665
- var xPadding = layoutOptions.isOriginLeft ? 'paddingLeft' : 'paddingRight';
1666
- var xProperty = layoutOptions.isOriginLeft ? 'left' : 'right';
1667
- var xResetProperty = layoutOptions.isOriginLeft ? 'right' : 'left';
1668
 
1669
  var x = this.position.x + layoutSize[ xPadding ];
1670
  // set in percentage or pixels
@@ -1673,9 +935,9 @@ Item.prototype.layoutPosition = function() {
1673
  style[ xResetProperty ] = '';
1674
 
1675
  // y
1676
- var yPadding = layoutOptions.isOriginTop ? 'paddingTop' : 'paddingBottom';
1677
- var yProperty = layoutOptions.isOriginTop ? 'top' : 'bottom';
1678
- var yResetProperty = layoutOptions.isOriginTop ? 'bottom' : 'top';
1679
 
1680
  var y = this.position.y + layoutSize[ yPadding ];
1681
  // set in percentage or pixels
@@ -1687,20 +949,19 @@ Item.prototype.layoutPosition = function() {
1687
  this.emitEvent( 'layout', [ this ] );
1688
  };
1689
 
1690
- Item.prototype.getXValue = function( x ) {
1691
- var layoutOptions = this.layout.options;
1692
- return layoutOptions.percentPosition && !layoutOptions.isHorizontal ?
1693
  ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';
1694
  };
1695
 
1696
- Item.prototype.getYValue = function( y ) {
1697
- var layoutOptions = this.layout.options;
1698
- return layoutOptions.percentPosition && layoutOptions.isHorizontal ?
1699
  ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';
1700
  };
1701
 
1702
-
1703
- Item.prototype._transitionTo = function( x, y ) {
1704
  this.getPosition();
1705
  // get current x & y from top/left
1706
  var curX = this.position.x;
@@ -1733,30 +994,24 @@ Item.prototype._transitionTo = function( x, y ) {
1733
  });
1734
  };
1735
 
1736
- Item.prototype.getTranslate = function( x, y ) {
1737
  // flip cooridinates if origin on right or bottom
1738
- var layoutOptions = this.layout.options;
1739
- x = layoutOptions.isOriginLeft ? x : -x;
1740
- y = layoutOptions.isOriginTop ? y : -y;
1741
-
1742
- if ( is3d ) {
1743
- return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
1744
- }
1745
-
1746
- return 'translate(' + x + 'px, ' + y + 'px)';
1747
  };
1748
 
1749
  // non transition + transform support
1750
- Item.prototype.goTo = function( x, y ) {
1751
  this.setPosition( x, y );
1752
  this.layoutPosition();
1753
  };
1754
 
1755
- // use transition and transforms if supported
1756
- Item.prototype.moveTo = supportsCSS3 ?
1757
- Item.prototype._transitionTo : Item.prototype.goTo;
1758
 
1759
- Item.prototype.setPosition = function( x, y ) {
1760
  this.position.x = parseInt( x, 10 );
1761
  this.position.y = parseInt( y, 10 );
1762
  };
@@ -1769,7 +1024,7 @@ Item.prototype.setPosition = function( x, y ) {
1769
  */
1770
 
1771
  // non transition, just trigger callback
1772
- Item.prototype._nonTransition = function( args ) {
1773
  this.css( args.to );
1774
  if ( args.isCleaning ) {
1775
  this._removeStyles( args.to );
@@ -1787,7 +1042,7 @@ Item.prototype._nonTransition = function( args ) {
1787
  * @param {Boolean} isCleaning - removes transition styles after transition
1788
  * @param {Function} onTransitionEnd - callback
1789
  */
1790
- Item.prototype._transition = function( args ) {
1791
  // redirect to nonTransition if no transition duration
1792
  if ( !parseFloat( this.layout.options.transitionDuration ) ) {
1793
  this._nonTransition( args );
@@ -1833,10 +1088,9 @@ function toDashedAll( str ) {
1833
  });
1834
  }
1835
 
1836
- var transitionProps = 'opacity,' +
1837
- toDashedAll( vendorProperties.transform || 'transform' );
1838
 
1839
- Item.prototype.enableTransition = function(/* style */) {
1840
  // HACK changing transitionProperty during a transition
1841
  // will cause transition to jump
1842
  if ( this.isTransitioning ) {
@@ -1852,35 +1106,35 @@ Item.prototype.enableTransition = function(/* style */) {
1852
  // prop = vendorProperties[ prop ] || prop;
1853
  // transitionValues.push( toDashedAll( prop ) );
1854
  // }
 
 
 
1855
  // enable transition styles
1856
  this.css({
1857
  transitionProperty: transitionProps,
1858
- transitionDuration: this.layout.options.transitionDuration
 
1859
  });
1860
  // listen for transition end event
1861
  this.element.addEventListener( transitionEndEvent, this, false );
1862
  };
1863
 
1864
- Item.prototype.transition = Item.prototype[ transitionProperty ? '_transition' : '_nonTransition' ];
1865
-
1866
  // ----- events ----- //
1867
 
1868
- Item.prototype.onwebkitTransitionEnd = function( event ) {
1869
  this.ontransitionend( event );
1870
  };
1871
 
1872
- Item.prototype.onotransitionend = function( event ) {
1873
  this.ontransitionend( event );
1874
  };
1875
 
1876
  // properties that I munge to make my life easier
1877
  var dashedVendorProperties = {
1878
- '-webkit-transform': 'transform',
1879
- '-moz-transform': 'transform',
1880
- '-o-transform': 'transform'
1881
  };
1882
 
1883
- Item.prototype.ontransitionend = function( event ) {
1884
  // disregard bubbled events from children
1885
  if ( event.target !== this.element ) {
1886
  return;
@@ -1912,7 +1166,7 @@ Item.prototype.ontransitionend = function( event ) {
1912
  this.emitEvent( 'transitionEnd', [ this ] );
1913
  };
1914
 
1915
- Item.prototype.disableTransition = function() {
1916
  this.removeTransitionStyles();
1917
  this.element.removeEventListener( transitionEndEvent, this, false );
1918
  this.isTransitioning = false;
@@ -1922,7 +1176,7 @@ Item.prototype.disableTransition = function() {
1922
  * removes style property from element
1923
  * @param {Object} style
1924
  **/
1925
- Item.prototype._removeStyles = function( style ) {
1926
  // clean up transition styles
1927
  var cleanStyle = {};
1928
  for ( var prop in style ) {
@@ -1933,25 +1187,33 @@ Item.prototype._removeStyles = function( style ) {
1933
 
1934
  var cleanTransitionStyle = {
1935
  transitionProperty: '',
1936
- transitionDuration: ''
 
1937
  };
1938
 
1939
- Item.prototype.removeTransitionStyles = function() {
1940
  // remove transition
1941
  this.css( cleanTransitionStyle );
1942
  };
1943
 
 
 
 
 
 
 
 
1944
  // ----- show/hide/remove ----- //
1945
 
1946
  // remove element from DOM
1947
- Item.prototype.removeElem = function() {
1948
  this.element.parentNode.removeChild( this.element );
1949
  // remove display: none
1950
  this.css({ display: '' });
1951
  this.emitEvent( 'remove', [ this ] );
1952
  };
1953
 
1954
- Item.prototype.remove = function() {
1955
  // just remove element if no transition support or no transition
1956
  if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
1957
  this.removeElem();
@@ -1959,14 +1221,13 @@ Item.prototype.remove = function() {
1959
  }
1960
 
1961
  // start transition
1962
- var _this = this;
1963
  this.once( 'transitionEnd', function() {
1964
- _this.removeElem();
1965
  });
1966
  this.hide();
1967
  };
1968
 
1969
- Item.prototype.reveal = function() {
1970
  delete this.isHidden;
1971
  // remove display: none
1972
  this.css({ display: '' });
@@ -1985,7 +1246,7 @@ Item.prototype.reveal = function() {
1985
  });
1986
  };
1987
 
1988
- Item.prototype.onRevealTransitionEnd = function() {
1989
  // check if still visible
1990
  // during transition, item may have been hidden
1991
  if ( !this.isHidden ) {
@@ -1998,7 +1259,7 @@ Item.prototype.onRevealTransitionEnd = function() {
1998
  * @param {String} styleProperty - hiddenStyle/visibleStyle
1999
  * @returns {String}
2000
  */
2001
- Item.prototype.getHideRevealTransitionEndProperty = function( styleProperty ) {
2002
  var optionStyle = this.layout.options[ styleProperty ];
2003
  // use opacity
2004
  if ( optionStyle.opacity ) {
@@ -2010,7 +1271,7 @@ Item.prototype.getHideRevealTransitionEndProperty = function( styleProperty ) {
2010
  }
2011
  };
2012
 
2013
- Item.prototype.hide = function() {
2014
  // set flag
2015
  this.isHidden = true;
2016
  // remove display: none
@@ -2031,7 +1292,7 @@ Item.prototype.hide = function() {
2031
  });
2032
  };
2033
 
2034
- Item.prototype.onHideTransitionEnd = function() {
2035
  // check if still hidden
2036
  // during transition, item may have been un-hidden
2037
  if ( this.isHidden ) {
@@ -2040,7 +1301,7 @@ Item.prototype.onHideTransitionEnd = function() {
2040
  }
2041
  };
2042
 
2043
- Item.prototype.destroy = function() {
2044
  this.css({
2045
  position: '',
2046
  left: '',
@@ -2057,7 +1318,7 @@ return Item;
2057
  }));
2058
 
2059
  /*!
2060
- * Outlayer v1.4.2
2061
  * the brains and guts of a layout library
2062
  * MIT license
2063
  */
@@ -2065,26 +1326,24 @@ return Item;
2065
  ( function( window, factory ) {
2066
  'use strict';
2067
  // universal module definition
2068
-
2069
  if ( typeof define == 'function' && define.amd ) {
2070
- // AMD
2071
  define( 'outlayer/outlayer',[
2072
- 'eventie/eventie',
2073
- 'eventEmitter/EventEmitter',
2074
  'get-size/get-size',
2075
  'fizzy-ui-utils/utils',
2076
  './item'
2077
  ],
2078
- function( eventie, EventEmitter, getSize, utils, Item ) {
2079
- return factory( window, eventie, EventEmitter, getSize, utils, Item);
2080
  }
2081
  );
2082
- } else if ( typeof exports == 'object' ) {
2083
- // CommonJS
2084
  module.exports = factory(
2085
  window,
2086
- require('eventie'),
2087
- require('wolfy87-eventemitter'),
2088
  require('get-size'),
2089
  require('fizzy-ui-utils'),
2090
  require('./item')
@@ -2093,15 +1352,14 @@ return Item;
2093
  // browser global
2094
  window.Outlayer = factory(
2095
  window,
2096
- window.eventie,
2097
- window.EventEmitter,
2098
  window.getSize,
2099
  window.fizzyUIUtils,
2100
  window.Outlayer.Item
2101
  );
2102
  }
2103
 
2104
- }( window, function factory( window, eventie, EventEmitter, getSize, utils, Item ) {
2105
  'use strict';
2106
 
2107
  // ----- vars ----- //
@@ -2150,7 +1408,8 @@ function Outlayer( element, options ) {
2150
  // kick it off
2151
  this._create();
2152
 
2153
- if ( this.options.isInitLayout ) {
 
2154
  this.layout();
2155
  }
2156
  }
@@ -2164,11 +1423,11 @@ Outlayer.defaults = {
2164
  containerStyle: {
2165
  position: 'relative'
2166
  },
2167
- isInitLayout: true,
2168
- isOriginLeft: true,
2169
- isOriginTop: true,
2170
- isResizeBound: true,
2171
- isResizingContainer: true,
2172
  // item options
2173
  transitionDuration: '0.4s',
2174
  hiddenStyle: {
@@ -2181,18 +1440,39 @@ Outlayer.defaults = {
2181
  }
2182
  };
2183
 
2184
- // inherit EventEmitter
2185
- utils.extend( Outlayer.prototype, EventEmitter.prototype );
 
2186
 
2187
  /**
2188
  * set options
2189
  * @param {Object} opts
2190
  */
2191
- Outlayer.prototype.option = function( opts ) {
2192
  utils.extend( this.options, opts );
2193
  };
2194
 
2195
- Outlayer.prototype._create = function() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2196
  // get items from children
2197
  this.reloadItems();
2198
  // elements that affect layout, but are not laid out
@@ -2202,13 +1482,14 @@ Outlayer.prototype._create = function() {
2202
  utils.extend( this.element.style, this.options.containerStyle );
2203
 
2204
  // bind resize method
2205
- if ( this.options.isResizeBound ) {
 
2206
  this.bindResize();
2207
  }
2208
  };
2209
 
2210
  // goes through all children again and gets bricks in proper order
2211
- Outlayer.prototype.reloadItems = function() {
2212
  // collection of item elements
2213
  this.items = this._itemize( this.element.children );
2214
  };
@@ -2219,14 +1500,14 @@ Outlayer.prototype.reloadItems = function() {
2219
  * @param {Array or NodeList or HTMLElement} elems
2220
  * @returns {Array} items - collection of new Outlayer Items
2221
  */
2222
- Outlayer.prototype._itemize = function( elems ) {
2223
 
2224
  var itemElems = this._filterFindItemElements( elems );
2225
  var Item = this.constructor.Item;
2226
 
2227
  // create new Outlayer Items for collection
2228
  var items = [];
2229
- for ( var i=0, len = itemElems.length; i < len; i++ ) {
2230
  var elem = itemElems[i];
2231
  var item = new Item( elem, this );
2232
  items.push( item );
@@ -2240,7 +1521,7 @@ Outlayer.prototype._itemize = function( elems ) {
2240
  * @param {Array or NodeList or HTMLElement} elems
2241
  * @returns {Array} items - item elements
2242
  */
2243
- Outlayer.prototype._filterFindItemElements = function( elems ) {
2244
  return utils.filterFindElements( elems, this.options.itemSelector );
2245
  };
2246
 
@@ -2248,12 +1529,10 @@ Outlayer.prototype._filterFindItemElements = function( elems ) {
2248
  * getter method for getting item elements
2249
  * @returns {Array} elems - collection of item elements
2250
  */
2251
- Outlayer.prototype.getItemElements = function() {
2252
- var elems = [];
2253
- for ( var i=0, len = this.items.length; i < len; i++ ) {
2254
- elems.push( this.items[i].element );
2255
- }
2256
- return elems;
2257
  };
2258
 
2259
  // ----- init & layout ----- //
@@ -2261,13 +1540,14 @@ Outlayer.prototype.getItemElements = function() {
2261
  /**
2262
  * lays out all items
2263
  */
2264
- Outlayer.prototype.layout = function() {
2265
  this._resetLayout();
2266
  this._manageStamps();
2267
 
2268
  // don't animate first layout
2269
- var isInstant = this.options.isLayoutInstant !== undefined ?
2270
- this.options.isLayoutInstant : !this._isLayoutInited;
 
2271
  this.layoutItems( this.items, isInstant );
2272
 
2273
  // flag for initalized
@@ -2275,17 +1555,17 @@ Outlayer.prototype.layout = function() {
2275
  };
2276
 
2277
  // _init is alias for layout
2278
- Outlayer.prototype._init = Outlayer.prototype.layout;
2279
 
2280
  /**
2281
  * logic before any new layout
2282
  */
2283
- Outlayer.prototype._resetLayout = function() {
2284
  this.getSize();
2285
  };
2286
 
2287
 
2288
- Outlayer.prototype.getSize = function() {
2289
  this.size = getSize( this.element );
2290
  };
2291
 
@@ -2299,7 +1579,7 @@ Outlayer.prototype.getSize = function() {
2299
  * @param {String} size - width or height
2300
  * @private
2301
  */
2302
- Outlayer.prototype._getMeasurement = function( measurement, size ) {
2303
  var option = this.options[ measurement ];
2304
  var elem;
2305
  if ( !option ) {
@@ -2307,9 +1587,9 @@ Outlayer.prototype._getMeasurement = function( measurement, size ) {
2307
  this[ measurement ] = 0;
2308
  } else {
2309
  // use option as an element
2310
- if ( typeof option === 'string' ) {
2311
  elem = this.element.querySelector( option );
2312
- } else if ( utils.isElement( option ) ) {
2313
  elem = option;
2314
  }
2315
  // use size of element, if element
@@ -2321,7 +1601,7 @@ Outlayer.prototype._getMeasurement = function( measurement, size ) {
2321
  * layout a collection of item elements
2322
  * @api public
2323
  */
2324
- Outlayer.prototype.layoutItems = function( items, isInstant ) {
2325
  items = this._getItemsForLayout( items );
2326
 
2327
  this._layoutItems( items, isInstant );
@@ -2335,15 +1615,10 @@ Outlayer.prototype.layoutItems = function( items, isInstant ) {
2335
  * @param {Array} items
2336
  * @returns {Array} items
2337
  */
2338
- Outlayer.prototype._getItemsForLayout = function( items ) {
2339
- var layoutItems = [];
2340
- for ( var i=0, len = items.length; i < len; i++ ) {
2341
- var item = items[i];
2342
- if ( !item.isIgnored ) {
2343
- layoutItems.push( item );
2344
- }
2345
- }
2346
- return layoutItems;
2347
  };
2348
 
2349
  /**
@@ -2351,7 +1626,7 @@ Outlayer.prototype._getItemsForLayout = function( items ) {
2351
  * @param {Array} items
2352
  * @param {Boolean} isInstant
2353
  */
2354
- Outlayer.prototype._layoutItems = function( items, isInstant ) {
2355
  this._emitCompleteOnItems( 'layout', items );
2356
 
2357
  if ( !items || !items.length ) {
@@ -2361,15 +1636,14 @@ Outlayer.prototype._layoutItems = function( items, isInstant ) {
2361
 
2362
  var queue = [];
2363
 
2364
- for ( var i=0, len = items.length; i < len; i++ ) {
2365
- var item = items[i];
2366
  // get x/y object from method
2367
  var position = this._getItemLayoutPosition( item );
2368
  // enqueue
2369
  position.item = item;
2370
  position.isInstant = isInstant || item.isLayoutInstant;
2371
  queue.push( position );
2372
- }
2373
 
2374
  this._processLayoutQueue( queue );
2375
  };
@@ -2379,7 +1653,7 @@ Outlayer.prototype._layoutItems = function( items, isInstant ) {
2379
  * @param {Outlayer.Item} item
2380
  * @returns {Object} x and y position
2381
  */
2382
- Outlayer.prototype._getItemLayoutPosition = function( /* item */ ) {
2383
  return {
2384
  x: 0,
2385
  y: 0
@@ -2392,11 +1666,22 @@ Outlayer.prototype._getItemLayoutPosition = function( /* item */ ) {
2392
  * thx @paul_irish
2393
  * @param {Array} queue
2394
  */
2395
- Outlayer.prototype._processLayoutQueue = function( queue ) {
2396
- for ( var i=0, len = queue.length; i < len; i++ ) {
2397
- var obj = queue[i];
2398
- this._positionItem( obj.item, obj.x, obj.y, obj.isInstant );
 
 
 
 
 
 
 
 
 
2399
  }
 
 
2400
  };
2401
 
2402
  /**
@@ -2406,11 +1691,12 @@ Outlayer.prototype._processLayoutQueue = function( queue ) {
2406
  * @param {Number} y - vertical position
2407
  * @param {Boolean} isInstant - disables transitions
2408
  */
2409
- Outlayer.prototype._positionItem = function( item, x, y, isInstant ) {
2410
  if ( isInstant ) {
2411
  // if not transition, just set CSS
2412
  item.goTo( x, y );
2413
  } else {
 
2414
  item.moveTo( x, y );
2415
  }
2416
  };
@@ -2419,12 +1705,13 @@ Outlayer.prototype._positionItem = function( item, x, y, isInstant ) {
2419
  * Any logic you want to do after each layout,
2420
  * i.e. size the container
2421
  */
2422
- Outlayer.prototype._postLayout = function() {
2423
  this.resizeContainer();
2424
  };
2425
 
2426
- Outlayer.prototype.resizeContainer = function() {
2427
- if ( !this.options.isResizingContainer ) {
 
2428
  return;
2429
  }
2430
  var size = this._getContainerSize();
@@ -2440,13 +1727,13 @@ Outlayer.prototype.resizeContainer = function() {
2440
  * @param {Number} width
2441
  * @param {Number} height
2442
  */
2443
- Outlayer.prototype._getContainerSize = noop;
2444
 
2445
  /**
2446
  * @param {Number} measure - size of width or height
2447
  * @param {Boolean} isWidth
2448
  */
2449
- Outlayer.prototype._setContainerMeasure = function( measure, isWidth ) {
2450
  if ( measure === undefined ) {
2451
  return;
2452
  }
@@ -2469,7 +1756,7 @@ Outlayer.prototype._setContainerMeasure = function( measure, isWidth ) {
2469
  * @param {String} eventName
2470
  * @param {Array} items - Outlayer.Items
2471
  */
2472
- Outlayer.prototype._emitCompleteOnItems = function( eventName, items ) {
2473
  var _this = this;
2474
  function onComplete() {
2475
  _this.dispatchEvent( eventName + 'Complete', null, [ items ] );
@@ -2484,25 +1771,24 @@ Outlayer.prototype._emitCompleteOnItems = function( eventName, items ) {
2484
  var doneCount = 0;
2485
  function tick() {
2486
  doneCount++;
2487
- if ( doneCount === count ) {
2488
  onComplete();
2489
  }
2490
  }
2491
 
2492
  // bind callback
2493
- for ( var i=0, len = items.length; i < len; i++ ) {
2494
- var item = items[i];
2495
  item.once( eventName, tick );
2496
- }
2497
  };
2498
 
2499
  /**
2500
- * emits events via eventEmitter and jQuery events
2501
  * @param {String} type - name of event
2502
  * @param {Event} event - original event
2503
  * @param {Array} args - extra arguments
2504
  */
2505
- Outlayer.prototype.dispatchEvent = function( type, event, args ) {
2506
  // add original event to arguments
2507
  var emitArgs = event ? [ event ].concat( args ) : args;
2508
  this.emitEvent( type, emitArgs );
@@ -2530,7 +1816,7 @@ Outlayer.prototype.dispatchEvent = function( type, event, args ) {
2530
  * ignored items do not get skipped in layout
2531
  * @param {Element} elem
2532
  */
2533
- Outlayer.prototype.ignore = function( elem ) {
2534
  var item = this.getItem( elem );
2535
  if ( item ) {
2536
  item.isIgnored = true;
@@ -2541,7 +1827,7 @@ Outlayer.prototype.ignore = function( elem ) {
2541
  * return item to layout collection
2542
  * @param {Element} elem
2543
  */
2544
- Outlayer.prototype.unignore = function( elem ) {
2545
  var item = this.getItem( elem );
2546
  if ( item ) {
2547
  delete item.isIgnored;
@@ -2552,7 +1838,7 @@ Outlayer.prototype.unignore = function( elem ) {
2552
  * adds elements to stamps
2553
  * @param {NodeList, Array, Element, or String} elems
2554
  */
2555
- Outlayer.prototype.stamp = function( elems ) {
2556
  elems = this._find( elems );
2557
  if ( !elems ) {
2558
  return;
@@ -2560,29 +1846,24 @@ Outlayer.prototype.stamp = function( elems ) {
2560
 
2561
  this.stamps = this.stamps.concat( elems );
2562
  // ignore
2563
- for ( var i=0, len = elems.length; i < len; i++ ) {
2564
- var elem = elems[i];
2565
- this.ignore( elem );
2566
- }
2567
  };
2568
 
2569
  /**
2570
  * removes elements to stamps
2571
  * @param {NodeList, Array, or Element} elems
2572
  */
2573
- Outlayer.prototype.unstamp = function( elems ) {
2574
  elems = this._find( elems );
2575
  if ( !elems ){
2576
  return;
2577
  }
2578
 
2579
- for ( var i=0, len = elems.length; i < len; i++ ) {
2580
- var elem = elems[i];
2581
  // filter out removed stamp elements
2582
  utils.removeFrom( this.stamps, elem );
2583
  this.unignore( elem );
2584
- }
2585
-
2586
  };
2587
 
2588
  /**
@@ -2590,33 +1871,30 @@ Outlayer.prototype.unstamp = function( elems ) {
2590
  * @param {NodeList, Array, Element, or String} elems
2591
  * @returns {Array} elems
2592
  */
2593
- Outlayer.prototype._find = function( elems ) {
2594
  if ( !elems ) {
2595
  return;
2596
  }
2597
  // if string, use argument as selector string
2598
- if ( typeof elems === 'string' ) {
2599
  elems = this.element.querySelectorAll( elems );
2600
  }
2601
  elems = utils.makeArray( elems );
2602
  return elems;
2603
  };
2604
 
2605
- Outlayer.prototype._manageStamps = function() {
2606
  if ( !this.stamps || !this.stamps.length ) {
2607
  return;
2608
  }
2609
 
2610
  this._getBoundingRect();
2611
 
2612
- for ( var i=0, len = this.stamps.length; i < len; i++ ) {
2613
- var stamp = this.stamps[i];
2614
- this._manageStamp( stamp );
2615
- }
2616
  };
2617
 
2618
  // update boundingLeft / Top
2619
- Outlayer.prototype._getBoundingRect = function() {
2620
  // get bounding rect for container element
2621
  var boundingRect = this.element.getBoundingClientRect();
2622
  var size = this.size;
@@ -2631,14 +1909,14 @@ Outlayer.prototype._getBoundingRect = function() {
2631
  /**
2632
  * @param {Element} stamp
2633
  **/
2634
- Outlayer.prototype._manageStamp = noop;
2635
 
2636
  /**
2637
  * get x/y position of element relative to container element
2638
  * @param {Element} elem
2639
  * @returns {Object} offset - has left, top, right, bottom
2640
  */
2641
- Outlayer.prototype._getElementOffset = function( elem ) {
2642
  var boundingRect = elem.getBoundingClientRect();
2643
  var thisRect = this._boundingRect;
2644
  var size = getSize( elem );
@@ -2655,55 +1933,31 @@ Outlayer.prototype._getElementOffset = function( elem ) {
2655
 
2656
  // enable event handlers for listeners
2657
  // i.e. resize -> onresize
2658
- Outlayer.prototype.handleEvent = function( event ) {
2659
- var method = 'on' + event.type;
2660
- if ( this[ method ] ) {
2661
- this[ method ]( event );
2662
- }
2663
- };
2664
 
2665
  /**
2666
  * Bind layout to window resizing
2667
  */
2668
- Outlayer.prototype.bindResize = function() {
2669
- // bind just one listener
2670
- if ( this.isResizeBound ) {
2671
- return;
2672
- }
2673
- eventie.bind( window, 'resize', this );
2674
  this.isResizeBound = true;
2675
  };
2676
 
2677
  /**
2678
  * Unbind layout to window resizing
2679
  */
2680
- Outlayer.prototype.unbindResize = function() {
2681
- if ( this.isResizeBound ) {
2682
- eventie.unbind( window, 'resize', this );
2683
- }
2684
  this.isResizeBound = false;
2685
  };
2686
 
2687
- // original debounce by John Hann
2688
- // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
2689
-
2690
- // this fires every resize
2691
- Outlayer.prototype.onresize = function() {
2692
- if ( this.resizeTimeout ) {
2693
- clearTimeout( this.resizeTimeout );
2694
- }
2695
-
2696
- var _this = this;
2697
- function delayed() {
2698
- _this.resize();
2699
- delete _this.resizeTimeout;
2700
- }
2701
-
2702
- this.resizeTimeout = setTimeout( delayed, 100 );
2703
  };
2704
 
2705
- // debounced, layout on resize
2706
- Outlayer.prototype.resize = function() {
 
2707
  // don't trigger if size did not change
2708
  // or if resize was unbound. See #9
2709
  if ( !this.isResizeBound || !this.needsResizeLayout() ) {
@@ -2717,7 +1971,7 @@ Outlayer.prototype.resize = function() {
2717
  * check if layout is needed post layout
2718
  * @returns Boolean
2719
  */
2720
- Outlayer.prototype.needsResizeLayout = function() {
2721
  var size = getSize( this.element );
2722
  // check that this.size and size are there
2723
  // IE8 triggers resize on body size change, so they might not be
@@ -2732,7 +1986,7 @@ Outlayer.prototype.needsResizeLayout = function() {
2732
  * @param {Array or NodeList or Element} elems
2733
  * @returns {Array} items - Outlayer.Items
2734
  **/
2735
- Outlayer.prototype.addItems = function( elems ) {
2736
  var items = this._itemize( elems );
2737
  // add items to collection
2738
  if ( items.length ) {
@@ -2745,7 +1999,7 @@ Outlayer.prototype.addItems = function( elems ) {
2745
  * Layout newly-appended item elements
2746
  * @param {Array or NodeList or Element} elems
2747
  */
2748
- Outlayer.prototype.appended = function( elems ) {
2749
  var items = this.addItems( elems );
2750
  if ( !items.length ) {
2751
  return;
@@ -2759,7 +2013,7 @@ Outlayer.prototype.appended = function( elems ) {
2759
  * Layout prepended elements
2760
  * @param {Array or NodeList or Element} elems
2761
  */
2762
- Outlayer.prototype.prepended = function( elems ) {
2763
  var items = this._itemize( elems );
2764
  if ( !items.length ) {
2765
  return;
@@ -2781,35 +2035,39 @@ Outlayer.prototype.prepended = function( elems ) {
2781
  * reveal a collection of items
2782
  * @param {Array of Outlayer.Items} items
2783
  */
2784
- Outlayer.prototype.reveal = function( items ) {
2785
  this._emitCompleteOnItems( 'reveal', items );
2786
-
2787
- var len = items && items.length;
2788
- for ( var i=0; len && i < len; i++ ) {
2789
- var item = items[i];
2790
- item.reveal();
2791
  }
 
 
 
 
 
2792
  };
2793
 
2794
  /**
2795
  * hide a collection of items
2796
  * @param {Array of Outlayer.Items} items
2797
  */
2798
- Outlayer.prototype.hide = function( items ) {
2799
  this._emitCompleteOnItems( 'hide', items );
2800
-
2801
- var len = items && items.length;
2802
- for ( var i=0; len && i < len; i++ ) {
2803
- var item = items[i];
2804
- item.hide();
2805
  }
 
 
 
 
 
2806
  };
2807
 
2808
  /**
2809
  * reveal item elements
2810
  * @param {Array}, {Element}, {NodeList} items
2811
  */
2812
- Outlayer.prototype.revealItemElements = function( elems ) {
2813
  var items = this.getItems( elems );
2814
  this.reveal( items );
2815
  };
@@ -2818,7 +2076,7 @@ Outlayer.prototype.revealItemElements = function( elems ) {
2818
  * hide item elements
2819
  * @param {Array}, {Element}, {NodeList} items
2820
  */
2821
- Outlayer.prototype.hideItemElements = function( elems ) {
2822
  var items = this.getItems( elems );
2823
  this.hide( items );
2824
  };
@@ -2829,11 +2087,11 @@ Outlayer.prototype.hideItemElements = function( elems ) {
2829
  * @param {Function} callback
2830
  * @returns {Outlayer.Item} item
2831
  */
2832
- Outlayer.prototype.getItem = function( elem ) {
2833
  // loop through items to get the one that matches
2834
- for ( var i=0, len = this.items.length; i < len; i++ ) {
2835
  var item = this.items[i];
2836
- if ( item.element === elem ) {
2837
  // return item
2838
  return item;
2839
  }
@@ -2845,16 +2103,15 @@ Outlayer.prototype.getItem = function( elem ) {
2845
  * @param {Array} elems
2846
  * @returns {Array} items - Outlayer.Items
2847
  */
2848
- Outlayer.prototype.getItems = function( elems ) {
2849
  elems = utils.makeArray( elems );
2850
  var items = [];
2851
- for ( var i=0, len = elems.length; i < len; i++ ) {
2852
- var elem = elems[i];
2853
  var item = this.getItem( elem );
2854
  if ( item ) {
2855
  items.push( item );
2856
  }
2857
- }
2858
 
2859
  return items;
2860
  };
@@ -2863,7 +2120,7 @@ Outlayer.prototype.getItems = function( elems ) {
2863
  * remove element(s) from instance and DOM
2864
  * @param {Array or NodeList or Element} elems
2865
  */
2866
- Outlayer.prototype.remove = function( elems ) {
2867
  var removeItems = this.getItems( elems );
2868
 
2869
  this._emitCompleteOnItems( 'remove', removeItems );
@@ -2873,28 +2130,26 @@ Outlayer.prototype.remove = function( elems ) {
2873
  return;
2874
  }
2875
 
2876
- for ( var i=0, len = removeItems.length; i < len; i++ ) {
2877
- var item = removeItems[i];
2878
  item.remove();
2879
  // remove item from collection
2880
  utils.removeFrom( this.items, item );
2881
- }
2882
  };
2883
 
2884
  // ----- destroy ----- //
2885
 
2886
  // remove and disable Outlayer instance
2887
- Outlayer.prototype.destroy = function() {
2888
  // clean up dynamic styles
2889
  var style = this.element.style;
2890
  style.height = '';
2891
  style.position = '';
2892
  style.width = '';
2893
  // destroy items
2894
- for ( var i=0, len = this.items.length; i < len; i++ ) {
2895
- var item = this.items[i];
2896
  item.destroy();
2897
- }
2898
 
2899
  this.unbindResize();
2900
 
@@ -2930,34 +2185,18 @@ Outlayer.data = function( elem ) {
2930
  */
2931
  Outlayer.create = function( namespace, options ) {
2932
  // sub-class Outlayer
2933
- function Layout() {
2934
- Outlayer.apply( this, arguments );
2935
- }
2936
- // inherit Outlayer prototype, use Object.create if there
2937
- if ( Object.create ) {
2938
- Layout.prototype = Object.create( Outlayer.prototype );
2939
- } else {
2940
- utils.extend( Layout.prototype, Outlayer.prototype );
2941
- }
2942
- // set contructor, used for namespace and Item
2943
- Layout.prototype.constructor = Layout;
2944
-
2945
  Layout.defaults = utils.extend( {}, Outlayer.defaults );
2946
- // apply new options
2947
  utils.extend( Layout.defaults, options );
2948
- // keep prototype.settings for backwards compatibility (Packery v1.2.0)
2949
- Layout.prototype.settings = {};
2950
 
2951
  Layout.namespace = namespace;
2952
 
2953
  Layout.data = Outlayer.data;
2954
 
2955
  // sub-class Item
2956
- Layout.Item = function LayoutItem() {
2957
- Item.apply( this, arguments );
2958
- };
2959
-
2960
- Layout.Item.prototype = new Item();
2961
 
2962
  // -------------------------- declarative -------------------------- //
2963
 
@@ -2973,6 +2212,42 @@ Outlayer.create = function( namespace, options ) {
2973
  return Layout;
2974
  };
2975
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2976
  // ----- fin ----- //
2977
 
2978
  // back in global
@@ -2982,21 +2257,20 @@ return Outlayer;
2982
 
2983
  }));
2984
 
2985
-
2986
  /**
2987
  * Enviratope Item
2988
  **/
2989
 
2990
  ( function( window, factory ) {
2991
- 'use strict';
2992
  // universal module definition
 
2993
  if ( typeof define == 'function' && define.amd ) {
2994
  // AMD
2995
- define( 'enviratope/js/item',[
2996
  'outlayer/outlayer'
2997
  ],
2998
  factory );
2999
- } else if ( typeof exports == 'object' ) {
3000
  // CommonJS
3001
  module.exports = factory(
3002
  require('outlayer')
@@ -3019,16 +2293,17 @@ function Item() {
3019
  Outlayer.Item.apply( this, arguments );
3020
  }
3021
 
3022
- Item.prototype = new Outlayer.Item();
3023
 
3024
- Item.prototype._create = function() {
 
3025
  // assign id, used for original-order sorting
3026
  this.id = this.layout.itemGUID++;
3027
- Outlayer.Item.prototype._create.call( this );
3028
  this.sortData = {};
3029
  };
3030
 
3031
- Item.prototype.updateSortData = function() {
3032
  if ( this.isIgnored ) {
3033
  return;
3034
  }
@@ -3046,8 +2321,8 @@ Item.prototype.updateSortData = function() {
3046
  }
3047
  };
3048
 
3049
- var _destroy = Item.prototype.destroy;
3050
- Item.prototype.destroy = function() {
3051
  // call super
3052
  _destroy.apply( this, arguments );
3053
  // reset display, #741
@@ -3065,17 +2340,16 @@ return Item;
3065
  */
3066
 
3067
  ( function( window, factory ) {
3068
- 'use strict';
3069
  // universal module definition
3070
-
3071
  if ( typeof define == 'function' && define.amd ) {
3072
  // AMD
3073
- define( 'enviratope/js/layout-mode',[
3074
  'get-size/get-size',
3075
  'outlayer/outlayer'
3076
  ],
3077
  factory );
3078
- } else if ( typeof exports == 'object' ) {
3079
  // CommonJS
3080
  module.exports = factory(
3081
  require('get-size'),
@@ -3105,36 +2379,32 @@ return Item;
3105
  }
3106
  }
3107
 
 
 
3108
  /**
3109
  * some methods should just defer to default Outlayer method
3110
  * and reference the Enviratope instance as `this`
3111
  **/
3112
- ( function() {
3113
- var facadeMethods = [
3114
- '_resetLayout',
3115
- '_getItemLayoutPosition',
3116
- '_manageStamp',
3117
- '_getContainerSize',
3118
- '_getElementOffset',
3119
- 'needsResizeLayout'
3120
- ];
3121
-
3122
- for ( var i=0, len = facadeMethods.length; i < len; i++ ) {
3123
- var methodName = facadeMethods[i];
3124
- LayoutMode.prototype[ methodName ] = getOutlayerMethod( methodName );
3125
- }
3126
-
3127
- function getOutlayerMethod( methodName ) {
3128
- return function() {
3129
- return Outlayer.prototype[ methodName ].apply( this.enviratope, arguments );
3130
- };
3131
- }
3132
- })();
3133
 
3134
  // ----- ----- //
3135
 
3136
  // for horizontal layout modes, check vertical size
3137
- LayoutMode.prototype.needsVerticalResizeLayout = function() {
3138
  // don't trigger if size did not change
3139
  var size = getSize( this.enviratope.element );
3140
  // check that this.size and size are there
@@ -3145,15 +2415,15 @@ return Item;
3145
 
3146
  // ----- measurements ----- //
3147
 
3148
- LayoutMode.prototype._getMeasurement = function() {
3149
  this.enviratope._getMeasurement.apply( this, arguments );
3150
  };
3151
 
3152
- LayoutMode.prototype.getColumnWidth = function() {
3153
  this.getSegmentSize( 'column', 'Width' );
3154
  };
3155
 
3156
- LayoutMode.prototype.getRowHeight = function() {
3157
  this.getSegmentSize( 'row', 'Height' );
3158
  };
3159
 
@@ -3162,7 +2432,7 @@ return Item;
3162
  * segment: 'column' or 'row'
3163
  * size 'Width' or 'Height'
3164
  **/
3165
- LayoutMode.prototype.getSegmentSize = function( segment, size ) {
3166
  var segmentName = segment + size;
3167
  var outerSize = 'outer' + size;
3168
  // columnWidth / outerWidth // rowHeight / outerHeight
@@ -3178,18 +2448,18 @@ return Item;
3178
  this.enviratope.size[ 'inner' + size ];
3179
  };
3180
 
3181
- LayoutMode.prototype.getFirstItemSize = function() {
3182
  var firstItem = this.enviratope.filteredItems[0];
3183
  return firstItem && firstItem.element && getSize( firstItem.element );
3184
  };
3185
 
3186
  // ----- methods that should reference enviratope ----- //
3187
 
3188
- LayoutMode.prototype.layout = function() {
3189
  this.enviratope.layout.apply( this.enviratope, arguments );
3190
  };
3191
 
3192
- LayoutMode.prototype.getSize = function() {
3193
  this.enviratope.getSize();
3194
  this.size = this.enviratope.size;
3195
  };
@@ -3204,7 +2474,8 @@ return Item;
3204
  LayoutMode.apply( this, arguments );
3205
  }
3206
 
3207
- Mode.prototype = new LayoutMode();
 
3208
 
3209
  // default options
3210
  if ( options ) {
@@ -3223,7 +2494,7 @@ return Item;
3223
  }));
3224
 
3225
  /*!
3226
- * Masonry v3.3.1
3227
  * Cascading grid layout library
3228
  * http://masonry.desandro.com
3229
  * MIT License
@@ -3231,33 +2502,30 @@ return Item;
3231
  */
3232
 
3233
  ( function( window, factory ) {
3234
- 'use strict';
3235
  // universal module definition
3236
- if ( typeof define === 'function' && define.amd ) {
 
3237
  // AMD
3238
  define( 'masonry/masonry',[
3239
  'outlayer/outlayer',
3240
- 'get-size/get-size',
3241
- 'fizzy-ui-utils/utils'
3242
  ],
3243
  factory );
3244
- } else if ( typeof exports === 'object' ) {
3245
  // CommonJS
3246
  module.exports = factory(
3247
  require('outlayer'),
3248
- require('get-size'),
3249
- require('fizzy-ui-utils')
3250
  );
3251
  } else {
3252
  // browser global
3253
  window.Masonry = factory(
3254
  window.Outlayer,
3255
- window.getSize,
3256
- window.fizzyUIUtils
3257
  );
3258
  }
3259
 
3260
- }( window, function factory( Outlayer, getSize, utils ) {
3261
 
3262
 
3263
 
@@ -3265,6 +2533,8 @@ return Item;
3265
 
3266
  // create an Outlayer layout class
3267
  var Masonry = Outlayer.create('masonry');
 
 
3268
 
3269
  Masonry.prototype._resetLayout = function() {
3270
  this.getSize();
@@ -3273,9 +2543,8 @@ return Item;
3273
  this.measureColumns();
3274
 
3275
  // reset column Y
3276
- var i = this.cols;
3277
  this.colYs = [];
3278
- while (i--) {
3279
  this.colYs.push( 0 );
3280
  }
3281
 
@@ -3309,7 +2578,8 @@ return Item;
3309
 
3310
  Masonry.prototype.getContainerWidth = function() {
3311
  // container is parent if fit width
3312
- var container = this.options.isFitWidth ? this.element.parentNode : this.element;
 
3313
  // check that this.size and size are there
3314
  // IE8 triggers resize on body size change, so they might not be
3315
  var size = getSize( container );
@@ -3328,7 +2598,7 @@ return Item;
3328
  var colGroup = this._getColGroup( colSpan );
3329
  // get the minimum Y value from the columns
3330
  var minimumY = Math.min.apply( Math, colGroup );
3331
- var shortColIndex = utils.indexOf( colGroup, minimumY );
3332
 
3333
  // position the brick
3334
  var position = {
@@ -3373,7 +2643,8 @@ return Item;
3373
  var stampSize = getSize( stamp );
3374
  var offset = this._getElementOffset( stamp );
3375
  // get the columns that this stamp affects
3376
- var firstX = this.options.isOriginLeft ? offset.left : offset.right;
 
3377
  var lastX = firstX + stampSize.outerWidth;
3378
  var firstCol = Math.floor( firstX / this.columnWidth );
3379
  firstCol = Math.max( 0, firstCol );
@@ -3382,7 +2653,9 @@ return Item;
3382
  lastCol -= lastX % this.columnWidth ? 0 : 1;
3383
  lastCol = Math.min( this.cols - 1, lastCol );
3384
  // set colYs to bottom of the stamp
3385
- var stampMaxY = ( this.options.isOriginTop ? offset.top : offset.bottom ) +
 
 
3386
  stampSize.outerHeight;
3387
  for ( var i = firstCol; i <= lastCol; i++ ) {
3388
  this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
@@ -3395,7 +2668,7 @@ return Item;
3395
  height: this.maxY
3396
  };
3397
 
3398
- if ( this.options.isFitWidth ) {
3399
  size.width = this._getContainerFitWidth();
3400
  }
3401
 
@@ -3419,7 +2692,7 @@ return Item;
3419
  Masonry.prototype.needsResizeLayout = function() {
3420
  var previousWidth = this.containerWidth;
3421
  this.getContainerWidth();
3422
- return previousWidth !== this.containerWidth;
3423
  };
3424
 
3425
  return Masonry;
@@ -3433,16 +2706,16 @@ return Item;
3433
  */
3434
 
3435
  ( function( window, factory ) {
3436
- 'use strict';
3437
  // universal module definition
 
3438
  if ( typeof define == 'function' && define.amd ) {
3439
  // AMD
3440
- define( 'enviratope/js/layout-modes/masonry',[
3441
  '../layout-mode',
3442
  'masonry/masonry'
3443
  ],
3444
  factory );
3445
- } else if ( typeof exports == 'object' ) {
3446
  // CommonJS
3447
  module.exports = factory(
3448
  require('../layout-mode'),
@@ -3459,47 +2732,42 @@ return Item;
3459
  }( window, function factory( LayoutMode, Masonry ) {
3460
  'use strict';
3461
 
3462
- // -------------------------- helpers -------------------------- //
3463
-
3464
- // extend objects
3465
- function extend( a, b ) {
3466
- for ( var prop in b ) {
3467
- a[ prop ] = b[ prop ];
3468
- }
3469
- return a;
3470
- }
3471
-
3472
  // -------------------------- masonryDefinition -------------------------- //
3473
 
3474
  // create an Outlayer layout class
3475
  var MasonryMode = LayoutMode.create('masonry');
3476
 
3477
- // save on to these methods
3478
- var _getElementOffset = MasonryMode.prototype._getElementOffset;
3479
- var layout = MasonryMode.prototype.layout;
3480
- var _getMeasurement = MasonryMode.prototype._getMeasurement;
3481
 
3482
- // sub-class Masonry
3483
- extend( MasonryMode.prototype, Masonry.prototype );
 
 
 
3484
 
3485
- // set back, as it was overwritten by Masonry
3486
- MasonryMode.prototype._getElementOffset = _getElementOffset;
3487
- MasonryMode.prototype.layout = layout;
3488
- MasonryMode.prototype._getMeasurement = _getMeasurement;
 
 
 
3489
 
3490
- var measureColumns = MasonryMode.prototype.measureColumns;
3491
- MasonryMode.prototype.measureColumns = function() {
3492
  // set items, used if measuring first item
3493
  this.items = this.enviratope.filteredItems;
3494
  measureColumns.call( this );
3495
  };
3496
 
3497
- // HACK copy over isOriginLeft/Top options
3498
- var _manageStamp = MasonryMode.prototype._manageStamp;
3499
- MasonryMode.prototype._manageStamp = function() {
3500
- this.options.isOriginLeft = this.enviratope.options.isOriginLeft;
3501
- this.options.isOriginTop = this.enviratope.options.isOriginTop;
3502
- _manageStamp.apply( this, arguments );
 
 
3503
  };
3504
 
3505
  return MasonryMode;
@@ -3511,11 +2779,11 @@ function extend( a, b ) {
3511
  */
3512
 
3513
  ( function( window, factory ) {
3514
- 'use strict';
3515
  // universal module definition
 
3516
  if ( typeof define == 'function' && define.amd ) {
3517
  // AMD
3518
- define( 'enviratope/js/layout-modes/fit-rows',[
3519
  '../layout-mode'
3520
  ],
3521
  factory );
@@ -3536,14 +2804,16 @@ function extend( a, b ) {
3536
 
3537
  var FitRows = LayoutMode.create('fitRows');
3538
 
3539
- FitRows.prototype._resetLayout = function() {
 
 
3540
  this.x = 0;
3541
  this.y = 0;
3542
  this.maxY = 0;
3543
  this._getMeasurement( 'gutter', 'outerWidth' );
3544
  };
3545
 
3546
- FitRows.prototype._getItemLayoutPosition = function( item ) {
3547
  item.getSize();
3548
 
3549
  var itemWidth = item.size.outerWidth + this.gutter;
@@ -3565,7 +2835,7 @@ FitRows.prototype._getItemLayoutPosition = function( item ) {
3565
  return position;
3566
  };
3567
 
3568
- FitRows.prototype._getContainerSize = function() {
3569
  return { height: this.maxY };
3570
  };
3571
 
@@ -3578,15 +2848,15 @@ return FitRows;
3578
  */
3579
 
3580
  ( function( window, factory ) {
3581
- 'use strict';
3582
  // universal module definition
 
3583
  if ( typeof define == 'function' && define.amd ) {
3584
  // AMD
3585
- define( 'enviratope/js/layout-modes/vertical',[
3586
  '../layout-mode'
3587
  ],
3588
  factory );
3589
- } else if ( typeof exports == 'object' ) {
3590
  // CommonJS
3591
  module.exports = factory(
3592
  require('../layout-mode')
@@ -3605,11 +2875,13 @@ var Vertical = LayoutMode.create( 'vertical', {
3605
  horizontalAlignment: 0
3606
  });
3607
 
3608
- Vertical.prototype._resetLayout = function() {
 
 
3609
  this.y = 0;
3610
  };
3611
 
3612
- Vertical.prototype._getItemLayoutPosition = function( item ) {
3613
  item.getSize();
3614
  var x = ( this.enviratope.size.innerWidth - item.size.outerWidth ) *
3615
  this.options.horizontalAlignment;
@@ -3618,7 +2890,7 @@ Vertical.prototype._getItemLayoutPosition = function( item ) {
3618
  return { x: x, y: y };
3619
  };
3620
 
3621
- Vertical.prototype._getContainerSize = function() {
3622
  return { height: this.y };
3623
  };
3624
 
@@ -3627,37 +2899,36 @@ return Vertical;
3627
  }));
3628
 
3629
  /*!
3630
- * Enviratope v2.2.2
3631
  *
3632
  * Licensed GPLv3 for open source use
3633
  * or Enviratope Commercial License for commercial use
3634
  *
3635
  * http://enviratope.metafizzy.co
3636
- * Copyright 2015 Metafizzy
3637
  */
3638
 
3639
  ( function( window, factory ) {
3640
- 'use strict';
3641
  // universal module definition
3642
-
3643
  if ( typeof define == 'function' && define.amd ) {
3644
  // AMD
3645
  define( [
3646
  'outlayer/outlayer',
3647
  'get-size/get-size',
3648
- 'matches-selector/matches-selector',
3649
  'fizzy-ui-utils/utils',
3650
- 'enviratope/js/item',
3651
- 'enviratope/js/layout-mode',
3652
  // include default layout modes
3653
- 'enviratope/js/layout-modes/masonry',
3654
- 'enviratope/js/layout-modes/fit-rows',
3655
- 'enviratope/js/layout-modes/vertical'
3656
  ],
3657
  function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) {
3658
  return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode );
3659
  });
3660
- } else if ( typeof exports == 'object' ) {
3661
  // CommonJS
3662
  module.exports = factory(
3663
  window,
@@ -3704,21 +2975,11 @@ var trim = String.prototype.trim ?
3704
  return str.replace( /^\s+|\s+$/g, '' );
3705
  };
3706
 
3707
- var docElem = document.documentElement;
3708
-
3709
- var getText = docElem.textContent ?
3710
- function( elem ) {
3711
- return elem.textContent;
3712
- } :
3713
- function( elem ) {
3714
- return elem.innerText;
3715
- };
3716
-
3717
  // -------------------------- enviratopeDefinition -------------------------- //
3718
 
3719
  // create an Outlayer layout class
3720
  var Enviratope = Outlayer.create( 'enviratope', {
3721
- layoutMode: "masonry",
3722
  isJQueryFiltering: true,
3723
  sortAscending: true
3724
  });
@@ -3726,7 +2987,9 @@ var getText = docElem.textContent ?
3726
  Enviratope.Item = Item;
3727
  Enviratope.LayoutMode = LayoutMode;
3728
 
3729
- Enviratope.prototype._create = function() {
 
 
3730
  this.itemGUID = 0;
3731
  // functions that sort items
3732
  this._sorters = {};
@@ -3746,17 +3009,17 @@ var getText = docElem.textContent ?
3746
  }
3747
  };
3748
 
3749
- Enviratope.prototype.reloadItems = function() {
3750
  // reset item ID counter
3751
  this.itemGUID = 0;
3752
  // call super
3753
  Outlayer.prototype.reloadItems.call( this );
3754
  };
3755
 
3756
- Enviratope.prototype._itemize = function() {
3757
  var items = Outlayer.prototype._itemize.apply( this, arguments );
3758
  // assign ID for original-order
3759
- for ( var i=0, len = items.length; i < len; i++ ) {
3760
  var item = items[i];
3761
  item.id = this.itemGUID++;
3762
  }
@@ -3767,7 +3030,7 @@ var getText = docElem.textContent ?
3767
 
3768
  // -------------------------- layout -------------------------- //
3769
 
3770
- Enviratope.prototype._initLayoutMode = function( name ) {
3771
  var Mode = LayoutMode.modes[ name ];
3772
  // set mode options
3773
  // HACK extend initial options, back-fill in default options
@@ -3779,9 +3042,9 @@ var getText = docElem.textContent ?
3779
  };
3780
 
3781
 
3782
- Enviratope.prototype.layout = function() {
3783
  // if first time doing layout, do all magic
3784
- if ( !this._isLayoutInited && this.options.isInitLayout ) {
3785
  this.arrange();
3786
  return;
3787
  }
@@ -3789,7 +3052,7 @@ var getText = docElem.textContent ?
3789
  };
3790
 
3791
  // private method to be used in layout() & magic()
3792
- Enviratope.prototype._layout = function() {
3793
  // don't animate first layout
3794
  var isInstant = this._getIsInstant();
3795
  // layout flow
@@ -3802,7 +3065,7 @@ var getText = docElem.textContent ?
3802
  };
3803
 
3804
  // filter + sort + layout
3805
- Enviratope.prototype.arrange = function( opts ) {
3806
  // set any options pass
3807
  this.option( opts );
3808
  this._getIsInstant();
@@ -3812,39 +3075,39 @@ var getText = docElem.textContent ?
3812
  var filtered = this._filter( this.items );
3813
  this.filteredItems = filtered.matches;
3814
 
3815
- var _this = this;
3816
- function hideReveal() {
3817
- _this.reveal( filtered.needReveal );
3818
- _this.hide( filtered.needHide );
3819
- }
3820
-
3821
  this._bindArrangeComplete();
3822
 
3823
  if ( this._isInstant ) {
3824
- this._noTransition( hideReveal );
3825
  } else {
3826
- hideReveal();
3827
  }
3828
 
3829
  this._sort();
3830
  this._layout();
3831
  };
3832
  // alias to _init for main plugin method
3833
- Enviratope.prototype._init = Enviratope.prototype.arrange;
 
 
 
 
 
3834
 
3835
  // HACK
3836
  // Don't animate/transition first layout
3837
  // Or don't animate/transition other layouts
3838
- Enviratope.prototype._getIsInstant = function() {
3839
- var isInstant = this.options.isLayoutInstant !== undefined ?
3840
- this.options.isLayoutInstant : !this._isLayoutInited;
 
3841
  this._isInstant = isInstant;
3842
  return isInstant;
3843
  };
3844
 
3845
  // listen for layoutComplete, hideComplete and revealComplete
3846
  // to trigger arrangeComplete
3847
- Enviratope.prototype._bindArrangeComplete = function() {
3848
  // listen for 3 events to trigger arrangeComplete
3849
  var isLayoutComplete, isHideComplete, isRevealComplete;
3850
  var _this = this;
@@ -3869,7 +3132,7 @@ var getText = docElem.textContent ?
3869
 
3870
  // -------------------------- filter -------------------------- //
3871
 
3872
- Enviratope.prototype._filter = function( items ) {
3873
  var filter = this.options.filter;
3874
  filter = filter || '*';
3875
  var matches = [];
@@ -3879,7 +3142,7 @@ var getText = docElem.textContent ?
3879
  var test = this._getFilterTest( filter );
3880
 
3881
  // test each item
3882
- for ( var i=0, len = items.length; i < len; i++ ) {
3883
  var item = items[i];
3884
  if ( item.isIgnored ) {
3885
  continue;
@@ -3908,7 +3171,7 @@ var getText = docElem.textContent ?
3908
  };
3909
 
3910
  // get a jQuery, function, or a matchesSelector test given the filter
3911
- Enviratope.prototype._getFilterTest = function( filter ) {
3912
  if ( jQuery && this.options.isJQueryFiltering ) {
3913
  // use jQuery
3914
  return function( item ) {
@@ -3933,7 +3196,7 @@ var getText = docElem.textContent ?
3933
  * @params {Array} elems
3934
  * @public
3935
  */
3936
- Enviratope.prototype.updateSortData = function( elems ) {
3937
  // get items
3938
  var items;
3939
  if ( elems ) {
@@ -3948,7 +3211,7 @@ var getText = docElem.textContent ?
3948
  this._updateItemsSortData( items );
3949
  };
3950
 
3951
- Enviratope.prototype._getSorters = function() {
3952
  var getSortData = this.options.getSortData;
3953
  for ( var key in getSortData ) {
3954
  var sorter = getSortData[ key ];
@@ -3960,7 +3223,7 @@ var getText = docElem.textContent ?
3960
  * @params {Array} items - of Enviratope.Items
3961
  * @private
3962
  */
3963
- Enviratope.prototype._updateItemsSortData = function( items ) {
3964
  // do not update if no items
3965
  var len = items && items.length;
3966
 
@@ -4008,20 +3271,18 @@ var getText = docElem.textContent ?
4008
 
4009
  // get an attribute getter, or get text of the querySelector
4010
  function getValueGetter( attr, query ) {
4011
- var getValue;
4012
  // if query looks like [foo-bar], get attribute
4013
  if ( attr ) {
4014
- getValue = function( elem ) {
4015
  return elem.getAttribute( attr );
4016
  };
4017
- } else {
4018
- // otherwise, assume its a querySelector, and get its text
4019
- getValue = function( elem ) {
4020
- var child = elem.querySelector( query );
4021
- return child && getText( child );
4022
- };
4023
  }
4024
- return getValue;
 
 
 
 
 
4025
  }
4026
 
4027
  return mungeSorter;
@@ -4040,7 +3301,7 @@ var getText = docElem.textContent ?
4040
  // ----- sort method ----- //
4041
 
4042
  // sort filteredItem order
4043
- Enviratope.prototype._sort = function() {
4044
  var sortByOpt = this.options.sortBy;
4045
  if ( !sortByOpt ) {
4046
  return;
@@ -4061,7 +3322,7 @@ var getText = docElem.textContent ?
4061
  function getItemSorter( sortBys, sortAsc ) {
4062
  return function sorter( itemA, itemB ) {
4063
  // cycle through all sortKeys
4064
- for ( var i = 0, len = sortBys.length; i < len; i++ ) {
4065
  var sortBy = sortBys[i];
4066
  var a = itemA.sortData[ sortBy ];
4067
  var b = itemB.sortData[ sortBy ];
@@ -4079,7 +3340,7 @@ var getText = docElem.textContent ?
4079
  // -------------------------- methods -------------------------- //
4080
 
4081
  // get layout mode
4082
- Enviratope.prototype._mode = function() {
4083
  var layoutMode = this.options.layoutMode;
4084
  var mode = this.modes[ layoutMode ];
4085
  if ( !mode ) {
@@ -4092,32 +3353,32 @@ var getText = docElem.textContent ?
4092
  return mode;
4093
  };
4094
 
4095
- Enviratope.prototype._resetLayout = function() {
4096
  // trigger original reset layout
4097
  Outlayer.prototype._resetLayout.call( this );
4098
  this._mode()._resetLayout();
4099
  };
4100
 
4101
- Enviratope.prototype._getItemLayoutPosition = function( item ) {
4102
  return this._mode()._getItemLayoutPosition( item );
4103
  };
4104
 
4105
- Enviratope.prototype._manageStamp = function( stamp ) {
4106
  this._mode()._manageStamp( stamp );
4107
  };
4108
 
4109
- Enviratope.prototype._getContainerSize = function() {
4110
  return this._mode()._getContainerSize();
4111
  };
4112
 
4113
- Enviratope.prototype.needsResizeLayout = function() {
4114
  return this._mode().needsResizeLayout();
4115
  };
4116
 
4117
  // -------------------------- adding & removing -------------------------- //
4118
 
4119
  // HEADS UP overwrites default Outlayer appended
4120
- Enviratope.prototype.appended = function( elems ) {
4121
  var items = this.addItems( elems );
4122
  if ( !items.length ) {
4123
  return;
@@ -4129,7 +3390,7 @@ var getText = docElem.textContent ?
4129
  };
4130
 
4131
  // HEADS UP overwrites default Outlayer prepended
4132
- Enviratope.prototype.prepended = function( elems ) {
4133
  var items = this._itemize( elems );
4134
  if ( !items.length ) {
4135
  return;
@@ -4146,7 +3407,7 @@ var getText = docElem.textContent ?
4146
  this.items = items.concat( this.items );
4147
  };
4148
 
4149
- Enviratope.prototype._filterRevealAdded = function( items ) {
4150
  var filtered = this._filter( items );
4151
  this.hide( filtered.needHide );
4152
  // reveal all new items
@@ -4160,7 +3421,7 @@ var getText = docElem.textContent ?
4160
  * Filter, sort, and layout newly-appended item elements
4161
  * @param {Array or NodeList or Element} elems
4162
  */
4163
- Enviratope.prototype.insert = function( elems ) {
4164
  var items = this.addItems( elems );
4165
  if ( !items.length ) {
4166
  return;
@@ -4186,28 +3447,25 @@ var getText = docElem.textContent ?
4186
  this.reveal( filteredInsertItems );
4187
  };
4188
 
4189
- var _remove = Enviratope.prototype.remove;
4190
- Enviratope.prototype.remove = function( elems ) {
4191
  elems = utils.makeArray( elems );
4192
  var removeItems = this.getItems( elems );
4193
  // do regular thing
4194
  _remove.call( this, elems );
4195
  // bail if no items to remove
4196
  var len = removeItems && removeItems.length;
4197
- if ( !len ) {
4198
- return;
4199
- }
4200
  // remove elems from filteredItems
4201
- for ( var i=0; i < len; i++ ) {
4202
  var item = removeItems[i];
4203
  // remove item from collection
4204
  utils.removeFrom( this.filteredItems, item );
4205
  }
4206
  };
4207
 
4208
- Enviratope.prototype.shuffle = function() {
4209
  // update random sortData
4210
- for ( var i=0, len = this.items.length; i < len; i++ ) {
4211
  var item = this.items[i];
4212
  item.sortData.random = Math.random();
4213
  }
@@ -4220,16 +3478,17 @@ var getText = docElem.textContent ?
4220
  * trigger fn without transition
4221
  * kind of hacky to have this in the first place
4222
  * @param {Function} fn
 
4223
  * @returns ret
4224
  * @private
4225
  */
4226
- Enviratope.prototype._noTransition = function( fn ) {
4227
  // save transitionDuration before disabling
4228
  var transitionDuration = this.options.transitionDuration;
4229
  // disable transition
4230
  this.options.transitionDuration = 0;
4231
  // do it
4232
- var returnValue = fn.call( this );
4233
  // re-enable transition for reveal
4234
  this.options.transitionDuration = transitionDuration;
4235
  return returnValue;
@@ -4241,16 +3500,14 @@ var getText = docElem.textContent ?
4241
  * getter method for getting filtered item elements
4242
  * @returns {Array} elems - collection of item elements
4243
  */
4244
- Enviratope.prototype.getFilteredItemElements = function() {
4245
- var elems = [];
4246
- for ( var i=0, len = this.filteredItems.length; i < len; i++ ) {
4247
- elems.push( this.filteredItems[i].element );
4248
- }
4249
- return elems;
4250
  };
4251
 
4252
  // ----- ----- //
4253
 
4254
  return Enviratope;
4255
 
4256
- }));
1
  /*!
2
+ * Enviratope PACKAGED v3.0.0
3
  *
4
  * Licensed GPLv3 for open source use
5
  * or Enviratope Commercial License for commercial use
6
  *
7
  * http://enviratope.metafizzy.co
8
+ * Copyright 2016 Metafizzy
9
  */
10
 
11
  /**
12
  * Bridget makes jQuery widgets
13
+ * v2.0.0
14
  * MIT license
15
  */
16
 
17
+ /* jshint browser: true, strict: true, undef: true, unused: true */
18
 
19
+ ( function( window, factory ) {
20
+ 'use strict';
21
+ /* globals define: false, module: false, require: false */
22
 
23
+ if ( typeof define == 'function' && define.amd ) {
24
+ // AMD
25
+ define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) {
26
+ factory( window, jQuery );
27
+ });
28
+ } else if ( typeof module == 'object' && module.exports ) {
29
+ // CommonJS
30
+ module.exports = factory(
31
+ window,
32
+ require('jquery')
33
+ );
34
+ } else {
35
+ // browser global
36
+ window.jQueryBridget = factory(
37
+ window,
38
+ window.jQuery
39
+ );
 
 
 
 
 
 
 
 
 
40
  }
41
 
42
+ }( window, function factory( window, jQuery ) {
43
+ 'use strict';
44
+
45
+ // ----- utils ----- //
 
 
 
 
 
46
 
47
+ var arraySlice = Array.prototype.slice;
48
 
49
  // helper function for logging errors
50
  // $.error breaks jQuery chaining
51
+ var console = window.console;
52
+ var logError = typeof console == 'undefined' ? function() {} :
53
  function( message ) {
54
  console.error( message );
55
  };
56
 
57
+ // ----- jQueryBridget ----- //
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
+ function jQueryBridget( namespace, PluginClass, $ ) {
60
+ $ = $ || jQuery || window.jQuery;
61
+ if ( !$ ) {
62
+ return;
63
+ }
64
 
65
+ // add option method -> $().plugin('option', {...})
66
+ if ( !PluginClass.prototype.option ) {
67
+ // option setter
68
+ PluginClass.prototype.option = function( opts ) {
69
+ // bail out if not an object
70
+ if ( !$.isPlainObject( opts ) ){
71
+ return;
72
  }
73
+ this.options = $.extend( true, this.options, opts );
74
+ };
75
+ }
76
+
77
+ // make jQuery plugin
78
+ $.fn[ namespace ] = function( arg0 /*, arg1 */ ) {
79
+ if ( typeof arg0 == 'string' ) {
80
+ // method call $().plugin( 'methodName', { options } )
81
+ // shift arguments by 1
82
+ var args = arraySlice.call( arguments, 1 );
83
+ return methodCall( this, arg0, args );
 
 
 
 
84
  }
85
+ // just $().plugin({ options })
86
+ plainCall( this, arg0 );
87
+ return this;
88
  };
89
 
90
+ // $().plugin('methodName')
91
+ function methodCall( $elems, methodName, args ) {
92
+ var returnValue;
93
+ var pluginMethodStr = '$().' + namespace + '("' + methodName + '")';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
+ $elems.each( function( i, elem ) {
96
+ // get instance
97
+ var instance = $.data( elem, namespace );
98
+ if ( !instance ) {
99
+ logError( namespace + ' not initialized. Cannot call methods, i.e. ' +
100
+ pluginMethodStr );
101
+ return;
102
+ }
103
 
104
+ var method = instance[ methodName ];
105
+ if ( !method || methodName.charAt(0) == '_' ) {
106
+ logError( pluginMethodStr + ' is not a valid method' );
107
+ return;
108
+ }
109
 
110
+ // apply method, get return value
111
+ var value = method.apply( instance, args );
112
+ // set return value if value is returned, use only first value
113
+ returnValue = returnValue === undefined ? value : returnValue;
114
+ });
115
 
116
+ return returnValue !== undefined ? returnValue : $elems;
117
+ }
 
 
 
 
118
 
119
+ function plainCall( $elems, options ) {
120
+ $elems.each( function( i, elem ) {
121
+ var instance = $.data( elem, namespace );
122
+ if ( instance ) {
123
+ // set options & init
124
+ instance.option( options );
125
+ instance._init();
126
+ } else {
127
+ // initialize new instance
128
+ instance = new PluginClass( elem, options );
129
+ $.data( elem, namespace, instance );
130
+ }
131
+ });
132
+ }
 
 
 
 
133
 
134
+ updateJQuery( $ );
135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  }
137
 
138
+ // ----- updateJQuery ----- //
 
 
 
139
 
140
+ // set $.bridget for v1 backwards compatibility
141
+ function updateJQuery( $ ) {
142
+ if ( !$ || ( $ && $.bridget ) ) {
143
+ return;
144
+ }
145
+ $.bridget = jQueryBridget;
 
 
 
 
 
146
  }
147
 
148
+ updateJQuery( jQuery || window.jQuery );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
 
150
+ // ----- ----- //
 
151
 
152
+ return jQueryBridget;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
 
154
+ }));
 
155
 
156
+ /**
157
+ * EvEmitter v1.0.2
158
+ * Lil' event emitter
159
+ * MIT License
160
+ */
 
 
 
 
 
 
 
 
 
 
 
 
161
 
162
+ /* jshint unused: true, undef: true, strict: true */
 
 
 
 
 
 
 
 
 
 
 
163
 
164
+ ( function( global, factory ) {
165
+ // universal module definition
166
+ /* jshint strict: false */ /* globals define, module */
167
+ if ( typeof define == 'function' && define.amd ) {
168
+ // AMD - RequireJS
169
+ define( 'ev-emitter/ev-emitter',factory );
170
+ } else if ( typeof module == 'object' && module.exports ) {
171
+ // CommonJS - Browserify, Webpack
172
+ module.exports = factory();
173
+ } else {
174
+ // Browser globals
175
+ global.EvEmitter = factory();
176
+ }
 
 
 
177
 
178
+ }( this, function() {
 
 
 
 
 
 
 
 
179
 
 
 
 
 
 
 
 
 
 
180
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
 
182
+ function EvEmitter() {}
 
 
 
 
 
183
 
184
+ var proto = EvEmitter.prototype;
 
185
 
186
+ proto.on = function( eventName, listener ) {
187
+ if ( !eventName || !listener ) {
188
+ return;
189
+ }
190
+ // set events hash
191
+ var events = this._events = this._events || {};
192
+ // set listeners array
193
+ var listeners = events[ eventName ] = events[ eventName ] || [];
194
+ // only add once
195
+ if ( listeners.indexOf( listener ) == -1 ) {
196
+ listeners.push( listener );
197
+ }
198
 
199
+ return this;
200
+ };
201
 
202
+ proto.once = function( eventName, listener ) {
203
+ if ( !eventName || !listener ) {
204
+ return;
205
+ }
206
+ // add event
207
+ this.on( eventName, listener );
208
+ // set once flag
209
+ // set onceEvents hash
210
+ var onceEvents = this._onceEvents = this._onceEvents || {};
211
+ // set onceListeners object
212
+ var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
213
+ // set flag
214
+ onceListeners[ listener ] = true;
215
 
216
+ return this;
217
+ };
218
 
219
+ proto.off = function( eventName, listener ) {
220
+ var listeners = this._events && this._events[ eventName ];
221
+ if ( !listeners || !listeners.length ) {
222
  return;
223
  }
224
+ var index = listeners.indexOf( listener );
225
+ if ( index != -1 ) {
226
+ listeners.splice( index, 1 );
 
227
  }
228
 
229
+ return this;
230
+ };
231
+
232
+ proto.emitEvent = function( eventName, args ) {
233
+ var listeners = this._events && this._events[ eventName ];
234
+ if ( !listeners || !listeners.length ) {
235
+ return;
236
+ }
237
+ var i = 0;
238
+ var listener = listeners[i];
239
+ args = args || [];
240
+ // once stuff
241
+ var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
242
 
243
+ while ( listener ) {
244
+ var isOnce = onceListeners && onceListeners[ listener ];
245
+ if ( isOnce ) {
246
+ // remove listener
247
+ // remove before trigger to prevent recursion
248
+ this.off( eventName, listener );
249
+ // unset once flag
250
+ delete onceListeners[ listener ];
251
  }
252
+ // trigger listener
253
+ listener.apply( this, args );
254
+ // get next listener
255
+ i += isOnce ? 0 : 1;
256
+ listener = listeners[i];
257
  }
 
258
 
259
+ return this;
260
+ };
261
+
262
+ return EvEmitter;
 
 
 
 
 
 
 
 
 
263
 
264
+ }));
265
 
266
  /*!
267
+ * getSize v2.0.2
268
  * measure size of elements
269
  * MIT license
270
  */
271
 
272
  /*jshint browser: true, strict: true, undef: true, unused: true */
273
+ /*global define: false, module: false, console: false */
274
 
275
+ ( function( window, factory ) {
276
+ 'use strict';
277
 
278
+ if ( typeof define == 'function' && define.amd ) {
279
+ // AMD
280
+ define( 'get-size/get-size',[],function() {
281
+ return factory();
282
+ });
283
+ } else if ( typeof module == 'object' && module.exports ) {
284
+ // CommonJS
285
+ module.exports = factory();
286
+ } else {
287
+ // browser global
288
+ window.getSize = factory();
289
+ }
290
 
291
+ })( window, function factory() {
292
+ 'use strict';
293
 
294
  // -------------------------- helpers -------------------------- //
295
 
297
  function getStyleSize( value ) {
298
  var num = parseFloat( value );
299
  // not a percent like '100%', and a number
300
+ var isValid = value.indexOf('%') == -1 && !isNaN( num );
301
  return isValid && num;
302
  }
303
 
304
  function noop() {}
305
 
306
+ var logError = typeof console == 'undefined' ? noop :
307
  function( message ) {
308
  console.error( message );
309
  };
325
  'borderBottomWidth'
326
  ];
327
 
328
+ var measurementsLength = measurements.length;
329
+
330
  function getZeroSize() {
331
  var size = {
332
  width: 0,
336
  outerWidth: 0,
337
  outerHeight: 0
338
  };
339
+ for ( var i=0; i < measurementsLength; i++ ) {
340
  var measurement = measurements[i];
341
  size[ measurement ] = 0;
342
  }
343
  return size;
344
  }
345
 
346
+ // -------------------------- getStyle -------------------------- //
347
 
348
+ /**
349
+ * getStyle, get style of element, check for Firefox bug
350
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=548397
351
+ */
352
+ function getStyle( elem ) {
353
+ var style = getComputedStyle( elem );
354
+ if ( !style ) {
355
+ logError( 'Style returned ' + style +
356
+ '. Are you running this code in a hidden iframe on Firefox? ' +
357
+ 'See http://bit.ly/getsizebug1' );
358
+ }
359
+ return style;
360
+ }
361
 
362
  // -------------------------- setup -------------------------- //
363
 
364
  var isSetup = false;
365
 
366
+ var isBoxSizeOuter;
367
 
368
  /**
369
+ * setup
370
+ * check isBoxSizerOuter
371
+ * do on first getSize() rather than on page load for Firefox bug
372
  */
373
  function setup() {
374
  // setup once
377
  }
378
  isSetup = true;
379
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
380
  // -------------------------- box sizing -------------------------- //
381
 
 
 
382
  /**
383
  * WebKit measures the outer-width on style.width on border-box elems
384
+ * IE & Firefox<29 measures the inner-width
385
  */
386
+ var div = document.createElement('div');
387
+ div.style.width = '200px';
388
+ div.style.padding = '1px 2px 3px 4px';
389
+ div.style.borderStyle = 'solid';
390
+ div.style.borderWidth = '1px 2px 3px 4px';
391
+ div.style.boxSizing = 'border-box';
392
+
393
+ var body = document.body || document.documentElement;
394
+ body.appendChild( div );
395
+ var style = getStyle( div );
396
+
397
+ getSize.isBoxSizeOuter = isBoxSizeOuter = getStyleSize( style.width ) == 200;
398
+ body.removeChild( div );
 
 
399
 
400
  }
401
 
405
  setup();
406
 
407
  // use querySeletor if elem is string
408
+ if ( typeof elem == 'string' ) {
409
  elem = document.querySelector( elem );
410
  }
411
 
412
  // do not proceed on non-objects
413
+ if ( !elem || typeof elem != 'object' || !elem.nodeType ) {
414
  return;
415
  }
416
 
417
  var style = getStyle( elem );
418
 
419
  // if hidden, everything is 0
420
+ if ( style.display == 'none' ) {
421
  return getZeroSize();
422
  }
423
 
425
  size.width = elem.offsetWidth;
426
  size.height = elem.offsetHeight;
427
 
428
+ var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';
 
429
 
430
  // get all measurements
431
+ for ( var i=0; i < measurementsLength; i++ ) {
432
  var measurement = measurements[i];
433
  var value = style[ measurement ];
 
434
  var num = parseFloat( value );
435
  // any 'auto', 'medium' value will be 0
436
  size[ measurement ] = !isNaN( num ) ? num : 0;
469
  return size;
470
  }
471
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
472
  return getSize;
473
 
474
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
475
 
476
  /**
477
+ * matchesSelector v2.0.1
478
  * matchesSelector( element, '.selector' )
479
  * MIT license
480
  */
481
 
482
  /*jshint browser: true, strict: true, undef: true, unused: true */
 
483
 
484
+ ( function( window, factory ) {
485
+ /*global define: false, module: false */
486
+ 'use strict';
487
+ // universal module definition
488
+ if ( typeof define == 'function' && define.amd ) {
489
+ // AMD
490
+ define( 'desandro-matches-selector/matches-selector',factory );
491
+ } else if ( typeof module == 'object' && module.exports ) {
492
+ // CommonJS
493
+ module.exports = factory();
494
+ } else {
495
+ // browser global
496
+ window.matchesSelector = factory();
497
+ }
498
 
499
+ }( window, function factory() {
500
  'use strict';
501
 
502
  var matchesMethod = ( function() {
503
+ var ElemProto = Element.prototype;
504
  // check for the standard method name first
505
  if ( ElemProto.matches ) {
506
  return 'matches';
512
  // check vendor prefixes
513
  var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
514
 
515
+ for ( var i=0; i < prefixes.length; i++ ) {
516
  var prefix = prefixes[i];
517
  var method = prefix + 'MatchesSelector';
518
  if ( ElemProto[ method ] ) {
521
  }
522
  })();
523
 
524
+ return function matchesSelector( elem, selector ) {
 
 
525
  return elem[ matchesMethod ]( selector );
526
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
527
 
528
+ }));
529
 
530
  /**
531
+ * Fizzy UI utils v2.0.1
532
  * MIT license
533
  */
534
 
535
  /*jshint browser: true, undef: true, unused: true, strict: true */
536
 
537
  ( function( window, factory ) {
 
 
538
  // universal module definition
539
+ /*jshint strict: false */ /*globals define, module, require */
540
 
541
  if ( typeof define == 'function' && define.amd ) {
542
  // AMD
543
  define( 'fizzy-ui-utils/utils',[
544
+ 'desandro-matches-selector/matches-selector'
545
+ ], function( matchesSelector ) {
546
+ return factory( window, matchesSelector );
 
547
  });
548
+ } else if ( typeof module == 'object' && module.exports ) {
549
  // CommonJS
550
  module.exports = factory(
551
  window,
 
552
  require('desandro-matches-selector')
553
  );
554
  } else {
555
  // browser global
556
  window.fizzyUIUtils = factory(
557
  window,
 
558
  window.matchesSelector
559
  );
560
  }
561
 
562
+ }( window, function factory( window, matchesSelector ) {
563
 
564
 
565
 
581
  return ( ( num % div ) + div ) % div;
582
  };
583
 
 
 
 
 
 
 
 
584
  // ----- makeArray ----- //
585
 
586
  // turn element or nodeList into an array
587
  utils.makeArray = function( obj ) {
588
  var ary = [];
589
+ if ( Array.isArray( obj ) ) {
590
  // use object if already an array
591
  ary = obj;
592
  } else if ( obj && typeof obj.length == 'number' ) {
593
  // convert nodeList to array
594
+ for ( var i=0; i < obj.length; i++ ) {
595
  ary.push( obj[i] );
596
  }
597
  } else {
601
  return ary;
602
  };
603
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
604
  // ----- removeFrom ----- //
605
 
606
  utils.removeFrom = function( ary, obj ) {
607
+ var index = ary.indexOf( obj );
608
  if ( index != -1 ) {
609
  ary.splice( index, 1 );
610
  }
611
  };
612
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
613
  // ----- getParent ----- //
614
 
615
  utils.getParent = function( elem, selector ) {
648
  elems = utils.makeArray( elems );
649
  var ffElems = [];
650
 
651
+ elems.forEach( function( elem ) {
 
652
  // check that elem is an actual element
653
+ if ( !( elem instanceof HTMLElement ) ) {
654
+ return;
655
+ }
656
+ // add elem if no selector
657
+ if ( !selector ) {
658
+ ffElems.push( elem );
659
+ return;
660
  }
661
  // filter & find items if we have a selector
662
+ // filter
663
+ if ( matchesSelector( elem, selector ) ) {
 
 
 
 
 
 
 
 
 
 
664
  ffElems.push( elem );
665
  }
666
+ // find children
667
+ var childElems = elem.querySelectorAll( selector );
668
+ // concat childElems to filterFound array
669
+ for ( var i=0; i < childElems.length; i++ ) {
670
+ ffElems.push( childElems[i] );
671
+ }
672
+ });
673
 
674
  return ffElems;
675
  };
696
  };
697
  };
698
 
699
+ // ----- docReady ----- //
700
+
701
+ utils.docReady = function( callback ) {
702
+ if ( document.readyState == 'complete' ) {
703
+ callback();
704
+ } else {
705
+ document.addEventListener( 'DOMContentLoaded', callback );
706
+ }
707
+ };
708
+
709
  // ----- htmlInit ----- //
710
 
711
  // http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
717
 
718
  var console = window.console;
719
  /**
720
+ * allow user to initialize classes via [data-namespace] or .js-namespace class
721
  * htmlInit( Widget, 'widgetName' )
722
+ * options are parsed from data-namespace-options
723
  */
724
  utils.htmlInit = function( WidgetClass, namespace ) {
725
+ utils.docReady( function() {
726
  var dashedNamespace = utils.toDashed( namespace );
727
+ var dataAttr = 'data-' + dashedNamespace;
728
+ var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
729
+ var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
730
+ var elems = utils.makeArray( dataAttrElems )
731
+ .concat( utils.makeArray( jsDashElems ) );
732
+ var dataOptionsAttr = dataAttr + '-options';
733
+ var jQuery = window.jQuery;
734
+
735
+ elems.forEach( function( elem ) {
736
+ var attr = elem.getAttribute( dataAttr ) ||
737
+ elem.getAttribute( dataOptionsAttr );
738
  var options;
739
  try {
740
  options = attr && JSON.parse( attr );
741
  } catch ( error ) {
742
  // log error, do not initialize
743
  if ( console ) {
744
+ console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
745
+ ': ' + error );
 
746
  }
747
+ return;
748
  }
749
  // initialize
750
  var instance = new WidgetClass( elem, options );
751
  // make available via $().data('layoutname')
 
752
  if ( jQuery ) {
753
  jQuery.data( elem, namespace, instance );
754
  }
755
+ });
756
+
757
  });
758
  };
759
 
768
  */
769
 
770
  ( function( window, factory ) {
 
771
  // universal module definition
772
+ /* jshint strict: false */ /* globals define, module, require */
773
+ if ( typeof define == 'function' && define.amd ) {
774
+ // AMD - RequireJS
775
  define( 'outlayer/item',[
776
+ 'ev-emitter/ev-emitter',
777
+ 'get-size/get-size'
 
 
778
  ],
779
+ factory
 
 
780
  );
781
+ } else if ( typeof module == 'object' && module.exports ) {
782
+ // CommonJS - Browserify, Webpack
783
  module.exports = factory(
784
+ require('ev-emitter'),
785
+ require('get-size')
 
 
 
786
  );
787
  } else {
788
  // browser global
789
  window.Outlayer = {};
790
  window.Outlayer.Item = factory(
791
+ window.EvEmitter,
792
+ window.getSize
 
 
 
793
  );
794
  }
795
 
796
+ }( window, function factory( EvEmitter, getSize ) {
797
  'use strict';
798
 
799
  // ----- helpers ----- //
800
 
 
 
 
 
 
 
 
 
 
 
801
  function isEmptyObj( obj ) {
802
  for ( var prop in obj ) {
803
  return false;
808
 
809
  // -------------------------- CSS3 support -------------------------- //
810
 
811
+
812
+ var docElemStyle = document.documentElement.style;
813
+
814
+ var transitionProperty = typeof docElemStyle.transition == 'string' ?
815
+ 'transition' : 'WebkitTransition';
816
+ var transformProperty = typeof docElemStyle.transform == 'string' ?
817
+ 'transform' : 'WebkitTransform';
818
 
819
  var transitionEndEvent = {
820
  WebkitTransition: 'webkitTransitionEnd',
 
 
821
  transition: 'transitionend'
822
  }[ transitionProperty ];
823
 
824
+ // cache all vendor properties that could have vendor prefix
825
+ var vendorProperties = {
826
+ transform: transformProperty,
827
+ transition: transitionProperty,
828
+ transitionDuration: transitionProperty + 'Duration',
829
+ transitionProperty: transitionProperty + 'Property',
830
+ transitionDelay: transitionProperty + 'Delay'
831
+ };
 
 
 
 
 
 
 
 
 
 
 
 
832
 
833
  // -------------------------- Item -------------------------- //
834
 
848
  this._create();
849
  }
850
 
851
+ // inherit EvEmitter
852
+ var proto = Item.prototype = Object.create( EvEmitter.prototype );
853
+ proto.constructor = Item;
854
 
855
+ proto._create = function() {
856
  // transition objects
857
  this._transn = {
858
  ingProperties: {},
866
  };
867
 
868
  // trigger specified handler for event type
869
+ proto.handleEvent = function( event ) {
870
  var method = 'on' + event.type;
871
  if ( this[ method ] ) {
872
  this[ method ]( event );
873
  }
874
  };
875
 
876
+ proto.getSize = function() {
877
  this.size = getSize( this.element );
878
  };
879
 
881
  * apply CSS styles to element
882
  * @param {Object} style
883
  */
884
+ proto.css = function( style ) {
885
  var elemStyle = this.element.style;
886
 
887
  for ( var prop in style ) {
892
  };
893
 
894
  // measure position, and sets it
895
+ proto.getPosition = function() {
896
+ var style = getComputedStyle( this.element );
897
+ var isOriginLeft = this.layout._getOption('originLeft');
898
+ var isOriginTop = this.layout._getOption('originTop');
 
899
  var xValue = style[ isOriginLeft ? 'left' : 'right' ];
900
  var yValue = style[ isOriginTop ? 'top' : 'bottom' ];
901
  // convert percent to pixels
917
  };
918
 
919
  // set settled position, apply padding
920
+ proto.layoutPosition = function() {
921
  var layoutSize = this.layout.size;
 
922
  var style = {};
923
+ var isOriginLeft = this.layout._getOption('originLeft');
924
+ var isOriginTop = this.layout._getOption('originTop');
925
 
926
  // x
927
+ var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight';
928
+ var xProperty = isOriginLeft ? 'left' : 'right';
929
+ var xResetProperty = isOriginLeft ? 'right' : 'left';
930
 
931
  var x = this.position.x + layoutSize[ xPadding ];
932
  // set in percentage or pixels
935
  style[ xResetProperty ] = '';
936
 
937
  // y
938
+ var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom';
939
+ var yProperty = isOriginTop ? 'top' : 'bottom';
940
+ var yResetProperty = isOriginTop ? 'bottom' : 'top';
941
 
942
  var y = this.position.y + layoutSize[ yPadding ];
943
  // set in percentage or pixels
949
  this.emitEvent( 'layout', [ this ] );
950
  };
951
 
952
+ proto.getXValue = function( x ) {
953
+ var isHorizontal = this.layout._getOption('horizontal');
954
+ return this.layout.options.percentPosition && !isHorizontal ?
955
  ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';
956
  };
957
 
958
+ proto.getYValue = function( y ) {
959
+ var isHorizontal = this.layout._getOption('horizontal');
960
+ return this.layout.options.percentPosition && isHorizontal ?
961
  ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';
962
  };
963
 
964
+ proto._transitionTo = function( x, y ) {
 
965
  this.getPosition();
966
  // get current x & y from top/left
967
  var curX = this.position.x;
994
  });
995
  };
996
 
997
+ proto.getTranslate = function( x, y ) {
998
  // flip cooridinates if origin on right or bottom
999
+ var isOriginLeft = this.layout._getOption('originLeft');
1000
+ var isOriginTop = this.layout._getOption('originTop');
1001
+ x = isOriginLeft ? x : -x;
1002
+ y = isOriginTop ? y : -y;
1003
+ return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
 
 
 
 
1004
  };
1005
 
1006
  // non transition + transform support
1007
+ proto.goTo = function( x, y ) {
1008
  this.setPosition( x, y );
1009
  this.layoutPosition();
1010
  };
1011
 
1012
+ proto.moveTo = proto._transitionTo;
 
 
1013
 
1014
+ proto.setPosition = function( x, y ) {
1015
  this.position.x = parseInt( x, 10 );
1016
  this.position.y = parseInt( y, 10 );
1017
  };
1024
  */
1025
 
1026
  // non transition, just trigger callback
1027
+ proto._nonTransition = function( args ) {
1028
  this.css( args.to );
1029
  if ( args.isCleaning ) {
1030
  this._removeStyles( args.to );
1042
  * @param {Boolean} isCleaning - removes transition styles after transition
1043
  * @param {Function} onTransitionEnd - callback
1044
  */
1045
+ proto.transition = function( args ) {
1046
  // redirect to nonTransition if no transition duration
1047
  if ( !parseFloat( this.layout.options.transitionDuration ) ) {
1048
  this._nonTransition( args );
1088
  });
1089
  }
1090
 
1091
+ var transitionProps = 'opacity,' + toDashedAll( transformProperty );
 
1092
 
1093
+ proto.enableTransition = function(/* style */) {
1094
  // HACK changing transitionProperty during a transition
1095
  // will cause transition to jump
1096
  if ( this.isTransitioning ) {
1106
  // prop = vendorProperties[ prop ] || prop;
1107
  // transitionValues.push( toDashedAll( prop ) );
1108
  // }
1109
+ // munge number to millisecond, to match stagger
1110
+ var duration = this.layout.options.transitionDuration;
1111
+ duration = typeof duration == 'number' ? duration + 'ms' : duration;
1112
  // enable transition styles
1113
  this.css({
1114
  transitionProperty: transitionProps,
1115
+ transitionDuration: duration,
1116
+ transitionDelay: this.staggerDelay || 0
1117
  });
1118
  // listen for transition end event
1119
  this.element.addEventListener( transitionEndEvent, this, false );
1120
  };
1121
 
 
 
1122
  // ----- events ----- //
1123
 
1124
+ proto.onwebkitTransitionEnd = function( event ) {
1125
  this.ontransitionend( event );
1126
  };
1127
 
1128
+ proto.onotransitionend = function( event ) {
1129
  this.ontransitionend( event );
1130
  };
1131
 
1132
  // properties that I munge to make my life easier
1133
  var dashedVendorProperties = {
1134
+ '-webkit-transform': 'transform'
 
 
1135
  };
1136
 
1137
+ proto.ontransitionend = function( event ) {
1138
  // disregard bubbled events from children
1139
  if ( event.target !== this.element ) {
1140
  return;
1166
  this.emitEvent( 'transitionEnd', [ this ] );
1167
  };
1168
 
1169
+ proto.disableTransition = function() {
1170
  this.removeTransitionStyles();
1171
  this.element.removeEventListener( transitionEndEvent, this, false );
1172
  this.isTransitioning = false;
1176
  * removes style property from element
1177
  * @param {Object} style
1178
  **/
1179
+ proto._removeStyles = function( style ) {
1180
  // clean up transition styles
1181
  var cleanStyle = {};
1182
  for ( var prop in style ) {
1187
 
1188
  var cleanTransitionStyle = {
1189
  transitionProperty: '',
1190
+ transitionDuration: '',
1191
+ transitionDelay: ''
1192
  };
1193
 
1194
+ proto.removeTransitionStyles = function() {
1195
  // remove transition
1196
  this.css( cleanTransitionStyle );
1197
  };
1198
 
1199
+ // ----- stagger ----- //
1200
+
1201
+ proto.stagger = function( delay ) {
1202
+ delay = isNaN( delay ) ? 0 : delay;
1203
+ this.staggerDelay = delay + 'ms';
1204
+ };
1205
+
1206
  // ----- show/hide/remove ----- //
1207
 
1208
  // remove element from DOM
1209
+ proto.removeElem = function() {
1210
  this.element.parentNode.removeChild( this.element );
1211
  // remove display: none
1212
  this.css({ display: '' });
1213
  this.emitEvent( 'remove', [ this ] );
1214
  };
1215
 
1216
+ proto.remove = function() {
1217
  // just remove element if no transition support or no transition
1218
  if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
1219
  this.removeElem();
1221
  }
1222
 
1223
  // start transition
 
1224
  this.once( 'transitionEnd', function() {
1225
+ this.removeElem();
1226
  });
1227
  this.hide();
1228
  };
1229
 
1230
+ proto.reveal = function() {
1231
  delete this.isHidden;
1232
  // remove display: none
1233
  this.css({ display: '' });
1246
  });
1247
  };
1248
 
1249
+ proto.onRevealTransitionEnd = function() {
1250
  // check if still visible
1251
  // during transition, item may have been hidden
1252
  if ( !this.isHidden ) {
1259
  * @param {String} styleProperty - hiddenStyle/visibleStyle
1260
  * @returns {String}
1261
  */
1262
+ proto.getHideRevealTransitionEndProperty = function( styleProperty ) {
1263
  var optionStyle = this.layout.options[ styleProperty ];
1264
  // use opacity
1265
  if ( optionStyle.opacity ) {
1271
  }
1272
  };
1273
 
1274
+ proto.hide = function() {
1275
  // set flag
1276
  this.isHidden = true;
1277
  // remove display: none
1292
  });
1293
  };
1294
 
1295
+ proto.onHideTransitionEnd = function() {
1296
  // check if still hidden
1297
  // during transition, item may have been un-hidden
1298
  if ( this.isHidden ) {
1301
  }
1302
  };
1303
 
1304
+ proto.destroy = function() {
1305
  this.css({
1306
  position: '',
1307
  left: '',
1318
  }));
1319
 
1320
  /*!
1321
+ * Outlayer v2.1.0
1322
  * the brains and guts of a layout library
1323
  * MIT license
1324
  */
1326
  ( function( window, factory ) {
1327
  'use strict';
1328
  // universal module definition
1329
+ /* jshint strict: false */ /* globals define, module, require */
1330
  if ( typeof define == 'function' && define.amd ) {
1331
+ // AMD - RequireJS
1332
  define( 'outlayer/outlayer',[
1333
+ 'ev-emitter/ev-emitter',
 
1334
  'get-size/get-size',
1335
  'fizzy-ui-utils/utils',
1336
  './item'
1337
  ],
1338
+ function( EvEmitter, getSize, utils, Item ) {
1339
+ return factory( window, EvEmitter, getSize, utils, Item);
1340
  }
1341
  );
1342
+ } else if ( typeof module == 'object' && module.exports ) {
1343
+ // CommonJS - Browserify, Webpack
1344
  module.exports = factory(
1345
  window,
1346
+ require('ev-emitter'),
 
1347
  require('get-size'),
1348
  require('fizzy-ui-utils'),
1349
  require('./item')
1352
  // browser global
1353
  window.Outlayer = factory(
1354
  window,
1355
+ window.EvEmitter,
 
1356
  window.getSize,
1357
  window.fizzyUIUtils,
1358
  window.Outlayer.Item
1359
  );
1360
  }
1361
 
1362
+ }( window, function factory( window, EvEmitter, getSize, utils, Item ) {
1363
  'use strict';
1364
 
1365
  // ----- vars ----- //
1408
  // kick it off
1409
  this._create();
1410
 
1411
+ var isInitLayout = this._getOption('initLayout');
1412
+ if ( isInitLayout ) {
1413
  this.layout();
1414
  }
1415
  }
1423
  containerStyle: {
1424
  position: 'relative'
1425
  },
1426
+ initLayout: true,
1427
+ originLeft: true,
1428
+ originTop: true,
1429
+ resize: true,
1430
+ resizeContainer: true,
1431
  // item options
1432
  transitionDuration: '0.4s',
1433
  hiddenStyle: {
1440
  }
1441
  };
1442
 
1443
+ var proto = Outlayer.prototype;
1444
+ // inherit EvEmitter
1445
+ utils.extend( proto, EvEmitter.prototype );
1446
 
1447
  /**
1448
  * set options
1449
  * @param {Object} opts
1450
  */
1451
+ proto.option = function( opts ) {
1452
  utils.extend( this.options, opts );
1453
  };
1454
 
1455
+ /**
1456
+ * get backwards compatible option value, check old name
1457
+ */
1458
+ proto._getOption = function( option ) {
1459
+ var oldOption = this.constructor.compatOptions[ option ];
1460
+ return oldOption && this.options[ oldOption ] !== undefined ?
1461
+ this.options[ oldOption ] : this.options[ option ];
1462
+ };
1463
+
1464
+ Outlayer.compatOptions = {
1465
+ // currentName: oldName
1466
+ initLayout: 'isInitLayout',
1467
+ horizontal: 'isHorizontal',
1468
+ layoutInstant: 'isLayoutInstant',
1469
+ originLeft: 'isOriginLeft',
1470
+ originTop: 'isOriginTop',
1471
+ resize: 'isResizeBound',
1472
+ resizeContainer: 'isResizingContainer'
1473
+ };
1474
+
1475
+ proto._create = function() {
1476
  // get items from children
1477
  this.reloadItems();
1478
  // elements that affect layout, but are not laid out
1482
  utils.extend( this.element.style, this.options.containerStyle );
1483
 
1484
  // bind resize method
1485
+ var canBindResize = this._getOption('resize');
1486
+ if ( canBindResize ) {
1487
  this.bindResize();
1488
  }
1489
  };
1490
 
1491
  // goes through all children again and gets bricks in proper order
1492
+ proto.reloadItems = function() {
1493
  // collection of item elements
1494
  this.items = this._itemize( this.element.children );
1495
  };
1500
  * @param {Array or NodeList or HTMLElement} elems
1501
  * @returns {Array} items - collection of new Outlayer Items
1502
  */
1503
+ proto._itemize = function( elems ) {
1504
 
1505
  var itemElems = this._filterFindItemElements( elems );
1506
  var Item = this.constructor.Item;
1507
 
1508
  // create new Outlayer Items for collection
1509
  var items = [];
1510
+ for ( var i=0; i < itemElems.length; i++ ) {
1511
  var elem = itemElems[i];
1512
  var item = new Item( elem, this );
1513
  items.push( item );
1521
  * @param {Array or NodeList or HTMLElement} elems
1522
  * @returns {Array} items - item elements
1523
  */
1524
+ proto._filterFindItemElements = function( elems ) {
1525
  return utils.filterFindElements( elems, this.options.itemSelector );
1526
  };
1527
 
1529
  * getter method for getting item elements
1530
  * @returns {Array} elems - collection of item elements
1531
  */
1532
+ proto.getItemElements = function() {
1533
+ return this.items.map( function( item ) {
1534
+ return item.element;
1535
+ });
 
 
1536
  };
1537
 
1538
  // ----- init & layout ----- //
1540
  /**
1541
  * lays out all items
1542
  */
1543
+ proto.layout = function() {
1544
  this._resetLayout();
1545
  this._manageStamps();
1546
 
1547
  // don't animate first layout
1548
+ var layoutInstant = this._getOption('layoutInstant');
1549
+ var isInstant = layoutInstant !== undefined ?
1550
+ layoutInstant : !this._isLayoutInited;
1551
  this.layoutItems( this.items, isInstant );
1552
 
1553
  // flag for initalized
1555
  };
1556
 
1557
  // _init is alias for layout
1558
+ proto._init = proto.layout;
1559
 
1560
  /**
1561
  * logic before any new layout
1562
  */
1563
+ proto._resetLayout = function() {
1564
  this.getSize();
1565
  };
1566
 
1567
 
1568
+ proto.getSize = function() {
1569
  this.size = getSize( this.element );
1570
  };
1571
 
1579
  * @param {String} size - width or height
1580
  * @private
1581
  */
1582
+ proto._getMeasurement = function( measurement, size ) {
1583
  var option = this.options[ measurement ];
1584
  var elem;
1585
  if ( !option ) {
1587
  this[ measurement ] = 0;
1588
  } else {
1589
  // use option as an element
1590
+ if ( typeof option == 'string' ) {
1591
  elem = this.element.querySelector( option );
1592
+ } else if ( option instanceof HTMLElement ) {
1593
  elem = option;
1594
  }
1595
  // use size of element, if element
1601
  * layout a collection of item elements
1602
  * @api public
1603
  */
1604
+ proto.layoutItems = function( items, isInstant ) {
1605
  items = this._getItemsForLayout( items );
1606
 
1607
  this._layoutItems( items, isInstant );
1615
  * @param {Array} items
1616
  * @returns {Array} items
1617
  */
1618
+ proto._getItemsForLayout = function( items ) {
1619
+ return items.filter( function( item ) {
1620
+ return !item.isIgnored;
1621
+ });
 
 
 
 
 
1622
  };
1623
 
1624
  /**
1626
  * @param {Array} items
1627
  * @param {Boolean} isInstant
1628
  */
1629
+ proto._layoutItems = function( items, isInstant ) {
1630
  this._emitCompleteOnItems( 'layout', items );
1631
 
1632
  if ( !items || !items.length ) {
1636
 
1637
  var queue = [];
1638
 
1639
+ items.forEach( function( item ) {
 
1640
  // get x/y object from method
1641
  var position = this._getItemLayoutPosition( item );
1642
  // enqueue
1643
  position.item = item;
1644
  position.isInstant = isInstant || item.isLayoutInstant;
1645
  queue.push( position );
1646
+ }, this );
1647
 
1648
  this._processLayoutQueue( queue );
1649
  };
1653
  * @param {Outlayer.Item} item
1654
  * @returns {Object} x and y position
1655
  */
1656
+ proto._getItemLayoutPosition = function( /* item */ ) {
1657
  return {
1658
  x: 0,
1659
  y: 0
1666
  * thx @paul_irish
1667
  * @param {Array} queue
1668
  */
1669
+ proto._processLayoutQueue = function( queue ) {
1670
+ this.updateStagger();
1671
+ queue.forEach( function( obj, i ) {
1672
+ this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i );
1673
+ }, this );
1674
+ };
1675
+
1676
+ // set stagger from option in milliseconds number
1677
+ proto.updateStagger = function() {
1678
+ var stagger = this.options.stagger;
1679
+ if ( stagger === null || stagger === undefined ) {
1680
+ this.stagger = 0;
1681
+ return;
1682
  }
1683
+ this.stagger = getMilliseconds( stagger );
1684
+ return this.stagger;
1685
  };
1686
 
1687
  /**
1691
  * @param {Number} y - vertical position
1692
  * @param {Boolean} isInstant - disables transitions
1693
  */
1694
+ proto._positionItem = function( item, x, y, isInstant, i ) {
1695
  if ( isInstant ) {
1696
  // if not transition, just set CSS
1697
  item.goTo( x, y );
1698
  } else {
1699
+ item.stagger( i * this.stagger );
1700
  item.moveTo( x, y );
1701
  }
1702
  };
1705
  * Any logic you want to do after each layout,
1706
  * i.e. size the container
1707
  */
1708
+ proto._postLayout = function() {
1709
  this.resizeContainer();
1710
  };
1711
 
1712
+ proto.resizeContainer = function() {
1713
+ var isResizingContainer = this._getOption('resizeContainer');
1714
+ if ( !isResizingContainer ) {
1715
  return;
1716
  }
1717
  var size = this._getContainerSize();
1727
  * @param {Number} width
1728
  * @param {Number} height
1729
  */
1730
+ proto._getContainerSize = noop;
1731
 
1732
  /**
1733
  * @param {Number} measure - size of width or height
1734
  * @param {Boolean} isWidth
1735
  */
1736
+ proto._setContainerMeasure = function( measure, isWidth ) {
1737
  if ( measure === undefined ) {
1738
  return;
1739
  }
1756
  * @param {String} eventName
1757
  * @param {Array} items - Outlayer.Items
1758
  */
1759
+ proto._emitCompleteOnItems = function( eventName, items ) {
1760
  var _this = this;
1761
  function onComplete() {
1762
  _this.dispatchEvent( eventName + 'Complete', null, [ items ] );
1771
  var doneCount = 0;
1772
  function tick() {
1773
  doneCount++;
1774
+ if ( doneCount == count ) {
1775
  onComplete();
1776
  }
1777
  }
1778
 
1779
  // bind callback
1780
+ items.forEach( function( item ) {
 
1781
  item.once( eventName, tick );
1782
+ });
1783
  };
1784
 
1785
  /**
1786
+ * emits events via EvEmitter and jQuery events
1787
  * @param {String} type - name of event
1788
  * @param {Event} event - original event
1789
  * @param {Array} args - extra arguments
1790
  */
1791
+ proto.dispatchEvent = function( type, event, args ) {
1792
  // add original event to arguments
1793
  var emitArgs = event ? [ event ].concat( args ) : args;
1794
  this.emitEvent( type, emitArgs );
1816
  * ignored items do not get skipped in layout
1817
  * @param {Element} elem
1818
  */
1819
+ proto.ignore = function( elem ) {
1820
  var item = this.getItem( elem );
1821
  if ( item ) {
1822
  item.isIgnored = true;
1827
  * return item to layout collection
1828
  * @param {Element} elem
1829
  */
1830
+ proto.unignore = function( elem ) {
1831
  var item = this.getItem( elem );
1832
  if ( item ) {
1833
  delete item.isIgnored;
1838
  * adds elements to stamps
1839
  * @param {NodeList, Array, Element, or String} elems
1840
  */
1841
+ proto.stamp = function( elems ) {
1842
  elems = this._find( elems );
1843
  if ( !elems ) {
1844
  return;
1846
 
1847
  this.stamps = this.stamps.concat( elems );
1848
  // ignore
1849
+ elems.forEach( this.ignore, this );
 
 
 
1850
  };
1851
 
1852
  /**
1853
  * removes elements to stamps
1854
  * @param {NodeList, Array, or Element} elems
1855
  */
1856
+ proto.unstamp = function( elems ) {
1857
  elems = this._find( elems );
1858
  if ( !elems ){
1859
  return;
1860
  }
1861
 
1862
+ elems.forEach( function( elem ) {
 
1863
  // filter out removed stamp elements
1864
  utils.removeFrom( this.stamps, elem );
1865
  this.unignore( elem );
1866
+ }, this );
 
1867
  };
1868
 
1869
  /**
1871
  * @param {NodeList, Array, Element, or String} elems
1872
  * @returns {Array} elems
1873
  */
1874
+ proto._find = function( elems ) {
1875
  if ( !elems ) {
1876
  return;
1877
  }
1878
  // if string, use argument as selector string
1879
+ if ( typeof elems == 'string' ) {
1880
  elems = this.element.querySelectorAll( elems );
1881
  }
1882
  elems = utils.makeArray( elems );
1883
  return elems;
1884
  };
1885
 
1886
+ proto._manageStamps = function() {
1887
  if ( !this.stamps || !this.stamps.length ) {
1888
  return;
1889
  }
1890
 
1891
  this._getBoundingRect();
1892
 
1893
+ this.stamps.forEach( this._manageStamp, this );
 
 
 
1894
  };
1895
 
1896
  // update boundingLeft / Top
1897
+ proto._getBoundingRect = function() {
1898
  // get bounding rect for container element
1899
  var boundingRect = this.element.getBoundingClientRect();
1900
  var size = this.size;
1909
  /**
1910
  * @param {Element} stamp
1911
  **/
1912
+ proto._manageStamp = noop;
1913
 
1914
  /**
1915
  * get x/y position of element relative to container element
1916
  * @param {Element} elem
1917
  * @returns {Object} offset - has left, top, right, bottom
1918
  */
1919
+ proto._getElementOffset = function( elem ) {
1920
  var boundingRect = elem.getBoundingClientRect();
1921
  var thisRect = this._boundingRect;
1922
  var size = getSize( elem );
1933
 
1934
  // enable event handlers for listeners
1935
  // i.e. resize -> onresize
1936
+ proto.handleEvent = utils.handleEvent;
 
 
 
 
 
1937
 
1938
  /**
1939
  * Bind layout to window resizing
1940
  */
1941
+ proto.bindResize = function() {
1942
+ window.addEventListener( 'resize', this );
 
 
 
 
1943
  this.isResizeBound = true;
1944
  };
1945
 
1946
  /**
1947
  * Unbind layout to window resizing
1948
  */
1949
+ proto.unbindResize = function() {
1950
+ window.removeEventListener( 'resize', this );
 
 
1951
  this.isResizeBound = false;
1952
  };
1953
 
1954
+ proto.onresize = function() {
1955
+ this.resize();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1956
  };
1957
 
1958
+ utils.debounceMethod( Outlayer, 'onresize', 100 );
1959
+
1960
+ proto.resize = function() {
1961
  // don't trigger if size did not change
1962
  // or if resize was unbound. See #9
1963
  if ( !this.isResizeBound || !this.needsResizeLayout() ) {
1971
  * check if layout is needed post layout
1972
  * @returns Boolean
1973
  */
1974
+ proto.needsResizeLayout = function() {
1975
  var size = getSize( this.element );
1976
  // check that this.size and size are there
1977
  // IE8 triggers resize on body size change, so they might not be
1986
  * @param {Array or NodeList or Element} elems
1987
  * @returns {Array} items - Outlayer.Items
1988
  **/
1989
+ proto.addItems = function( elems ) {
1990
  var items = this._itemize( elems );
1991
  // add items to collection
1992
  if ( items.length ) {
1999
  * Layout newly-appended item elements
2000
  * @param {Array or NodeList or Element} elems
2001
  */
2002
+ proto.appended = function( elems ) {
2003
  var items = this.addItems( elems );
2004
  if ( !items.length ) {
2005
  return;
2013
  * Layout prepended elements
2014
  * @param {Array or NodeList or Element} elems
2015
  */
2016
+ proto.prepended = function( elems ) {
2017
  var items = this._itemize( elems );
2018
  if ( !items.length ) {
2019
  return;
2035
  * reveal a collection of items
2036
  * @param {Array of Outlayer.Items} items
2037
  */
2038
+ proto.reveal = function( items ) {
2039
  this._emitCompleteOnItems( 'reveal', items );
2040
+ if ( !items || !items.length ) {
2041
+ return;
 
 
 
2042
  }
2043
+ var stagger = this.updateStagger();
2044
+ items.forEach( function( item, i ) {
2045
+ item.stagger( i * stagger );
2046
+ item.reveal();
2047
+ });
2048
  };
2049
 
2050
  /**
2051
  * hide a collection of items
2052
  * @param {Array of Outlayer.Items} items
2053
  */
2054
+ proto.hide = function( items ) {
2055
  this._emitCompleteOnItems( 'hide', items );
2056
+ if ( !items || !items.length ) {
2057
+ return;
 
 
 
2058
  }
2059
+ var stagger = this.updateStagger();
2060
+ items.forEach( function( item, i ) {
2061
+ item.stagger( i * stagger );
2062
+ item.hide();
2063
+ });
2064
  };
2065
 
2066
  /**
2067
  * reveal item elements
2068
  * @param {Array}, {Element}, {NodeList} items
2069
  */
2070
+ proto.revealItemElements = function( elems ) {
2071
  var items = this.getItems( elems );
2072
  this.reveal( items );
2073
  };
2076
  * hide item elements
2077
  * @param {Array}, {Element}, {NodeList} items
2078
  */
2079
+ proto.hideItemElements = function( elems ) {
2080
  var items = this.getItems( elems );
2081
  this.hide( items );
2082
  };
2087
  * @param {Function} callback
2088
  * @returns {Outlayer.Item} item
2089
  */
2090
+ proto.getItem = function( elem ) {
2091
  // loop through items to get the one that matches
2092
+ for ( var i=0; i < this.items.length; i++ ) {
2093
  var item = this.items[i];
2094
+ if ( item.element == elem ) {
2095
  // return item
2096
  return item;
2097
  }
2103
  * @param {Array} elems
2104
  * @returns {Array} items - Outlayer.Items
2105
  */
2106
+ proto.getItems = function( elems ) {
2107
  elems = utils.makeArray( elems );
2108
  var items = [];
2109
+ elems.forEach( function( elem ) {
 
2110
  var item = this.getItem( elem );
2111
  if ( item ) {
2112
  items.push( item );
2113
  }
2114
+ }, this );
2115
 
2116
  return items;
2117
  };
2120
  * remove element(s) from instance and DOM
2121
  * @param {Array or NodeList or Element} elems
2122
  */
2123
+ proto.remove = function( elems ) {
2124
  var removeItems = this.getItems( elems );
2125
 
2126
  this._emitCompleteOnItems( 'remove', removeItems );
2130
  return;
2131
  }
2132
 
2133
+ removeItems.forEach( function( item ) {
 
2134
  item.remove();
2135
  // remove item from collection
2136
  utils.removeFrom( this.items, item );
2137
+ }, this );
2138
  };
2139
 
2140
  // ----- destroy ----- //
2141
 
2142
  // remove and disable Outlayer instance
2143
+ proto.destroy = function() {
2144
  // clean up dynamic styles
2145
  var style = this.element.style;
2146
  style.height = '';
2147
  style.position = '';
2148
  style.width = '';
2149
  // destroy items
2150
+ this.items.forEach( function( item ) {
 
2151
  item.destroy();
2152
+ });
2153
 
2154
  this.unbindResize();
2155
 
2185
  */
2186
  Outlayer.create = function( namespace, options ) {
2187
  // sub-class Outlayer
2188
+ var Layout = subclass( Outlayer );
2189
+ // apply new options and compatOptions
 
 
 
 
 
 
 
 
 
 
2190
  Layout.defaults = utils.extend( {}, Outlayer.defaults );
 
2191
  utils.extend( Layout.defaults, options );
2192
+ Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions );
 
2193
 
2194
  Layout.namespace = namespace;
2195
 
2196
  Layout.data = Outlayer.data;
2197
 
2198
  // sub-class Item
2199
+ Layout.Item = subclass( Item );
 
 
 
 
2200
 
2201
  // -------------------------- declarative -------------------------- //
2202
 
2212
  return Layout;
2213
  };
2214
 
2215
+ function subclass( Parent ) {
2216
+ function SubClass() {
2217
+ Parent.apply( this, arguments );
2218
+ }
2219
+
2220
+ SubClass.prototype = Object.create( Parent.prototype );
2221
+ SubClass.prototype.constructor = SubClass;
2222
+
2223
+ return SubClass;
2224
+ }
2225
+
2226
+ // ----- helpers ----- //
2227
+
2228
+ // how many milliseconds are in each unit
2229
+ var msUnits = {
2230
+ ms: 1,
2231
+ s: 1000
2232
+ };
2233
+
2234
+ // munge time-like parameter into millisecond number
2235
+ // '0.4s' -> 40
2236
+ function getMilliseconds( time ) {
2237
+ if ( typeof time == 'number' ) {
2238
+ return time;
2239
+ }
2240
+ var matches = time.match( /(^\d*\.?\d*)(\w*)/ );
2241
+ var num = matches && matches[1];
2242
+ var unit = matches && matches[2];
2243
+ if ( !num.length ) {
2244
+ return 0;
2245
+ }
2246
+ num = parseFloat( num );
2247
+ var mult = msUnits[ unit ] || 1;
2248
+ return num * mult;
2249
+ }
2250
+
2251
  // ----- fin ----- //
2252
 
2253
  // back in global
2257
 
2258
  }));
2259
 
 
2260
  /**
2261
  * Enviratope Item
2262
  **/
2263
 
2264
  ( function( window, factory ) {
 
2265
  // universal module definition
2266
+ /* jshint strict: false */ /*globals define, module, require */
2267
  if ( typeof define == 'function' && define.amd ) {
2268
  // AMD
2269
+ define( 'enviratope/item',[
2270
  'outlayer/outlayer'
2271
  ],
2272
  factory );
2273
+ } else if ( typeof module == 'object' && module.exports ) {
2274
  // CommonJS
2275
  module.exports = factory(
2276
  require('outlayer')
2293
  Outlayer.Item.apply( this, arguments );
2294
  }
2295
 
2296
+ var proto = Item.prototype = Object.create( Outlayer.Item.prototype );
2297
 
2298
+ var _create = proto._create;
2299
+ proto._create = function() {
2300
  // assign id, used for original-order sorting
2301
  this.id = this.layout.itemGUID++;
2302
+ _create.call( this );
2303
  this.sortData = {};
2304
  };
2305
 
2306
+ proto.updateSortData = function() {
2307
  if ( this.isIgnored ) {
2308
  return;
2309
  }
2321
  }
2322
  };
2323
 
2324
+ var _destroy = proto.destroy;
2325
+ proto.destroy = function() {
2326
  // call super
2327
  _destroy.apply( this, arguments );
2328
  // reset display, #741
2340
  */
2341
 
2342
  ( function( window, factory ) {
 
2343
  // universal module definition
2344
+ /* jshint strict: false */ /*globals define, module, require */
2345
  if ( typeof define == 'function' && define.amd ) {
2346
  // AMD
2347
+ define( 'enviratope/layout-mode',[
2348
  'get-size/get-size',
2349
  'outlayer/outlayer'
2350
  ],
2351
  factory );
2352
+ } else if ( typeof module == 'object' && module.exports ) {
2353
  // CommonJS
2354
  module.exports = factory(
2355
  require('get-size'),
2379
  }
2380
  }
2381
 
2382
+ var proto = LayoutMode.prototype;
2383
+
2384
  /**
2385
  * some methods should just defer to default Outlayer method
2386
  * and reference the Enviratope instance as `this`
2387
  **/
2388
+ var facadeMethods = [
2389
+ '_resetLayout',
2390
+ '_getItemLayoutPosition',
2391
+ '_manageStamp',
2392
+ '_getContainerSize',
2393
+ '_getElementOffset',
2394
+ 'needsResizeLayout',
2395
+ '_getOption'
2396
+ ];
2397
+
2398
+ facadeMethods.forEach( function( methodName ) {
2399
+ proto[ methodName ] = function() {
2400
+ return Outlayer.prototype[ methodName ].apply( this.enviratope, arguments );
2401
+ };
2402
+ });
 
 
 
 
 
 
2403
 
2404
  // ----- ----- //
2405
 
2406
  // for horizontal layout modes, check vertical size
2407
+ proto.needsVerticalResizeLayout = function() {
2408
  // don't trigger if size did not change
2409
  var size = getSize( this.enviratope.element );
2410
  // check that this.size and size are there
2415
 
2416
  // ----- measurements ----- //
2417
 
2418
+ proto._getMeasurement = function() {
2419
  this.enviratope._getMeasurement.apply( this, arguments );
2420
  };
2421
 
2422
+ proto.getColumnWidth = function() {
2423
  this.getSegmentSize( 'column', 'Width' );
2424
  };
2425
 
2426
+ proto.getRowHeight = function() {
2427
  this.getSegmentSize( 'row', 'Height' );
2428
  };
2429
 
2432
  * segment: 'column' or 'row'
2433
  * size 'Width' or 'Height'
2434
  **/
2435
+ proto.getSegmentSize = function( segment, size ) {
2436
  var segmentName = segment + size;
2437
  var outerSize = 'outer' + size;
2438
  // columnWidth / outerWidth // rowHeight / outerHeight
2448
  this.enviratope.size[ 'inner' + size ];
2449
  };
2450
 
2451
+ proto.getFirstItemSize = function() {
2452
  var firstItem = this.enviratope.filteredItems[0];
2453
  return firstItem && firstItem.element && getSize( firstItem.element );
2454
  };
2455
 
2456
  // ----- methods that should reference enviratope ----- //
2457
 
2458
+ proto.layout = function() {
2459
  this.enviratope.layout.apply( this.enviratope, arguments );
2460
  };
2461
 
2462
+ proto.getSize = function() {
2463
  this.enviratope.getSize();
2464
  this.size = this.enviratope.size;
2465
  };
2474
  LayoutMode.apply( this, arguments );
2475
  }
2476
 
2477
+ Mode.prototype = Object.create( proto );
2478
+ Mode.prototype.constructor = Mode;
2479
 
2480
  // default options
2481
  if ( options ) {
2494
  }));
2495
 
2496
  /*!
2497
+ * Masonry v4.1.0
2498
  * Cascading grid layout library
2499
  * http://masonry.desandro.com
2500
  * MIT License
2502
  */
2503
 
2504
  ( function( window, factory ) {
 
2505
  // universal module definition
2506
+ /* jshint strict: false */ /*globals define, module, require */
2507
+ if ( typeof define == 'function' && define.amd ) {
2508
  // AMD
2509
  define( 'masonry/masonry',[
2510
  'outlayer/outlayer',
2511
+ 'get-size/get-size'
 
2512
  ],
2513
  factory );
2514
+ } else if ( typeof module == 'object' && module.exports ) {
2515
  // CommonJS
2516
  module.exports = factory(
2517
  require('outlayer'),
2518
+ require('get-size')
 
2519
  );
2520
  } else {
2521
  // browser global
2522
  window.Masonry = factory(
2523
  window.Outlayer,
2524
+ window.getSize
 
2525
  );
2526
  }
2527
 
2528
+ }( window, function factory( Outlayer, getSize ) {
2529
 
2530
 
2531
 
2533
 
2534
  // create an Outlayer layout class
2535
  var Masonry = Outlayer.create('masonry');
2536
+ // isFitWidth -> fitWidth
2537
+ Masonry.compatOptions.fitWidth = 'isFitWidth';
2538
 
2539
  Masonry.prototype._resetLayout = function() {
2540
  this.getSize();
2543
  this.measureColumns();
2544
 
2545
  // reset column Y
 
2546
  this.colYs = [];
2547
+ for ( var i=0; i < this.cols; i++ ) {
2548
  this.colYs.push( 0 );
2549
  }
2550
 
2578
 
2579
  Masonry.prototype.getContainerWidth = function() {
2580
  // container is parent if fit width
2581
+ var isFitWidth = this._getOption('fitWidth');
2582
+ var container = isFitWidth ? this.element.parentNode : this.element;
2583
  // check that this.size and size are there
2584
  // IE8 triggers resize on body size change, so they might not be
2585
  var size = getSize( container );
2598
  var colGroup = this._getColGroup( colSpan );
2599
  // get the minimum Y value from the columns
2600
  var minimumY = Math.min.apply( Math, colGroup );
2601
+ var shortColIndex = colGroup.indexOf( minimumY );
2602
 
2603
  // position the brick
2604
  var position = {
2643
  var stampSize = getSize( stamp );
2644
  var offset = this._getElementOffset( stamp );
2645
  // get the columns that this stamp affects
2646
+ var isOriginLeft = this._getOption('originLeft');
2647
+ var firstX = isOriginLeft ? offset.left : offset.right;
2648
  var lastX = firstX + stampSize.outerWidth;
2649
  var firstCol = Math.floor( firstX / this.columnWidth );
2650
  firstCol = Math.max( 0, firstCol );
2653
  lastCol -= lastX % this.columnWidth ? 0 : 1;
2654
  lastCol = Math.min( this.cols - 1, lastCol );
2655
  // set colYs to bottom of the stamp
2656
+
2657
+ var isOriginTop = this._getOption('originTop');
2658
+ var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) +
2659
  stampSize.outerHeight;
2660
  for ( var i = firstCol; i <= lastCol; i++ ) {
2661
  this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
2668
  height: this.maxY
2669
  };
2670
 
2671
+ if ( this._getOption('fitWidth') ) {
2672
  size.width = this._getContainerFitWidth();
2673
  }
2674
 
2692
  Masonry.prototype.needsResizeLayout = function() {
2693
  var previousWidth = this.containerWidth;
2694
  this.getContainerWidth();
2695
+ return previousWidth != this.containerWidth;
2696
  };
2697
 
2698
  return Masonry;
2706
  */
2707
 
2708
  ( function( window, factory ) {
 
2709
  // universal module definition
2710
+ /* jshint strict: false */ /*globals define, module, require */
2711
  if ( typeof define == 'function' && define.amd ) {
2712
  // AMD
2713
+ define( 'enviratope/layout-modes/masonry',[
2714
  '../layout-mode',
2715
  'masonry/masonry'
2716
  ],
2717
  factory );
2718
+ } else if ( typeof module == 'object' && module.exports ) {
2719
  // CommonJS
2720
  module.exports = factory(
2721
  require('../layout-mode'),
2732
  }( window, function factory( LayoutMode, Masonry ) {
2733
  'use strict';
2734
 
 
 
 
 
 
 
 
 
 
 
2735
  // -------------------------- masonryDefinition -------------------------- //
2736
 
2737
  // create an Outlayer layout class
2738
  var MasonryMode = LayoutMode.create('masonry');
2739
 
2740
+ var proto = MasonryMode.prototype;
 
 
 
2741
 
2742
+ var keepModeMethods = {
2743
+ _getElementOffset: true,
2744
+ layout: true,
2745
+ _getMeasurement: true
2746
+ };
2747
 
2748
+ // inherit Masonry prototype
2749
+ for ( var method in Masonry.prototype ) {
2750
+ // do not inherit mode methods
2751
+ if ( !keepModeMethods[ method ] ) {
2752
+ proto[ method ] = Masonry.prototype[ method ];
2753
+ }
2754
+ }
2755
 
2756
+ var measureColumns = proto.measureColumns;
2757
+ proto.measureColumns = function() {
2758
  // set items, used if measuring first item
2759
  this.items = this.enviratope.filteredItems;
2760
  measureColumns.call( this );
2761
  };
2762
 
2763
+ // point to mode options for fitWidth
2764
+ var _getOption = proto._getOption;
2765
+ proto._getOption = function( option ) {
2766
+ if ( option == 'fitWidth' ) {
2767
+ return this.options.isFitWidth !== undefined ?
2768
+ this.options.isFitWidth : this.options.fitWidth;
2769
+ }
2770
+ return _getOption.apply( this.enviratope, arguments );
2771
  };
2772
 
2773
  return MasonryMode;
2779
  */
2780
 
2781
  ( function( window, factory ) {
 
2782
  // universal module definition
2783
+ /* jshint strict: false */ /*globals define, module, require */
2784
  if ( typeof define == 'function' && define.amd ) {
2785
  // AMD
2786
+ define( 'enviratope/layout-modes/fit-rows',[
2787
  '../layout-mode'
2788
  ],
2789
  factory );
2804
 
2805
  var FitRows = LayoutMode.create('fitRows');
2806
 
2807
+ var proto = FitRows.prototype;
2808
+
2809
+ proto._resetLayout = function() {
2810
  this.x = 0;
2811
  this.y = 0;
2812
  this.maxY = 0;
2813
  this._getMeasurement( 'gutter', 'outerWidth' );
2814
  };
2815
 
2816
+ proto._getItemLayoutPosition = function( item ) {
2817
  item.getSize();
2818
 
2819
  var itemWidth = item.size.outerWidth + this.gutter;
2835
  return position;
2836
  };
2837
 
2838
+ proto._getContainerSize = function() {
2839
  return { height: this.maxY };
2840
  };
2841
 
2848
  */
2849
 
2850
  ( function( window, factory ) {
 
2851
  // universal module definition
2852
+ /* jshint strict: false */ /*globals define, module, require */
2853
  if ( typeof define == 'function' && define.amd ) {
2854
  // AMD
2855
+ define( 'enviratope/layout-modes/vertical',[
2856
  '../layout-mode'
2857
  ],
2858
  factory );
2859
+ } else if ( typeof module == 'object' && module.exports ) {
2860
  // CommonJS
2861
  module.exports = factory(
2862
  require('../layout-mode')
2875
  horizontalAlignment: 0
2876
  });
2877
 
2878
+ var proto = Vertical.prototype;
2879
+
2880
+ proto._resetLayout = function() {
2881
  this.y = 0;
2882
  };
2883
 
2884
+ proto._getItemLayoutPosition = function( item ) {
2885
  item.getSize();
2886
  var x = ( this.enviratope.size.innerWidth - item.size.outerWidth ) *
2887
  this.options.horizontalAlignment;
2890
  return { x: x, y: y };
2891
  };
2892
 
2893
+ proto._getContainerSize = function() {
2894
  return { height: this.y };
2895
  };
2896
 
2899
  }));
2900
 
2901
  /*!
2902
+ * Enviratope v3.0.0
2903
  *
2904
  * Licensed GPLv3 for open source use
2905
  * or Enviratope Commercial License for commercial use
2906
  *
2907
  * http://enviratope.metafizzy.co
2908
+ * Copyright 2016 Metafizzy
2909
  */
2910
 
2911
  ( function( window, factory ) {
 
2912
  // universal module definition
2913
+ /* jshint strict: false */ /*globals define, module, require */
2914
  if ( typeof define == 'function' && define.amd ) {
2915
  // AMD
2916
  define( [
2917
  'outlayer/outlayer',
2918
  'get-size/get-size',
2919
+ 'desandro-matches-selector/matches-selector',
2920
  'fizzy-ui-utils/utils',
2921
+ './item',
2922
+ './layout-mode',
2923
  // include default layout modes
2924
+ './layout-modes/masonry',
2925
+ './layout-modes/fit-rows',
2926
+ './layout-modes/vertical'
2927
  ],
2928
  function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) {
2929
  return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode );
2930
  });
2931
+ } else if ( typeof module == 'object' && module.exports ) {
2932
  // CommonJS
2933
  module.exports = factory(
2934
  window,
2975
  return str.replace( /^\s+|\s+$/g, '' );
2976
  };
2977
 
 
 
 
 
 
 
 
 
 
 
2978
  // -------------------------- enviratopeDefinition -------------------------- //
2979
 
2980
  // create an Outlayer layout class
2981
  var Enviratope = Outlayer.create( 'enviratope', {
2982
+ layoutMode: 'masonry',
2983
  isJQueryFiltering: true,
2984
  sortAscending: true
2985
  });
2987
  Enviratope.Item = Item;
2988
  Enviratope.LayoutMode = LayoutMode;
2989
 
2990
+ var proto = Enviratope.prototype;
2991
+
2992
+ proto._create = function() {
2993
  this.itemGUID = 0;
2994
  // functions that sort items
2995
  this._sorters = {};
3009
  }
3010
  };
3011
 
3012
+ proto.reloadItems = function() {
3013
  // reset item ID counter
3014
  this.itemGUID = 0;
3015
  // call super
3016
  Outlayer.prototype.reloadItems.call( this );
3017
  };
3018
 
3019
+ proto._itemize = function() {
3020
  var items = Outlayer.prototype._itemize.apply( this, arguments );
3021
  // assign ID for original-order
3022
+ for ( var i=0; i < items.length; i++ ) {
3023
  var item = items[i];
3024
  item.id = this.itemGUID++;
3025
  }
3030
 
3031
  // -------------------------- layout -------------------------- //
3032
 
3033
+ proto._initLayoutMode = function( name ) {
3034
  var Mode = LayoutMode.modes[ name ];
3035
  // set mode options
3036
  // HACK extend initial options, back-fill in default options
3042
  };
3043
 
3044
 
3045
+ proto.layout = function() {
3046
  // if first time doing layout, do all magic
3047
+ if ( !this._isLayoutInited && this._getOption('initLayout') ) {
3048
  this.arrange();
3049
  return;
3050
  }
3052
  };
3053
 
3054
  // private method to be used in layout() & magic()
3055
+ proto._layout = function() {
3056
  // don't animate first layout
3057
  var isInstant = this._getIsInstant();
3058
  // layout flow
3065
  };
3066
 
3067
  // filter + sort + layout
3068
+ proto.arrange = function( opts ) {
3069
  // set any options pass
3070
  this.option( opts );
3071
  this._getIsInstant();
3075
  var filtered = this._filter( this.items );
3076
  this.filteredItems = filtered.matches;
3077
 
 
 
 
 
 
 
3078
  this._bindArrangeComplete();
3079
 
3080
  if ( this._isInstant ) {
3081
+ this._noTransition( this._hideReveal, [ filtered ] );
3082
  } else {
3083
+ this._hideReveal( filtered );
3084
  }
3085
 
3086
  this._sort();
3087
  this._layout();
3088
  };
3089
  // alias to _init for main plugin method
3090
+ proto._init = proto.arrange;
3091
+
3092
+ proto._hideReveal = function( filtered ) {
3093
+ this.reveal( filtered.needReveal );
3094
+ this.hide( filtered.needHide );
3095
+ };
3096
 
3097
  // HACK
3098
  // Don't animate/transition first layout
3099
  // Or don't animate/transition other layouts
3100
+ proto._getIsInstant = function() {
3101
+ var isLayoutInstant = this._getOption('layoutInstant');
3102
+ var isInstant = isLayoutInstant !== undefined ? isLayoutInstant :
3103
+ !this._isLayoutInited;
3104
  this._isInstant = isInstant;
3105
  return isInstant;
3106
  };
3107
 
3108
  // listen for layoutComplete, hideComplete and revealComplete
3109
  // to trigger arrangeComplete
3110
+ proto._bindArrangeComplete = function() {
3111
  // listen for 3 events to trigger arrangeComplete
3112
  var isLayoutComplete, isHideComplete, isRevealComplete;
3113
  var _this = this;
3132
 
3133
  // -------------------------- filter -------------------------- //
3134
 
3135
+ proto._filter = function( items ) {
3136
  var filter = this.options.filter;
3137
  filter = filter || '*';
3138
  var matches = [];
3142
  var test = this._getFilterTest( filter );
3143
 
3144
  // test each item
3145
+ for ( var i=0; i < items.length; i++ ) {
3146
  var item = items[i];
3147
  if ( item.isIgnored ) {
3148
  continue;
3171
  };
3172
 
3173
  // get a jQuery, function, or a matchesSelector test given the filter
3174
+ proto._getFilterTest = function( filter ) {
3175
  if ( jQuery && this.options.isJQueryFiltering ) {
3176
  // use jQuery
3177
  return function( item ) {
3196
  * @params {Array} elems
3197
  * @public
3198
  */
3199
+ proto.updateSortData = function( elems ) {
3200
  // get items
3201
  var items;
3202
  if ( elems ) {
3211
  this._updateItemsSortData( items );
3212
  };
3213
 
3214
+ proto._getSorters = function() {
3215
  var getSortData = this.options.getSortData;
3216
  for ( var key in getSortData ) {
3217
  var sorter = getSortData[ key ];
3223
  * @params {Array} items - of Enviratope.Items
3224
  * @private
3225
  */
3226
+ proto._updateItemsSortData = function( items ) {
3227
  // do not update if no items
3228
  var len = items && items.length;
3229
 
3271
 
3272
  // get an attribute getter, or get text of the querySelector
3273
  function getValueGetter( attr, query ) {
 
3274
  // if query looks like [foo-bar], get attribute
3275
  if ( attr ) {
3276
+ return function getAttribute( elem ) {
3277
  return elem.getAttribute( attr );
3278
  };
 
 
 
 
 
 
3279
  }
3280
+
3281
+ // otherwise, assume its a querySelector, and get its text
3282
+ return function getChildText( elem ) {
3283
+ var child = elem.querySelector( query );
3284
+ return child && child.textContent;
3285
+ };
3286
  }
3287
 
3288
  return mungeSorter;
3301
  // ----- sort method ----- //
3302
 
3303
  // sort filteredItem order
3304
+ proto._sort = function() {
3305
  var sortByOpt = this.options.sortBy;
3306
  if ( !sortByOpt ) {
3307
  return;
3322
  function getItemSorter( sortBys, sortAsc ) {
3323
  return function sorter( itemA, itemB ) {
3324
  // cycle through all sortKeys
3325
+ for ( var i = 0; i < sortBys.length; i++ ) {
3326
  var sortBy = sortBys[i];
3327
  var a = itemA.sortData[ sortBy ];
3328
  var b = itemB.sortData[ sortBy ];
3340
  // -------------------------- methods -------------------------- //
3341
 
3342
  // get layout mode
3343
+ proto._mode = function() {
3344
  var layoutMode = this.options.layoutMode;
3345
  var mode = this.modes[ layoutMode ];
3346
  if ( !mode ) {
3353
  return mode;
3354
  };
3355
 
3356
+ proto._resetLayout = function() {
3357
  // trigger original reset layout
3358
  Outlayer.prototype._resetLayout.call( this );
3359
  this._mode()._resetLayout();
3360
  };
3361
 
3362
+ proto._getItemLayoutPosition = function( item ) {
3363
  return this._mode()._getItemLayoutPosition( item );
3364
  };
3365
 
3366
+ proto._manageStamp = function( stamp ) {
3367
  this._mode()._manageStamp( stamp );
3368
  };
3369
 
3370
+ proto._getContainerSize = function() {
3371
  return this._mode()._getContainerSize();
3372
  };
3373
 
3374
+ proto.needsResizeLayout = function() {
3375
  return this._mode().needsResizeLayout();
3376
  };
3377
 
3378
  // -------------------------- adding & removing -------------------------- //
3379
 
3380
  // HEADS UP overwrites default Outlayer appended
3381
+ proto.appended = function( elems ) {
3382
  var items = this.addItems( elems );
3383
  if ( !items.length ) {
3384
  return;
3390
  };
3391
 
3392
  // HEADS UP overwrites default Outlayer prepended
3393
+ proto.prepended = function( elems ) {
3394
  var items = this._itemize( elems );
3395
  if ( !items.length ) {
3396
  return;
3407
  this.items = items.concat( this.items );
3408
  };
3409
 
3410
+ proto._filterRevealAdded = function( items ) {
3411
  var filtered = this._filter( items );
3412
  this.hide( filtered.needHide );
3413
  // reveal all new items
3421
  * Filter, sort, and layout newly-appended item elements
3422
  * @param {Array or NodeList or Element} elems
3423
  */
3424
+ proto.insert = function( elems ) {
3425
  var items = this.addItems( elems );
3426
  if ( !items.length ) {
3427
  return;
3447
  this.reveal( filteredInsertItems );
3448
  };
3449
 
3450
+ var _remove = proto.remove;
3451
+ proto.remove = function( elems ) {
3452
  elems = utils.makeArray( elems );
3453
  var removeItems = this.getItems( elems );
3454
  // do regular thing
3455
  _remove.call( this, elems );
3456
  // bail if no items to remove
3457
  var len = removeItems && removeItems.length;
 
 
 
3458
  // remove elems from filteredItems
3459
+ for ( var i=0; len && i < len; i++ ) {
3460
  var item = removeItems[i];
3461
  // remove item from collection
3462
  utils.removeFrom( this.filteredItems, item );
3463
  }
3464
  };
3465
 
3466
+ proto.shuffle = function() {
3467
  // update random sortData
3468
+ for ( var i=0; i < this.items.length; i++ ) {
3469
  var item = this.items[i];
3470
  item.sortData.random = Math.random();
3471
  }
3478
  * trigger fn without transition
3479
  * kind of hacky to have this in the first place
3480
  * @param {Function} fn
3481
+ * @param {Array} args
3482
  * @returns ret
3483
  * @private
3484
  */
3485
+ proto._noTransition = function( fn, args ) {
3486
  // save transitionDuration before disabling
3487
  var transitionDuration = this.options.transitionDuration;
3488
  // disable transition
3489
  this.options.transitionDuration = 0;
3490
  // do it
3491
+ var returnValue = fn.apply( this, args );
3492
  // re-enable transition for reveal
3493
  this.options.transitionDuration = transitionDuration;
3494
  return returnValue;
3500
  * getter method for getting filtered item elements
3501
  * @returns {Array} elems - collection of item elements
3502
  */
3503
+ proto.getFilteredItemElements = function() {
3504
+ return this.filteredItems.map( function( item ) {
3505
+ return item.element;
3506
+ });
 
 
3507
  };
3508
 
3509
  // ----- ----- //
3510
 
3511
  return Enviratope;
3512
 
3513
+ }));
assets/js/lib/jquery.easing.js ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // t: current time, b: begInnIng value, c: change In value, d: duration
2
+ jQuery.easing['jswing'] = jQuery.easing['swing'];
3
+
4
+ jQuery.extend( jQuery.easing,
5
+ {
6
+ def: 'easeOutQuad',
7
+ swing: function (x, t, b, c, d) {
8
+ //alert(jQuery.easing.default);
9
+ return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
10
+ },
11
+ easeInQuad: function (x, t, b, c, d) {
12
+ return c*(t/=d)*t + b;
13
+ },
14
+ easeOutQuad: function (x, t, b, c, d) {
15
+ return -c *(t/=d)*(t-2) + b;
16
+ },
17
+ easeInOutQuad: function (x, t, b, c, d) {
18
+ if ((t/=d/2) < 1) return c/2*t*t + b;
19
+ return -c/2 * ((--t)*(t-2) - 1) + b;
20
+ },
21
+ easeInCubic: function (x, t, b, c, d) {
22
+ return c*(t/=d)*t*t + b;
23
+ },
24
+ easeOutCubic: function (x, t, b, c, d) {
25
+ return c*((t=t/d-1)*t*t + 1) + b;
26
+ },
27
+ easeInOutCubic: function (x, t, b, c, d) {
28
+ if ((t/=d/2) < 1) return c/2*t*t*t + b;
29
+ return c/2*((t-=2)*t*t + 2) + b;
30
+ },
31
+ easeInQuart: function (x, t, b, c, d) {
32
+ return c*(t/=d)*t*t*t + b;
33
+ },
34
+ easeOutQuart: function (x, t, b, c, d) {
35
+ return -c * ((t=t/d-1)*t*t*t - 1) + b;
36
+ },
37
+ easeInOutQuart: function (x, t, b, c, d) {
38
+ if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
39
+ return -c/2 * ((t-=2)*t*t*t - 2) + b;
40
+ },
41
+ easeInQuint: function (x, t, b, c, d) {
42
+ return c*(t/=d)*t*t*t*t + b;
43
+ },
44
+ easeOutQuint: function (x, t, b, c, d) {
45
+ return c*((t=t/d-1)*t*t*t*t + 1) + b;
46
+ },
47
+ easeInOutQuint: function (x, t, b, c, d) {
48
+ if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
49
+ return c/2*((t-=2)*t*t*t*t + 2) + b;
50
+ },
51
+ easeInSine: function (x, t, b, c, d) {
52
+ return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
53
+ },
54
+ easeOutSine: function (x, t, b, c, d) {
55
+ return c * Math.sin(t/d * (Math.PI/2)) + b;
56
+ },
57
+ easeInOutSine: function (x, t, b, c, d) {
58
+ return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
59
+ },
60
+ easeInExpo: function (x, t, b, c, d) {
61
+ return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
62
+ },
63
+ easeOutExpo: function (x, t, b, c, d) {
64
+ return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
65
+ },
66
+ easeInOutExpo: function (x, t, b, c, d) {
67
+ if (t==0) return b;
68
+ if (t==d) return b+c;
69
+ if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
70
+ return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
71
+ },
72
+ easeInCirc: function (x, t, b, c, d) {
73
+ return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
74
+ },
75
+ easeOutCirc: function (x, t, b, c, d) {
76
+ return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
77
+ },
78
+ easeInOutCirc: function (x, t, b, c, d) {
79
+ if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
80
+ return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
81
+ },
82
+ easeInElastic: function (x, t, b, c, d) {
83
+ var s=1.70158;var p=0;var a=c;
84
+ if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
85
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
86
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
87
+ return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
88
+ },
89
+ easeOutElastic: function (x, t, b, c, d) {
90
+ var s=1.70158;var p=0;var a=c;
91
+ if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
92
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
93
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
94
+ return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
95
+ },
96
+ easeInOutElastic: function (x, t, b, c, d) {
97
+ var s=1.70158;var p=0;var a=c;
98
+ if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
99
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
100
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
101
+ if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
102
+ return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
103
+ },
104
+ easeInBack: function (x, t, b, c, d, s) {
105
+ if (s == undefined) s = 1.70158;
106
+ return c*(t/=d)*t*((s+1)*t - s) + b;
107
+ },
108
+ easeOutBack: function (x, t, b, c, d, s) {
109
+ if (s == undefined) s = 1.70158;
110
+ return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
111
+ },
112
+ easeInOutBack: function (x, t, b, c, d, s) {
113
+ if (s == undefined) s = 1.70158;
114
+ if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
115
+ return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
116
+ },
117
+ easeInBounce: function (x, t, b, c, d) {
118
+ return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
119
+ },
120
+ easeOutBounce: function (x, t, b, c, d) {
121
+ if ((t/=d) < (1/2.75)) {
122
+ return c*(7.5625*t*t) + b;
123
+ } else if (t < (2/2.75)) {
124
+ return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
125
+ } else if (t < (2.5/2.75)) {
126
+ return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
127
+ } else {
128
+ return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
129
+ }
130
+ },
131
+ easeInOutBounce: function (x, t, b, c, d) {
132
+ if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
133
+ return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
134
+ }
135
+ });
assets/js/media-edit.js CHANGED
@@ -149,10 +149,8 @@ var EnviraGalleryEditView = wp.Backbone.View.extend( {
149
  QTags._buttonsInit();
150
  }, 500 );
151
 
152
- // Init Link Searching on Captions, if Captions enabled
153
- if ( typeof wpLink !== 'undefined' ) {
154
- wpLink.init;
155
- }
156
 
157
  // Enable / disable the buttons depending on the index
158
  if ( this.attachment_index == 0 ) {
@@ -270,7 +268,7 @@ var EnviraGalleryEditView = wp.Backbone.View.extend( {
270
 
271
  // Update the model's value, depending on the input type
272
  if ( event.target.type == 'checkbox' ) {
273
- value = ( event.target.checked ? 1 : 0 );
274
  } else {
275
  value = event.target.value;
276
  }
149
  QTags._buttonsInit();
150
  }, 500 );
151
 
152
+ // Init Link Searching
153
+ wpLink.init;
 
 
154
 
155
  // Enable / disable the buttons depending on the index
156
  if ( this.attachment_index == 0 ) {
268
 
269
  // Update the model's value, depending on the input type
270
  if ( event.target.type == 'checkbox' ) {
271
+ value = ( event.target.checked ? event.target.value : 0 );
272
  } else {
273
  value = event.target.value;
274
  }
assets/js/media-manage.js CHANGED
@@ -12,10 +12,131 @@ var envira_gallery_output = '#envira-gallery-output',
12
  envira_gallery_last_selected_image = false;
13
 
14
  jQuery( document ).ready( function( $ ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
  // Enable sortable functionality on images
17
  envira_gallery_sortable( $ );
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  } );
20
 
21
  /**
12
  envira_gallery_last_selected_image = false;
13
 
14
  jQuery( document ).ready( function( $ ) {
15
+
16
+ // Toggle List / Grid View
17
+ $( document ).on( 'click', 'nav.envira-tab-options a', function( e ) {
18
+
19
+ e.preventDefault();
20
+
21
+ // Get the view the user has chosen
22
+ var envira_tab_nav = $( this ).closest( '.envira-tab-options' ),
23
+ envira_tab_view = $( this ).data( 'view' ),
24
+ envira_tab_view_style = $( this ).data( 'view-style' );
25
+
26
+ // If this view style is already displayed, don't do anything
27
+ if ( $( envira_tab_view ).hasClass( envira_tab_view_style ) ) {
28
+ return;
29
+ }
30
+
31
+ // Update the view class
32
+ $( envira_tab_view ).removeClass( 'list' ).removeClass( 'grid' ).addClass( envira_tab_view_style );
33
+
34
+ // Mark the current view icon as selected
35
+ $( 'a', envira_tab_nav ).removeClass( 'selected' );
36
+ $( this ).addClass( 'selected' );
37
+
38
+ // Send an AJAX request to store this user's preference for the view
39
+ // This means when they add or edit any other Gallery, the image view will default to this setting
40
+ $.ajax( {
41
+ url: envira_gallery_metabox.ajax,
42
+ type: 'post',
43
+ dataType: 'json',
44
+ data: {
45
+ action: 'envira_gallery_set_user_setting',
46
+ name: 'envira_gallery_image_view',
47
+ value: envira_tab_view_style,
48
+ nonce: envira_gallery_metabox.set_user_setting_nonce
49
+ },
50
+ success: function( response ) {
51
+ },
52
+ error: function( xhr, textStatus, e ) {
53
+ // Inject the error message into the tab settings area
54
+ $( envira_gallery_output ).before( '<div class="error"><p>' + textStatus.responseText + '</p></div>' );
55
+ }
56
+ } );
57
+
58
+ } );
59
+
60
+ // Toggle Select All / Deselect All
61
+ $( document ).on( 'change', 'nav.envira-tab-options input', function( e ) {
62
+
63
+ if ( $( this ).prop( 'checked' ) ) {
64
+ $( 'li', $( envira_gallery_output ) ).addClass( 'selected' );
65
+ $( 'nav.envira-select-options' ).fadeIn();
66
+ } else {
67
+ $( 'li', $( envira_gallery_output ) ).removeClass( 'selected' );
68
+ $( 'nav.envira-select-options' ).fadeOut();
69
+ }
70
+
71
+ } );
72
 
73
  // Enable sortable functionality on images
74
  envira_gallery_sortable( $ );
75
 
76
+ // When the Gallery Type is changed, reinitialise the sortable
77
+ $( document ).on( 'enviraGalleryType', function() {
78
+
79
+ if ( $( envira_gallery_output ).length > 0 ) {
80
+ // Re-enable sortable functionality on images, now we're viewing the default gallery type
81
+ envira_gallery_sortable( $ );
82
+ }
83
+
84
+ } );
85
+
86
+ // Select / deselect images
87
+ $( document ).on( 'click', 'ul#envira-gallery-output li.envira-gallery-image > img, li.envira-gallery-image > div, li.envira-gallery-image > a.check', function( e ) {
88
+
89
+ // Prevent default action
90
+ e.preventDefault();
91
+
92
+ // Get the selected gallery item
93
+ var gallery_item = $( this ).parent();
94
+
95
+ if ( $( gallery_item ).hasClass( 'selected' ) ) {
96
+ $( gallery_item ).removeClass( 'selected' );
97
+ envira_gallery_last_selected_image = false;
98
+ } else {
99
+
100
+ // If the shift key is being held down, and there's another image selected, select every image between this clicked image
101
+ // and the other selected image
102
+ if ( envira_gallery_shift_key_pressed && envira_gallery_last_selected_image !== false ) {
103
+ // Get index of the selected image and the last image
104
+ var start_index = $( 'ul#envira-gallery-output li' ).index( $( envira_gallery_last_selected_image ) ),
105
+ end_index = $( 'ul#envira-gallery-output li' ).index( $( gallery_item ) ),
106
+ i = 0;
107
+
108
+ // Select images within the range
109
+ if ( start_index < end_index ) {
110
+ for ( i = start_index; i <= end_index; i++ ) {
111
+ $( 'ul#envira-gallery-output li:eq( ' + i + ')' ).addClass( 'selected' );
112
+ }
113
+ } else {
114
+ for ( i = end_index; i <= start_index; i++ ) {
115
+ $( 'ul#envira-gallery-output li:eq( ' + i + ')' ).addClass( 'selected' );
116
+ }
117
+ }
118
+ }
119
+
120
+ // Select the clicked image
121
+ $( gallery_item ).addClass( 'selected' );
122
+ envira_gallery_last_selected_image = $( gallery_item );
123
+
124
+ }
125
+
126
+ // Show/hide buttons depending on whether
127
+ // any galleries have been selected
128
+ if ( $( 'ul#envira-gallery-output > li.selected' ).length > 0 ) {
129
+ $( 'nav.envira-select-options' ).fadeIn();
130
+ } else {
131
+ $( 'nav.envira-select-options' ).fadeOut();
132
+ }
133
+ } );
134
+
135
+ // Determine whether the shift key is pressed or not
136
+ $( document ).on( 'keyup keydown', function( e ) {
137
+ envira_gallery_shift_key_pressed = e.shiftKey;
138
+ } );
139
+
140
  } );
141
 
142
  /**
assets/js/media-upload.js CHANGED
@@ -13,11 +13,21 @@
13
  $( 'input#plupload-browse-button' ).val( envira_gallery_metabox.uploader_files_computer );
14
 
15
  // Set a custom progress bar
16
- $( '#envira-gallery .drag-drop-inside' ).append( '<div class="envira-progress-bar"><div></div></div>' );
17
  var envira_bar = $( '#envira-gallery .envira-progress-bar' ),
18
- envira_progress = $( '#envira-gallery .envira-progress-bar div' ),
19
- envira_output = $( '#envira-gallery-output'),
20
- envira_error = $( '#envira-gallery-upload-error' );
 
 
 
 
 
 
 
 
 
 
 
21
 
22
  // Files Added for Uploading
23
  uploader.bind( 'FilesAdded', function ( up, files ) {
@@ -25,6 +35,15 @@
25
  // Hide any existing errors
26
  $( envira_error ).html( '' );
27
 
 
 
 
 
 
 
 
 
 
28
  // Fade in the upload progress bar
29
  $( envira_bar ).fadeIn();
30
 
@@ -32,9 +51,15 @@
32
 
33
  // File Uploading - show progress bar
34
  uploader.bind( 'UploadProgress', function( up, file ) {
 
 
 
 
 
35
  $( envira_progress ).css({
36
  'width': up.total.percent + '%'
37
  });
 
38
  });
39
 
40
  // File Uploaded - AJAX call to process image and add to screen.
@@ -73,8 +98,14 @@
73
  // Files Uploaded
74
  uploader.bind( 'UploadComplete', function() {
75
 
 
 
 
 
76
  // Hide Progress Bar
77
- $( envira_bar ).fadeOut();
 
 
78
 
79
  });
80
 
13
  $( 'input#plupload-browse-button' ).val( envira_gallery_metabox.uploader_files_computer );
14
 
15
  // Set a custom progress bar
 
16
  var envira_bar = $( '#envira-gallery .envira-progress-bar' ),
17
+ envira_progress = $( '#envira-gallery .envira-progress-bar div.envira-progress-bar-inner' ),
18
+ envira_status = $( '#envira-gallery .envira-progress-bar div.envira-progress-bar-status' ),
19
+ envira_output = $( '#envira-gallery-output' ),
20
+ envira_error = $( '#envira-gallery-upload-error' ),
21
+ envira_file_count = 0;
22
+
23
+ // Uploader has initialized
24
+ uploader.bind( 'Init', function( up ) {
25
+
26
+ // Fade in the uploader, as it's hidden with CSS so the user doesn't see elements reposition on screen and look messy.
27
+ $( '#drag-drop-area' ).fadeIn();
28
+ $( 'a.envira-media-library.button' ).fadeIn();
29
+
30
+ } );
31
 
32
  // Files Added for Uploading
33
  uploader.bind( 'FilesAdded', function ( up, files ) {
35
  // Hide any existing errors
36
  $( envira_error ).html( '' );
37
 
38
+ // Get the number of files to be uploaded
39
+ envira_file_count = files.length;
40
+
41
+ // Set the status text, to tell the user what's happening
42
+ $( '.uploading .current', $( envira_status ) ).text( '1' );
43
+ $( '.uploading .total', $( envira_status ) ).text( envira_file_count );
44
+ $( '.uploading', $( envira_status ) ).show();
45
+ $( '.done', $( envira_status ) ).hide();
46
+
47
  // Fade in the upload progress bar
48
  $( envira_bar ).fadeIn();
49
 
51
 
52
  // File Uploading - show progress bar
53
  uploader.bind( 'UploadProgress', function( up, file ) {
54
+
55
+ // Update the status text
56
+ $( '.uploading .current', $( envira_status ) ).text( ( envira_file_count - up.total.queued ) + 1 );
57
+
58
+ // Update the progress bar
59
  $( envira_progress ).css({
60
  'width': up.total.percent + '%'
61
  });
62
+
63
  });
64
 
65
  // File Uploaded - AJAX call to process image and add to screen.
98
  // Files Uploaded
99
  uploader.bind( 'UploadComplete', function() {
100
 
101
+ // Update status
102
+ $( '.uploading', $( envira_status ) ).hide();
103
+ $( '.done', $( envira_status ) ).show();
104
+
105
  // Hide Progress Bar
106
+ setTimeout( function() {
107
+ $( envira_bar ).fadeOut();
108
+ }, 1000 );
109
 
110
  });
111
 
assets/js/metabox.js CHANGED
@@ -3,10 +3,34 @@
3
  * the following JS files into min/metabox-min.js:
4
  *
5
  * - conditional-fields.js
 
 
6
  * - gallery-help.js
 
7
  * - media-delete.js
8
  * - media-edit.js
9
  * - media-insert.js
10
  * - media-manage.js
 
11
  * - media-upload.js
12
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  * the following JS files into min/metabox-min.js:
4
  *
5
  * - conditional-fields.js
6
+ * - gallery-preview.js
7
+ * - gallery-types.js
8
  * - gallery-help.js
9
+ * - media-bulk-edit.js
10
  * - media-delete.js
11
  * - media-edit.js
12
  * - media-insert.js
13
  * - media-manage.js
14
+ * - media-move.js
15
  * - media-upload.js
16
+ */
17
+
18
+ jQuery( document ).ready( function( $ ) {
19
+
20
+ // Image Size: Random
21
+ // conditional-fields doesn't support multiple conditions, so we manually show/hide
22
+ // the Random Image Sizes option depending on the Image Size value
23
+ $( 'select[name="_envira_gallery[image_size]"]' ).on( 'change', function() {
24
+
25
+ if ( $( this ).val() == 'envira_gallery_random' ) {
26
+ $( 'tr#envira-config-image-sizes-random-box' ).show();
27
+ } else {
28
+ $( 'tr#envira-config-image-sizes-random-box' ).hide();
29
+ }
30
+
31
+ } );
32
+
33
+ // Run the above conditions on load.
34
+ $( 'select[name="_envira_gallery[image_size]"]' ).trigger( 'change' );
35
+
36
+ } );
assets/js/min/admin-min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function($){if("undefined"!=typeof Clipboard){var i=new Clipboard(".envira-clipboard");$(document).on("click",".envira-clipboard",function(i){i.preventDefault()})}$("div.envira-notice").on("click",".notice-dismiss",function(i){i.preventDefault(),$(this).closest("div.envira-notice").fadeOut(),$(this).hasClass("is-dismissible")&&$.post(envira_gallery_admin.ajax,{action:"envira_gallery_ajax_dismiss_notice",nonce:envira_gallery_admin.dismiss_notice_nonce,notice:$(this).parent().data("notice")},function(i){},"json")})});
1
+ jQuery(document).ready(function($){if($("#screen-meta-links").prependTo("#envira-header-temp"),$("#screen-meta").prependTo("#envira-header-temp"),"undefined"!=typeof Clipboard){var e=new Clipboard(".envira-clipboard");$(document).on("click",".envira-clipboard",function(e){e.preventDefault()})}$("div.envira-notice").on("click",".notice-dismiss",function(e){e.preventDefault(),$(this).closest("div.envira-notice").fadeOut(),$(this).hasClass("is-dismissible")&&$.post(envira_gallery_admin.ajax,{action:"envira_gallery_ajax_dismiss_notice",nonce:envira_gallery_admin.dismiss_notice_nonce,notice:$(this).parent().data("notice")},function(e){},"json")})});
assets/js/min/conditional-fields-min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(document).ready(function($){$("input, select").conditional({data:"envira-conditional",value:"envira-conditional-value",displayOnEnabled:"envira-conditional-display"})}),function($){"use strict";$.fn.conditional=function(t){var a=$.extend({data:"conditional",value:"conditional-value",displayOnEnabled:"conditional-display"},t);return this.each(function(){if("undefined"==typeof $(this).data(a.data))return!0;var t,i,n,e;$(this).on("change",function(){switch(t=$(this).data(a.data).split(","),i=$(this).data(a.displayOnEnabled),"undefined"==typeof i&&(i=!0),n=$(this).data(a.value),"undefined"==typeof n&&(n=""),e=!1,$(this).attr("type")){case"checkbox":e=i?$(this).is(":checked"):$(this).is(":checked")?!1:!0;break;default:e=i?""!==n?String($(this).val())!==String(n)?!1:!0:""===$(this).val()||"0"===$(this).val()?!1:!0:""!==n?$(this).val()!==n?!0:!1:""===$(this).val()||"0"===$(this).val()?!0:!1}for(var d=0;d<t.length;d++)e?$("#"+t[d]).fadeIn(300):$("#"+t[d]).fadeOut(300)}),$(this).trigger("change")}),this}}(jQuery);
assets/js/min/editor-min.js CHANGED
@@ -1 +1 @@
1
- if("undefined"==typeof EnviraGalleryModalWindow)var EnviraGalleryModalWindow=new wp.media.view.Modal({controller:{trigger:function(){}}});wp.media.view.EnviraGalleryError=wp.Backbone.View.extend({tagName:"div",className:"notice error envira-gallery-error",render:function(){return this.template=wp.media.template("envira-gallery-error"),this.$el.html(this.template(this.model)),this}});var EnviraGallerySelectionItemView=wp.Backbone.View.extend({tagName:"li",className:"attachment",template:wp.template("envira-selection-item"),initialize:function(e){this.model=e.model},render:function(){return this.$el.html(this.template(this.model.attributes)),this}}),EnviraGallerySelectionView=wp.Backbone.View.extend({tagName:"div",className:"media-frame mode-select wp-core-ui hide-router hide-menu",template:wp.template("envira-selection"),events:{"click .attachment":"click",keyup:"search",search:"search","click button.media-button-insert":"insert"},initialize:function(e){this.action=e.action,this.selection=new Backbone.Collection,this.collection=new Backbone.Collection,this.is_loading=!1,this.search_timeout=!1,this.on("loading",this.loading,this),this.on("loaded",this.loaded,this),this.getItems(!1,"")},click:function(e){var i=jQuery(e.currentTarget),t=jQuery("div.attachment-preview",i).attr("data-id");i.hasClass("selected")?this.removeFromSelection(i,t):this.addToSelection(i,t)},search:function(e){if(!this.is_loading){clearTimeout(this.search_timeout);var i=e.target.value;if(0==i.length)return void this.getItems(!1,"");if(!(i.length<3)){var t=this;this.search_timeout=setTimeout(function(){t.getItems(!0,i)},1e3)}}},getItems:function(e,i){if(!this.is_loading){this.clearSelection(),this.$el.find("ul.attachments").empty(),this.$el.find("div.envira-gallery-error").remove(),this.trigger("loading");var t="";switch(this.action){case"gallery":t="envira_gallery_editor_get_galleries";break;case"album":t="envira_albums_editor_get_albums"}wp.media.ajax(t,{context:this,data:{nonce:envira_gallery_editor.get_galleries_nonce,search:e,search_terms:i},success:function(e){var i=new Backbone.Collection(e);this.collection.reset(),this.collection.add(i.models),this.collection.each(function(e){var i=new EnviraGallerySelectionItemView({model:e});this.$el.find("ul.attachments").append(i.render().el)},this),this.trigger("loaded")},error:function(e){this.trigger("loaded",e)}})}},render:function(){return this.$el.html(this.template()),this},renderError:function(e){var i={};i.error=e;var t=new wp.media.view.EnviraGalleryError({model:i});return t.render().el},loading:function(){this.is_loading=!0,this.$el.find(".spinner").css("visibility","visible")},loaded:function(e){this.is_loading=!1,this.$el.find(".spinner").css("visibility","hidden"),"undefined"!=typeof e&&this.$el.find("ul.attachments").before(this.renderError(e))},addToSelection:function(e,i){this.trigger("loading"),this.collection.each(function(e){e.get("id")==i&&this.selection.add(e)},this),e.addClass("selected details"),this.selection.length>0&&this.$el.find("button.media-button-insert").attr("disabled",!1),this.trigger("loaded")},removeFromSelection:function(e,i){this.trigger("loading"),this.selection.each(function(e){this.selection.remove([{cid:e.cid}])},this),e.removeClass("selected details"),0==this.selection.length&&this.$el.find("button.media-button-insert").attr("disabled","disabled"),this.trigger("loaded")},clearSelection:function(){this.selection.each(function(e){this.$el.find('div[data-id="'+e.get("id")+'"]').parent().removeClass("selected details")},this),this.$el.find("button.media-button-insert").attr("disabled","disabled"),this.selection.reset()},insert:function(){this.trigger("loading"),this.selection.forEach(function(e){wp.media.editor.insert("[envira-"+this.action+' id="'+e.id+'"]')},this),this.trigger("loaded"),EnviraGalleryModalWindow.close()}});jQuery(document).ready(function($){$(document).on("click","a.envira-gallery-choose-gallery, a.envira-albums-choose-album",function(e){e.preventDefault();var i=$(this).data("action");EnviraGalleryModalWindow.content(new EnviraGallerySelectionView({action:i})),EnviraGalleryModalWindow.open()})});
1
+ jQuery(document).ready(function($){$(document).on("click","a.envira-gallery-choose-gallery, a.envira-albums-choose-album, .envira-gallery-modal-trigger",function(e){e.preventDefault();var a=$(this).data("action");EnviraGalleryModalWindow.content(new EnviraGallerySelectionView({action:a,multiple:!0,modal_title:envira_gallery_editor.modal_title,insert_button_label:envira_gallery_editor.insert_button_label})),EnviraGalleryModalWindow.open()})});
assets/js/min/envira-min.js CHANGED
@@ -1,3 +1,3 @@
1
- !function(t,e,$,i){"use strict";var n=$("html"),o=$(t),r=$(e),s=$.envirabox=function(){s.open.apply(this,arguments)},a=navigator.userAgent.match(/msie/i),u=null,l=e.createTouch!==i,h=function(t){return t&&t.hasOwnProperty&&t instanceof $},p=function(t){return t&&"string"===$.type(t)},c=function(t){return p(t)&&t.indexOf("%")>0},d=function(t){return t&&!(t.style.overflow&&"hidden"===t.style.overflow)&&(t.clientWidth&&t.scrollWidth>t.clientWidth||t.clientHeight&&t.scrollHeight>t.clientHeight)},f=function(t,e){var i=parseInt(t,10)||0;return e&&c(t)&&(i=s.getViewport()[e]/100*i),Math.ceil(i)},m=function(t,e){return f(t,e)+"px"};$.extend(s,{version:"2.1.5",defaults:{padding:15,margin:40,width:800,height:600,minWidth:100,minHeight:100,maxWidth:9999,maxHeight:9999,pixelRatio:1,autoSize:!0,autoHeight:!1,autoWidth:!1,autoResize:!0,autoCenter:!l,fitToView:!0,aspectRatio:!1,topRatio:.5,leftRatio:.5,scrolling:"auto",wrapCSS:"",arrows:!0,closeBtn:!0,closeClick:!1,nextClick:!1,mouseWheel:!0,autoPlay:!1,playSpeed:3e3,preload:3,modal:!1,loop:!0,ajax:{dataType:"html",headers:{"X-envirabox":!0}},iframe:{scrolling:"auto",preload:!0},swf:{wmode:"transparent",allowfullscreen:"true",allowscriptaccess:"always"},keys:{next:{13:"left",34:"up",39:"left",40:"up"},prev:{8:"right",33:"down",37:"right",38:"down"},close:[27],play:[32],toggle:[70]},direction:{next:"left",prev:"right"},scrollOutside:!0,index:0,type:null,href:null,content:null,title:null,tpl:{wrap:'<div class="envirabox-wrap" tabIndex="-1"><div class="envirabox-skin"><div class="envirabox-outer"><div class="envirabox-inner"></div></div></div></div>',image:'<img class="envirabox-image" src="{href}" />',iframe:'<iframe id="envirabox-frame{rnd}" name="envirabox-frame{rnd}" class="envirabox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen'+(a?' allowtransparency="true"':"")+"></iframe>",error:'<p class="envirabox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',closeBtn:'<a title="Close" class="envirabox-item envirabox-close" href="javascript:;"></a>',next:'<a title="Next" class="envirabox-nav envirabox-next" href="javascript:;"><span></span></a>',prev:'<a title="Previous" class="envirabox-nav envirabox-prev" href="javascript:;"><span></span></a>'},openEffect:"fade",openSpeed:250,openEasing:"swing",openOpacity:!0,openMethod:"zoomIn",closeEffect:"fade",closeSpeed:250,closeEasing:"swing",closeOpacity:!0,closeMethod:"zoomOut",nextEffect:"elastic",nextSpeed:250,nextEasing:"swing",nextMethod:"changeIn",prevEffect:"elastic",prevSpeed:250,prevEasing:"swing",prevMethod:"changeOut",helpers:{overlay:!0,title:!0},onCancel:$.noop,beforeLoad:$.noop,afterLoad:$.noop,beforeShow:$.noop,afterShow:$.noop,beforeChange:$.noop,beforeClose:$.noop,afterClose:$.noop},group:{},opts:{},previous:null,coming:null,current:null,isActive:!1,isOpen:!1,isOpened:!1,wrap:null,skin:null,outer:null,inner:null,player:{timer:null,isActive:!1},ajaxLoad:null,imgPreload:null,transitions:{},helpers:{},open:function(t,e){return t&&($.isPlainObject(e)||(e={}),!1!==s.close(!0))?($.isArray(t)||(t=h(t)?$(t).get():[t]),$.each(t,function(n,o){var r={},a,u,l,c,d,f,m;"object"===$.type(o)&&(o.nodeType&&(o=$(o)),h(o)?(r={href:o.data("envirabox-href")||o.attr("href"),title:$("<div/>").text(o.data("envirabox-title")||o.attr("title")).html(),isDom:!0,element:o},$.metadata&&$.extend(!0,r,o.metadata())):r=o),a=e.href||r.href||(p(o)?o:null),u=e.title!==i?e.title:r.title||"",l=e.content||r.content,c=l?"html":e.type||r.type,!c&&r.isDom&&(c=o.data("envirabox-type"),c||(d=o.prop("class").match(/envirabox\.(\w+)/),c=d?d[1]:null)),p(a)&&(c||(s.isImage(a)?c="image":s.isSWF(a)?c="swf":"#"===a.charAt(0)?c="inline":p(o)&&(c="html",l=o)),"ajax"===c&&(f=a.split(/\s+/,2),a=f.shift(),m=f.shift())),l||("inline"===c?a?l=$(p(a)?a.replace(/.*(?=#[^\s]+$)/,""):a):r.isDom&&(l=o):"html"===c?l=a:c||a||!r.isDom||(c="inline",l=o)),$.extend(r,{href:a,type:c,content:l,title:u,selector:m}),t[n]=r}),s.opts=$.extend(!0,{},s.defaults,e),e.keys!==i&&(s.opts.keys=e.keys?$.extend({},s.defaults.keys,e.keys):!1),s.group=t,s._start(s.opts.index)):void 0},cancel:function(){var t=s.coming;t&&!1===s.trigger("onCancel")||(s.hideLoading(),t&&(s.ajaxLoad&&s.ajaxLoad.abort(),s.ajaxLoad=null,s.imgPreload&&(s.imgPreload.onload=s.imgPreload.onerror=null),t.wrap&&t.wrap.stop(!0,!0).trigger("onReset").remove(),s.coming=null,s.current||s._afterZoomOut(t)))},close:function(t){s.cancel(),!1!==s.trigger("beforeClose")&&(s.unbindEvents(),s.isActive&&(s.isOpen&&t!==!0?(s.isOpen=s.isOpened=!1,s.isClosing=!0,$(".envirabox-item, .envirabox-nav").remove(),s.wrap.stop(!0,!0).removeClass("envirabox-opened"),s.transitions[s.current.closeMethod]()):($(".envirabox-wrap").stop(!0).trigger("onReset").remove(),s._afterZoomOut())))},play:function(t){var e=function(){clearTimeout(s.player.timer)},i=function(){e(),s.current&&s.player.isActive&&(s.player.timer=setTimeout(s.next,s.current.playSpeed))},n=function(){e(),r.unbind(".player"),s.player.isActive=!1,s.trigger("onPlayEnd")},o=function(){s.current&&(s.current.loop||s.current.index<s.group.length-1)&&(s.player.isActive=!0,r.bind({"onCancel.player beforeClose.player":n,"onUpdate.player":i,"beforeLoad.player":e}),i(),s.trigger("onPlayStart"))};t===!0||!s.player.isActive&&t!==!1?o():n()},next:function(t){var e=s.current;e&&(p(t)||(t=e.direction.next),s.jumpto(e.index+1,t,"next"))},prev:function(t){var e=s.current;e&&(p(t)||(t=e.direction.prev),s.jumpto(e.index-1,t,"prev"))},jumpto:function(t,e,n){var o=s.current;o&&(t=f(t),s.direction=e||o.direction[t>=o.index?"next":"prev"],s.router=n||"jumpto",o.loop&&(0>t&&(t=o.group.length+t%o.group.length),t%=o.group.length),o.group[t]!==i&&(s.cancel(),s._start(t)))},reposition:function(t,e){var i=s.current,n=i?i.wrap:null,o;n&&(o=s._getPosition(e),t&&"scroll"===t.type?(delete o.position,n.stop(!0,!0).animate(o,200)):(n.css(o),i.pos=$.extend({},i.dim,o)))},update:function(t){var e=t&&t.originalEvent&&t.originalEvent.type,i=!e||"orientationchange"===e;i&&(clearTimeout(u),u=null),s.isOpen&&!u&&(u=setTimeout(function(){var n=s.current;n&&!s.isClosing&&(s.wrap.removeClass("envirabox-tmp"),(i||"load"===e||"resize"===e&&n.autoResize)&&s._setDimension(),"scroll"===e&&n.canShrink||s.reposition(t),s.trigger("onUpdate"),u=null)},i&&!l?0:300))},toggle:function(t){s.isOpen&&(s.current.fitToView="boolean"===$.type(t)?t:!s.current.fitToView,l&&(s.wrap.removeAttr("style").addClass("envirabox-tmp"),s.trigger("onUpdate")),s.update())},hideLoading:function(){r.unbind(".loading"),$("#envirabox-loading").remove()},showLoading:function(){var t,e;s.hideLoading(),t=$('<div id="envirabox-loading"><div></div></div>').click(s.cancel).appendTo("body"),r.bind("keydown.loading",function(t){27===(t.which||t.keyCode)&&(t.preventDefault(),s.cancel())}),s.defaults.fixed||(e=s.getViewport(),t.css({position:"absolute",top:.5*e.h+e.y,left:.5*e.w+e.x})),s.trigger("onLoading")},getViewport:function(){var e=s.current&&s.current.locked||!1,i={x:o.scrollLeft(),y:o.scrollTop()};return e&&e.length?(i.w=e[0].clientWidth,i.h=e[0].clientHeight):(i.w=l&&t.innerWidth?t.innerWidth:o.width(),i.h=l&&t.innerHeight?t.innerHeight:o.height()),i},unbindEvents:function(){s.wrap&&h(s.wrap)&&s.wrap.unbind(".fb"),r.unbind(".fb"),o.unbind(".fb")},bindEvents:function(){var t=s.current,e;t&&(o.bind("orientationchange.fb"+(l?"":" resize.fb")+(t.autoCenter&&!t.locked?" scroll.fb":""),s.update),e=t.keys,e&&r.bind("keydown.fb",function(n){var o=n.which||n.keyCode,r=n.target||n.srcElement;return 27===o&&s.coming?!1:void(n.ctrlKey||n.altKey||n.shiftKey||n.metaKey||r&&(r.type||$(r).is("[contenteditable]"))||$.each(e,function(e,r){return t.group.length>1&&r[o]!==i?(s[e](r[o]),n.preventDefault(),!1):$.inArray(o,r)>-1?(s[e](),n.preventDefault(),!1):void 0}))}),$.fn.mousewheel&&t.mouseWheel&&s.wrap.bind("mousewheel.fb",function(e,i,n,o){for(var r=e.target||null,a=$(r),u=!1;a.length&&!(u||a.is(".envirabox-skin")||a.is(".envirabox-wrap"));)u=d(a[0]),a=$(a).parent();0===i||u||s.group.length>1&&!t.canShrink&&(o>0||n>0?s.prev(o>0?"down":"left"):(0>o||0>n)&&s.next(0>o?"up":"right"),e.preventDefault())}))},trigger:function(t,e){var i,n=e||s.coming||s.current;if(n){if($.isFunction(n[t])&&(i=n[t].apply(n,Array.prototype.slice.call(arguments,1))),i===!1)return!1;n.helpers&&$.each(n.helpers,function(e,i){i&&s.helpers[e]&&$.isFunction(s.helpers[e][t])&&s.helpers[e][t]($.extend(!0,{},s.helpers[e].defaults,i),n)})}r.trigger(t)},isImage:function(t){return p(t)&&t.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i)},isSWF:function(t){return p(t)&&t.match(/\.(swf)((\?|#).*)?$/i)},_start:function(t){var e={},i,n,o,r,a;if(t=f(t),i=s.group[t]||null,!i)return!1;if(e=$.extend(!0,{},s.opts,i),r=e.margin,a=e.padding,"number"===$.type(r)&&(e.margin=[r,r,r,r]),"number"===$.type(a)&&(e.padding=[a,a,a,a]),e.modal&&$.extend(!0,e,{closeBtn:!1,closeClick:!1,nextClick:!1,arrows:!1,mouseWheel:!1,keys:null,helpers:{overlay:{closeClick:!1}}}),e.autoSize&&(e.autoWidth=e.autoHeight=!0),"auto"===e.width&&(e.autoWidth=!0),"auto"===e.height&&(e.autoHeight=!0),e.group=s.group,e.index=t,s.coming=e,!1===s.trigger("beforeLoad"))return void(s.coming=null);if(o=e.type,n=e.href,!o)return s.coming=null,s.current&&s.router&&"jumpto"!==s.router?(s.current.index=t,s[s.router](s.direction)):!1;if(s.isActive=!0,("image"===o||"swf"===o)&&(e.autoHeight=e.autoWidth=!1,e.scrolling="visible"),"image"===o&&(e.aspectRatio=!0),"iframe"===o&&l&&(e.scrolling="scroll"),e.wrap=$(e.tpl.wrap).addClass("envirabox-"+(l?"mobile":"desktop")+" envirabox-type-"+o+" envirabox-tmp "+e.wrapCSS).appendTo(e.parent||"body"),$.extend(e,{skin:$(".envirabox-skin",e.wrap),outer:$(".envirabox-outer",e.wrap),inner:$(".envirabox-inner",e.wrap)}),$.each(["Top","Right","Bottom","Left"],function(t,i){e.skin.css("padding"+i,m(e.padding[t]))}),s.trigger("onReady"),"inline"===o||"html"===o){if(!e.content||!e.content.length)return s._error("content")}else if(!n)return s._error("href");"image"===o?s._loadImage():"ajax"===o?s._loadAjax():"iframe"===o?s._loadIframe():s._afterLoad()},_error:function(t){$.extend(s.coming,{type:"html",autoWidth:!0,autoHeight:!0,minWidth:0,minHeight:0,scrolling:"no",hasError:t,content:s.coming.tpl.error}),s._afterLoad()},_loadImage:function(){var t=s.imgPreload=new Image;t.onload=function(){this.onload=this.onerror=null,s.coming.width=this.width/s.opts.pixelRatio,s.coming.height=this.height/s.opts.pixelRatio,s._afterLoad()},t.onerror=function(){this.onload=this.onerror=null,s._error("image")},t.src=s.coming.href,t.complete!==!0&&s.showLoading()},_loadAjax:function(){var t=s.coming;s.showLoading(),s.ajaxLoad=$.ajax($.extend({},t.ajax,{url:t.href,error:function(t,e){s.coming&&"abort"!==e?s._error("ajax",t):s.hideLoading()},success:function(e,i){"success"===i&&(t.content=e,s._afterLoad())}}))},_loadIframe:function(){var t=s.coming,e=$(t.tpl.iframe.replace(/\{rnd\}/g,(new Date).getTime())).attr("scrolling",l?"auto":t.iframe.scrolling).attr("src",t.href);$(t.wrap).bind("onReset",function(){try{$(this).find("iframe").hide().attr("src","//about:blank").end().empty()}catch(t){}}),t.iframe.preload&&(s.showLoading(),e.one("load",function(){$(this).data("ready",1),l||$(this).bind("load.fb",s.update),$(this).parents(".envirabox-wrap").width("100%").removeClass("envirabox-tmp").show(),s._afterLoad()})),t.content=e.appendTo(t.inner),t.iframe.preload||s._afterLoad()},_preloadImages:function(){var t=s.group,e=s.current,i=t.length,n=e.preload?Math.min(e.preload,i-1):0,o,r;for(r=1;n>=r;r+=1)o=t[(e.index+r)%i],"image"===o.type&&o.href&&((new Image).src=o.href)},_afterLoad:function(){var t=s.coming,e=s.current,i="envirabox-placeholder",n,o,r,a,u,l;if(s.hideLoading(),t&&s.isActive!==!1){if(!1===s.trigger("afterLoad",t,e))return t.wrap.stop(!0).trigger("onReset").remove(),void(s.coming=null);switch(e&&(s.trigger("beforeChange",e),e.wrap.stop(!0).removeClass("envirabox-opened").find(".envirabox-item, .envirabox-nav").remove()),s.unbindEvents(),n=t,o=t.content,r=t.type,a=t.scrolling,$.extend(s,{wrap:n.wrap,skin:n.skin,outer:n.outer,inner:n.inner,current:n,previous:e}),u=n.href,r){case"inline":case"ajax":case"html":n.selector?o=$("<div>").html(o).find(n.selector):h(o)&&(o.data(i)||o.data(i,$('<div class="'+i+'"></div>').insertAfter(o).hide()),o=o.show().detach(),n.wrap.bind("onReset",function(){$(this).find(o).length&&o.hide().replaceAll(o.data(i)).data(i,!1)}));break;case"image":o=n.tpl.image.replace(/\{href\}/g,u);break;case"swf":o='<object id="envirabox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="'+u+'"></param>',l="",$.each(n.swf,function(t,e){o+='<param name="'+t+'" value="'+e+'"></param>',l+=" "+t+'="'+e+'"'}),o+='<embed src="'+u+'" type="application/x-shockwave-flash" width="100%" height="100%"'+l+"></embed></object>"}h(o)&&o.parent().is(n.inner)||n.inner.append(o),s.trigger("beforeShow"),n.inner.css("overflow","yes"===a?"scroll":"no"===a?"hidden":a),s._setDimension(),s.reposition(),s.isOpen=!1,s.coming=null,s.bindEvents(),s.isOpened?e.prevMethod&&s.transitions[e.prevMethod]():$(".envirabox-wrap").not(n.wrap).stop(!0).trigger("onReset").remove(),s.transitions[s.isOpened?n.nextMethod:n.openMethod](),s._preloadImages()}},_setDimension:function(){var t=s.getViewport(),e=0,i=!1,n=!1,o=s.wrap,r=s.skin,a=s.inner,u=s.current,l=u.width,h=u.height,p=u.minWidth,d=u.minHeight,g=u.maxWidth,v=u.maxHeight,y=u.scrolling,w=u.scrollOutside?u.scrollbarWidth:0,x=u.margin,b=f(x[1]+x[3]),E=f(x[0]+x[2]),_,L,T,S,I,z,O,C,M,R,k,j,P,W,D;if(o.add(r).add(a).width("auto").height("auto").removeClass("envirabox-tmp"),_=f(r.outerWidth(!0)-r.width()),L=f(r.outerHeight(!0)-r.height()),T=b+_,S=E+L,I=c(l)?(t.w-T)*f(l)/100:l,z=c(h)?(t.h-S)*f(h)/100:h,"iframe"===u.type){if(W=u.content,u.autoHeight&&1===W.data("ready"))try{W[0].contentWindow.document.location&&(a.width(I).height(9999),D=W.contents().find("body"),w&&D.css("overflow-x","hidden"),z=D.outerHeight(!0))}catch(A){}}else(u.autoWidth||u.autoHeight)&&(a.addClass("envirabox-tmp"),u.autoWidth||a.width(I),u.autoHeight||a.height(z),u.autoWidth&&(I=a.width()),u.autoHeight&&(z=a.height()),a.removeClass("envirabox-tmp"));if(l=f(I),h=f(z),M=I/z,p=f(c(p)?f(p,"w")-T:p),g=f(c(g)?f(g,"w")-T:g),d=f(c(d)?f(d,"h")-S:d),v=f(c(v)?f(v,"h")-S:v),O=g,C=v,u.fitToView&&(g=Math.min(t.w-T,g),v=Math.min(t.h-S,v)),j=t.w-b,P=t.h-E,u.aspectRatio?(l>g&&(l=g,h=f(l/M)),h>v&&(h=v,l=f(h*M)),p>l&&(l=p,h=f(l/M)),d>h&&(h=d,l=f(h*M))):(l=Math.max(p,Math.min(l,g)),u.autoHeight&&"iframe"!==u.type&&(a.width(l),h=a.height()),h=Math.max(d,Math.min(h,v))),u.fitToView)if(a.width(l).height(h),o.width(l+_),R=o.width(),k=o.height(),u.aspectRatio)for(;(R>j||k>P)&&l>p&&h>d&&!(e++>19);)h=Math.max(d,Math.min(v,h-10)),l=f(h*M),p>l&&(l=p,h=f(l/M)),l>g&&(l=g,h=f(l/M)),a.width(l).height(h),o.width(l+_),R=o.width(),k=o.height();else l=Math.max(p,Math.min(l,l-(R-j))),h=Math.max(d,Math.min(h,h-(k-P)));w&&"auto"===y&&z>h&&j>l+_+w&&(l+=w),a.width(l).height(h),o.width(l+_),R=o.width(),k=o.height(),i=(R>j||k>P)&&l>p&&h>d,n=u.aspectRatio?O>l&&C>h&&I>l&&z>h:(O>l||C>h)&&(I>l||z>h),$.extend(u,{dim:{width:m(R),height:m(k)},origWidth:I,origHeight:z,canShrink:i,canExpand:n,wPadding:_,hPadding:L,wrapSpace:k-r.outerHeight(!0),skinSpace:r.height()-h}),!W&&u.autoHeight&&h>d&&v>h&&!n&&a.height("auto")},_getPosition:function(t){var e=s.current,i=s.getViewport(),n=e.margin,o=s.wrap.width()+n[1]+n[3],r=s.wrap.height()+n[0]+n[2],a={position:"absolute",top:n[0],left:n[3]};return e.helpers.title.type&&"float"==e.helpers.title.type&&(r+=$(".envirabox-skin .envirabox-title").height()),e.autoCenter&&e.fixed&&!t&&r<=i.h&&o<=i.w?a.position="fixed":e.locked||(a.top+=i.y,a.left+=i.x),a.top=m(Math.max(a.top,a.top+(i.h-r)*e.topRatio)),a.left=m(Math.max(a.left,a.left+(i.w-o)*e.leftRatio)),a},_afterZoomIn:function(){var t=s.current;t&&(s.isOpen=s.isOpened=!0,s.wrap.css("overflow","visible").addClass("envirabox-opened").hide().show(0),s.update(),(t.closeClick||t.nextClick&&s.group.length>1)&&s.inner.css("cursor","pointer").bind("click.fb",function(e){$(e.target).is("a")||$(e.target).parent().is("a")||(e.preventDefault(),s[t.closeClick?"close":"next"]())}),t.closeBtn&&$(t.tpl.closeBtn).appendTo(s.skin).bind("click.fb",function(t){t.preventDefault(),s.close()}),t.arrows&&s.group.length>1&&((t.loop||t.index>0)&&$(t.tpl.prev).appendTo(s.outer).bind("click.fb",s.prev),(t.loop||t.index<s.group.length-1)&&$(t.tpl.next).appendTo(s.outer).bind("click.fb",s.next)),s.trigger("afterShow"),t.loop||t.index!==t.group.length-1?s.opts.autoPlay&&!s.player.isActive&&(s.opts.autoPlay=!1,s.play(!0)):s.play(!1))},_afterZoomOut:function(t){t=t||s.current,$(".envirabox-wrap").trigger("onReset").remove(),$.extend(s,{group:{},opts:{},router:!1,current:null,isActive:!1,isOpened:!1,isOpen:!1,isClosing:!1,wrap:null,skin:null,outer:null,inner:null}),s.trigger("afterClose",t)}}),s.transitions={getOrigPosition:function(){var t=s.current,e=t.element,i=t.orig,n={},o=50,r=50,a=t.hPadding,u=t.wPadding,l=s.getViewport();return!i&&t.isDom&&e.is(":visible")&&(i=e.find("img:first"),i.length||(i=e)),h(i)?(n=i.offset(),i.is("img")&&(o=i.outerWidth(),r=i.outerHeight())):(n.top=l.y+(l.h-r)*t.topRatio,n.left=l.x+(l.w-o)*t.leftRatio),("fixed"===s.wrap.css("position")||t.locked)&&(n.top-=l.y,n.left-=l.x),n={top:m(n.top-a*t.topRatio),left:m(n.left-u*t.leftRatio),width:m(o+u),height:m(r+a)}},step:function(t,e){var i,n,o,r=e.prop,a=s.current,u=a.wrapSpace,l=a.skinSpace;("width"===r||"height"===r)&&(i=e.end===e.start?1:(t-e.start)/(e.end-e.start),s.isClosing&&(i=1-i),n="width"===r?a.wPadding:a.hPadding,o=t-n,s.skin[r](f("width"===r?o:o-u*i)),s.inner[r](f("width"===r?o:o-u*i-l*i)))},zoomIn:function(){var t=s.current,e=t.pos,i=t.openEffect,n="elastic"===i,o=$.extend({opacity:1},e);delete o.position,n?(e=this.getOrigPosition(),t.openOpacity&&(e.opacity=.1)):"fade"===i&&(e.opacity=.1),s.wrap.css(e).animate(o,{duration:"none"===i?0:t.openSpeed,easing:t.openEasing,step:n?this.step:null,complete:s._afterZoomIn})},zoomOut:function(){var t=s.current,e=t.closeEffect,i="elastic"===e,n={opacity:.1};i&&(n=this.getOrigPosition(),t.closeOpacity&&(n.opacity=.1)),s.wrap.animate(n,{duration:"none"===e?0:t.closeSpeed,easing:t.closeEasing,step:i?this.step:null,complete:s._afterZoomOut})},changeIn:function(){var t=s.current,e=t.nextEffect,i=t.pos,n={opacity:1},o=s.direction,r=200,a;i.opacity=.1,"elastic"===e&&(a="down"===o||"up"===o?"top":"left","down"===o||"right"===o?(i[a]=m(f(i[a])-r),n[a]="+="+r+"px"):(i[a]=m(f(i[a])+r),n[a]="-="+r+"px")),"none"===e?s._afterZoomIn():s.wrap.css(i).animate(n,{duration:t.nextSpeed,easing:t.nextEasing,complete:s._afterZoomIn})},changeOut:function(){var t=s.previous,e=t.prevEffect,i={opacity:.1},n=s.direction,o=200;"elastic"===e&&(i["down"===n||"up"===n?"top":"left"]=("up"===n||"left"===n?"-":"+")+"="+o+"px"),t.wrap.animate(i,{duration:"none"===e?0:t.prevSpeed,easing:t.prevEasing,complete:function(){$(this).trigger("onReset").remove()}})}},s.helpers.overlay={defaults:{closeClick:!0,speedOut:200,showEarly:!0,css:{},locked:!l,fixed:!0},overlay:null,fixed:!1,el:$("html"),create:function(t){var e;t=$.extend({},this.defaults,t),this.overlay&&this.close(),e=s.coming?s.coming.parent:t.parent,this.overlay=$('<div class="envirabox-overlay"></div>').appendTo(e&&e.lenth?e:"body"),this.fixed=!1,t.fixed&&s.defaults.fixed&&(this.overlay.addClass("envirabox-overlay-fixed"),this.fixed=!0)},open:function(t){var e=this;t=$.extend({},this.defaults,t),this.overlay?this.overlay.unbind(".overlay").width("auto").height("auto"):this.create(t),this.fixed||(o.bind("resize.overlay",$.proxy(this.update,this)),this.update()),t.closeClick&&this.overlay.bind("click.overlay",function(t){return $(t.target).hasClass("envirabox-overlay")?(s.isActive?s.close():e.close(),!1):void 0}),this.overlay.css(t.css).show()},close:function(){o.unbind("resize.overlay"),this.el.hasClass("envirabox-lock")&&($(".envirabox-margin").removeClass("envirabox-margin"),this.el.removeClass("envirabox-lock"),o.scrollTop(this.scrollV).scrollLeft(this.scrollH)),$(".envirabox-overlay").remove().hide(),$.extend(this,{overlay:null,fixed:!1})},update:function(){var t="100%",i;this.overlay.width(t).height("100%"),a?(i=Math.max(e.documentElement.offsetWidth,e.body.offsetWidth),r.width()>i&&(t=r.width())):r.width()>o.width()&&(t=r.width()),this.overlay.width(t).height(r.height())},onReady:function(t,e){var i=this.overlay;$(".envirabox-overlay").stop(!0,!0),i||this.create(t),t.locked&&this.fixed&&e.fixed&&(e.locked=this.overlay.append(e.wrap),e.fixed=!1),t.showEarly===!0&&this.beforeShow.apply(this,arguments)},beforeShow:function(t,e){e.locked&&!this.el.hasClass("envirabox-lock")&&(this.fixPosition!==!1&&$("*").filter(function(){return"fixed"===$(this).css("position")&&!$(this).hasClass("envirabox-overlay")&&!$(this).hasClass("envirabox-wrap")}).addClass("envirabox-margin"),this.el.addClass("envirabox-margin"),this.scrollV=o.scrollTop(),this.scrollH=o.scrollLeft(),this.el.addClass("envirabox-lock"),o.scrollTop(this.scrollV).scrollLeft(this.scrollH)),this.open(t)},onUpdate:function(){this.fixed||this.update()},afterClose:function(t){this.overlay&&!s.coming&&this.overlay.fadeOut(t.speedOut,$.proxy(this.close,this))}},s.helpers.title={defaults:{type:"float",position:"bottom"},beforeShow:function(t){var e=s.current,i=e.title,n=t.type,o,r;if($.isFunction(i)&&(i=i.call(e.element,e)),p(i)&&""!==$.trim(i)){switch(o=$('<div class="envirabox-title envirabox-title-'+n+'-wrap">'+i+"</div>"),n){case"inside":r=s.skin;break;case"outside":r=s.wrap;break;case"over":r=s.inner;break;default:r=s.skin,o.appendTo("body"),a&&o.width(o.width()),o.wrapInner('<span class="child"></span>'),s.current.margin[2]+=Math.abs(f(o.css("margin-bottom")))}o["top"===t.position?"prependTo":"appendTo"](r)}}},$.fn.envirabox=function(t){var e,i=$(this),n=this.selector||"",o=function(o){var r=$(this).blur(),a=e,u,l;o.ctrlKey||o.altKey||o.shiftKey||o.metaKey||r.is(".envirabox-wrap")||(u=t.groupAttr||"data-envirabox-group",l=r.attr(u),l||(u="rel",l=r.get(0)[u]),l&&""!==l&&"nofollow"!==l&&(r=n.length?$(n):i,r=r.filter("["+u+'="'+l+'"]'),a=r.index(this)),t.index=a,s.open(r,t)!==!1&&o.preventDefault())};return t=t||{},e=t.index||0,n&&t.live!==!1?r.undelegate(n,"click.fb-start").delegate(n+":not('.envirabox-item, .envirabox-nav')","click.fb-start",o):i.unbind("click.fb-start").bind("click.fb-start",o),this.filter("[data-envirabox-start=1]").trigger("click"),this},r.ready(function(){var e,o;$.scrollbarWidth===i&&($.scrollbarWidth=function(){var t=$('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo("body"),e=t.children(),i=e.innerWidth()-e.height(99).innerWidth();return t.remove(),i}),$.support.fixedPosition===i&&($.support.fixedPosition=function(){var t=$('<div style="position:fixed;top:20px;"></div>').appendTo("body"),e=20===t[0].offsetTop||15===t[0].offsetTop;return t.remove(),e}()),$.extend(s.defaults,{scrollbarWidth:$.scrollbarWidth(),fixed:$.support.fixedPosition,parent:$("body")}),e=$(t).width(),n.addClass("envirabox-lock-test"),o=$(t).width(),n.removeClass("envirabox-lock-test"),$("<style type='text/css'>.envirabox-margin{margin-right:"+(o-e)+"px;}</style>").appendTo("head")})}(window,document,jQuery),function(){function t(){}function e(t,e){for(var i=t.length;i--;)if(t[i].listener===e)return i;return-1}function i(t){return function e(){return this[t].apply(this,arguments)}}var n=t.prototype,o=this,r=o.EventEmitter;n.getListeners=function s(t){var e=this._getEvents(),i,n;if("object"==typeof t){i={};for(n in e)e.hasOwnProperty(n)&&t.test(n)&&(i[n]=e[n])}else i=e[t]||(e[t]=[]);return i},n.flattenListeners=function a(t){var e=[],i;for(i=0;i<t.length;i+=1)e.push(t[i].listener);return e},n.getListenersAsObject=function u(t){var e=this.getListeners(t),i;return e instanceof Array&&(i={},i[t]=e),i||e},n.addListener=function l(t,i){var n=this.getListenersAsObject(t),o="object"==typeof i,r;for(r in n)n.hasOwnProperty(r)&&-1===e(n[r],i)&&n[r].push(o?i:{listener:i,once:!1});return this},n.on=i("addListener"),n.addOnceListener=function h(t,e){return this.addListener(t,{listener:e,once:!0})},n.once=i("addOnceListener"),n.defineEvent=function p(t){return this.getListeners(t),this},n.defineEvents=function c(t){for(var e=0;e<t.length;e+=1)this.defineEvent(t[e]);return this},n.removeListener=function d(t,i){var n=this.getListenersAsObject(t),o,r;for(r in n)n.hasOwnProperty(r)&&(o=e(n[r],i),-1!==o&&n[r].splice(o,1));return this},n.off=i("removeListener"),n.addListeners=function f(t,e){return this.manipulateListeners(!1,t,e)},n.removeListeners=function m(t,e){return this.manipulateListeners(!0,t,e)},n.manipulateListeners=function g(t,e,i){var n,o,r=t?this.removeListener:this.addListener,s=t?this.removeListeners:this.addListeners;if("object"!=typeof e||e instanceof RegExp)for(n=i.length;n--;)r.call(this,e,i[n]);else for(n in e)e.hasOwnProperty(n)&&(o=e[n])&&("function"==typeof o?r.call(this,n,o):s.call(this,n,o));return this},n.removeEvent=function v(t){var e=typeof t,i=this._getEvents(),n;if("string"===e)delete i[t];else if("object"===e)for(n in i)i.hasOwnProperty(n)&&t.test(n)&&delete i[n];else delete this._events;return this},n.removeAllListeners=i("removeEvent"),n.emitEvent=function y(t,e){var i=this.getListenersAsObject(t),n,o,r,s;for(r in i)if(i.hasOwnProperty(r))for(o=i[r].length;o--;)n=i[r][o],n.once===!0&&this.removeListener(t,n.listener),s=n.listener.apply(this,e||[]),s===this._getOnceReturnValue()&&this.removeListener(t,n.listener);return this},n.trigger=i("emitEvent"),n.emit=function w(t){var e=Array.prototype.slice.call(arguments,1);return this.emitEvent(t,e)},n.setOnceReturnValue=function x(t){return this._onceReturnValue=t,this},n._getOnceReturnValue=function b(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},n._getEvents=function E(){return this._events||(this._events={})},t.noConflict=function _(){return o.EventEmitter=r,t},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return t}):"object"==typeof module&&module.exports?module.exports=t:this.EventEmitter=t}.call(this),function(t){function e(e){var i=t.event;return i.target=i.target||i.srcElement||e,i}var i=document.documentElement,n=function(){};i.addEventListener?n=function(t,e,i){t.addEventListener(e,i,!1)}:i.attachEvent&&(n=function(t,i,n){t[i+n]=n.handleEvent?function(){var i=e(t);n.handleEvent.call(n,i)}:function(){var i=e(t);n.call(t,i)},t.attachEvent("on"+i,t[i+n])});var o=function(){};i.removeEventListener?o=function(t,e,i){t.removeEventListener(e,i,!1)}:i.detachEvent&&(o=function(t,e,i){t.detachEvent("on"+e,t[e+i]);try{delete t[e+i]}catch(n){t[e+i]=void 0}});var r={bind:n,unbind:o};"function"==typeof define&&define.amd?define("eventie/eventie",r):t.eventie=r}(this),function(t,e){"function"==typeof define&&define.amd?define(["eventEmitter/EventEmitter","eventie/eventie"],function(i,n){return e(t,i,n)}):"object"==typeof exports?module.exports=e(t,require("wolfy87-eventemitter"),require("eventie")):t.imagesLoaded=e(t,t.EventEmitter,t.eventie)}(window,function t(e,i,n){function o(t,e){for(var i in e)t[i]=e[i];return t}function r(t){return"[object Array]"===c.call(t)}function s(t){var e=[];if(r(t))e=t;else if("number"==typeof t.length)for(var i=0,n=t.length;n>i;i++)e.push(t[i]);else e.push(t);return e}function a(t,e,i){if(!(this instanceof a))return new a(t,e);"string"==typeof t&&(t=document.querySelectorAll(t)),this.elements=s(t),this.options=o({},this.options),"function"==typeof e?i=e:o(this.options,e),i&&this.on("always",i),this.getImages(),$&&(this.jqDeferred=new $.Deferred);var n=this;setTimeout(function(){n.check()})}function u(t){this.img=t}function l(t){this.src=t,d[t]=this}var $=e.jQuery,h=e.console,p="undefined"!=typeof h,c=Object.prototype.toString;a.prototype=new i,a.prototype.options={},a.prototype.getImages=function(){this.images=[];for(var t=0,e=this.elements.length;e>t;t++){var i=this.elements[t];"IMG"===i.nodeName&&this.addImage(i);var n=i.nodeType;if(n&&(1===n||9===n||11===n))for(var o=i.querySelectorAll("img"),r=0,s=o.length;s>r;r++){var a=o[r];this.addImage(a)}}},a.prototype.addImage=function(t){var e=new u(t);this.images.push(e)},a.prototype.check=function(){function t(t,o){return e.options.debug&&p&&h.log("confirm",t,o),e.progress(t),i++,i===n&&e.complete(),!0}var e=this,i=0,n=this.images.length;if(this.hasAnyBroken=!1,!n)return void this.complete();for(var o=0;n>o;o++){var r=this.images[o];r.on("confirm",t),r.check()}},a.prototype.progress=function(t){this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded;var e=this;setTimeout(function(){e.emit("progress",e,t),e.jqDeferred&&e.jqDeferred.notify&&e.jqDeferred.notify(e,t)})},a.prototype.complete=function(){var t=this.hasAnyBroken?"fail":"done";this.isComplete=!0;var e=this;setTimeout(function(){if(e.emit(t,e),e.emit("always",e),e.jqDeferred){var i=e.hasAnyBroken?"reject":"resolve";e.jqDeferred[i](e)}})},$&&($.fn.imagesLoaded=function(t,e){var i=new a(this,t,e);return i.jqDeferred.promise($(this))}),u.prototype=new i,u.prototype.check=function(){var t=d[this.img.src]||new l(this.img.src);if(t.isConfirmed)return void this.confirm(t.isLoaded,"cached was confirmed");if(this.img.complete&&void 0!==this.img.naturalWidth)return void this.confirm(0!==this.img.naturalWidth,"naturalWidth");var e=this;t.on("confirm",function(t,i){return e.confirm(t.isLoaded,i),!0}),t.check()},u.prototype.confirm=function(t,e){this.isLoaded=t,this.emit("confirm",this,e)};var d={};return l.prototype=new i,l.prototype.check=function(){if(!this.isChecked){var t=new Image;n.bind(t,"load",this),n.bind(t,"error",this),t.src=this.src,this.isChecked=!0}},l.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},l.prototype.onload=function(t){this.confirm(!0,"onload"),this.unbindProxyEvents(t)},l.prototype.onerror=function(t){this.confirm(!1,"onerror"),this.unbindProxyEvents(t)},l.prototype.confirm=function(t,e){this.isConfirmed=!0,this.isLoaded=t,this.emit("confirm",this,e)},l.prototype.unbindProxyEvents=function(t){n.unbind(t.target,"load",this),n.unbind(t.target,"error",this)},a}),function(t){function e(){}function i($){function t(t){t.prototype.option||(t.prototype.option=function(t){$.isPlainObject(t)&&(this.options=$.extend(!0,this.options,t))})}function i(t,e){$.fn[t]=function(i){if("string"==typeof i){for(var r=n.call(arguments,1),s=0,a=this.length;a>s;s++){var u=this[s],l=$.data(u,t);if(l)if($.isFunction(l[i])&&"_"!==i.charAt(0)){var h=l[i].apply(l,r);if(void 0!==h)return h}else o("no such method '"+i+"' for "+t+" instance");else o("cannot call methods on "+t+" prior to initialization; attempted to call '"+i+"'")}return this}return this.each(function(){var n=$.data(this,t);n?(n.option(i),n._init()):(n=new e(this,i),$.data(this,t,n))})}}if($){var o="undefined"==typeof console?e:function(t){console.error(t)};return $.bridget=function(e,n){t(n),i(e,n)},$.bridget}}var n=Array.prototype.slice;"function"==typeof define&&define.amd?define("jquery-bridget/jquery.bridget",["jquery"],i):i("object"==typeof exports?require("jquery"):t.jQuery)}(window),function(t){function e(e){var i=t.event;return i.target=i.target||i.srcElement||e,i}var i=document.documentElement,n=function(){};i.addEventListener?n=function(t,e,i){t.addEventListener(e,i,!1)}:i.attachEvent&&(n=function(t,i,n){t[i+n]=n.handleEvent?function(){var i=e(t);n.handleEvent.call(n,i)}:function(){var i=e(t);n.call(t,i)},t.attachEvent("on"+i,t[i+n])});var o=function(){};i.removeEventListener?o=function(t,e,i){t.removeEventListener(e,i,!1)}:i.detachEvent&&(o=function(t,e,i){t.detachEvent("on"+e,t[e+i]);try{delete t[e+i]}catch(n){t[e+i]=void 0}});var r={bind:n,unbind:o};"function"==typeof define&&define.amd?define("eventie/eventie",r):"object"==typeof exports?module.exports=r:t.eventie=r}(window),function(){"use strict";function t(){}function e(t,e){for(var i=t.length;i--;)if(t[i].listener===e)return i;return-1}function i(t){return function e(){return this[t].apply(this,arguments);
2
- }}var n=t.prototype,o=this,r=o.EventEmitter;n.getListeners=function s(t){var e=this._getEvents(),i,n;if(t instanceof RegExp){i={};for(n in e)e.hasOwnProperty(n)&&t.test(n)&&(i[n]=e[n])}else i=e[t]||(e[t]=[]);return i},n.flattenListeners=function a(t){var e=[],i;for(i=0;i<t.length;i+=1)e.push(t[i].listener);return e},n.getListenersAsObject=function u(t){var e=this.getListeners(t),i;return e instanceof Array&&(i={},i[t]=e),i||e},n.addListener=function l(t,i){var n=this.getListenersAsObject(t),o="object"==typeof i,r;for(r in n)n.hasOwnProperty(r)&&-1===e(n[r],i)&&n[r].push(o?i:{listener:i,once:!1});return this},n.on=i("addListener"),n.addOnceListener=function h(t,e){return this.addListener(t,{listener:e,once:!0})},n.once=i("addOnceListener"),n.defineEvent=function p(t){return this.getListeners(t),this},n.defineEvents=function c(t){for(var e=0;e<t.length;e+=1)this.defineEvent(t[e]);return this},n.removeListener=function d(t,i){var n=this.getListenersAsObject(t),o,r;for(r in n)n.hasOwnProperty(r)&&(o=e(n[r],i),-1!==o&&n[r].splice(o,1));return this},n.off=i("removeListener"),n.addListeners=function f(t,e){return this.manipulateListeners(!1,t,e)},n.removeListeners=function m(t,e){return this.manipulateListeners(!0,t,e)},n.manipulateListeners=function g(t,e,i){var n,o,r=t?this.removeListener:this.addListener,s=t?this.removeListeners:this.addListeners;if("object"!=typeof e||e instanceof RegExp)for(n=i.length;n--;)r.call(this,e,i[n]);else for(n in e)e.hasOwnProperty(n)&&(o=e[n])&&("function"==typeof o?r.call(this,n,o):s.call(this,n,o));return this},n.removeEvent=function v(t){var e=typeof t,i=this._getEvents(),n;if("string"===e)delete i[t];else if(t instanceof RegExp)for(n in i)i.hasOwnProperty(n)&&t.test(n)&&delete i[n];else delete this._events;return this},n.removeAllListeners=i("removeEvent"),n.emitEvent=function y(t,e){var i=this.getListenersAsObject(t),n,o,r,s;for(r in i)if(i.hasOwnProperty(r))for(o=i[r].length;o--;)n=i[r][o],n.once===!0&&this.removeListener(t,n.listener),s=n.listener.apply(this,e||[]),s===this._getOnceReturnValue()&&this.removeListener(t,n.listener);return this},n.trigger=i("emitEvent"),n.emit=function w(t){var e=Array.prototype.slice.call(arguments,1);return this.emitEvent(t,e)},n.setOnceReturnValue=function x(t){return this._onceReturnValue=t,this},n._getOnceReturnValue=function b(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},n._getEvents=function E(){return this._events||(this._events={})},t.noConflict=function _(){return o.EventEmitter=r,t},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return t}):"object"==typeof module&&module.exports?module.exports=t:o.EventEmitter=t}.call(this),function(t){function e(t){if(t){if("string"==typeof n[t])return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e,o=0,r=i.length;r>o;o++)if(e=i[o]+t,"string"==typeof n[e])return e}}var i="Webkit Moz ms Ms O".split(" "),n=document.documentElement.style;"function"==typeof define&&define.amd?define("get-style-property/get-style-property",[],function(){return e}):"object"==typeof exports?module.exports=e:t.getStyleProperty=e}(window),function(t,e){function i(t){var e=parseFloat(t),i=-1===t.indexOf("%")&&!isNaN(e);return i&&e}function n(){}function o(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0,i=a.length;i>e;e++){var n=a[e];t[n]=0}return t}function r(e){function n(){if(!l){l=!0;var n=t.getComputedStyle;if(h=function(){var t=n?function(t){return n(t,null)}:function(t){return t.currentStyle};return function e(i){var n=t(i);return n||s("Style returned "+n+". Are you running this code in a hidden iframe on Firefox? See http://bit.ly/getsizebug1"),n}}(),p=e("boxSizing")){var o=document.createElement("div");o.style.width="200px",o.style.padding="1px 2px 3px 4px",o.style.borderStyle="solid",o.style.borderWidth="1px 2px 3px 4px",o.style[p]="border-box";var r=document.body||document.documentElement;r.appendChild(o);var a=h(o);c=200===i(a.width),r.removeChild(o)}}}function r(t){if(n(),"string"==typeof t&&(t=document.querySelector(t)),t&&"object"==typeof t&&t.nodeType){var e=h(t);if("none"===e.display)return o();var r={};r.width=t.offsetWidth,r.height=t.offsetHeight;for(var s=r.isBorderBox=!(!p||!e[p]||"border-box"!==e[p]),l=0,d=a.length;d>l;l++){var f=a[l],m=e[f];m=u(t,m);var g=parseFloat(m);r[f]=isNaN(g)?0:g}var v=r.paddingLeft+r.paddingRight,y=r.paddingTop+r.paddingBottom,w=r.marginLeft+r.marginRight,x=r.marginTop+r.marginBottom,b=r.borderLeftWidth+r.borderRightWidth,E=r.borderTopWidth+r.borderBottomWidth,_=s&&c,L=i(e.width);L!==!1&&(r.width=L+(_?0:v+b));var T=i(e.height);return T!==!1&&(r.height=T+(_?0:y+E)),r.innerWidth=r.width-(v+b),r.innerHeight=r.height-(y+E),r.outerWidth=r.width+w,r.outerHeight=r.height+x,r}}function u(e,i){if(t.getComputedStyle||-1===i.indexOf("%"))return i;var n=e.style,o=n.left,r=e.runtimeStyle,s=r&&r.left;return s&&(r.left=e.currentStyle.left),n.left=i,i=n.pixelLeft,n.left=o,s&&(r.left=s),i}var l=!1,h,p,c;return r}var s="undefined"==typeof console?n:function(t){console.error(t)},a=["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"],r):"object"==typeof exports?module.exports=r(require("desandro-get-style-property")):t.getSize=r(t.getStyleProperty)}(window),function(t){function e(t){"function"==typeof t&&(e.isReady?t():s.push(t))}function i(t){var i="readystatechange"===t.type&&"complete"!==r.readyState;e.isReady||i||n()}function n(){e.isReady=!0;for(var t=0,i=s.length;i>t;t++){var n=s[t];n()}}function o(o){return"complete"===r.readyState?n():(o.bind(r,"DOMContentLoaded",i),o.bind(r,"readystatechange",i),o.bind(t,"load",i)),e}var r=t.document,s=[];e.isReady=!1,"function"==typeof define&&define.amd?define("doc-ready/doc-ready",["eventie/eventie"],o):"object"==typeof exports?module.exports=o(require("eventie")):t.docReady=o(t.eventie)}(window),function(t){"use strict";function e(t,e){return t[r](e)}function i(t){if(!t.parentNode){var e=document.createDocumentFragment();e.appendChild(t)}}function n(t,e){i(t);for(var n=t.parentNode.querySelectorAll(e),o=0,r=n.length;r>o;o++)if(n[o]===t)return!0;return!1}function o(t,n){return i(t),e(t,n)}var r=function(){if(t.matches)return"matches";if(t.matchesSelector)return"matchesSelector";for(var e=["webkit","moz","ms","o"],i=0,n=e.length;n>i;i++){var o=e[i],r=o+"MatchesSelector";if(t[r])return r}}(),s;if(r){var a=document.createElement("div"),u=e(a,"div");s=u?e:o}else s=n;"function"==typeof define&&define.amd?define("matches-selector/matches-selector",[],function(){return s}):"object"==typeof exports?module.exports=s:window.matchesSelector=s}(Element.prototype),function(t,e){"use strict";"function"==typeof define&&define.amd?define("fizzy-ui-utils/utils",["doc-ready/doc-ready","matches-selector/matches-selector"],function(i,n){return e(t,i,n)}):"object"==typeof exports?module.exports=e(t,require("doc-ready"),require("desandro-matches-selector")):t.fizzyUIUtils=e(t,t.docReady,t.matchesSelector)}(window,function e(t,i,n){var o={};o.extend=function(t,e){for(var i in e)t[i]=e[i];return t},o.modulo=function(t,e){return(t%e+e)%e};var r=Object.prototype.toString;o.isArray=function(t){return"[object Array]"==r.call(t)},o.makeArray=function(t){var e=[];if(o.isArray(t))e=t;else if(t&&"number"==typeof t.length)for(var i=0,n=t.length;n>i;i++)e.push(t[i]);else e.push(t);return e},o.indexOf=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var i=0,n=t.length;n>i;i++)if(t[i]===e)return i;return-1},o.removeFrom=function(t,e){var i=o.indexOf(t,e);-1!=i&&t.splice(i,1)},o.isElement="function"==typeof HTMLElement||"object"==typeof HTMLElement?function a(t){return t instanceof HTMLElement}:function u(t){return t&&"object"==typeof t&&1==t.nodeType&&"string"==typeof t.nodeName},o.setText=function(){function t(t,i){e=e||(void 0!==document.documentElement.textContent?"textContent":"innerText"),t[e]=i}var e;return t}(),o.getParent=function(t,e){for(;t!=document.body;)if(t=t.parentNode,n(t,e))return t},o.getQueryElement=function(t){return"string"==typeof t?document.querySelector(t):t},o.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},o.filterFindElements=function(t,e){t=o.makeArray(t);for(var i=[],r=0,s=t.length;s>r;r++){var a=t[r];if(o.isElement(a))if(e){n(a,e)&&i.push(a);for(var u=a.querySelectorAll(e),l=0,h=u.length;h>l;l++)i.push(u[l])}else i.push(a)}return i},o.debounceMethod=function(t,e,i){var n=t.prototype[e],o=e+"Timeout";t.prototype[e]=function(){var t=this[o];t&&clearTimeout(t);var e=arguments,r=this;this[o]=setTimeout(function(){n.apply(r,e),delete r[o]},i||100)}},o.toDashed=function(t){return t.replace(/(.)([A-Z])/g,function(t,e,i){return e+"-"+i}).toLowerCase()};var s=t.console;return o.htmlInit=function(e,n){i(function(){for(var i=o.toDashed(n),r=document.querySelectorAll(".js-"+i),a="data-"+i+"-options",u=0,l=r.length;l>u;u++){var h=r[u],p=h.getAttribute(a),c;try{c=p&&JSON.parse(p)}catch(d){s&&s.error("Error parsing "+a+" on "+h.nodeName.toLowerCase()+(h.id?"#"+h.id:"")+": "+d);continue}var f=new e(h,c),m=t.jQuery;m&&m.data(h,n,f)}})},o}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("outlayer/item",["eventEmitter/EventEmitter","get-size/get-size","get-style-property/get-style-property","fizzy-ui-utils/utils"],function(i,n,o,r){return e(t,i,n,o,r)}):"object"==typeof exports?module.exports=e(t,require("wolfy87-eventemitter"),require("get-size"),require("desandro-get-style-property"),require("fizzy-ui-utils")):(t.Outlayer={},t.Outlayer.Item=e(t,t.EventEmitter,t.getSize,t.getStyleProperty,t.fizzyUIUtils))}(window,function i(t,e,n,o,r){"use strict";function s(t){for(var e in t)return!1;return e=null,!0}function a(t,e){t&&(this.element=t,this.layout=e,this.position={x:0,y:0},this._create())}function u(t){return t.replace(/([A-Z])/g,function(t){return"-"+t.toLowerCase()})}var l=t.getComputedStyle,h=l?function(t){return l(t,null)}:function(t){return t.currentStyle},p=o("transition"),c=o("transform"),d=p&&c,f=!!o("perspective"),m={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"otransitionend",transition:"transitionend"}[p],g=["transform","transition","transitionDuration","transitionProperty"],v=function(){for(var t={},e=0,i=g.length;i>e;e++){var n=g[e],r=o(n);r&&r!==n&&(t[n]=r)}return t}();r.extend(a.prototype,e.prototype),a.prototype._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},a.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},a.prototype.getSize=function(){this.size=n(this.element)},a.prototype.css=function(t){var e=this.element.style;for(var i in t){var n=v[i]||i;e[n]=t[i]}},a.prototype.getPosition=function(){var t=h(this.element),e=this.layout.options,i=e.isOriginLeft,n=e.isOriginTop,o=t[i?"left":"right"],r=t[n?"top":"bottom"],s=this.layout.size,a=-1!=o.indexOf("%")?parseFloat(o)/100*s.width:parseInt(o,10),u=-1!=r.indexOf("%")?parseFloat(r)/100*s.height:parseInt(r,10);a=isNaN(a)?0:a,u=isNaN(u)?0:u,a-=i?s.paddingLeft:s.paddingRight,u-=n?s.paddingTop:s.paddingBottom,this.position.x=a,this.position.y=u},a.prototype.layoutPosition=function(){var t=this.layout.size,e=this.layout.options,i={},n=e.isOriginLeft?"paddingLeft":"paddingRight",o=e.isOriginLeft?"left":"right",r=e.isOriginLeft?"right":"left",s=this.position.x+t[n];i[o]=this.getXValue(s),i[r]="";var a=e.isOriginTop?"paddingTop":"paddingBottom",u=e.isOriginTop?"top":"bottom",l=e.isOriginTop?"bottom":"top",h=this.position.y+t[a];i[u]=this.getYValue(h),i[l]="",this.css(i),this.emitEvent("layout",[this])},a.prototype.getXValue=function(t){var e=this.layout.options;return e.percentPosition&&!e.isHorizontal?t/this.layout.size.width*100+"%":t+"px"},a.prototype.getYValue=function(t){var e=this.layout.options;return e.percentPosition&&e.isHorizontal?t/this.layout.size.height*100+"%":t+"px"},a.prototype._transitionTo=function(t,e){this.getPosition();var i=this.position.x,n=this.position.y,o=parseInt(t,10),r=parseInt(e,10),s=o===this.position.x&&r===this.position.y;if(this.setPosition(t,e),s&&!this.isTransitioning)return void this.layoutPosition();var a=t-i,u=e-n,l={};l.transform=this.getTranslate(a,u),this.transition({to:l,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},a.prototype.getTranslate=function(t,e){var i=this.layout.options;return t=i.isOriginLeft?t:-t,e=i.isOriginTop?e:-e,f?"translate3d("+t+"px, "+e+"px, 0)":"translate("+t+"px, "+e+"px)"},a.prototype.goTo=function(t,e){this.setPosition(t,e),this.layoutPosition()},a.prototype.moveTo=d?a.prototype._transitionTo:a.prototype.goTo,a.prototype.setPosition=function(t,e){this.position.x=parseInt(t,10),this.position.y=parseInt(e,10)},a.prototype._nonTransition=function(t){this.css(t.to),t.isCleaning&&this._removeStyles(t.to);for(var e in t.onTransitionEnd)t.onTransitionEnd[e].call(this)},a.prototype._transition=function(t){if(!parseFloat(this.layout.options.transitionDuration))return void this._nonTransition(t);var e=this._transn;for(var i in t.onTransitionEnd)e.onEnd[i]=t.onTransitionEnd[i];for(i in t.to)e.ingProperties[i]=!0,t.isCleaning&&(e.clean[i]=!0);if(t.from){this.css(t.from);var n=this.element.offsetHeight;n=null}this.enableTransition(t.to),this.css(t.to),this.isTransitioning=!0};var y="opacity,"+u(v.transform||"transform");a.prototype.enableTransition=function(){this.isTransitioning||(this.css({transitionProperty:y,transitionDuration:this.layout.options.transitionDuration}),this.element.addEventListener(m,this,!1))},a.prototype.transition=a.prototype[p?"_transition":"_nonTransition"],a.prototype.onwebkitTransitionEnd=function(t){this.ontransitionend(t)},a.prototype.onotransitionend=function(t){this.ontransitionend(t)};var w={"-webkit-transform":"transform","-moz-transform":"transform","-o-transform":"transform"};a.prototype.ontransitionend=function(t){if(t.target===this.element){var e=this._transn,i=w[t.propertyName]||t.propertyName;if(delete e.ingProperties[i],s(e.ingProperties)&&this.disableTransition(),i in e.clean&&(this.element.style[t.propertyName]="",delete e.clean[i]),i in e.onEnd){var n=e.onEnd[i];n.call(this),delete e.onEnd[i]}this.emitEvent("transitionEnd",[this])}},a.prototype.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(m,this,!1),this.isTransitioning=!1},a.prototype._removeStyles=function(t){var e={};for(var i in t)e[i]="";this.css(e)};var x={transitionProperty:"",transitionDuration:""};return a.prototype.removeTransitionStyles=function(){this.css(x)},a.prototype.removeElem=function(){this.element.parentNode.removeChild(this.element),this.css({display:""}),this.emitEvent("remove",[this])},a.prototype.remove=function(){if(!p||!parseFloat(this.layout.options.transitionDuration))return void this.removeElem();var t=this;this.once("transitionEnd",function(){t.removeElem()}),this.hide()},a.prototype.reveal=function(){delete this.isHidden,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("visibleStyle");e[i]=this.onRevealTransitionEnd,this.transition({from:t.hiddenStyle,to:t.visibleStyle,isCleaning:!0,onTransitionEnd:e})},a.prototype.onRevealTransitionEnd=function(){this.isHidden||this.emitEvent("reveal")},a.prototype.getHideRevealTransitionEndProperty=function(t){var e=this.layout.options[t];if(e.opacity)return"opacity";for(var i in e)return i},a.prototype.hide=function(){this.isHidden=!0,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("hiddenStyle");e[i]=this.onHideTransitionEnd,this.transition({from:t.visibleStyle,to:t.hiddenStyle,isCleaning:!0,onTransitionEnd:e})},a.prototype.onHideTransitionEnd=function(){this.isHidden&&(this.css({display:"none"}),this.emitEvent("hide"))},a.prototype.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},a}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("outlayer/outlayer",["eventie/eventie","eventEmitter/EventEmitter","get-size/get-size","fizzy-ui-utils/utils","./item"],function(i,n,o,r,s){return e(t,i,n,o,r,s)}):"object"==typeof exports?module.exports=e(t,require("eventie"),require("wolfy87-eventemitter"),require("get-size"),require("fizzy-ui-utils"),require("./item")):t.Outlayer=e(t,t.eventie,t.EventEmitter,t.getSize,t.fizzyUIUtils,t.Outlayer.Item)}(window,function n(t,e,i,o,r,s){"use strict";function a(t,e){var i=r.getQueryElement(t);if(!i)return void(u&&u.error("Bad element for "+this.constructor.namespace+": "+(i||t)));this.element=i,l&&(this.$element=l(this.element)),this.options=r.extend({},this.constructor.defaults),this.option(e);var n=++p;this.element.outlayerGUID=n,c[n]=this,this._create(),this.options.isInitLayout&&this.layout()}var u=t.console,l=t.jQuery,h=function(){},p=0,c={};return a.namespace="outlayer",a.Item=s,a.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)"}},r.extend(a.prototype,i.prototype),a.prototype.option=function(t){r.extend(this.options,t)},a.prototype._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),r.extend(this.element.style,this.options.containerStyle),this.options.isResizeBound&&this.bindResize()},a.prototype.reloadItems=function(){this.items=this._itemize(this.element.children)},a.prototype._itemize=function(t){for(var e=this._filterFindItemElements(t),i=this.constructor.Item,n=[],o=0,r=e.length;r>o;o++){var s=e[o],a=new i(s,this);n.push(a)}return n},a.prototype._filterFindItemElements=function(t){return r.filterFindElements(t,this.options.itemSelector)},a.prototype.getItemElements=function(){for(var t=[],e=0,i=this.items.length;i>e;e++)t.push(this.items[e].element);return t},a.prototype.layout=function(){this._resetLayout(),this._manageStamps();var t=void 0!==this.options.isLayoutInstant?this.options.isLayoutInstant:!this._isLayoutInited;this.layoutItems(this.items,t),this._isLayoutInited=!0},a.prototype._init=a.prototype.layout,a.prototype._resetLayout=function(){this.getSize()},a.prototype.getSize=function(){this.size=o(this.element)},a.prototype._getMeasurement=function(t,e){var i=this.options[t],n;i?("string"==typeof i?n=this.element.querySelector(i):r.isElement(i)&&(n=i),this[t]=n?o(n)[e]:i):this[t]=0},a.prototype.layoutItems=function(t,e){t=this._getItemsForLayout(t),this._layoutItems(t,e),this._postLayout()},a.prototype._getItemsForLayout=function(t){for(var e=[],i=0,n=t.length;n>i;i++){var o=t[i];o.isIgnored||e.push(o)}return e},a.prototype._layoutItems=function(t,e){if(this._emitCompleteOnItems("layout",t),t&&t.length){for(var i=[],n=0,o=t.length;o>n;n++){var r=t[n],s=this._getItemLayoutPosition(r);s.item=r,s.isInstant=e||r.isLayoutInstant,i.push(s)}this._processLayoutQueue(i)}},a.prototype._getItemLayoutPosition=function(){return{x:0,y:0}},a.prototype._processLayoutQueue=function(t){for(var e=0,i=t.length;i>e;e++){var n=t[e];this._positionItem(n.item,n.x,n.y,n.isInstant)}},a.prototype._positionItem=function(t,e,i,n){n?t.goTo(e,i):t.moveTo(e,i)},a.prototype._postLayout=function(){this.resizeContainer()},a.prototype.resizeContainer=function(){if(this.options.isResizingContainer){var t=this._getContainerSize();t&&(this._setContainerMeasure(t.width,!0),this._setContainerMeasure(t.height,!1))}},a.prototype._getContainerSize=h,a.prototype._setContainerMeasure=function(t,e){if(void 0!==t){var i=this.size;i.isBorderBox&&(t+=e?i.paddingLeft+i.paddingRight+i.borderLeftWidth+i.borderRightWidth:i.paddingBottom+i.paddingTop+i.borderTopWidth+i.borderBottomWidth),t=Math.max(t,0),this.element.style[e?"width":"height"]=t+"px"}},a.prototype._emitCompleteOnItems=function(t,e){function i(){o.dispatchEvent(t+"Complete",null,[e])}function n(){s++,s===r&&i()}var o=this,r=e.length;if(!e||!r)return void i();for(var s=0,a=0,u=e.length;u>a;a++){var l=e[a];l.once(t,n)}},a.prototype.dispatchEvent=function(t,e,i){var n=e?[e].concat(i):i;if(this.emitEvent(t,n),l)if(this.$element=this.$element||l(this.element),e){var o=l.Event(e);o.type=t,this.$element.trigger(o,i)}else this.$element.trigger(t,i)},a.prototype.ignore=function(t){var e=this.getItem(t);e&&(e.isIgnored=!0)},a.prototype.unignore=function(t){var e=this.getItem(t);e&&delete e.isIgnored},a.prototype.stamp=function(t){if(t=this._find(t)){this.stamps=this.stamps.concat(t);for(var e=0,i=t.length;i>e;e++){var n=t[e];this.ignore(n)}}},a.prototype.unstamp=function(t){if(t=this._find(t))for(var e=0,i=t.length;i>e;e++){var n=t[e];r.removeFrom(this.stamps,n),this.unignore(n)}},a.prototype._find=function(t){return t?("string"==typeof t&&(t=this.element.querySelectorAll(t)),t=r.makeArray(t)):void 0},a.prototype._manageStamps=function(){if(this.stamps&&this.stamps.length){this._getBoundingRect();for(var t=0,e=this.stamps.length;e>t;t++){var i=this.stamps[t];this._manageStamp(i)}}},a.prototype._getBoundingRect=function(){var t=this.element.getBoundingClientRect(),e=this.size;this._boundingRect={left:t.left+e.paddingLeft+e.borderLeftWidth,top:t.top+e.paddingTop+e.borderTopWidth,right:t.right-(e.paddingRight+e.borderRightWidth),bottom:t.bottom-(e.paddingBottom+e.borderBottomWidth)}},a.prototype._manageStamp=h,a.prototype._getElementOffset=function(t){var e=t.getBoundingClientRect(),i=this._boundingRect,n=o(t),r={left:e.left-i.left-n.marginLeft,top:e.top-i.top-n.marginTop,right:i.right-e.right-n.marginRight,bottom:i.bottom-e.bottom-n.marginBottom};return r},a.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},a.prototype.bindResize=function(){this.isResizeBound||(e.bind(t,"resize",this),this.isResizeBound=!0)},a.prototype.unbindResize=function(){this.isResizeBound&&e.unbind(t,"resize",this),this.isResizeBound=!1},a.prototype.onresize=function(){function t(){e.resize(),delete e.resizeTimeout}this.resizeTimeout&&clearTimeout(this.resizeTimeout);var e=this;this.resizeTimeout=setTimeout(t,100)},a.prototype.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},a.prototype.needsResizeLayout=function(){var t=o(this.element),e=this.size&&t;return e&&t.innerWidth!==this.size.innerWidth},a.prototype.addItems=function(t){var e=this._itemize(t);return e.length&&(this.items=this.items.concat(e)),e},a.prototype.appended=function(t){var e=this.addItems(t);e.length&&(this.layoutItems(e,!0),this.reveal(e))},a.prototype.prepended=function(t){var e=this._itemize(t);if(e.length){var i=this.items.slice(0);this.items=e.concat(i),this._resetLayout(),this._manageStamps(),this.layoutItems(e,!0),this.reveal(e),this.layoutItems(i)}},a.prototype.reveal=function(t){this._emitCompleteOnItems("reveal",t);for(var e=t&&t.length,i=0;e&&e>i;i++){var n=t[i];n.reveal()}},a.prototype.hide=function(t){this._emitCompleteOnItems("hide",t);for(var e=t&&t.length,i=0;e&&e>i;i++){var n=t[i];n.hide()}},a.prototype.revealItemElements=function(t){var e=this.getItems(t);this.reveal(e)},a.prototype.hideItemElements=function(t){var e=this.getItems(t);this.hide(e)},a.prototype.getItem=function(t){for(var e=0,i=this.items.length;i>e;e++){var n=this.items[e];if(n.element===t)return n}},a.prototype.getItems=function(t){t=r.makeArray(t);for(var e=[],i=0,n=t.length;n>i;i++){var o=t[i],s=this.getItem(o);s&&e.push(s)}return e},a.prototype.remove=function(t){var e=this.getItems(t);if(this._emitCompleteOnItems("remove",e),e&&e.length)for(var i=0,n=e.length;n>i;i++){var o=e[i];o.remove(),r.removeFrom(this.items,o)}},a.prototype.destroy=function(){var t=this.element.style;t.height="",t.position="",t.width="";for(var e=0,i=this.items.length;i>e;e++){var n=this.items[e];n.destroy()}this.unbindResize();var o=this.element.outlayerGUID;delete c[o],delete this.element.outlayerGUID,l&&l.removeData(this.element,this.constructor.namespace)},a.data=function(t){t=r.getQueryElement(t);var e=t&&t.outlayerGUID;return e&&c[e]},a.create=function(t,e){function i(){a.apply(this,arguments)}return Object.create?i.prototype=Object.create(a.prototype):r.extend(i.prototype,a.prototype),i.prototype.constructor=i,i.defaults=r.extend({},a.defaults),r.extend(i.defaults,e),i.prototype.settings={},i.namespace=t,i.data=a.data,i.Item=function n(){s.apply(this,arguments)},i.Item.prototype=new s,r.htmlInit(i,t),l&&l.bridget&&l.bridget(t,i),i},a.Item=s,a}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("enviratope/js/item",["outlayer/outlayer"],e):"object"==typeof exports?module.exports=e(require("outlayer")):(t.Enviratope=t.Enviratope||{},t.Enviratope.Item=e(t.Outlayer))}(window,function o(t){"use strict";function e(){t.Item.apply(this,arguments)}e.prototype=new t.Item,e.prototype._create=function(){this.id=this.layout.itemGUID++,t.Item.prototype._create.call(this),this.sortData={}},e.prototype.updateSortData=function(){if(!this.isIgnored){this.sortData.id=this.id,this.sortData["original-order"]=this.id,this.sortData.random=Math.random();var t=this.layout.options.getSortData,e=this.layout._sorters;for(var i in t){var n=e[i];this.sortData[i]=n(this.element,this)}}};var i=e.prototype.destroy;return e.prototype.destroy=function(){i.apply(this,arguments),this.css({display:""})},e}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("enviratope/js/layout-mode",["get-size/get-size","outlayer/outlayer"],e):"object"==typeof exports?module.exports=e(require("get-size"),require("outlayer")):(t.Enviratope=t.Enviratope||{},t.Enviratope.LayoutMode=e(t.getSize,t.Outlayer))}(window,function r(t,e){"use strict";function i(t){this.enviratope=t,t&&(this.options=t.options[this.namespace],this.element=t.element,this.items=t.filteredItems,this.size=t.size)}return function(){function t(t){return function(){return e.prototype[t].apply(this.enviratope,arguments)}}for(var n=["_resetLayout","_getItemLayoutPosition","_manageStamp","_getContainerSize","_getElementOffset","needsResizeLayout"],o=0,r=n.length;r>o;o++){var s=n[o];i.prototype[s]=t(s)}}(),i.prototype.needsVerticalResizeLayout=function(){var e=t(this.enviratope.element),i=this.enviratope.size&&e;return i&&e.innerHeight!=this.enviratope.size.innerHeight},i.prototype._getMeasurement=function(){this.enviratope._getMeasurement.apply(this,arguments)},i.prototype.getColumnWidth=function(){this.getSegmentSize("column","Width")},i.prototype.getRowHeight=function(){this.getSegmentSize("row","Height")},i.prototype.getSegmentSize=function(t,e){var i=t+e,n="outer"+e;if(this._getMeasurement(i,n),!this[i]){var o=this.getFirstItemSize();this[i]=o&&o[n]||this.enviratope.size["inner"+e]}},i.prototype.getFirstItemSize=function(){var e=this.enviratope.filteredItems[0];return e&&e.element&&t(e.element)},i.prototype.layout=function(){this.enviratope.layout.apply(this.enviratope,arguments)},i.prototype.getSize=function(){this.enviratope.getSize(),this.size=this.enviratope.size},i.modes={},i.create=function(t,e){function n(){i.apply(this,arguments)}return n.prototype=new i,e&&(n.options=e),n.prototype.namespace=t,i.modes[t]=n,n},i}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("masonry/masonry",["outlayer/outlayer","get-size/get-size","fizzy-ui-utils/utils"],e):"object"==typeof exports?module.exports=e(require("outlayer"),require("get-size"),require("fizzy-ui-utils")):t.Masonry=e(t.Outlayer,t.getSize,t.fizzyUIUtils)}(window,function s(t,e,i){var n=t.create("masonry");return n.prototype._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns();var t=this.cols;for(this.colYs=[];t--;)this.colYs.push(0);this.maxY=0},n.prototype.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var t=this.items[0],i=t&&t.element;this.columnWidth=i&&e(i).outerWidth||this.containerWidth}var n=this.columnWidth+=this.gutter,o=this.containerWidth+this.gutter,r=o/n,s=n-o%n,a=s&&1>s?"round":"floor";r=Math[a](r),this.cols=Math.max(r,1)},n.prototype.getContainerWidth=function(){var t=this.options.isFitWidth?this.element.parentNode:this.element,i=e(t);this.containerWidth=i&&i.innerWidth},n.prototype._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,n=e&&1>e?"round":"ceil",o=Math[n](t.size.outerWidth/this.columnWidth);o=Math.min(o,this.cols);for(var r=this._getColGroup(o),s=Math.min.apply(Math,r),a=i.indexOf(r,s),u={x:this.columnWidth*a,y:s},l=s+t.size.outerHeight,h=this.cols+1-r.length,p=0;h>p;p++)this.colYs[a+p]=l;return u},n.prototype._getColGroup=function(t){if(2>t)return this.colYs;for(var e=[],i=this.cols+1-t,n=0;i>n;n++){var o=this.colYs.slice(n,n+t);e[n]=Math.max.apply(Math,o)}return e},n.prototype._manageStamp=function(t){var i=e(t),n=this._getElementOffset(t),o=this.options.isOriginLeft?n.left:n.right,r=o+i.outerWidth,s=Math.floor(o/this.columnWidth);s=Math.max(0,s);var a=Math.floor(r/this.columnWidth);a-=r%this.columnWidth?0:1,a=Math.min(this.cols-1,a);for(var u=(this.options.isOriginTop?n.top:n.bottom)+i.outerHeight,l=s;a>=l;l++)this.colYs[l]=Math.max(u,this.colYs[l])},n.prototype._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this.options.isFitWidth&&(t.width=this._getContainerFitWidth()),t},n.prototype._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},n.prototype.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!==this.containerWidth},n}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("enviratope/js/layout-modes/masonry",["../layout-mode","masonry/masonry"],e):"object"==typeof exports?module.exports=e(require("../layout-mode"),require("masonry-layout")):e(t.Enviratope.LayoutMode,t.Masonry)}(window,function a(t,e){"use strict";function i(t,e){for(var i in e)t[i]=e[i];return t}var n=t.create("masonry"),o=n.prototype._getElementOffset,r=n.prototype.layout,s=n.prototype._getMeasurement;i(n.prototype,e.prototype),n.prototype._getElementOffset=o,n.prototype.layout=r,n.prototype._getMeasurement=s;var a=n.prototype.measureColumns;n.prototype.measureColumns=function(){this.items=this.enviratope.filteredItems,a.call(this)};var u=n.prototype._manageStamp;return n.prototype._manageStamp=function(){this.options.isOriginLeft=this.enviratope.options.isOriginLeft,this.options.isOriginTop=this.enviratope.options.isOriginTop,u.apply(this,arguments)},n}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("enviratope/js/layout-modes/fit-rows",["../layout-mode"],e):"object"==typeof exports?module.exports=e(require("../layout-mode")):e(t.Enviratope.LayoutMode)}(window,function u(t){"use strict";var e=t.create("fitRows");return e.prototype._resetLayout=function(){this.x=0,this.y=0,this.maxY=0,this._getMeasurement("gutter","outerWidth")},e.prototype._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth+this.gutter,i=this.enviratope.size.innerWidth+this.gutter;0!==this.x&&e+this.x>i&&(this.x=0,this.y=this.maxY);var n={x:this.x,y:this.y};return this.maxY=Math.max(this.maxY,this.y+t.size.outerHeight),this.x+=e,n},e.prototype._getContainerSize=function(){return{height:this.maxY}},e}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("enviratope/js/layout-modes/vertical",["../layout-mode"],e):"object"==typeof exports?module.exports=e(require("../layout-mode")):e(t.Enviratope.LayoutMode)}(window,function l(t){"use strict";var e=t.create("vertical",{horizontalAlignment:0});return e.prototype._resetLayout=function(){this.y=0},e.prototype._getItemLayoutPosition=function(t){t.getSize();var e=(this.enviratope.size.innerWidth-t.size.outerWidth)*this.options.horizontalAlignment,i=this.y;
3
- return this.y+=t.size.outerHeight,{x:e,y:i}},e.prototype._getContainerSize=function(){return{height:this.y}},e}),function(t,e){"use strict";"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size","matches-selector/matches-selector","fizzy-ui-utils/utils","enviratope/js/item","enviratope/js/layout-mode","enviratope/js/layout-modes/masonry","enviratope/js/layout-modes/fit-rows","enviratope/js/layout-modes/vertical"],function(i,n,o,r,s,a){return e(t,i,n,o,r,s,a)}):"object"==typeof exports?module.exports=e(t,require("outlayer"),require("get-size"),require("desandro-matches-selector"),require("fizzy-ui-utils"),require("./item"),require("./layout-mode"),require("./layout-modes/masonry"),require("./layout-modes/fit-rows"),require("./layout-modes/vertical")):t.Enviratope=e(t,t.Outlayer,t.getSize,t.matchesSelector,t.fizzyUIUtils,t.Enviratope.Item,t.Enviratope.LayoutMode)}(window,function h(t,e,i,n,o,r,s){function a(t,e){return function i(n,o){for(var r=0,s=t.length;s>r;r++){var a=t[r],u=n.sortData[a],l=o.sortData[a];if(u>l||l>u){var h=void 0!==e[a]?e[a]:e,p=h?1:-1;return(u>l?1:-1)*p}}return 0}}var u=t.jQuery,l=String.prototype.trim?function(t){return t.trim()}:function(t){return t.replace(/^\s+|\s+$/g,"")},h=document.documentElement,p=h.textContent?function(t){return t.textContent}:function(t){return t.innerText},c=e.create("enviratope",{layoutMode:"masonry",isJQueryFiltering:!0,sortAscending:!0});c.Item=r,c.LayoutMode=s,c.prototype._create=function(){this.itemGUID=0,this._sorters={},this._getSorters(),e.prototype._create.call(this),this.modes={},this.filteredItems=this.items,this.sortHistory=["original-order"];for(var t in s.modes)this._initLayoutMode(t)},c.prototype.reloadItems=function(){this.itemGUID=0,e.prototype.reloadItems.call(this)},c.prototype._itemize=function(){for(var t=e.prototype._itemize.apply(this,arguments),i=0,n=t.length;n>i;i++){var o=t[i];o.id=this.itemGUID++}return this._updateItemsSortData(t),t},c.prototype._initLayoutMode=function(t){var e=s.modes[t],i=this.options[t]||{};this.options[t]=e.options?o.extend(e.options,i):i,this.modes[t]=new e(this)},c.prototype.layout=function(){return!this._isLayoutInited&&this.options.isInitLayout?void this.arrange():void this._layout()},c.prototype._layout=function(){var t=this._getIsInstant();this._resetLayout(),this._manageStamps(),this.layoutItems(this.filteredItems,t),this._isLayoutInited=!0},c.prototype.arrange=function(t){function e(){n.reveal(i.needReveal),n.hide(i.needHide)}this.option(t),this._getIsInstant();var i=this._filter(this.items);this.filteredItems=i.matches;var n=this;this._bindArrangeComplete(),this._isInstant?this._noTransition(e):e(),this._sort(),this._layout()},c.prototype._init=c.prototype.arrange,c.prototype._getIsInstant=function(){var t=void 0!==this.options.isLayoutInstant?this.options.isLayoutInstant:!this._isLayoutInited;return this._isInstant=t,t},c.prototype._bindArrangeComplete=function(){function t(){e&&i&&n&&o.dispatchEvent("arrangeComplete",null,[o.filteredItems])}var e,i,n,o=this;this.once("layoutComplete",function(){e=!0,t()}),this.once("hideComplete",function(){i=!0,t()}),this.once("revealComplete",function(){n=!0,t()})},c.prototype._filter=function(t){var e=this.options.filter;e=e||"*";for(var i=[],n=[],o=[],r=this._getFilterTest(e),s=0,a=t.length;a>s;s++){var u=t[s];if(!u.isIgnored){var l=r(u);l&&i.push(u),l&&u.isHidden?n.push(u):l||u.isHidden||o.push(u)}}return{matches:i,needReveal:n,needHide:o}},c.prototype._getFilterTest=function(t){return u&&this.options.isJQueryFiltering?function(e){return u(e.element).is(t)}:"function"==typeof t?function(e){return t(e.element)}:function(e){return n(e.element,t)}},c.prototype.updateSortData=function(t){var e;t?(t=o.makeArray(t),e=this.getItems(t)):e=this.items,this._getSorters(),this._updateItemsSortData(e)},c.prototype._getSorters=function(){var t=this.options.getSortData;for(var e in t){var i=t[e];this._sorters[e]=d(i)}},c.prototype._updateItemsSortData=function(t){for(var e=t&&t.length,i=0;e&&e>i;i++){var n=t[i];n.updateSortData()}};var d=function(){function t(t){if("string"!=typeof t)return t;var i=l(t).split(" "),n=i[0],o=n.match(/^\[(.+)\]$/),r=o&&o[1],s=e(r,n),a=c.sortDataParsers[i[1]];return t=a?function(t){return t&&a(s(t))}:function(t){return t&&s(t)}}function e(t,e){var i;return i=t?function(e){return e.getAttribute(t)}:function(t){var i=t.querySelector(e);return i&&p(i)}}return t}();c.sortDataParsers={parseInt:function(t){return parseInt(t,10)},parseFloat:function(t){return parseFloat(t)}},c.prototype._sort=function(){var t=this.options.sortBy;if(t){var e=[].concat.apply(t,this.sortHistory),i=a(e,this.options.sortAscending);this.filteredItems.sort(i),t!=this.sortHistory[0]&&this.sortHistory.unshift(t)}},c.prototype._mode=function(){var t=this.options.layoutMode,e=this.modes[t];if(!e)throw new Error("No layout mode: "+t);return e.options=this.options[t],e},c.prototype._resetLayout=function(){e.prototype._resetLayout.call(this),this._mode()._resetLayout()},c.prototype._getItemLayoutPosition=function(t){return this._mode()._getItemLayoutPosition(t)},c.prototype._manageStamp=function(t){this._mode()._manageStamp(t)},c.prototype._getContainerSize=function(){return this._mode()._getContainerSize()},c.prototype.needsResizeLayout=function(){return this._mode().needsResizeLayout()},c.prototype.appended=function(t){var e=this.addItems(t);if(e.length){var i=this._filterRevealAdded(e);this.filteredItems=this.filteredItems.concat(i)}},c.prototype.prepended=function(t){var e=this._itemize(t);if(e.length){this._resetLayout(),this._manageStamps();var i=this._filterRevealAdded(e);this.layoutItems(this.filteredItems),this.filteredItems=i.concat(this.filteredItems),this.items=e.concat(this.items)}},c.prototype._filterRevealAdded=function(t){var e=this._filter(t);return this.hide(e.needHide),this.reveal(e.matches),this.layoutItems(e.matches,!0),e.matches},c.prototype.insert=function(t){var e=this.addItems(t);if(e.length){var i,n,o=e.length;for(i=0;o>i;i++)n=e[i],this.element.appendChild(n.element);var r=this._filter(e).matches;for(i=0;o>i;i++)e[i].isLayoutInstant=!0;for(this.arrange(),i=0;o>i;i++)delete e[i].isLayoutInstant;this.reveal(r)}};var f=c.prototype.remove;return c.prototype.remove=function(t){t=o.makeArray(t);var e=this.getItems(t);f.call(this,t);var i=e&&e.length;if(i)for(var n=0;i>n;n++){var r=e[n];o.removeFrom(this.filteredItems,r)}},c.prototype.shuffle=function(){for(var t=0,e=this.items.length;e>t;t++){var i=this.items[t];i.sortData.random=Math.random()}this.options.sortBy="random",this._sort(),this._layout()},c.prototype._noTransition=function(t){var e=this.options.transitionDuration;this.options.transitionDuration=0;var i=t.call(this);return this.options.transitionDuration=e,i},c.prototype.getFilteredItemElements=function(){for(var t=[],e=0,i=this.filteredItems.length;i>e;e++)t.push(this.filteredItems[e].element);return t},c}),function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof exports?module.exports=t:t(jQuery)}(function($){function t(t){var n=t||window.event,o=r.call(arguments,1),u=0,h=0,p=0,c=0,d=0,f=0;if(t=$.event.fix(n),t.type="mousewheel","detail"in n&&(p=-1*n.detail),"wheelDelta"in n&&(p=n.wheelDelta),"wheelDeltaY"in n&&(p=n.wheelDeltaY),"wheelDeltaX"in n&&(h=-1*n.wheelDeltaX),"axis"in n&&n.axis===n.HORIZONTAL_AXIS&&(h=-1*p,p=0),u=0===p?h:p,"deltaY"in n&&(p=-1*n.deltaY,u=p),"deltaX"in n&&(h=n.deltaX,0===p&&(u=-1*h)),0!==p||0!==h){if(1===n.deltaMode){var m=$.data(this,"mousewheel-line-height");u*=m,p*=m,h*=m}else if(2===n.deltaMode){var g=$.data(this,"mousewheel-page-height");u*=g,p*=g,h*=g}if(c=Math.max(Math.abs(p),Math.abs(h)),(!a||a>c)&&(a=c,i(n,c)&&(a/=40)),i(n,c)&&(u/=40,h/=40,p/=40),u=Math[u>=1?"floor":"ceil"](u/a),h=Math[h>=1?"floor":"ceil"](h/a),p=Math[p>=1?"floor":"ceil"](p/a),l.settings.normalizeOffset&&this.getBoundingClientRect){var v=this.getBoundingClientRect();d=t.clientX-v.left,f=t.clientY-v.top}return t.deltaX=h,t.deltaY=p,t.deltaFactor=a,t.offsetX=d,t.offsetY=f,t.deltaMode=0,o.unshift(t,u,h,p),s&&clearTimeout(s),s=setTimeout(e,200),($.event.dispatch||$.event.handle).apply(this,o)}}function e(){a=null}function i(t,e){return l.settings.adjustOldDeltas&&"mousewheel"===t.type&&e%120===0}var n=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],o="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],r=Array.prototype.slice,s,a;if($.event.fixHooks)for(var u=n.length;u;)$.event.fixHooks[n[--u]]=$.event.mouseHooks;var l=$.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var e=o.length;e;)this.addEventListener(o[--e],t,!1);else this.onmousewheel=t;$.data(this,"mousewheel-line-height",l.getLineHeight(this)),$.data(this,"mousewheel-page-height",l.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var e=o.length;e;)this.removeEventListener(o[--e],t,!1);else this.onmousewheel=null;$.removeData(this,"mousewheel-line-height"),$.removeData(this,"mousewheel-page-height")},getLineHeight:function(t){var e=$(t),i=e["offsetParent"in $.fn?"offsetParent":"parent"]();return i.length||(i=$("body")),parseInt(i.css("fontSize"),10)||parseInt(e.css("fontSize"),10)||16},getPageHeight:function(t){return $(t).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};$.fn.extend({mousewheel:function(t){return t?this.bind("mousewheel",t):this.trigger("mousewheel")},unmousewheel:function(t){return this.unbind("mousewheel",t)}})}),jQuery(document).ready(function($){var t="ontouchstart"in document.documentElement;t&&$("body").addClass("envira-touch")}),function(t){"function"==typeof define&&define.amd&&define.amd.jQuery?define(["jquery"],t):t(jQuery)}(function($){"use strict";function t(t){return!t||void 0!==t.allowPageScroll||void 0===t.swipe&&void 0===t.swipeStatus||(t.allowPageScroll=u),void 0!==t.click&&void 0===t.tap&&(t.tap=t.click),t||(t={}),t=$.extend({},$.fn.swipe.defaults,t),this.each(function(){var i=$(this),n=i.data(I);n||(n=new e(this,t),i.data(I,n))})}function e(t,e){function m(t){if(!(lt()||$(t.target).closest(e.excludedElements,Ut).length>0)){var i=t.originalEvent?t.originalEvent:t,n,o=L?i.touches[0]:i;return Vt=x,L?Yt=i.touches.length:t.preventDefault(),Pt=0,Wt=null,Ft=null,Dt=0,At=0,Ht=0,qt=1,Bt=0,Qt=ft(),Nt=vt(),at(),!L||Yt===e.fingers||e.fingers===y||F()?(pt(0,o),Xt=St(),2==Yt&&(pt(1,i.touches[1]),At=Ht=xt(Qt[0].start,Qt[1].start)),(e.swipeStatus||e.pinchStatus)&&(n=j(i,Vt))):n=!1,n===!1?(Vt=_,j(i,Vt),n):(e.hold&&(te=setTimeout($.proxy(function(){Ut.trigger("hold",[i.target]),e.hold&&(n=e.hold.call(Ut,i,i.target))},this),e.longTapThreshold)),ht(!0),null)}}function z(t){var i=t.originalEvent?t.originalEvent:t;if(Vt!==E&&Vt!==_&&!ut()){var n,o=L?i.touches[0]:i,r=ct(o);if(Gt=St(),L&&(Yt=i.touches.length),e.hold&&clearTimeout(te),Vt=b,2==Yt&&(0==At?(pt(1,i.touches[1]),At=Ht=xt(Qt[0].start,Qt[1].start)):(ct(i.touches[1]),Ht=xt(Qt[0].end,Qt[1].end),Ft=Et(Qt[0].end,Qt[1].end)),qt=bt(At,Ht),Bt=Math.abs(At-Ht)),Yt===e.fingers||e.fingers===y||!L||F()){if(Wt=Tt(r.start,r.end),q(t,Wt),Pt=_t(r.start,r.end),Dt=wt(),mt(Wt,Pt),(e.swipeStatus||e.pinchStatus)&&(n=j(i,Vt)),!e.triggerOnTouchEnd||e.triggerOnTouchLeave){var s=!0;if(e.triggerOnTouchLeave){var a=It(this);s=zt(r.end,a)}!e.triggerOnTouchEnd&&s?Vt=k(b):e.triggerOnTouchLeave&&!s&&(Vt=k(E)),(Vt==_||Vt==E)&&j(i,Vt)}}else Vt=_,j(i,Vt);n===!1&&(Vt=_,j(i,Vt))}}function O(t){var i=t.originalEvent;return L&&i.touches.length>0?(st(),!0):(ut()&&(Yt=$t),Gt=St(),Dt=wt(),D()||!W()?(Vt=_,j(i,Vt)):e.triggerOnTouchEnd||0==e.triggerOnTouchEnd&&Vt===b?(t.preventDefault(),Vt=E,j(i,Vt)):!e.triggerOnTouchEnd&&G()?(Vt=E,P(i,Vt,c)):Vt===b&&(Vt=_,j(i,Vt)),ht(!1),null)}function C(){Yt=0,Gt=0,Xt=0,At=0,Ht=0,qt=1,at(),ht(!1)}function M(t){var i=t.originalEvent;e.triggerOnTouchLeave&&(Vt=k(E),j(i,Vt))}function R(){Ut.unbind(Ct,m),Ut.unbind(jt,C),Ut.unbind(Mt,z),Ut.unbind(Rt,O),kt&&Ut.unbind(kt,M),ht(!1)}function k(t){var i=t,n=H(),o=W(),r=D();return!n||r?i=_:!o||t!=b||e.triggerOnTouchEnd&&!e.triggerOnTouchLeave?!o&&t==E&&e.triggerOnTouchLeave&&(i=_):i=E,i}function j(t,e){var i=void 0;return Y()||V()?i=P(t,e,h):(N()||F())&&i!==!1&&(i=P(t,e,p)),ot()&&i!==!1?i=P(t,e,d):rt()&&i!==!1?i=P(t,e,f):nt()&&i!==!1&&(i=P(t,e,c)),e===_&&C(t),e===E&&(L?0==t.touches.length&&C(t):C(t)),i}function P(t,u,l){var m=void 0;if(l==h){if(Ut.trigger("swipeStatus",[u,Wt||null,Pt||0,Dt||0,Yt,Qt]),e.swipeStatus&&(m=e.swipeStatus.call(Ut,t,u,Wt||null,Pt||0,Dt||0,Yt,Qt),m===!1))return!1;if(u==E&&U()){if(Ut.trigger("swipe",[Wt,Pt,Dt,Yt,Qt]),e.swipe&&(m=e.swipe.call(Ut,t,Wt,Pt,Dt,Yt,Qt),m===!1))return!1;switch(Wt){case i:Ut.trigger("swipeLeft",[Wt,Pt,Dt,Yt,Qt]),e.swipeLeft&&(m=e.swipeLeft.call(Ut,t,Wt,Pt,Dt,Yt,Qt));break;case n:Ut.trigger("swipeRight",[Wt,Pt,Dt,Yt,Qt]),e.swipeRight&&(m=e.swipeRight.call(Ut,t,Wt,Pt,Dt,Yt,Qt));break;case o:Ut.trigger("swipeUp",[Wt,Pt,Dt,Yt,Qt]),e.swipeUp&&(m=e.swipeUp.call(Ut,t,Wt,Pt,Dt,Yt,Qt));break;case r:Ut.trigger("swipeDown",[Wt,Pt,Dt,Yt,Qt]),e.swipeDown&&(m=e.swipeDown.call(Ut,t,Wt,Pt,Dt,Yt,Qt))}}}if(l==p){if(Ut.trigger("pinchStatus",[u,Ft||null,Bt||0,Dt||0,Yt,qt,Qt]),e.pinchStatus&&(m=e.pinchStatus.call(Ut,t,u,Ft||null,Bt||0,Dt||0,Yt,qt,Qt),m===!1))return!1;if(u==E&&B())switch(Ft){case s:Ut.trigger("pinchIn",[Ft||null,Bt||0,Dt||0,Yt,qt,Qt]),e.pinchIn&&(m=e.pinchIn.call(Ut,t,Ft||null,Bt||0,Dt||0,Yt,qt,Qt));break;case a:Ut.trigger("pinchOut",[Ft||null,Bt||0,Dt||0,Yt,qt,Qt]),e.pinchOut&&(m=e.pinchOut.call(Ut,t,Ft||null,Bt||0,Dt||0,Yt,qt,Qt))}}return l==c?(u===_||u===E)&&(clearTimeout(Jt),clearTimeout(te),Z()&&!tt()?(Kt=St(),Jt=setTimeout($.proxy(function(){Kt=null,Ut.trigger("tap",[t.target]),e.tap&&(m=e.tap.call(Ut,t,t.target))},this),e.doubleTapThreshold)):(Kt=null,Ut.trigger("tap",[t.target]),e.tap&&(m=e.tap.call(Ut,t,t.target)))):l==d?(u===_||u===E)&&(clearTimeout(Jt),Kt=null,Ut.trigger("doubletap",[t.target]),e.doubleTap&&(m=e.doubleTap.call(Ut,t,t.target))):l==f&&(u===_||u===E)&&(clearTimeout(Jt),Kt=null,Ut.trigger("longtap",[t.target]),e.longTap&&(m=e.longTap.call(Ut,t,t.target))),m}function W(){var t=!0;return null!==e.threshold&&(t=Pt>=e.threshold),t}function D(){var t=!1;return null!==e.cancelThreshold&&null!==Wt&&(t=gt(Wt)-Pt>=e.cancelThreshold),t}function A(){return null!==e.pinchThreshold?Bt>=e.pinchThreshold:!0}function H(){var t;return t=e.maxTimeThreshold&&Dt>=e.maxTimeThreshold?!1:!0}function q(t,s){if(e.allowPageScroll===u||F())t.preventDefault();else{var a=e.allowPageScroll===l;switch(s){case i:(e.swipeLeft&&a||!a&&e.allowPageScroll!=g)&&t.preventDefault();break;case n:(e.swipeRight&&a||!a&&e.allowPageScroll!=g)&&t.preventDefault();break;case o:(e.swipeUp&&a||!a&&e.allowPageScroll!=v)&&t.preventDefault();break;case r:(e.swipeDown&&a||!a&&e.allowPageScroll!=v)&&t.preventDefault()}}}function B(){var t=Q(),e=X(),i=A();return t&&e&&i}function F(){return!!(e.pinchStatus||e.pinchIn||e.pinchOut)}function N(){return!(!B()||!F())}function U(){var t=H(),e=W(),i=Q(),n=X(),o=D(),r=!o&&n&&i&&e&&t;return r}function V(){return!!(e.swipe||e.swipeStatus||e.swipeLeft||e.swipeRight||e.swipeUp||e.swipeDown)}function Y(){return!(!U()||!V())}function Q(){return Yt===e.fingers||e.fingers===y||!L}function X(){return 0!==Qt[0].end.x}function G(){return!!e.tap}function Z(){return!!e.doubleTap}function K(){return!!e.longTap}function J(){if(null==Kt)return!1;var t=St();return Z()&&t-Kt<=e.doubleTapThreshold}function tt(){return J()}function et(){return(1===Yt||!L)&&(isNaN(Pt)||Pt<e.threshold)}function it(){return Dt>e.longTapThreshold&&w>Pt}function nt(){return!(!et()||!G())}function ot(){return!(!J()||!Z())}function rt(){return!(!it()||!K())}function st(){Zt=St(),$t=event.touches.length+1}function at(){Zt=0,$t=0}function ut(){var t=!1;if(Zt){var i=St()-Zt;i<=e.fingerReleaseThreshold&&(t=!0)}return t}function lt(){return!(Ut.data(I+"_intouch")!==!0)}function ht(t){t===!0?(Ut.bind(Mt,z),Ut.bind(Rt,O),kt&&Ut.bind(kt,M)):(Ut.unbind(Mt,z,!1),Ut.unbind(Rt,O,!1),kt&&Ut.unbind(kt,M,!1)),Ut.data(I+"_intouch",t===!0)}function pt(t,e){var i=void 0!==e.identifier?e.identifier:0;return Qt[t].identifier=i,Qt[t].start.x=Qt[t].end.x=e.pageX||e.clientX,Qt[t].start.y=Qt[t].end.y=e.pageY||e.clientY,Qt[t]}function ct(t){var e=void 0!==t.identifier?t.identifier:0,i=dt(e);return i.end.x=t.pageX||t.clientX,i.end.y=t.pageY||t.clientY,i}function dt(t){for(var e=0;e<Qt.length;e++)if(Qt[e].identifier==t)return Qt[e]}function ft(){for(var t=[],e=0;5>=e;e++)t.push({start:{x:0,y:0},end:{x:0,y:0},identifier:0});return t}function mt(t,e){e=Math.max(e,gt(t)),Nt[t].distance=e}function gt(t){return Nt[t]?Nt[t].distance:void 0}function vt(){var t={};return t[i]=yt(i),t[n]=yt(n),t[o]=yt(o),t[r]=yt(r),t}function yt(t){return{direction:t,distance:0}}function wt(){return Gt-Xt}function xt(t,e){var i=Math.abs(t.x-e.x),n=Math.abs(t.y-e.y);return Math.round(Math.sqrt(i*i+n*n))}function bt(t,e){var i=e/t*1;return i.toFixed(2)}function Et(){return 1>qt?a:s}function _t(t,e){return Math.round(Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2)))}function Lt(t,e){var i=t.x-e.x,n=e.y-t.y,o=Math.atan2(n,i),r=Math.round(180*o/Math.PI);return 0>r&&(r=360-Math.abs(r)),r}function Tt(t,e){var s=Lt(t,e);return 45>=s&&s>=0?i:360>=s&&s>=315?i:s>=135&&225>=s?n:s>45&&135>s?r:o}function St(){var t=new Date;return t.getTime()}function It(t){t=$(t);var e=t.offset(),i={left:e.left,right:e.left+t.outerWidth(),top:e.top,bottom:e.top+t.outerHeight()};return i}function zt(t,e){return t.x>e.left&&t.x<e.right&&t.y>e.top&&t.y<e.bottom}var Ot=L||S||!e.fallbackToMouseEvents,Ct=Ot?S?T?"MSPointerDown":"pointerdown":"touchstart":"mousedown",Mt=Ot?S?T?"MSPointerMove":"pointermove":"touchmove":"mousemove",Rt=Ot?S?T?"MSPointerUp":"pointerup":"touchend":"mouseup",kt=Ot?null:"mouseleave",jt=S?T?"MSPointerCancel":"pointercancel":"touchcancel",Pt=0,Wt=null,Dt=0,At=0,Ht=0,qt=1,Bt=0,Ft=0,Nt=null,Ut=$(t),Vt="start",Yt=0,Qt=null,Xt=0,Gt=0,Zt=0,$t=0,Kt=0,Jt=null,te=null;try{Ut.bind(Ct,m),Ut.bind(jt,C)}catch(ee){$.error("events not supported "+Ct+","+jt+" on jQuery.swipe")}this.enable=function(){return Ut.bind(Ct,m),Ut.bind(jt,C),Ut},this.disable=function(){return R(),Ut},this.destroy=function(){R(),Ut.data(I,null),Ut=null},this.option=function(t,i){if(void 0!==e[t]){if(void 0===i)return e[t];e[t]=i}else $.error("Option "+t+" does not exist on jQuery.swipe.options");return null}}var i="left",n="right",o="up",r="down",s="in",a="out",u="none",l="auto",h="swipe",p="pinch",c="tap",d="doubletap",f="longtap",m="hold",g="horizontal",v="vertical",y="all",w=10,x="start",b="move",E="end",_="cancel",L="ontouchstart"in window,T=window.navigator.msPointerEnabled&&!window.navigator.pointerEnabled,S=window.navigator.pointerEnabled||window.navigator.msPointerEnabled,I="TouchSwipe",z={fingers:1,threshold:75,cancelThreshold:null,pinchThreshold:20,maxTimeThreshold:null,fingerReleaseThreshold:250,longTapThreshold:500,doubleTapThreshold:200,swipe:null,swipeLeft:null,swipeRight:null,swipeUp:null,swipeDown:null,swipeStatus:null,pinchIn:null,pinchOut:null,pinchStatus:null,click:null,tap:null,doubleTap:null,longTap:null,hold:null,triggerOnTouchEnd:!0,triggerOnTouchLeave:!1,allowPageScroll:"auto",fallbackToMouseEvents:!0,excludedElements:"label, button, input, select, textarea, a, .noSwipe"};$.fn.swipe=function(e){var i=$(this),n=i.data(I);if(n&&"string"==typeof e){if(n[e])return n[e].apply(this,Array.prototype.slice.call(arguments,1));$.error("Method "+e+" does not exist on jQuery.swipe")}else if(!(n||"object"!=typeof e&&e))return t.apply(this,arguments);return i},$.fn.swipe.defaults=z,$.fn.swipe.phases={PHASE_START:x,PHASE_MOVE:b,PHASE_END:E,PHASE_CANCEL:_},$.fn.swipe.directions={LEFT:i,RIGHT:n,UP:o,DOWN:r,IN:s,OUT:a},$.fn.swipe.pageScroll={NONE:u,HORIZONTAL:g,VERTICAL:v,AUTO:l},$.fn.swipe.fingers={ONE:1,TWO:2,THREE:3,ALL:y}});
1
+ !function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}(this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||[];return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=0,o=i[n];e=e||[];for(var r=this._onceEvents&&this._onceEvents[t];o;){var s=r&&r[o];s&&(this.off(t,o),delete r[o]),o.apply(this,e),n+=s?0:1,o=i[n]}return this}},t}),function(t,e){"use strict";"function"==typeof define&&define.amd?define(["ev-emitter/ev-emitter"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter")):t.imagesLoaded=e(t,t.EvEmitter)}(window,function t(e,i){function n(t,e){for(var i in e)t[i]=e[i];return t}function o(t){var e=[];if(Array.isArray(t))e=t;else if("number"==typeof t.length)for(var i=0;i<t.length;i++)e.push(t[i]);else e.push(t);return e}function r(t,e,i){return this instanceof r?("string"==typeof t&&(t=document.querySelectorAll(t)),this.elements=o(t),this.options=n({},this.options),"function"==typeof e?i=e:n(this.options,e),i&&this.on("always",i),this.getImages(),$&&(this.jqDeferred=new $.Deferred),void setTimeout(function(){this.check()}.bind(this))):new r(t,e,i)}function s(t){this.img=t}function a(t,e){this.url=t,this.element=e,this.img=new Image}var $=e.jQuery,u=e.console;r.prototype=Object.create(i.prototype),r.prototype.options={},r.prototype.getImages=function(){this.images=[],this.elements.forEach(this.addElementImages,this)},r.prototype.addElementImages=function(t){"IMG"==t.nodeName&&this.addImage(t),this.options.background===!0&&this.addElementBackgroundImages(t);var e=t.nodeType;if(e&&l[e]){for(var i=t.querySelectorAll("img"),n=0;n<i.length;n++){var o=i[n];this.addImage(o)}if("string"==typeof this.options.background){var r=t.querySelectorAll(this.options.background);for(n=0;n<r.length;n++){var s=r[n];this.addElementBackgroundImages(s)}}}};var l={1:!0,9:!0,11:!0};return r.prototype.addElementBackgroundImages=function(t){var e=getComputedStyle(t);if(e)for(var i=/url\((['"])?(.*?)\1\)/gi,n=i.exec(e.backgroundImage);null!==n;){var o=n&&n[2];o&&this.addBackground(o,t),n=i.exec(e.backgroundImage)}},r.prototype.addImage=function(t){var e=new s(t);this.images.push(e)},r.prototype.addBackground=function(t,e){var i=new a(t,e);this.images.push(i)},r.prototype.check=function(){function t(t,i,n){setTimeout(function(){e.progress(t,i,n)})}var e=this;return this.progressedCount=0,this.hasAnyBroken=!1,this.images.length?void this.images.forEach(function(e){e.once("progress",t),e.check()}):void this.complete()},r.prototype.progress=function(t,e,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded,this.emitEvent("progress",[this,t,e]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,t),this.progressedCount==this.images.length&&this.complete(),this.options.debug&&u&&u.log("progress: "+i,t,e)},r.prototype.complete=function(){var t=this.hasAnyBroken?"fail":"done";if(this.isComplete=!0,this.emitEvent(t,[this]),this.emitEvent("always",[this]),this.jqDeferred){var e=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[e](this)}},s.prototype=Object.create(i.prototype),s.prototype.check=function(){var t=this.getIsImageComplete();return t?void this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),void(this.proxyImage.src=this.img.src))},s.prototype.getIsImageComplete=function(){return this.img.complete&&void 0!==this.img.naturalWidth},s.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.img,e])},s.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},s.prototype.onload=function(){this.confirm(!0,"onload"),this.unbindEvents()},s.prototype.onerror=function(){this.confirm(!1,"onerror"),this.unbindEvents()},s.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},a.prototype=Object.create(s.prototype),a.prototype.check=function(){this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url;var t=this.getIsImageComplete();t&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())},a.prototype.unbindEvents=function(){this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},a.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.element,e])},r.makeJQueryPlugin=function(t){t=t||e.jQuery,t&&($=t,$.fn.imagesLoaded=function(t,e){var i=new r(this,t,e);return i.jqDeferred.promise($(this))})},r.makeJQueryPlugin(),r}),function(t,e,$,i){"use strict";var n=$("html"),o=$(t),r=$(e),s=$.envirabox=function(){s.open.apply(this,arguments)},a=navigator.userAgent.match(/msie/i),u=null,l=e.createTouch!==i,h=function(t){return t&&t.hasOwnProperty&&t instanceof $},c=function(t){return t&&"string"===$.type(t)},d=function(t){return c(t)&&t.indexOf("%")>0},p=function(t){return t&&!(t.style.overflow&&"hidden"===t.style.overflow)&&(t.clientWidth&&t.scrollWidth>t.clientWidth||t.clientHeight&&t.scrollHeight>t.clientHeight)},f=function(t,e){var i=parseInt(t,10)||0;return e&&d(t)&&(i=s.getViewport()[e]/100*i),Math.ceil(i)},m=function(t,e){return f(t,e)+"px"};$.extend(s,{version:"2.1.5",defaults:{padding:15,margin:40,width:800,height:600,minWidth:100,minHeight:100,maxWidth:9999,maxHeight:9999,pixelRatio:1,autoSize:!0,autoHeight:!1,autoWidth:!1,autoResize:!0,autoCenter:!l,fitToView:!0,aspectRatio:!1,topRatio:.5,leftRatio:.5,scrolling:"auto",wrapCSS:"",arrows:!0,closeBtn:!0,closeClick:!1,nextClick:!1,mouseWheel:!0,autoPlay:!1,playSpeed:3e3,preload:3,modal:!1,loop:!0,ajax:{dataType:"html",headers:{"X-envirabox":!0}},iframe:{scrolling:"auto",preload:!0},swf:{wmode:"transparent",allowfullscreen:"true",allowscriptaccess:"always"},keys:{next:{13:"left",34:"up",39:"left",40:"up"},prev:{8:"right",33:"down",37:"right",38:"down"},close:[27],play:[32],toggle:[70]},direction:{next:"left",prev:"right"},scrollOutside:!0,index:0,type:null,href:null,content:null,title:null,tpl:{wrap:'<div class="envirabox-wrap" tabIndex="-1"><div class="envirabox-skin"><div class="envirabox-outer"><div class="envirabox-inner"></div></div></div></div>',image:'<img class="envirabox-image" src="{href}" />',iframe:'<iframe id="envirabox-frame{rnd}" name="envirabox-frame{rnd}" class="envirabox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen'+(a?' allowtransparency="true"':"")+"></iframe>",error:'<p class="envirabox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',closeBtn:'<a title="Close" class="envirabox-item envirabox-close" href="javascript:;"></a>',next:'<a title="Next" class="envirabox-nav envirabox-next" href="javascript:;"><span></span></a>',prev:'<a title="Previous" class="envirabox-nav envirabox-prev" href="javascript:;"><span></span></a>'},openEffect:"fade",openSpeed:250,openEasing:"swing",openOpacity:!0,openMethod:"zoomIn",closeEffect:"fade",closeSpeed:250,closeEasing:"swing",closeOpacity:!0,closeMethod:"zoomOut",nextEffect:"elastic",nextSpeed:250,nextEasing:"swing",nextMethod:"changeIn",prevEffect:"elastic",prevSpeed:250,prevEasing:"swing",prevMethod:"changeOut",helpers:{overlay:!0,title:!0},onCancel:$.noop,beforeLoad:$.noop,afterLoad:$.noop,beforeShow:$.noop,afterShow:$.noop,beforeChange:$.noop,beforeClose:$.noop,afterClose:$.noop},group:{},opts:{},previous:null,coming:null,current:null,isActive:!1,isOpen:!1,isOpened:!1,wrap:null,skin:null,outer:null,inner:null,player:{timer:null,isActive:!1},ajaxLoad:null,imgPreload:null,transitions:{},helpers:{},open:function(t,e){return t&&($.isPlainObject(e)||(e={}),!1!==s.close(!0))?($.isArray(t)||(t=h(t)?$(t).get():[t]),$.each(t,function(n,o){var r={},a,u,l,d,p,f,m;"object"===$.type(o)&&(o.nodeType&&(o=$(o)),h(o)?(r={href:o.data("envirabox-href")||o.attr("href"),title:$("<div/>").text(o.data("envirabox-title")||o.attr("title")).html(),isDom:!0,element:o},$.metadata&&$.extend(!0,r,o.metadata())):r=o),a=e.href||r.href||(c(o)?o:null),u=e.title!==i?e.title:r.title||"",l=e.content||r.content,d=l?"html":e.type||r.type,!d&&r.isDom&&(d=o.data("envirabox-type"),d||(p=o.prop("class").match(/envirabox\.(\w+)/),d=p?p[1]:null)),c(a)&&(d||(s.isImage(a)?d="image":s.isSWF(a)?d="swf":"#"===a.charAt(0)?d="inline":c(o)&&(d="html",l=o)),"ajax"===d&&(f=a.split(/\s+/,2),a=f.shift(),m=f.shift())),l||("inline"===d?a?l=$(c(a)?a.replace(/.*(?=#[^\s]+$)/,""):a):r.isDom&&(l=o):"html"===d?l=a:d||a||!r.isDom||(d="inline",l=o)),$.extend(r,{href:a,type:d,content:l,title:u,selector:m}),t[n]=r}),s.opts=$.extend(!0,{},s.defaults,e),e.keys!==i&&(s.opts.keys=e.keys?$.extend({},s.defaults.keys,e.keys):!1),s.group=t,s._start(s.opts.index)):void 0},cancel:function(){var t=s.coming;t&&!1===s.trigger("onCancel")||(s.hideLoading(),t&&(s.ajaxLoad&&s.ajaxLoad.abort(),s.ajaxLoad=null,s.imgPreload&&(s.imgPreload.onload=s.imgPreload.onerror=null),t.wrap&&t.wrap.stop(!0,!0).trigger("onReset").remove(),s.coming=null,s.current||s._afterZoomOut(t)))},close:function(t){s.cancel(),!1!==s.trigger("beforeClose")&&(s.unbindEvents(),s.isActive&&(s.isOpen&&t!==!0?(s.isOpen=s.isOpened=!1,s.isClosing=!0,$(".envirabox-item, .envirabox-nav").remove(),s.wrap.stop(!0,!0).removeClass("envirabox-opened"),s.transitions[s.current.closeMethod]()):($(".envirabox-wrap").stop(!0).trigger("onReset").remove(),s._afterZoomOut())))},play:function(t){var e=function(){clearTimeout(s.player.timer)},i=function(){e(),s.current&&s.player.isActive&&(s.player.timer=setTimeout(s.next,s.current.playSpeed))},n=function(){e(),r.unbind(".player"),s.player.isActive=!1,s.trigger("onPlayEnd")},o=function(){s.current&&(s.current.loop||s.current.index<s.group.length-1)&&(s.player.isActive=!0,r.bind({"onCancel.player beforeClose.player":n,"onUpdate.player":i,"beforeLoad.player":e}),i(),s.trigger("onPlayStart"))};t===!0||!s.player.isActive&&t!==!1?o():n()},next:function(t){var e=s.current;e&&(c(t)||(t=e.direction.next),s.jumpto(e.index+1,t,"next"))},prev:function(t){var e=s.current;e&&(c(t)||(t=e.direction.prev),s.jumpto(e.index-1,t,"prev"))},jumpto:function(t,e,n){var o=s.current;o&&(t=f(t),s.direction=e||o.direction[t>=o.index?"next":"prev"],s.router=n||"jumpto",o.loop&&(0>t&&(t=o.group.length+t%o.group.length),t%=o.group.length),o.group[t]!==i&&(s.cancel(),s._start(t)))},reposition:function(t,e){var i=s.current,n=i?i.wrap:null,o;n&&(o=s._getPosition(e),t&&"scroll"===t.type?(delete o.position,n.stop(!0,!0).animate(o,200)):(n.css(o),i.pos=$.extend({},i.dim,o)))},update:function(t){var e=t&&t.originalEvent&&t.originalEvent.type,i=!e||"orientationchange"===e;i&&(clearTimeout(u),u=null),s.isOpen&&!u&&(u=setTimeout(function(){var n=s.current;n&&!s.isClosing&&(s.wrap.removeClass("envirabox-tmp"),(i||"load"===e||"resize"===e&&n.autoResize)&&s._setDimension(),"scroll"===e&&n.canShrink||s.reposition(t),s.trigger("onUpdate"),u=null)},i&&!l?0:300))},toggle:function(t){s.isOpen&&(s.current.fitToView="boolean"===$.type(t)?t:!s.current.fitToView,l&&(s.wrap.removeAttr("style").addClass("envirabox-tmp"),s.trigger("onUpdate")),s.update())},hideLoading:function(){r.unbind(".loading"),$("#envirabox-loading").remove()},showLoading:function(){var t,e;s.hideLoading(),t=$('<div id="envirabox-loading"><div></div></div>').click(s.cancel).appendTo("body"),r.bind("keydown.loading",function(t){27===(t.which||t.keyCode)&&(t.preventDefault(),s.cancel())}),s.defaults.fixed||(e=s.getViewport(),t.css({position:"absolute",top:.5*e.h+e.y,left:.5*e.w+e.x})),s.trigger("onLoading")},getViewport:function(){var e=s.current&&s.current.locked||!1,i={x:o.scrollLeft(),y:o.scrollTop()};return e&&e.length?(i.w=e[0].clientWidth,i.h=e[0].clientHeight):(i.w=l&&t.innerWidth?t.innerWidth:o.width(),i.h=l&&t.innerHeight?t.innerHeight:o.height()),i},unbindEvents:function(){s.wrap&&h(s.wrap)&&s.wrap.unbind(".fb"),r.unbind(".fb"),o.unbind(".fb")},bindEvents:function(){var t=s.current,e;t&&(o.bind("orientationchange.fb"+(l?"":" resize.fb")+(t.autoCenter&&!t.locked?" scroll.fb":""),s.update),e=t.keys,e&&r.bind("keydown.fb",function(n){var o=n.which||n.keyCode,r=n.target||n.srcElement;return 27===o&&s.coming?!1:void(n.ctrlKey||n.altKey||n.shiftKey||n.metaKey||r&&(r.type||$(r).is("[contenteditable]"))||$.each(e,function(e,r){return t.group.length>1&&r[o]!==i?(s[e](r[o]),n.preventDefault(),!1):$.inArray(o,r)>-1?(s[e](),n.preventDefault(),!1):void 0}))}),$.fn.mousewheel&&t.mouseWheel&&s.wrap.bind("mousewheel.fb",function(e,i,n,o){for(var r=e.target||null,a=$(r),u=!1;a.length&&!(u||a.is(".envirabox-skin")||a.is(".envirabox-wrap"));)u=p(a[0]),a=$(a).parent();0===i||u||s.group.length>1&&!t.canShrink&&(o>0||n>0?s.prev(o>0?"down":"left"):(0>o||0>n)&&s.next(0>o?"up":"right"),e.preventDefault())}))},trigger:function(t,e){var i,n=e||s.coming||s.current;if(n){if($.isFunction(n[t])&&(i=n[t].apply(n,Array.prototype.slice.call(arguments,1))),i===!1)return!1;n.helpers&&$.each(n.helpers,function(e,i){i&&s.helpers[e]&&$.isFunction(s.helpers[e][t])&&s.helpers[e][t]($.extend(!0,{},s.helpers[e].defaults,i),n)})}r.trigger(t)},isImage:function(t){return c(t)&&t.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i)},isSWF:function(t){return c(t)&&t.match(/\.(swf)((\?|#).*)?$/i)},_start:function(t){var e={},i,n,o,r,a;if(t=f(t),i=s.group[t]||null,!i)return!1;if(e=$.extend(!0,{},s.opts,i),r=e.margin,a=e.padding,"number"===$.type(r)&&(e.margin=[r,r,r,r]),"number"===$.type(a)&&(e.padding=[a,a,a,a]),e.modal&&$.extend(!0,e,{closeBtn:!1,closeClick:!1,nextClick:!1,arrows:!1,mouseWheel:!1,keys:null,helpers:{overlay:{closeClick:!1}}}),e.autoSize&&(e.autoWidth=e.autoHeight=!0),"auto"===e.width&&(e.autoWidth=!0),"auto"===e.height&&(e.autoHeight=!0),e.group=s.group,e.index=t,s.coming=e,!1===s.trigger("beforeLoad"))return void(s.coming=null);if(o=e.type,n=e.href,!o)return s.coming=null,s.current&&s.router&&"jumpto"!==s.router?(s.current.index=t,s[s.router](s.direction)):!1;if(s.isActive=!0,("image"===o||"swf"===o)&&(e.autoHeight=e.autoWidth=!1,e.scrolling="visible"),"image"===o&&(e.aspectRatio=!0),"iframe"===o&&l&&(e.scrolling="scroll"),e.wrap=$(e.tpl.wrap).addClass("envirabox-"+(l?"mobile":"desktop")+" envirabox-type-"+o+" envirabox-tmp "+e.wrapCSS).appendTo(e.parent||"body"),$.extend(e,{skin:$(".envirabox-skin",e.wrap),outer:$(".envirabox-outer",e.wrap),inner:$(".envirabox-inner",e.wrap)}),$.each(["Top","Right","Bottom","Left"],function(t,i){e.skin.css("padding"+i,m(e.padding[t]))}),s.trigger("onReady"),"inline"===o||"html"===o){if(!e.content||!e.content.length)return s._error("content")}else if(!n)return s._error("href");"image"===o?s._loadImage():"ajax"===o?s._loadAjax():"iframe"===o?s._loadIframe():s._afterLoad()},_error:function(t){$.extend(s.coming,{type:"html",autoWidth:!0,autoHeight:!0,minWidth:0,minHeight:0,scrolling:"no",hasError:t,content:s.coming.tpl.error}),s._afterLoad()},_loadImage:function(){var t=s.imgPreload=new Image;t.onload=function(){this.onload=this.onerror=null,s.coming.width=this.width/s.opts.pixelRatio,s.coming.height=this.height/s.opts.pixelRatio,s._afterLoad()},t.onerror=function(){this.onload=this.onerror=null,s._error("image")},t.src=s.coming.href,t.complete!==!0&&s.showLoading()},_loadAjax:function(){var t=s.coming;s.showLoading(),s.ajaxLoad=$.ajax($.extend({},t.ajax,{url:t.href,error:function(t,e){s.coming&&"abort"!==e?s._error("ajax",t):s.hideLoading()},success:function(e,i){"success"===i&&(t.content=e,s._afterLoad())}}))},_loadIframe:function(){var t=s.coming,e=$(t.tpl.iframe.replace(/\{rnd\}/g,(new Date).getTime())).attr("scrolling",l?"auto":t.iframe.scrolling).attr("src",t.href);$(t.wrap).bind("onReset",function(){try{$(this).find("iframe").hide().attr("src","//about:blank").end().empty()}catch(t){}}),t.iframe.preload&&(s.showLoading(),e.one("load",function(){$(this).data("ready",1),l||$(this).bind("load.fb",s.update),$(this).parents(".envirabox-wrap").width("100%").removeClass("envirabox-tmp").show(),s._afterLoad()})),t.content=e.appendTo(t.inner),t.iframe.preload||s._afterLoad()},_preloadImages:function(){var t=s.group,e=s.current,i=t.length,n=e.preload?Math.min(e.preload,i-1):0,o,r;for(r=1;n>=r;r+=1)o=t[(e.index+r)%i],"image"===o.type&&o.href&&((new Image).src=o.href)},_afterLoad:function(){var t=s.coming,e=s.current,i="envirabox-placeholder",n,o,r,a,u,l;if(s.hideLoading(),t&&s.isActive!==!1){if(!1===s.trigger("afterLoad",t,e))return t.wrap.stop(!0).trigger("onReset").remove(),void(s.coming=null);switch(e&&(s.trigger("beforeChange",e),e.wrap.stop(!0).removeClass("envirabox-opened").find(".envirabox-item, .envirabox-nav").remove()),s.unbindEvents(),n=t,o=t.content,r=t.type,a=t.scrolling,$.extend(s,{wrap:n.wrap,skin:n.skin,outer:n.outer,inner:n.inner,current:n,previous:e}),u=n.href,r){case"inline":case"ajax":case"html":n.selector?o=$("<div>").html(o).find(n.selector):h(o)&&(o.data(i)||o.data(i,$('<div class="'+i+'"></div>').insertAfter(o).hide()),o=o.show().detach(),n.wrap.bind("onReset",function(){$(this).find(o).length&&o.hide().replaceAll(o.data(i)).data(i,!1)}));break;case"image":o=n.tpl.image.replace(/\{href\}/g,u);break;case"swf":o='<object id="envirabox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="'+u+'"></param>',l="",$.each(n.swf,function(t,e){o+='<param name="'+t+'" value="'+e+'"></param>',l+=" "+t+'="'+e+'"'}),o+='<embed src="'+u+'" type="application/x-shockwave-flash" width="100%" height="100%"'+l+"></embed></object>"}h(o)&&o.parent().is(n.inner)||n.inner.append(o),s.trigger("beforeShow"),n.inner.css("overflow","yes"===a?"scroll":"no"===a?"hidden":a),s._setDimension(),s.reposition(),s.isOpen=!1,s.coming=null,s.bindEvents(),s.isOpened?e.prevMethod&&s.transitions[e.prevMethod]():$(".envirabox-wrap").not(n.wrap).stop(!0).trigger("onReset").remove(),s.transitions[s.isOpened?n.nextMethod:n.openMethod](),s._preloadImages()}},_setDimension:function(){var t=s.getViewport(),e=0,i=!1,n=!1,o=s.wrap,r=s.skin,a=s.inner,u=s.current,l=u.width,h=u.height,c=u.minWidth,p=u.minHeight,g=u.maxWidth,v=u.maxHeight,y=u.scrolling,w=u.scrollOutside?u.scrollbarWidth:0,x=u.margin,b=f(x[1]+x[3]),_=f(x[0]+x[2]),I,E,S,T,O,L,z,M,C,k,W,D,P,j,R;if(o.add(r).add(a).width("auto").height("auto").removeClass("envirabox-tmp"),I=f(r.outerWidth(!0)-r.width()),E=f(r.outerHeight(!0)-r.height()),S=b+I,T=_+E,O=d(l)?(t.w-S)*f(l)/100:l,L=d(h)?(t.h-T)*f(h)/100:h,"iframe"===u.type){if(j=u.content,u.autoHeight&&1===j.data("ready"))try{j[0].contentWindow.document.location&&(a.width(O).height(9999),R=j.contents().find("body"),w&&R.css("overflow-x","hidden"),L=R.outerHeight(!0))}catch(H){}}else(u.autoWidth||u.autoHeight)&&(a.addClass("envirabox-tmp"),u.autoWidth||a.width(O),u.autoHeight||a.height(L),u.autoWidth&&(O=a.width()),u.autoHeight&&(L=a.height()),a.removeClass("envirabox-tmp"));if(l=f(O),h=f(L),C=O/L,c=f(d(c)?f(c,"w")-S:c),g=f(d(g)?f(g,"w")-S:g),p=f(d(p)?f(p,"h")-T:p),v=f(d(v)?f(v,"h")-T:v),z=g,M=v,u.fitToView&&(g=Math.min(t.w-S,g),v=Math.min(t.h-T,v)),D=t.w-b,P=t.h-_,u.aspectRatio?(l>g&&(l=g,h=f(l/C)),h>v&&(h=v,l=f(h*C)),c>l&&(l=c,h=f(l/C)),p>h&&(h=p,l=f(h*C))):(l=Math.max(c,Math.min(l,g)),u.autoHeight&&"iframe"!==u.type&&(a.width(l),h=a.height()),h=Math.max(p,Math.min(h,v))),u.fitToView)if(a.width(l).height(h),o.width(l+I),k=o.width(),W=o.height(),u.aspectRatio)for(;(k>D||W>P)&&l>c&&h>p&&!(e++>19);)h=Math.max(p,Math.min(v,h-10)),l=f(h*C),c>l&&(l=c,h=f(l/C)),l>g&&(l=g,h=f(l/C)),a.width(l).height(h),o.width(l+I),k=o.width(),W=o.height();else l=Math.max(c,Math.min(l,l-(k-D))),h=Math.max(p,Math.min(h,h-(W-P)));w&&"auto"===y&&L>h&&D>l+I+w&&(l+=w),a.width(l).height(h),o.width(l+I),k=o.width(),W=o.height(),i=(k>D||W>P)&&l>c&&h>p,n=u.aspectRatio?z>l&&M>h&&O>l&&L>h:(z>l||M>h)&&(O>l||L>h),$.extend(u,{dim:{width:m(k),height:m(W)},origWidth:O,origHeight:L,canShrink:i,canExpand:n,wPadding:I,hPadding:E,wrapSpace:W-r.outerHeight(!0),skinSpace:r.height()-h}),!j&&u.autoHeight&&h>p&&v>h&&!n&&a.height("auto")},_getPosition:function(t){var e=s.current,i=s.getViewport(),n=e.margin,o=s.wrap.width()+n[1]+n[3],r=s.wrap.height()+n[0]+n[2],a={position:"absolute",top:n[0],left:n[3]};return e.helpers.title.type&&"float"==e.helpers.title.type&&(r+=$(".envirabox-skin .envirabox-title").height()),e.autoCenter&&e.fixed&&!t&&r<=i.h&&o<=i.w?a.position="fixed":e.locked||(a.top+=i.y,a.left+=i.x),a.top=m(Math.max(a.top,a.top+(i.h-r)*e.topRatio)),a.left=m(Math.max(a.left,a.left+(i.w-o)*e.leftRatio)),a},_afterZoomIn:function(){var t=s.current;t&&(s.isOpen=s.isOpened=!0,s.wrap.css("overflow","visible").addClass("envirabox-opened").hide().show(0),s.update(),(t.closeClick||t.nextClick&&s.group.length>1)&&s.inner.css("cursor","pointer").bind("click.fb",function(e){$(e.target).is("a")||$(e.target).parent().is("a")||(e.preventDefault(),s[t.closeClick?"close":"next"]())}),t.closeBtn&&$(t.tpl.closeBtn).appendTo(s.skin).bind("click.fb",function(t){t.preventDefault(),s.close()}),t.arrows&&s.group.length>1&&((t.loop||t.index>0)&&$(t.tpl.prev).appendTo(s.outer).bind("click.fb",s.prev),(t.loop||t.index<s.group.length-1)&&$(t.tpl.next).appendTo(s.outer).bind("click.fb",s.next)),s.trigger("afterShow"),t.loop||t.index!==t.group.length-1?s.opts.autoPlay&&!s.player.isActive&&(s.opts.autoPlay=!1,s.play(!0)):s.play(!1))},_afterZoomOut:function(t){t=t||s.current,$(".envirabox-wrap").trigger("onReset").remove(),$.extend(s,{group:{},opts:{},router:!1,current:null,isActive:!1,isOpened:!1,isOpen:!1,isClosing:!1,wrap:null,skin:null,outer:null,inner:null}),s.trigger("afterClose",t)}}),s.transitions={getOrigPosition:function(){var t=s.current,e=t.element,i=t.orig,n={},o=50,r=50,a=t.hPadding,u=t.wPadding,l=s.getViewport();return!i&&t.isDom&&e.is(":visible")&&(i=e.find("img:first"),i.length||(i=e)),h(i)?(n=i.offset(),i.is("img")&&(o=i.outerWidth(),r=i.outerHeight())):(n.top=l.y+(l.h-r)*t.topRatio,n.left=l.x+(l.w-o)*t.leftRatio),("fixed"===s.wrap.css("position")||t.locked)&&(n.top-=l.y,n.left-=l.x),n={top:m(n.top-a*t.topRatio),left:m(n.left-u*t.leftRatio),width:m(o+u),height:m(r+a)}},step:function(t,e){var i,n,o,r=e.prop,a=s.current,u=a.wrapSpace,l=a.skinSpace;("width"===r||"height"===r)&&(i=e.end===e.start?1:(t-e.start)/(e.end-e.start),s.isClosing&&(i=1-i),n="width"===r?a.wPadding:a.hPadding,o=t-n,s.skin[r](f("width"===r?o:o-u*i)),s.inner[r](f("width"===r?o:o-u*i-l*i)))},zoomIn:function(){var t=s.current,e=t.pos,i=t.openEffect,n="elastic"===i,o=$.extend({opacity:1},e);delete o.position,n?(e=this.getOrigPosition(),t.openOpacity&&(e.opacity=.1)):"fade"===i&&(e.opacity=.1),s.wrap.css(e).animate(o,{duration:"none"===i?0:t.openSpeed,easing:t.openEasing,step:n?this.step:null,complete:s._afterZoomIn})},zoomOut:function(){var t=s.current,e=t.closeEffect,i="elastic"===e,n={opacity:.1};i&&(n=this.getOrigPosition(),t.closeOpacity&&(n.opacity=.1)),s.wrap.animate(n,{duration:"none"===e?0:t.closeSpeed,easing:t.closeEasing,step:i?this.step:null,complete:s._afterZoomOut})},changeIn:function(){var t=s.current,e=t.nextEffect,i=t.pos,n={opacity:1},o=s.direction,r=200,a;i.opacity=.1,"elastic"===e&&(a="down"===o||"up"===o?"top":"left","down"===o||"right"===o?(i[a]=m(f(i[a])-r),n[a]="+="+r+"px"):(i[a]=m(f(i[a])+r),n[a]="-="+r+"px")),"none"===e?s._afterZoomIn():s.wrap.css(i).animate(n,{duration:t.nextSpeed,easing:t.nextEasing,complete:s._afterZoomIn})},changeOut:function(){var t=s.previous,e=t.prevEffect,i={opacity:.1},n=s.direction,o=200;"elastic"===e&&(i["down"===n||"up"===n?"top":"left"]=("up"===n||"left"===n?"-":"+")+"="+o+"px"),t.wrap.animate(i,{duration:"none"===e?0:t.prevSpeed,easing:t.prevEasing,complete:function(){$(this).trigger("onReset").remove()}})}},s.helpers.overlay={defaults:{closeClick:!0,speedOut:200,showEarly:!0,css:{},locked:!l,fixed:!0},overlay:null,fixed:!1,el:$("html"),create:function(t){var e;t=$.extend({},this.defaults,t),this.overlay&&this.close(),e=s.coming?s.coming.parent:t.parent,this.overlay=$('<div class="envirabox-overlay"></div>').appendTo(e&&e.lenth?e:"body"),this.fixed=!1,t.fixed&&s.defaults.fixed&&(this.overlay.addClass("envirabox-overlay-fixed"),this.fixed=!0)},open:function(t){var e=this;t=$.extend({},this.defaults,t),this.overlay?this.overlay.unbind(".overlay").width("auto").height("auto"):this.create(t),this.fixed||(o.bind("resize.overlay",$.proxy(this.update,this)),this.update()),t.closeClick&&this.overlay.bind("click.overlay",function(t){return $(t.target).hasClass("envirabox-overlay")?(s.isActive?s.close():e.close(),!1):void 0}),this.overlay.css(t.css).show()},close:function(){o.unbind("resize.overlay"),this.el.hasClass("envirabox-lock")&&($(".envirabox-margin").removeClass("envirabox-margin"),this.el.removeClass("envirabox-lock"),o.scrollTop(this.scrollV).scrollLeft(this.scrollH)),$(".envirabox-overlay").remove().hide(),$.extend(this,{overlay:null,fixed:!1})},update:function(){var t="100%",i;this.overlay.width(t).height("100%"),a?(i=Math.max(e.documentElement.offsetWidth,e.body.offsetWidth),r.width()>i&&(t=r.width())):r.width()>o.width()&&(t=r.width()),this.overlay.width(t).height(r.height())},onReady:function(t,e){var i=this.overlay;$(".envirabox-overlay").stop(!0,!0),i||this.create(t),t.locked&&this.fixed&&e.fixed&&(e.locked=this.overlay.append(e.wrap),e.fixed=!1),t.showEarly===!0&&this.beforeShow.apply(this,arguments)},beforeShow:function(t,e){e.locked&&!this.el.hasClass("envirabox-lock")&&(this.fixPosition!==!1&&$("*").filter(function(){return"fixed"===$(this).css("position")&&!$(this).hasClass("envirabox-overlay")&&!$(this).hasClass("envirabox-wrap")}).addClass("envirabox-margin"),this.el.addClass("envirabox-margin"),this.scrollV=o.scrollTop(),this.scrollH=o.scrollLeft(),this.el.addClass("envirabox-lock"),o.scrollTop(this.scrollV).scrollLeft(this.scrollH)),this.open(t)},onUpdate:function(){this.fixed||this.update()},afterClose:function(t){this.overlay&&!s.coming&&this.overlay.fadeOut(t.speedOut,$.proxy(this.close,this))}},s.helpers.title={defaults:{type:"float",position:"bottom"},beforeShow:function(t){var e=s.current,i=e.title,n=t.type,o,r;if($.isFunction(i)&&(i=i.call(e.element,e)),c(i)&&""!==$.trim(i)){switch(o=$('<div class="envirabox-title envirabox-title-'+n+'-wrap">'+i+"</div>"),n){case"inside":r=s.skin;break;case"outside":r=s.wrap;break;case"over":r=s.inner;break;default:r=s.skin,o.appendTo("body"),a&&o.width(o.width()),o.wrapInner('<span class="child"></span>'),s.current.margin[2]+=Math.abs(f(o.css("margin-bottom")))}o["top"===t.position?"prependTo":"appendTo"](r)}}},$.fn.envirabox=function(t){var e,i=$(this),n=this.selector||"",o=function(o){var r=$(this).blur(),a=e,u,l;o.ctrlKey||o.altKey||o.shiftKey||o.metaKey||r.is(".envirabox-wrap")||(u=t.groupAttr||"data-envirabox-group",l=r.attr(u),l||(u="rel",l=r.get(0)[u]),l&&""!==l&&"nofollow"!==l&&(r=n.length?$(n):i,r=r.filter("["+u+'="'+l+'"]'),a=r.index(this)),t.index=a,s.open(r,t)!==!1&&o.preventDefault())};return t=t||{},e=t.index||0,n&&t.live!==!1?r.undelegate(n,"click.fb-start").delegate(n+":not('.envirabox-item, .envirabox-nav')","click.fb-start",o):i.unbind("click.fb-start").bind("click.fb-start",o),this.filter("[data-envirabox-start=1]").trigger("click"),this},r.ready(function(){var e,o;$.scrollbarWidth===i&&($.scrollbarWidth=function(){var t=$('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo("body"),e=t.children(),i=e.innerWidth()-e.height(99).innerWidth();return t.remove(),i}),$.support.fixedPosition===i&&($.support.fixedPosition=function(){var t=$('<div style="position:fixed;top:20px;"></div>').appendTo("body"),e=20===t[0].offsetTop||15===t[0].offsetTop;return t.remove(),e}()),$.extend(s.defaults,{scrollbarWidth:$.scrollbarWidth(),fixed:$.support.fixedPosition,parent:$("body")}),e=$(t).width(),n.addClass("envirabox-lock-test"),o=$(t).width(),n.removeClass("envirabox-lock-test"),$("<style type='text/css'>.envirabox-margin{margin-right:"+(o-e)+"px;}</style>").appendTo("head")})}(window,document,jQuery),function(t,e){"use strict";"function"==typeof define&&define.amd?define("jquery-bridget/jquery-bridget",["jquery"],function(i){e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("jquery")):t.jQueryBridget=e(t,t.jQuery)}(window,function e(t,i){"use strict";function n(e,n,$){function s(t,i,n){var o,r="$()."+e+'("'+i+'")';return t.each(function(t,s){var u=$.data(s,e);if(!u)return void a(e+" not initialized. Cannot call methods, i.e. "+r);var l=u[i];if(!l||"_"==i.charAt(0))return void a(r+" is not a valid method");var h=l.apply(u,n);o=void 0===o?h:o}),void 0!==o?o:t}function u(t,i){t.each(function(t,o){var r=$.data(o,e);r?(r.option(i),r._init()):(r=new n(o,i),$.data(o,e,r))})}$=$||i||t.jQuery,$&&(n.prototype.option||(n.prototype.option=function(t){$.isPlainObject(t)&&(this.options=$.extend(!0,this.options,t))}),$.fn[e]=function(t){if("string"==typeof t){var e=r.call(arguments,1);return s(this,t,e)}return u(this,t),this},o($))}function o($){!$||$&&$.bridget||($.bridget=n)}var r=Array.prototype.slice,s=t.console,a="undefined"==typeof s?function(){}:function(t){s.error(t)};return o(i||t.jQuery),n}),function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}(this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=0,o=i[n];e=e||[];for(var r=this._onceEvents&&this._onceEvents[t];o;){var s=r&&r[o];s&&(this.off(t,o),delete r[o]),o.apply(this,e),n+=s?0:1,o=i[n]}return this}},t}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("get-size/get-size",[],function(){return e()}):"object"==typeof module&&module.exports?module.exports=e():t.getSize=e()}(window,function i(){"use strict";function t(t){var e=parseFloat(t),i=-1==t.indexOf("%")&&!isNaN(e);return i&&e}function e(){}function i(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0;u>e;e++){var i=a[e];t[i]=0}return t}function n(t){var e=getComputedStyle(t);return e||s("Style returned "+e+". Are you running this code in a hidden iframe on Firefox? See http://bit.ly/getsizebug1"),e}function o(){if(!l){l=!0;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.boxSizing="border-box";var i=document.body||document.documentElement;i.appendChild(e);var o=n(e);r.isBoxSizeOuter=h=200==t(o.width),i.removeChild(e)}}function r(e){if(o(),"string"==typeof e&&(e=document.querySelector(e)),e&&"object"==typeof e&&e.nodeType){var r=n(e);if("none"==r.display)return i();var s={};s.width=e.offsetWidth,s.height=e.offsetHeight;for(var l=s.isBorderBox="border-box"==r.boxSizing,c=0;u>c;c++){var d=a[c],p=r[d],f=parseFloat(p);s[d]=isNaN(f)?0:f}var m=s.paddingLeft+s.paddingRight,g=s.paddingTop+s.paddingBottom,v=s.marginLeft+s.marginRight,y=s.marginTop+s.marginBottom,w=s.borderLeftWidth+s.borderRightWidth,x=s.borderTopWidth+s.borderBottomWidth,b=l&&h,_=t(r.width);
2
+ _!==!1&&(s.width=_+(b?0:m+w));var I=t(r.height);return I!==!1&&(s.height=I+(b?0:g+x)),s.innerWidth=s.width-(m+w),s.innerHeight=s.height-(g+x),s.outerWidth=s.width+v,s.outerHeight=s.height+y,s}}var s="undefined"==typeof console?e:function(t){console.error(t)},a=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"],u=a.length,l=!1,h;return r}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("desandro-matches-selector/matches-selector",e):"object"==typeof module&&module.exports?module.exports=e():t.matchesSelector=e()}(window,function n(){"use strict";var t=function(){var t=Element.prototype;if(t.matches)return"matches";if(t.matchesSelector)return"matchesSelector";for(var e=["webkit","moz","ms","o"],i=0;i<e.length;i++){var n=e[i],o=n+"MatchesSelector";if(t[o])return o}}();return function e(i,n){return i[t](n)}}),function(t,e){"function"==typeof define&&define.amd?define("fizzy-ui-utils/utils",["desandro-matches-selector/matches-selector"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("desandro-matches-selector")):t.fizzyUIUtils=e(t,t.matchesSelector)}(window,function o(t,e){var i={};i.extend=function(t,e){for(var i in e)t[i]=e[i];return t},i.modulo=function(t,e){return(t%e+e)%e},i.makeArray=function(t){var e=[];if(Array.isArray(t))e=t;else if(t&&"number"==typeof t.length)for(var i=0;i<t.length;i++)e.push(t[i]);else e.push(t);return e},i.removeFrom=function(t,e){var i=t.indexOf(e);-1!=i&&t.splice(i,1)},i.getParent=function(t,i){for(;t!=document.body;)if(t=t.parentNode,e(t,i))return t},i.getQueryElement=function(t){return"string"==typeof t?document.querySelector(t):t},i.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},i.filterFindElements=function(t,n){t=i.makeArray(t);var o=[];return t.forEach(function(t){if(t instanceof HTMLElement){if(!n)return void o.push(t);e(t,n)&&o.push(t);for(var i=t.querySelectorAll(n),r=0;r<i.length;r++)o.push(i[r])}}),o},i.debounceMethod=function(t,e,i){var n=t.prototype[e],o=e+"Timeout";t.prototype[e]=function(){var t=this[o];t&&clearTimeout(t);var e=arguments,r=this;this[o]=setTimeout(function(){n.apply(r,e),delete r[o]},i||100)}},i.docReady=function(t){"complete"==document.readyState?t():document.addEventListener("DOMContentLoaded",t)},i.toDashed=function(t){return t.replace(/(.)([A-Z])/g,function(t,e,i){return e+"-"+i}).toLowerCase()};var n=t.console;return i.htmlInit=function(e,o){i.docReady(function(){var r=i.toDashed(o),s="data-"+r,a=document.querySelectorAll("["+s+"]"),u=document.querySelectorAll(".js-"+r),l=i.makeArray(a).concat(i.makeArray(u)),h=s+"-options",c=t.jQuery;l.forEach(function(t){var i=t.getAttribute(s)||t.getAttribute(h),r;try{r=i&&JSON.parse(i)}catch(a){return void(n&&n.error("Error parsing "+s+" on "+t.className+": "+a))}var u=new e(t,r);c&&c.data(t,o,u)})})},i}),function(t,e){"function"==typeof define&&define.amd?define("outlayer/item",["ev-emitter/ev-emitter","get-size/get-size"],e):"object"==typeof module&&module.exports?module.exports=e(require("ev-emitter"),require("get-size")):(t.Outlayer={},t.Outlayer.Item=e(t.EvEmitter,t.getSize))}(window,function r(t,e){"use strict";function i(t){for(var e in t)return!1;return e=null,!0}function n(t,e){t&&(this.element=t,this.layout=e,this.position={x:0,y:0},this._create())}function o(t){return t.replace(/([A-Z])/g,function(t){return"-"+t.toLowerCase()})}var r=document.documentElement.style,s="string"==typeof r.transition?"transition":"WebkitTransition",a="string"==typeof r.transform?"transform":"WebkitTransform",u={WebkitTransition:"webkitTransitionEnd",transition:"transitionend"}[s],l={transform:a,transition:s,transitionDuration:s+"Duration",transitionProperty:s+"Property",transitionDelay:s+"Delay"},h=n.prototype=Object.create(t.prototype);h.constructor=n,h._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},h.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},h.getSize=function(){this.size=e(this.element)},h.css=function(t){var e=this.element.style;for(var i in t){var n=l[i]||i;e[n]=t[i]}},h.getPosition=function(){var t=getComputedStyle(this.element),e=this.layout._getOption("originLeft"),i=this.layout._getOption("originTop"),n=t[e?"left":"right"],o=t[i?"top":"bottom"],r=this.layout.size,s=-1!=n.indexOf("%")?parseFloat(n)/100*r.width:parseInt(n,10),a=-1!=o.indexOf("%")?parseFloat(o)/100*r.height:parseInt(o,10);s=isNaN(s)?0:s,a=isNaN(a)?0:a,s-=e?r.paddingLeft:r.paddingRight,a-=i?r.paddingTop:r.paddingBottom,this.position.x=s,this.position.y=a},h.layoutPosition=function(){var t=this.layout.size,e={},i=this.layout._getOption("originLeft"),n=this.layout._getOption("originTop"),o=i?"paddingLeft":"paddingRight",r=i?"left":"right",s=i?"right":"left",a=this.position.x+t[o];e[r]=this.getXValue(a),e[s]="";var u=n?"paddingTop":"paddingBottom",l=n?"top":"bottom",h=n?"bottom":"top",c=this.position.y+t[u];e[l]=this.getYValue(c),e[h]="",this.css(e),this.emitEvent("layout",[this])},h.getXValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&!e?t/this.layout.size.width*100+"%":t+"px"},h.getYValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&e?t/this.layout.size.height*100+"%":t+"px"},h._transitionTo=function(t,e){this.getPosition();var i=this.position.x,n=this.position.y,o=parseInt(t,10),r=parseInt(e,10),s=o===this.position.x&&r===this.position.y;if(this.setPosition(t,e),s&&!this.isTransitioning)return void this.layoutPosition();var a=t-i,u=e-n,l={};l.transform=this.getTranslate(a,u),this.transition({to:l,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},h.getTranslate=function(t,e){var i=this.layout._getOption("originLeft"),n=this.layout._getOption("originTop");return t=i?t:-t,e=n?e:-e,"translate3d("+t+"px, "+e+"px, 0)"},h.goTo=function(t,e){this.setPosition(t,e),this.layoutPosition()},h.moveTo=h._transitionTo,h.setPosition=function(t,e){this.position.x=parseInt(t,10),this.position.y=parseInt(e,10)},h._nonTransition=function(t){this.css(t.to),t.isCleaning&&this._removeStyles(t.to);for(var e in t.onTransitionEnd)t.onTransitionEnd[e].call(this)},h.transition=function(t){if(!parseFloat(this.layout.options.transitionDuration))return void this._nonTransition(t);var e=this._transn;for(var i in t.onTransitionEnd)e.onEnd[i]=t.onTransitionEnd[i];for(i in t.to)e.ingProperties[i]=!0,t.isCleaning&&(e.clean[i]=!0);if(t.from){this.css(t.from);var n=this.element.offsetHeight;n=null}this.enableTransition(t.to),this.css(t.to),this.isTransitioning=!0};var c="opacity,"+o(a);h.enableTransition=function(){if(!this.isTransitioning){var t=this.layout.options.transitionDuration;t="number"==typeof t?t+"ms":t,this.css({transitionProperty:c,transitionDuration:t,transitionDelay:this.staggerDelay||0}),this.element.addEventListener(u,this,!1)}},h.onwebkitTransitionEnd=function(t){this.ontransitionend(t)},h.onotransitionend=function(t){this.ontransitionend(t)};var d={"-webkit-transform":"transform"};h.ontransitionend=function(t){if(t.target===this.element){var e=this._transn,n=d[t.propertyName]||t.propertyName;if(delete e.ingProperties[n],i(e.ingProperties)&&this.disableTransition(),n in e.clean&&(this.element.style[t.propertyName]="",delete e.clean[n]),n in e.onEnd){var o=e.onEnd[n];o.call(this),delete e.onEnd[n]}this.emitEvent("transitionEnd",[this])}},h.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(u,this,!1),this.isTransitioning=!1},h._removeStyles=function(t){var e={};for(var i in t)e[i]="";this.css(e)};var p={transitionProperty:"",transitionDuration:"",transitionDelay:""};return h.removeTransitionStyles=function(){this.css(p)},h.stagger=function(t){t=isNaN(t)?0:t,this.staggerDelay=t+"ms"},h.removeElem=function(){this.element.parentNode.removeChild(this.element),this.css({display:""}),this.emitEvent("remove",[this])},h.remove=function(){return s&&parseFloat(this.layout.options.transitionDuration)?(this.once("transitionEnd",function(){this.removeElem()}),void this.hide()):void this.removeElem()},h.reveal=function(){delete this.isHidden,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("visibleStyle");e[i]=this.onRevealTransitionEnd,this.transition({from:t.hiddenStyle,to:t.visibleStyle,isCleaning:!0,onTransitionEnd:e})},h.onRevealTransitionEnd=function(){this.isHidden||this.emitEvent("reveal")},h.getHideRevealTransitionEndProperty=function(t){var e=this.layout.options[t];if(e.opacity)return"opacity";for(var i in e)return i},h.hide=function(){this.isHidden=!0,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("hiddenStyle");e[i]=this.onHideTransitionEnd,this.transition({from:t.visibleStyle,to:t.hiddenStyle,isCleaning:!0,onTransitionEnd:e})},h.onHideTransitionEnd=function(){this.isHidden&&(this.css({display:"none"}),this.emitEvent("hide"))},h.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},n}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("outlayer/outlayer",["ev-emitter/ev-emitter","get-size/get-size","fizzy-ui-utils/utils","./item"],function(i,n,o,r){return e(t,i,n,o,r)}):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter"),require("get-size"),require("fizzy-ui-utils"),require("./item")):t.Outlayer=e(t,t.EvEmitter,t.getSize,t.fizzyUIUtils,t.Outlayer.Item)}(window,function s(t,e,i,n,o){"use strict";function r(t,e){var i=n.getQueryElement(t);if(!i)return void(u&&u.error("Bad element for "+this.constructor.namespace+": "+(i||t)));this.element=i,l&&(this.$element=l(this.element)),this.options=n.extend({},this.constructor.defaults),this.option(e);var o=++c;this.element.outlayerGUID=o,d[o]=this,this._create();var r=this._getOption("initLayout");r&&this.layout()}function s(t){function e(){t.apply(this,arguments)}return e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e}function a(t){if("number"==typeof t)return t;var e=t.match(/(^\d*\.?\d*)(\w*)/),i=e&&e[1],n=e&&e[2];if(!i.length)return 0;i=parseFloat(i);var o=f[n]||1;return i*o}var u=t.console,l=t.jQuery,h=function(){},c=0,d={};r.namespace="outlayer",r.Item=o,r.defaults={containerStyle:{position:"relative"},initLayout:!0,originLeft:!0,originTop:!0,resize:!0,resizeContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}};var p=r.prototype;n.extend(p,e.prototype),p.option=function(t){n.extend(this.options,t)},p._getOption=function(t){var e=this.constructor.compatOptions[t];return e&&void 0!==this.options[e]?this.options[e]:this.options[t]},r.compatOptions={initLayout:"isInitLayout",horizontal:"isHorizontal",layoutInstant:"isLayoutInstant",originLeft:"isOriginLeft",originTop:"isOriginTop",resize:"isResizeBound",resizeContainer:"isResizingContainer"},p._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),n.extend(this.element.style,this.options.containerStyle);var t=this._getOption("resize");t&&this.bindResize()},p.reloadItems=function(){this.items=this._itemize(this.element.children)},p._itemize=function(t){for(var e=this._filterFindItemElements(t),i=this.constructor.Item,n=[],o=0;o<e.length;o++){var r=e[o],s=new i(r,this);n.push(s)}return n},p._filterFindItemElements=function(t){return n.filterFindElements(t,this.options.itemSelector)},p.getItemElements=function(){return this.items.map(function(t){return t.element})},p.layout=function(){this._resetLayout(),this._manageStamps();var t=this._getOption("layoutInstant"),e=void 0!==t?t:!this._isLayoutInited;this.layoutItems(this.items,e),this._isLayoutInited=!0},p._init=p.layout,p._resetLayout=function(){this.getSize()},p.getSize=function(){this.size=i(this.element)},p._getMeasurement=function(t,e){var n=this.options[t],o;n?("string"==typeof n?o=this.element.querySelector(n):n instanceof HTMLElement&&(o=n),this[t]=o?i(o)[e]:n):this[t]=0},p.layoutItems=function(t,e){t=this._getItemsForLayout(t),this._layoutItems(t,e),this._postLayout()},p._getItemsForLayout=function(t){return t.filter(function(t){return!t.isIgnored})},p._layoutItems=function(t,e){if(this._emitCompleteOnItems("layout",t),t&&t.length){var i=[];t.forEach(function(t){var n=this._getItemLayoutPosition(t);n.item=t,n.isInstant=e||t.isLayoutInstant,i.push(n)},this),this._processLayoutQueue(i)}},p._getItemLayoutPosition=function(){return{x:0,y:0}},p._processLayoutQueue=function(t){this.updateStagger(),t.forEach(function(t,e){this._positionItem(t.item,t.x,t.y,t.isInstant,e)},this)},p.updateStagger=function(){var t=this.options.stagger;return null===t||void 0===t?void(this.stagger=0):(this.stagger=a(t),this.stagger)},p._positionItem=function(t,e,i,n,o){n?t.goTo(e,i):(t.stagger(o*this.stagger),t.moveTo(e,i))},p._postLayout=function(){this.resizeContainer()},p.resizeContainer=function(){var t=this._getOption("resizeContainer");if(t){var e=this._getContainerSize();e&&(this._setContainerMeasure(e.width,!0),this._setContainerMeasure(e.height,!1))}},p._getContainerSize=h,p._setContainerMeasure=function(t,e){if(void 0!==t){var i=this.size;i.isBorderBox&&(t+=e?i.paddingLeft+i.paddingRight+i.borderLeftWidth+i.borderRightWidth:i.paddingBottom+i.paddingTop+i.borderTopWidth+i.borderBottomWidth),t=Math.max(t,0),this.element.style[e?"width":"height"]=t+"px"}},p._emitCompleteOnItems=function(t,e){function i(){o.dispatchEvent(t+"Complete",null,[e])}function n(){s++,s==r&&i()}var o=this,r=e.length;if(!e||!r)return void i();var s=0;e.forEach(function(e){e.once(t,n)})},p.dispatchEvent=function(t,e,i){var n=e?[e].concat(i):i;if(this.emitEvent(t,n),l)if(this.$element=this.$element||l(this.element),e){var o=l.Event(e);o.type=t,this.$element.trigger(o,i)}else this.$element.trigger(t,i)},p.ignore=function(t){var e=this.getItem(t);e&&(e.isIgnored=!0)},p.unignore=function(t){var e=this.getItem(t);e&&delete e.isIgnored},p.stamp=function(t){t=this._find(t),t&&(this.stamps=this.stamps.concat(t),t.forEach(this.ignore,this))},p.unstamp=function(t){t=this._find(t),t&&t.forEach(function(t){n.removeFrom(this.stamps,t),this.unignore(t)},this)},p._find=function(t){return t?("string"==typeof t&&(t=this.element.querySelectorAll(t)),t=n.makeArray(t)):void 0},p._manageStamps=function(){this.stamps&&this.stamps.length&&(this._getBoundingRect(),this.stamps.forEach(this._manageStamp,this))},p._getBoundingRect=function(){var t=this.element.getBoundingClientRect(),e=this.size;this._boundingRect={left:t.left+e.paddingLeft+e.borderLeftWidth,top:t.top+e.paddingTop+e.borderTopWidth,right:t.right-(e.paddingRight+e.borderRightWidth),bottom:t.bottom-(e.paddingBottom+e.borderBottomWidth)}},p._manageStamp=h,p._getElementOffset=function(t){var e=t.getBoundingClientRect(),n=this._boundingRect,o=i(t),r={left:e.left-n.left-o.marginLeft,top:e.top-n.top-o.marginTop,right:n.right-e.right-o.marginRight,bottom:n.bottom-e.bottom-o.marginBottom};return r},p.handleEvent=n.handleEvent,p.bindResize=function(){t.addEventListener("resize",this),this.isResizeBound=!0},p.unbindResize=function(){t.removeEventListener("resize",this),this.isResizeBound=!1},p.onresize=function(){this.resize()},n.debounceMethod(r,"onresize",100),p.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},p.needsResizeLayout=function(){var t=i(this.element),e=this.size&&t;return e&&t.innerWidth!==this.size.innerWidth},p.addItems=function(t){var e=this._itemize(t);return e.length&&(this.items=this.items.concat(e)),e},p.appended=function(t){var e=this.addItems(t);e.length&&(this.layoutItems(e,!0),this.reveal(e))},p.prepended=function(t){var e=this._itemize(t);if(e.length){var i=this.items.slice(0);this.items=e.concat(i),this._resetLayout(),this._manageStamps(),this.layoutItems(e,!0),this.reveal(e),this.layoutItems(i)}},p.reveal=function(t){if(this._emitCompleteOnItems("reveal",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.reveal()})}},p.hide=function(t){if(this._emitCompleteOnItems("hide",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.hide()})}},p.revealItemElements=function(t){var e=this.getItems(t);this.reveal(e)},p.hideItemElements=function(t){var e=this.getItems(t);this.hide(e)},p.getItem=function(t){for(var e=0;e<this.items.length;e++){var i=this.items[e];if(i.element==t)return i}},p.getItems=function(t){t=n.makeArray(t);var e=[];return t.forEach(function(t){var i=this.getItem(t);i&&e.push(i)},this),e},p.remove=function(t){var e=this.getItems(t);this._emitCompleteOnItems("remove",e),e&&e.length&&e.forEach(function(t){t.remove(),n.removeFrom(this.items,t)},this)},p.destroy=function(){var t=this.element.style;t.height="",t.position="",t.width="",this.items.forEach(function(t){t.destroy()}),this.unbindResize();var e=this.element.outlayerGUID;delete d[e],delete this.element.outlayerGUID,l&&l.removeData(this.element,this.constructor.namespace)},r.data=function(t){t=n.getQueryElement(t);var e=t&&t.outlayerGUID;return e&&d[e]},r.create=function(t,e){var i=s(r);return i.defaults=n.extend({},r.defaults),n.extend(i.defaults,e),i.compatOptions=n.extend({},r.compatOptions),i.namespace=t,i.data=r.data,i.Item=s(o),n.htmlInit(i,t),l&&l.bridget&&l.bridget(t,i),i};var f={ms:1,s:1e3};return r.Item=o,r}),function(t,e){"function"==typeof define&&define.amd?define("enviratope/item",["outlayer/outlayer"],e):"object"==typeof module&&module.exports?module.exports=e(require("outlayer")):(t.Enviratope=t.Enviratope||{},t.Enviratope.Item=e(t.Outlayer))}(window,function a(t){"use strict";function e(){t.Item.apply(this,arguments)}var i=e.prototype=Object.create(t.Item.prototype),n=i._create;i._create=function(){this.id=this.layout.itemGUID++,n.call(this),this.sortData={}},i.updateSortData=function(){if(!this.isIgnored){this.sortData.id=this.id,this.sortData["original-order"]=this.id,this.sortData.random=Math.random();var t=this.layout.options.getSortData,e=this.layout._sorters;for(var i in t){var n=e[i];this.sortData[i]=n(this.element,this)}}};var o=i.destroy;return i.destroy=function(){o.apply(this,arguments),this.css({display:""})},e}),function(t,e){"function"==typeof define&&define.amd?define("enviratope/layout-mode",["get-size/get-size","outlayer/outlayer"],e):"object"==typeof module&&module.exports?module.exports=e(require("get-size"),require("outlayer")):(t.Enviratope=t.Enviratope||{},t.Enviratope.LayoutMode=e(t.getSize,t.Outlayer))}(window,function u(t,e){"use strict";function i(t){this.enviratope=t,t&&(this.options=t.options[this.namespace],this.element=t.element,this.items=t.filteredItems,this.size=t.size)}var n=i.prototype,o=["_resetLayout","_getItemLayoutPosition","_manageStamp","_getContainerSize","_getElementOffset","needsResizeLayout","_getOption"];return o.forEach(function(t){n[t]=function(){return e.prototype[t].apply(this.enviratope,arguments)}}),n.needsVerticalResizeLayout=function(){var e=t(this.enviratope.element),i=this.enviratope.size&&e;return i&&e.innerHeight!=this.enviratope.size.innerHeight},n._getMeasurement=function(){this.enviratope._getMeasurement.apply(this,arguments)},n.getColumnWidth=function(){this.getSegmentSize("column","Width")},n.getRowHeight=function(){this.getSegmentSize("row","Height")},n.getSegmentSize=function(t,e){var i=t+e,n="outer"+e;if(this._getMeasurement(i,n),!this[i]){var o=this.getFirstItemSize();this[i]=o&&o[n]||this.enviratope.size["inner"+e]}},n.getFirstItemSize=function(){var e=this.enviratope.filteredItems[0];return e&&e.element&&t(e.element)},n.layout=function(){this.enviratope.layout.apply(this.enviratope,arguments)},n.getSize=function(){this.enviratope.getSize(),this.size=this.enviratope.size},i.modes={},i.create=function(t,e){function o(){i.apply(this,arguments)}return o.prototype=Object.create(n),o.prototype.constructor=o,e&&(o.options=e),o.prototype.namespace=t,i.modes[t]=o,o},i}),function(t,e){"function"==typeof define&&define.amd?define("masonry/masonry",["outlayer/outlayer","get-size/get-size"],e):"object"==typeof module&&module.exports?module.exports=e(require("outlayer"),require("get-size")):t.Masonry=e(t.Outlayer,t.getSize)}(window,function l(t,e){var i=t.create("masonry");return i.compatOptions.fitWidth="isFitWidth",i.prototype._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns(),this.colYs=[];for(var t=0;t<this.cols;t++)this.colYs.push(0);this.maxY=0},i.prototype.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var t=this.items[0],i=t&&t.element;this.columnWidth=i&&e(i).outerWidth||this.containerWidth}var n=this.columnWidth+=this.gutter,o=this.containerWidth+this.gutter,r=o/n,s=n-o%n,a=s&&1>s?"round":"floor";r=Math[a](r),this.cols=Math.max(r,1)},i.prototype.getContainerWidth=function(){var t=this._getOption("fitWidth"),i=t?this.element.parentNode:this.element,n=e(i);this.containerWidth=n&&n.innerWidth},i.prototype._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,i=e&&1>e?"round":"ceil",n=Math[i](t.size.outerWidth/this.columnWidth);n=Math.min(n,this.cols);for(var o=this._getColGroup(n),r=Math.min.apply(Math,o),s=o.indexOf(r),a={x:this.columnWidth*s,y:r},u=r+t.size.outerHeight,l=this.cols+1-o.length,h=0;l>h;h++)this.colYs[s+h]=u;return a},i.prototype._getColGroup=function(t){if(2>t)return this.colYs;for(var e=[],i=this.cols+1-t,n=0;i>n;n++){var o=this.colYs.slice(n,n+t);e[n]=Math.max.apply(Math,o)}return e},i.prototype._manageStamp=function(t){var i=e(t),n=this._getElementOffset(t),o=this._getOption("originLeft"),r=o?n.left:n.right,s=r+i.outerWidth,a=Math.floor(r/this.columnWidth);a=Math.max(0,a);var u=Math.floor(s/this.columnWidth);u-=s%this.columnWidth?0:1,u=Math.min(this.cols-1,u);for(var l=this._getOption("originTop"),h=(l?n.top:n.bottom)+i.outerHeight,c=a;u>=c;c++)this.colYs[c]=Math.max(h,this.colYs[c])},i.prototype._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this._getOption("fitWidth")&&(t.width=this._getContainerFitWidth()),t},i.prototype._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},i.prototype.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!=this.containerWidth},i}),function(t,e){"function"==typeof define&&define.amd?define("enviratope/layout-modes/masonry",["../layout-mode","masonry/masonry"],e):"object"==typeof module&&module.exports?module.exports=e(require("../layout-mode"),require("masonry-layout")):e(t.Enviratope.LayoutMode,t.Masonry)}(window,function h(t,e){"use strict";var i=t.create("masonry"),n=i.prototype,o={_getElementOffset:!0,layout:!0,_getMeasurement:!0};for(var r in e.prototype)o[r]||(n[r]=e.prototype[r]);var s=n.measureColumns;n.measureColumns=function(){this.items=this.enviratope.filteredItems,s.call(this)};var a=n._getOption;return n._getOption=function(t){return"fitWidth"==t?void 0!==this.options.isFitWidth?this.options.isFitWidth:this.options.fitWidth:a.apply(this.enviratope,arguments)},i}),function(t,e){"function"==typeof define&&define.amd?define("enviratope/layout-modes/fit-rows",["../layout-mode"],e):"object"==typeof exports?module.exports=e(require("../layout-mode")):e(t.Enviratope.LayoutMode)}(window,function c(t){"use strict";var e=t.create("fitRows"),i=e.prototype;return i._resetLayout=function(){this.x=0,this.y=0,this.maxY=0,this._getMeasurement("gutter","outerWidth")},i._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth+this.gutter,i=this.enviratope.size.innerWidth+this.gutter;0!==this.x&&e+this.x>i&&(this.x=0,this.y=this.maxY);var n={x:this.x,y:this.y};return this.maxY=Math.max(this.maxY,this.y+t.size.outerHeight),this.x+=e,n},i._getContainerSize=function(){return{height:this.maxY}},e}),function(t,e){"function"==typeof define&&define.amd?define("enviratope/layout-modes/vertical",["../layout-mode"],e):"object"==typeof module&&module.exports?module.exports=e(require("../layout-mode")):e(t.Enviratope.LayoutMode)}(window,function d(t){"use strict";var e=t.create("vertical",{horizontalAlignment:0}),i=e.prototype;return i._resetLayout=function(){this.y=0},i._getItemLayoutPosition=function(t){t.getSize();var e=(this.enviratope.size.innerWidth-t.size.outerWidth)*this.options.horizontalAlignment,i=this.y;return this.y+=t.size.outerHeight,{x:e,y:i}},i._getContainerSize=function(){return{height:this.y}},e}),function(t,e){"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size","desandro-matches-selector/matches-selector","fizzy-ui-utils/utils","./item","./layout-mode","./layout-modes/masonry","./layout-modes/fit-rows","./layout-modes/vertical"],function(i,n,o,r,s,a){return e(t,i,n,o,r,s,a)}):"object"==typeof module&&module.exports?module.exports=e(t,require("outlayer"),require("get-size"),require("desandro-matches-selector"),require("fizzy-ui-utils"),require("./item"),require("./layout-mode"),require("./layout-modes/masonry"),require("./layout-modes/fit-rows"),require("./layout-modes/vertical")):t.Enviratope=e(t,t.Outlayer,t.getSize,t.matchesSelector,t.fizzyUIUtils,t.Enviratope.Item,t.Enviratope.LayoutMode)}(window,function p(t,e,i,n,o,r,s){function a(t,e){return function i(n,o){for(var r=0;r<t.length;r++){var s=t[r],a=n.sortData[s],u=o.sortData[s];if(a>u||u>a){var l=void 0!==e[s]?e[s]:e,h=l?1:-1;return(a>u?1:-1)*h}}return 0}}var u=t.jQuery,l=String.prototype.trim?function(t){return t.trim()}:function(t){return t.replace(/^\s+|\s+$/g,"")},h=e.create("enviratope",{layoutMode:"masonry",isJQueryFiltering:!0,sortAscending:!0});h.Item=r,h.LayoutMode=s;var c=h.prototype;c._create=function(){this.itemGUID=0,this._sorters={},this._getSorters(),e.prototype._create.call(this),this.modes={},this.filteredItems=this.items,this.sortHistory=["original-order"];for(var t in s.modes)this._initLayoutMode(t)},c.reloadItems=function(){this.itemGUID=0,e.prototype.reloadItems.call(this)},c._itemize=function(){for(var t=e.prototype._itemize.apply(this,arguments),i=0;i<t.length;i++){var n=t[i];n.id=this.itemGUID++}return this._updateItemsSortData(t),t},c._initLayoutMode=function(t){var e=s.modes[t],i=this.options[t]||{};this.options[t]=e.options?o.extend(e.options,i):i,this.modes[t]=new e(this)},c.layout=function(){return!this._isLayoutInited&&this._getOption("initLayout")?void this.arrange():void this._layout()},c._layout=function(){var t=this._getIsInstant();this._resetLayout(),this._manageStamps(),this.layoutItems(this.filteredItems,t),this._isLayoutInited=!0},c.arrange=function(t){this.option(t),this._getIsInstant();var e=this._filter(this.items);this.filteredItems=e.matches,this._bindArrangeComplete(),this._isInstant?this._noTransition(this._hideReveal,[e]):this._hideReveal(e),this._sort(),this._layout()},c._init=c.arrange,c._hideReveal=function(t){this.reveal(t.needReveal),this.hide(t.needHide)},c._getIsInstant=function(){var t=this._getOption("layoutInstant"),e=void 0!==t?t:!this._isLayoutInited;return this._isInstant=e,e},c._bindArrangeComplete=function(){function t(){e&&i&&n&&o.dispatchEvent("arrangeComplete",null,[o.filteredItems])}var e,i,n,o=this;this.once("layoutComplete",function(){e=!0,t()}),this.once("hideComplete",function(){i=!0,t()}),this.once("revealComplete",function(){n=!0,t()})},c._filter=function(t){var e=this.options.filter;e=e||"*";for(var i=[],n=[],o=[],r=this._getFilterTest(e),s=0;s<t.length;s++){var a=t[s];if(!a.isIgnored){var u=r(a);u&&i.push(a),u&&a.isHidden?n.push(a):u||a.isHidden||o.push(a)}}return{matches:i,needReveal:n,needHide:o}},c._getFilterTest=function(t){return u&&this.options.isJQueryFiltering?function(e){return u(e.element).is(t)}:"function"==typeof t?function(e){return t(e.element)}:function(e){return n(e.element,t)}},c.updateSortData=function(t){var e;t?(t=o.makeArray(t),e=this.getItems(t)):e=this.items,this._getSorters(),this._updateItemsSortData(e)},c._getSorters=function(){var t=this.options.getSortData;for(var e in t){var i=t[e];this._sorters[e]=d(i)}},c._updateItemsSortData=function(t){for(var e=t&&t.length,i=0;e&&e>i;i++){var n=t[i];n.updateSortData()}};var d=function(){function t(t){if("string"!=typeof t)return t;var i=l(t).split(" "),n=i[0],o=n.match(/^\[(.+)\]$/),r=o&&o[1],s=e(r,n),a=h.sortDataParsers[i[1]];return t=a?function(t){return t&&a(s(t))}:function(t){return t&&s(t)}}function e(t,e){return t?function i(e){return e.getAttribute(t)}:function n(t){var i=t.querySelector(e);return i&&i.textContent}}return t}();h.sortDataParsers={parseInt:function(t){return parseInt(t,10)},parseFloat:function(t){return parseFloat(t)}},c._sort=function(){var t=this.options.sortBy;if(t){var e=[].concat.apply(t,this.sortHistory),i=a(e,this.options.sortAscending);this.filteredItems.sort(i),t!=this.sortHistory[0]&&this.sortHistory.unshift(t)}},c._mode=function(){var t=this.options.layoutMode,e=this.modes[t];if(!e)throw new Error("No layout mode: "+t);return e.options=this.options[t],e},c._resetLayout=function(){e.prototype._resetLayout.call(this),this._mode()._resetLayout()},c._getItemLayoutPosition=function(t){return this._mode()._getItemLayoutPosition(t)},c._manageStamp=function(t){this._mode()._manageStamp(t)},c._getContainerSize=function(){return this._mode()._getContainerSize()},c.needsResizeLayout=function(){return this._mode().needsResizeLayout()},c.appended=function(t){var e=this.addItems(t);if(e.length){var i=this._filterRevealAdded(e);this.filteredItems=this.filteredItems.concat(i)}},c.prepended=function(t){var e=this._itemize(t);if(e.length){this._resetLayout(),this._manageStamps();var i=this._filterRevealAdded(e);this.layoutItems(this.filteredItems),this.filteredItems=i.concat(this.filteredItems),this.items=e.concat(this.items)}},c._filterRevealAdded=function(t){var e=this._filter(t);return this.hide(e.needHide),this.reveal(e.matches),this.layoutItems(e.matches,!0),e.matches},c.insert=function(t){var e=this.addItems(t);if(e.length){var i,n,o=e.length;for(i=0;o>i;i++)n=e[i],this.element.appendChild(n.element);var r=this._filter(e).matches;for(i=0;o>i;i++)e[i].isLayoutInstant=!0;for(this.arrange(),i=0;o>i;i++)delete e[i].isLayoutInstant;this.reveal(r)}};var p=c.remove;return c.remove=function(t){t=o.makeArray(t);var e=this.getItems(t);p.call(this,t);for(var i=e&&e.length,n=0;i&&i>n;n++){var r=e[n];o.removeFrom(this.filteredItems,r)}},c.shuffle=function(){for(var t=0;t<this.items.length;t++){var e=this.items[t];e.sortData.random=Math.random()}this.options.sortBy="random",this._sort(),this._layout()},c._noTransition=function(t,e){var i=this.options.transitionDuration;this.options.transitionDuration=0;var n=t.apply(this,e);return this.options.transitionDuration=i,n},c.getFilteredItemElements=function(){return this.filteredItems.map(function(t){return t.element})},h}),jQuery.easing.jswing=jQuery.easing.swing,jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(t,e,i,n,o){return jQuery.easing[jQuery.easing.def](t,e,i,n,o)},easeInQuad:function(t,e,i,n,o){return n*(e/=o)*e+i},easeOutQuad:function(t,e,i,n,o){return-n*(e/=o)*(e-2)+i},easeInOutQuad:function(t,e,i,n,o){return(e/=o/2)<1?n/2*e*e+i:-n/2*(--e*(e-2)-1)+i},easeInCubic:function(t,e,i,n,o){return n*(e/=o)*e*e+i},easeOutCubic:function(t,e,i,n,o){return n*((e=e/o-1)*e*e+1)+i},easeInOutCubic:function(t,e,i,n,o){return(e/=o/2)<1?n/2*e*e*e+i:n/2*((e-=2)*e*e+2)+i},easeInQuart:function(t,e,i,n,o){return n*(e/=o)*e*e*e+i},easeOutQuart:function(t,e,i,n,o){return-n*((e=e/o-1)*e*e*e-1)+i},easeInOutQuart:function(t,e,i,n,o){return(e/=o/2)<1?n/2*e*e*e*e+i:-n/2*((e-=2)*e*e*e-2)+i},easeInQuint:function(t,e,i,n,o){return n*(e/=o)*e*e*e*e+i},easeOutQuint:function(t,e,i,n,o){return n*((e=e/o-1)*e*e*e*e+1)+i},easeInOutQuint:function(t,e,i,n,o){return(e/=o/2)<1?n/2*e*e*e*e*e+i:n/2*((e-=2)*e*e*e*e+2)+i},easeInSine:function(t,e,i,n,o){
3
+ return-n*Math.cos(e/o*(Math.PI/2))+n+i},easeOutSine:function(t,e,i,n,o){return n*Math.sin(e/o*(Math.PI/2))+i},easeInOutSine:function(t,e,i,n,o){return-n/2*(Math.cos(Math.PI*e/o)-1)+i},easeInExpo:function(t,e,i,n,o){return 0==e?i:n*Math.pow(2,10*(e/o-1))+i},easeOutExpo:function(t,e,i,n,o){return e==o?i+n:n*(-Math.pow(2,-10*e/o)+1)+i},easeInOutExpo:function(t,e,i,n,o){return 0==e?i:e==o?i+n:(e/=o/2)<1?n/2*Math.pow(2,10*(e-1))+i:n/2*(-Math.pow(2,-10*--e)+2)+i},easeInCirc:function(t,e,i,n,o){return-n*(Math.sqrt(1-(e/=o)*e)-1)+i},easeOutCirc:function(t,e,i,n,o){return n*Math.sqrt(1-(e=e/o-1)*e)+i},easeInOutCirc:function(t,e,i,n,o){return(e/=o/2)<1?-n/2*(Math.sqrt(1-e*e)-1)+i:n/2*(Math.sqrt(1-(e-=2)*e)+1)+i},easeInElastic:function(t,e,i,n,o){var r=1.70158,s=0,a=n;if(0==e)return i;if(1==(e/=o))return i+n;if(s||(s=.3*o),a<Math.abs(n)){a=n;var r=s/4}else var r=s/(2*Math.PI)*Math.asin(n/a);return-(a*Math.pow(2,10*(e-=1))*Math.sin((e*o-r)*(2*Math.PI)/s))+i},easeOutElastic:function(t,e,i,n,o){var r=1.70158,s=0,a=n;if(0==e)return i;if(1==(e/=o))return i+n;if(s||(s=.3*o),a<Math.abs(n)){a=n;var r=s/4}else var r=s/(2*Math.PI)*Math.asin(n/a);return a*Math.pow(2,-10*e)*Math.sin((e*o-r)*(2*Math.PI)/s)+n+i},easeInOutElastic:function(t,e,i,n,o){var r=1.70158,s=0,a=n;if(0==e)return i;if(2==(e/=o/2))return i+n;if(s||(s=o*(.3*1.5)),a<Math.abs(n)){a=n;var r=s/4}else var r=s/(2*Math.PI)*Math.asin(n/a);return 1>e?-.5*(a*Math.pow(2,10*(e-=1))*Math.sin((e*o-r)*(2*Math.PI)/s))+i:a*Math.pow(2,-10*(e-=1))*Math.sin((e*o-r)*(2*Math.PI)/s)*.5+n+i},easeInBack:function(t,e,i,n,o,r){return void 0==r&&(r=1.70158),n*(e/=o)*e*((r+1)*e-r)+i},easeOutBack:function(t,e,i,n,o,r){return void 0==r&&(r=1.70158),n*((e=e/o-1)*e*((r+1)*e+r)+1)+i},easeInOutBack:function(t,e,i,n,o,r){return void 0==r&&(r=1.70158),(e/=o/2)<1?n/2*(e*e*(((r*=1.525)+1)*e-r))+i:n/2*((e-=2)*e*(((r*=1.525)+1)*e+r)+2)+i},easeInBounce:function(t,e,i,n,o){return n-jQuery.easing.easeOutBounce(t,o-e,0,n,o)+i},easeOutBounce:function(t,e,i,n,o){return(e/=o)<1/2.75?n*(7.5625*e*e)+i:2/2.75>e?n*(7.5625*(e-=1.5/2.75)*e+.75)+i:2.5/2.75>e?n*(7.5625*(e-=2.25/2.75)*e+.9375)+i:n*(7.5625*(e-=2.625/2.75)*e+.984375)+i},easeInOutBounce:function(t,e,i,n,o){return o/2>e?.5*jQuery.easing.easeInBounce(t,2*e,0,n,o)+i:.5*jQuery.easing.easeOutBounce(t,2*e-o,0,n,o)+.5*n+i}}),function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof exports?module.exports=t:t(jQuery)}(function($){function t(t){var n=t||window.event,o=r.call(arguments,1),u=0,h=0,c=0,d=0,p=0,f=0;if(t=$.event.fix(n),t.type="mousewheel","detail"in n&&(c=-1*n.detail),"wheelDelta"in n&&(c=n.wheelDelta),"wheelDeltaY"in n&&(c=n.wheelDeltaY),"wheelDeltaX"in n&&(h=-1*n.wheelDeltaX),"axis"in n&&n.axis===n.HORIZONTAL_AXIS&&(h=-1*c,c=0),u=0===c?h:c,"deltaY"in n&&(c=-1*n.deltaY,u=c),"deltaX"in n&&(h=n.deltaX,0===c&&(u=-1*h)),0!==c||0!==h){if(1===n.deltaMode){var m=$.data(this,"mousewheel-line-height");u*=m,c*=m,h*=m}else if(2===n.deltaMode){var g=$.data(this,"mousewheel-page-height");u*=g,c*=g,h*=g}if(d=Math.max(Math.abs(c),Math.abs(h)),(!a||a>d)&&(a=d,i(n,d)&&(a/=40)),i(n,d)&&(u/=40,h/=40,c/=40),u=Math[u>=1?"floor":"ceil"](u/a),h=Math[h>=1?"floor":"ceil"](h/a),c=Math[c>=1?"floor":"ceil"](c/a),l.settings.normalizeOffset&&this.getBoundingClientRect){var v=this.getBoundingClientRect();p=t.clientX-v.left,f=t.clientY-v.top}return t.deltaX=h,t.deltaY=c,t.deltaFactor=a,t.offsetX=p,t.offsetY=f,t.deltaMode=0,o.unshift(t,u,h,c),s&&clearTimeout(s),s=setTimeout(e,200),($.event.dispatch||$.event.handle).apply(this,o)}}function e(){a=null}function i(t,e){return l.settings.adjustOldDeltas&&"mousewheel"===t.type&&e%120===0}var n=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],o="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],r=Array.prototype.slice,s,a;if($.event.fixHooks)for(var u=n.length;u;)$.event.fixHooks[n[--u]]=$.event.mouseHooks;var l=$.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var e=o.length;e;)this.addEventListener(o[--e],t,!1);else this.onmousewheel=t;$.data(this,"mousewheel-line-height",l.getLineHeight(this)),$.data(this,"mousewheel-page-height",l.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var e=o.length;e;)this.removeEventListener(o[--e],t,!1);else this.onmousewheel=null;$.removeData(this,"mousewheel-line-height"),$.removeData(this,"mousewheel-page-height")},getLineHeight:function(t){var e=$(t),i=e["offsetParent"in $.fn?"offsetParent":"parent"]();return i.length||(i=$("body")),parseInt(i.css("fontSize"),10)||parseInt(e.css("fontSize"),10)||16},getPageHeight:function(t){return $(t).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};$.fn.extend({mousewheel:function(t){return t?this.bind("mousewheel",t):this.trigger("mousewheel")},unmousewheel:function(t){return this.unbind("mousewheel",t)}})}),jQuery(document).ready(function($){var t="ontouchstart"in document.documentElement;t&&$("body").addClass("envira-touch")}),function(t){"function"==typeof define&&define.amd&&define.amd.jQuery?define(["jquery"],t):t(jQuery)}(function($){"use strict";function t(t){return!t||void 0!==t.allowPageScroll||void 0===t.swipe&&void 0===t.swipeStatus||(t.allowPageScroll=u),void 0!==t.click&&void 0===t.tap&&(t.tap=t.click),t||(t={}),t=$.extend({},$.fn.swipe.defaults,t),this.each(function(){var i=$(this),n=i.data(O);n||(n=new e(this,t),i.data(O,n))})}function e(t,e){function m(t){if(!(lt()||$(t.target).closest(e.excludedElements,Nt).length>0)){var i=t.originalEvent?t.originalEvent:t,n,o=E?i.touches[0]:i;return Yt=x,E?Ut=i.touches.length:t.preventDefault(),Pt=0,jt=null,Qt=null,Rt=0,Ht=0,At=0,Bt=1,qt=0,Vt=ft(),Ft=vt(),at(),!E||Ut===e.fingers||e.fingers===y||Q()?(ct(0,o),Xt=Tt(),2==Ut&&(ct(1,i.touches[1]),Ht=At=xt(Vt[0].start,Vt[1].start)),(e.swipeStatus||e.pinchStatus)&&(n=D(i,Yt))):n=!1,n===!1?(Yt=I,D(i,Yt),n):(e.hold&&(te=setTimeout($.proxy(function(){Nt.trigger("hold",[i.target]),e.hold&&(n=e.hold.call(Nt,i,i.target))},this),e.longTapThreshold)),ht(!0),null)}}function L(t){var i=t.originalEvent?t.originalEvent:t;if(Yt!==_&&Yt!==I&&!ut()){var n,o=E?i.touches[0]:i,r=dt(o);if(Gt=Tt(),E&&(Ut=i.touches.length),e.hold&&clearTimeout(te),Yt=b,2==Ut&&(0==Ht?(ct(1,i.touches[1]),Ht=At=xt(Vt[0].start,Vt[1].start)):(dt(i.touches[1]),At=xt(Vt[0].end,Vt[1].end),Qt=_t(Vt[0].end,Vt[1].end)),Bt=bt(Ht,At),qt=Math.abs(Ht-At)),Ut===e.fingers||e.fingers===y||!E||Q()){if(jt=St(r.start,r.end),B(t,jt),Pt=It(r.start,r.end),Rt=wt(),mt(jt,Pt),(e.swipeStatus||e.pinchStatus)&&(n=D(i,Yt)),!e.triggerOnTouchEnd||e.triggerOnTouchLeave){var s=!0;if(e.triggerOnTouchLeave){var a=Ot(this);s=Lt(r.end,a)}!e.triggerOnTouchEnd&&s?Yt=W(b):e.triggerOnTouchLeave&&!s&&(Yt=W(_)),(Yt==I||Yt==_)&&D(i,Yt)}}else Yt=I,D(i,Yt);n===!1&&(Yt=I,D(i,Yt))}}function z(t){var i=t.originalEvent;return E&&i.touches.length>0?(st(),!0):(ut()&&(Ut=$t),Gt=Tt(),Rt=wt(),R()||!j()?(Yt=I,D(i,Yt)):e.triggerOnTouchEnd||0==e.triggerOnTouchEnd&&Yt===b?(t.preventDefault(),Yt=_,D(i,Yt)):!e.triggerOnTouchEnd&&G()?(Yt=_,P(i,Yt,d)):Yt===b&&(Yt=I,D(i,Yt)),ht(!1),null)}function M(){Ut=0,Gt=0,Xt=0,Ht=0,At=0,Bt=1,at(),ht(!1)}function C(t){var i=t.originalEvent;e.triggerOnTouchLeave&&(Yt=W(_),D(i,Yt))}function k(){Nt.unbind(Mt,m),Nt.unbind(Dt,M),Nt.unbind(Ct,L),Nt.unbind(kt,z),Wt&&Nt.unbind(Wt,C),ht(!1)}function W(t){var i=t,n=A(),o=j(),r=R();return!n||r?i=I:!o||t!=b||e.triggerOnTouchEnd&&!e.triggerOnTouchLeave?!o&&t==_&&e.triggerOnTouchLeave&&(i=I):i=_,i}function D(t,e){var i=void 0;return U()||Y()?i=P(t,e,h):(F()||Q())&&i!==!1&&(i=P(t,e,c)),ot()&&i!==!1?i=P(t,e,p):rt()&&i!==!1?i=P(t,e,f):nt()&&i!==!1&&(i=P(t,e,d)),e===I&&M(t),e===_&&(E?0==t.touches.length&&M(t):M(t)),i}function P(t,u,l){var m=void 0;if(l==h){if(Nt.trigger("swipeStatus",[u,jt||null,Pt||0,Rt||0,Ut,Vt]),e.swipeStatus&&(m=e.swipeStatus.call(Nt,t,u,jt||null,Pt||0,Rt||0,Ut,Vt),m===!1))return!1;if(u==_&&N()){if(Nt.trigger("swipe",[jt,Pt,Rt,Ut,Vt]),e.swipe&&(m=e.swipe.call(Nt,t,jt,Pt,Rt,Ut,Vt),m===!1))return!1;switch(jt){case i:Nt.trigger("swipeLeft",[jt,Pt,Rt,Ut,Vt]),e.swipeLeft&&(m=e.swipeLeft.call(Nt,t,jt,Pt,Rt,Ut,Vt));break;case n:Nt.trigger("swipeRight",[jt,Pt,Rt,Ut,Vt]),e.swipeRight&&(m=e.swipeRight.call(Nt,t,jt,Pt,Rt,Ut,Vt));break;case o:Nt.trigger("swipeUp",[jt,Pt,Rt,Ut,Vt]),e.swipeUp&&(m=e.swipeUp.call(Nt,t,jt,Pt,Rt,Ut,Vt));break;case r:Nt.trigger("swipeDown",[jt,Pt,Rt,Ut,Vt]),e.swipeDown&&(m=e.swipeDown.call(Nt,t,jt,Pt,Rt,Ut,Vt))}}}if(l==c){if(Nt.trigger("pinchStatus",[u,Qt||null,qt||0,Rt||0,Ut,Bt,Vt]),e.pinchStatus&&(m=e.pinchStatus.call(Nt,t,u,Qt||null,qt||0,Rt||0,Ut,Bt,Vt),m===!1))return!1;if(u==_&&q())switch(Qt){case s:Nt.trigger("pinchIn",[Qt||null,qt||0,Rt||0,Ut,Bt,Vt]),e.pinchIn&&(m=e.pinchIn.call(Nt,t,Qt||null,qt||0,Rt||0,Ut,Bt,Vt));break;case a:Nt.trigger("pinchOut",[Qt||null,qt||0,Rt||0,Ut,Bt,Vt]),e.pinchOut&&(m=e.pinchOut.call(Nt,t,Qt||null,qt||0,Rt||0,Ut,Bt,Vt))}}return l==d?(u===I||u===_)&&(clearTimeout(Jt),clearTimeout(te),Z()&&!tt()?(Kt=Tt(),Jt=setTimeout($.proxy(function(){Kt=null,Nt.trigger("tap",[t.target]),e.tap&&(m=e.tap.call(Nt,t,t.target))},this),e.doubleTapThreshold)):(Kt=null,Nt.trigger("tap",[t.target]),e.tap&&(m=e.tap.call(Nt,t,t.target)))):l==p?(u===I||u===_)&&(clearTimeout(Jt),Kt=null,Nt.trigger("doubletap",[t.target]),e.doubleTap&&(m=e.doubleTap.call(Nt,t,t.target))):l==f&&(u===I||u===_)&&(clearTimeout(Jt),Kt=null,Nt.trigger("longtap",[t.target]),e.longTap&&(m=e.longTap.call(Nt,t,t.target))),m}function j(){var t=!0;return null!==e.threshold&&(t=Pt>=e.threshold),t}function R(){var t=!1;return null!==e.cancelThreshold&&null!==jt&&(t=gt(jt)-Pt>=e.cancelThreshold),t}function H(){return null!==e.pinchThreshold?qt>=e.pinchThreshold:!0}function A(){var t;return t=e.maxTimeThreshold&&Rt>=e.maxTimeThreshold?!1:!0}function B(t,s){if(e.allowPageScroll===u||Q())t.preventDefault();else{var a=e.allowPageScroll===l;switch(s){case i:(e.swipeLeft&&a||!a&&e.allowPageScroll!=g)&&t.preventDefault();break;case n:(e.swipeRight&&a||!a&&e.allowPageScroll!=g)&&t.preventDefault();break;case o:(e.swipeUp&&a||!a&&e.allowPageScroll!=v)&&t.preventDefault();break;case r:(e.swipeDown&&a||!a&&e.allowPageScroll!=v)&&t.preventDefault()}}}function q(){var t=V(),e=X(),i=H();return t&&e&&i}function Q(){return!!(e.pinchStatus||e.pinchIn||e.pinchOut)}function F(){return!(!q()||!Q())}function N(){var t=A(),e=j(),i=V(),n=X(),o=R(),r=!o&&n&&i&&e&&t;return r}function Y(){return!!(e.swipe||e.swipeStatus||e.swipeLeft||e.swipeRight||e.swipeUp||e.swipeDown)}function U(){return!(!N()||!Y())}function V(){return Ut===e.fingers||e.fingers===y||!E}function X(){return 0!==Vt[0].end.x}function G(){return!!e.tap}function Z(){return!!e.doubleTap}function K(){return!!e.longTap}function J(){if(null==Kt)return!1;var t=Tt();return Z()&&t-Kt<=e.doubleTapThreshold}function tt(){return J()}function et(){return(1===Ut||!E)&&(isNaN(Pt)||Pt<e.threshold)}function it(){return Rt>e.longTapThreshold&&w>Pt}function nt(){return!(!et()||!G())}function ot(){return!(!J()||!Z())}function rt(){return!(!it()||!K())}function st(){Zt=Tt(),$t=event.touches.length+1}function at(){Zt=0,$t=0}function ut(){var t=!1;if(Zt){var i=Tt()-Zt;i<=e.fingerReleaseThreshold&&(t=!0)}return t}function lt(){return!(Nt.data(O+"_intouch")!==!0)}function ht(t){t===!0?(Nt.bind(Ct,L),Nt.bind(kt,z),Wt&&Nt.bind(Wt,C)):(Nt.unbind(Ct,L,!1),Nt.unbind(kt,z,!1),Wt&&Nt.unbind(Wt,C,!1)),Nt.data(O+"_intouch",t===!0)}function ct(t,e){var i=void 0!==e.identifier?e.identifier:0;return Vt[t].identifier=i,Vt[t].start.x=Vt[t].end.x=e.pageX||e.clientX,Vt[t].start.y=Vt[t].end.y=e.pageY||e.clientY,Vt[t]}function dt(t){var e=void 0!==t.identifier?t.identifier:0,i=pt(e);return i.end.x=t.pageX||t.clientX,i.end.y=t.pageY||t.clientY,i}function pt(t){for(var e=0;e<Vt.length;e++)if(Vt[e].identifier==t)return Vt[e]}function ft(){for(var t=[],e=0;5>=e;e++)t.push({start:{x:0,y:0},end:{x:0,y:0},identifier:0});return t}function mt(t,e){e=Math.max(e,gt(t)),Ft[t].distance=e}function gt(t){return Ft[t]?Ft[t].distance:void 0}function vt(){var t={};return t[i]=yt(i),t[n]=yt(n),t[o]=yt(o),t[r]=yt(r),t}function yt(t){return{direction:t,distance:0}}function wt(){return Gt-Xt}function xt(t,e){var i=Math.abs(t.x-e.x),n=Math.abs(t.y-e.y);return Math.round(Math.sqrt(i*i+n*n))}function bt(t,e){var i=e/t*1;return i.toFixed(2)}function _t(){return 1>Bt?a:s}function It(t,e){return Math.round(Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2)))}function Et(t,e){var i=t.x-e.x,n=e.y-t.y,o=Math.atan2(n,i),r=Math.round(180*o/Math.PI);return 0>r&&(r=360-Math.abs(r)),r}function St(t,e){var s=Et(t,e);return 45>=s&&s>=0?i:360>=s&&s>=315?i:s>=135&&225>=s?n:s>45&&135>s?r:o}function Tt(){var t=new Date;return t.getTime()}function Ot(t){t=$(t);var e=t.offset(),i={left:e.left,right:e.left+t.outerWidth(),top:e.top,bottom:e.top+t.outerHeight()};return i}function Lt(t,e){return t.x>e.left&&t.x<e.right&&t.y>e.top&&t.y<e.bottom}var zt=E||T||!e.fallbackToMouseEvents,Mt=zt?T?S?"MSPointerDown":"pointerdown":"touchstart":"mousedown",Ct=zt?T?S?"MSPointerMove":"pointermove":"touchmove":"mousemove",kt=zt?T?S?"MSPointerUp":"pointerup":"touchend":"mouseup",Wt=zt?null:"mouseleave",Dt=T?S?"MSPointerCancel":"pointercancel":"touchcancel",Pt=0,jt=null,Rt=0,Ht=0,At=0,Bt=1,qt=0,Qt=0,Ft=null,Nt=$(t),Yt="start",Ut=0,Vt=null,Xt=0,Gt=0,Zt=0,$t=0,Kt=0,Jt=null,te=null;try{Nt.bind(Mt,m),Nt.bind(Dt,M)}catch(ee){$.error("events not supported "+Mt+","+Dt+" on jQuery.swipe")}this.enable=function(){return Nt.bind(Mt,m),Nt.bind(Dt,M),Nt},this.disable=function(){return k(),Nt},this.destroy=function(){k(),Nt.data(O,null),Nt=null},this.option=function(t,i){if(void 0!==e[t]){if(void 0===i)return e[t];e[t]=i}else $.error("Option "+t+" does not exist on jQuery.swipe.options");return null}}var i="left",n="right",o="up",r="down",s="in",a="out",u="none",l="auto",h="swipe",c="pinch",d="tap",p="doubletap",f="longtap",m="hold",g="horizontal",v="vertical",y="all",w=10,x="start",b="move",_="end",I="cancel",E="ontouchstart"in window,S=window.navigator.msPointerEnabled&&!window.navigator.pointerEnabled,T=window.navigator.pointerEnabled||window.navigator.msPointerEnabled,O="TouchSwipe",L={fingers:1,threshold:75,cancelThreshold:null,pinchThreshold:20,maxTimeThreshold:null,fingerReleaseThreshold:250,longTapThreshold:500,doubleTapThreshold:200,swipe:null,swipeLeft:null,swipeRight:null,swipeUp:null,swipeDown:null,swipeStatus:null,pinchIn:null,pinchOut:null,pinchStatus:null,click:null,tap:null,doubleTap:null,longTap:null,hold:null,triggerOnTouchEnd:!0,triggerOnTouchLeave:!1,allowPageScroll:"auto",fallbackToMouseEvents:!0,excludedElements:"label, button, input, select, textarea, a, .noSwipe"};$.fn.swipe=function(e){var i=$(this),n=i.data(O);if(n&&"string"==typeof e){if(n[e])return n[e].apply(this,Array.prototype.slice.call(arguments,1));$.error("Method "+e+" does not exist on jQuery.swipe")}else if(!(n||"object"!=typeof e&&e))return t.apply(this,arguments);return i},$.fn.swipe.defaults=L,$.fn.swipe.phases={PHASE_START:x,PHASE_MOVE:b,PHASE_END:_,PHASE_CANCEL:I},$.fn.swipe.directions={LEFT:i,RIGHT:n,UP:o,DOWN:r,IN:s,OUT:a},$.fn.swipe.pageScroll={NONE:u,HORIZONTAL:g,VERTICAL:v,AUTO:l},$.fn.swipe.fingers={ONE:1,TWO:2,THREE:3,ALL:y}}),jQuery(document).ready(function($){$("body").on("click",'div.envirabox-title a[href*="#"]:not([href="#"])',function(t){return location.pathname.replace(/^\//,"")==this.pathname.replace(/^\//,"")&&location.hostname==this.hostname?($.envirabox.close(),!1):void 0})});
assets/js/min/gallery-select-min.js ADDED
@@ -0,0 +1 @@
 
1
+ if("undefined"==typeof EnviraGalleryModalWindow)var EnviraGalleryModalWindow=new wp.media.view.Modal({controller:{trigger:function(){}}});wp.media.view.EnviraGalleryError=wp.Backbone.View.extend({tagName:"div",className:"notice error envira-gallery-error",render:function(){return this.template=wp.media.template("envira-gallery-error"),this.$el.html(this.template(this.model)),this}});var EnviraGallerySelectionItemView=wp.Backbone.View.extend({tagName:"li",className:"attachment",template:wp.template("envira-selection-item"),initialize:function(e){this.model=e.model},render:function(){return this.$el.html(this.template(this.model.attributes)),this}}),EnviraGallerySelectionSidebarView=wp.Backbone.View.extend({tagName:"div",className:"sidebar",initialize:function(e){this.view="undefined"==typeof e?"envira-selection-sidebar":e},render:function(){return this.$el.html(wp.template(this.view)),this}}),EnviraGallerySelectionView=wp.Backbone.View.extend({tagName:"div",className:"media-frame mode-select wp-core-ui hide-router hide-menu",template:wp.template("envira-selection"),events:{"click .attachment":"click",keyup:"search",search:"search","change select":"updateInsertOption","click button.media-button-insert":"insert"},initialize:function(e){this.action=e.action,this.multiple=e.multiple,this.sidebar_view="undefined"==typeof e.sidebar_view?"envira-selection-sidebar":e.sidebar_view,this.onInsert=e.onInsert,this.prepend_ids="undefined"==typeof e.prepend_ids?!1:e.prepend_ids,this.select_ids="undefined"==typeof e.select_ids?!1:e.select_ids,this.selection=new Backbone.Collection,this.collection=new Backbone.Collection,this.insert_options=new Backbone.Model({modal_title:"undefined"==typeof e.modal_title?envira_gallery_select.modal_title:e.modal_title,title:0,insert_button_label:"undefined"==typeof e.modal_title?envira_gallery_select.insert_button_label:e.insert_button_label}),this.is_loading=!1,this.search_timeout=!1,this.on("loading",this.loading,this),this.on("loaded",this.loaded,this),this.getItems(!1,"")},click:function(e){var t=jQuery(e.currentTarget),i=jQuery("div.attachment-preview",t).attr("data-id");t.hasClass("selected")?this.removeFromSelection(t,i):(this.multiple||this.clearSelection(),this.addToSelection(t,i))},search:function(e){if(!this.is_loading){clearTimeout(this.search_timeout);var t=e.target.value;if(0==t.length)return void this.getItems(!1,"");if(!(t.length<3)){var i=this;this.search_timeout=setTimeout(function(){i.getItems(!0,t)},1e3)}}},getItems:function(e,t){if(!this.is_loading){this.clearSelection(),this.$el.find("ul.attachments").empty(),this.$el.find("div.envira-gallery-error").remove(),this.trigger("loading");var i="";switch(this.action){case"gallery":i="envira_gallery_editor_get_galleries";break;case"album":i="envira_albums_editor_get_albums"}wp.media.ajax(i,{context:this,data:{nonce:envira_gallery_select.get_galleries_nonce,search:e,search_terms:t,prepend_ids:this.prepend_ids},success:function(e){var t=new Backbone.Collection(e);this.collection.reset(),this.collection.add(t.models),this.collection.each(function(e){var t=new EnviraGallerySelectionItemView({model:e});if(this.$el.find("ul.attachments").append(t.render().el),this.select_ids!==!1){var i=jQuery.inArray(parseInt(e.get("id")),this.select_ids);i>-1&&this.addToSelection(jQuery(t.render().el),e.get("id"))}},this),this.trigger("loaded")},error:function(e){this.trigger("loaded",e)}})}},updateInsertOption:function(e){""!=e.target.name&&("checkbox"==e.target.type?value=e.target.checked?1:0:value=e.target.value,this.insert_options.set(e.target.name,value))},render:function(){this.$el.html(this.template(this.insert_options.attributes));var e=new EnviraGallerySelectionSidebarView(this.sidebar_view);return this.$el.find("div.media-sidebar").append(e.render().el),this},renderError:function(e){var t={};t.error=e;var i=new wp.media.view.EnviraGalleryError({model:t});return i.render().el},loading:function(){this.is_loading=!0,this.$el.find(".spinner").css("visibility","visible")},loaded:function(e){this.is_loading=!1,this.$el.find(".spinner").css("visibility","hidden"),"undefined"!=typeof e&&this.$el.find("ul.attachments").before(this.renderError(e))},addToSelection:function(e,t){this.trigger("loading"),this.collection.each(function(e){e.get("id")==t&&this.selection.add(e)},this),e.addClass("selected details"),this.selection.length>0&&this.$el.find("button.media-button-insert").attr("disabled",!1),this.trigger("loaded")},removeFromSelection:function(e,t){this.trigger("loading"),this.selection.each(function(e){this.selection.remove([{cid:e.cid}])},this),e.removeClass("selected details"),0==this.selection.length&&this.$el.find("button.media-button-insert").attr("disabled","disabled"),this.trigger("loaded")},clearSelection:function(){this.selection.each(function(e){this.$el.find('div[data-id="'+e.get("id")+'"]').parent().removeClass("selected details")},this),this.$el.find("button.media-button-insert").attr("disabled","disabled"),this.selection.reset()},insert:function(){if(this.trigger("loading"),"undefined"==typeof this.onInsert){var e=[];this.selection.forEach(function(t){e.push(t.attributes);var i="";0!=this.insert_options.get("title")&&(i="<"+this.insert_options.get("title")+">"+t.get("title")+"</"+this.insert_options.get("title")+">"),i+="[envira-"+this.action+' id="'+t.id+'"]',wp.media.editor.insert(i)},this),jQuery(document).trigger({type:"enviraGalleryModalData",items:e,insert_options:this.insert_options,action:this.action});var t=!0}else var t=this.onInsert();this.trigger("loaded"),t&&EnviraGalleryModalWindow.close()}});
assets/js/min/metabox-min.js CHANGED
@@ -1 +1 @@
1
- function EnviraGalleryImagesUpdate(e){EnviraGalleryImages.reset();var a="ul#envira-gallery-output li.envira-gallery-image"+(e?".selected":"");jQuery(a).each(function(){var e=jQuery.parseJSON(jQuery(this).attr("data-envira-gallery-image-model"));e.alt=EnviraGalleryStripslashes(e.alt),EnviraGalleryImages.add(new EnviraGalleryImage(e))}),jQuery("#envira-gallery-main span.count").text(jQuery("ul#envira-gallery-output li.envira-gallery-image").length)}function EnviraGalleryStripslashes(e){return(e+"").replace(/\\(.?)/g,function(e,a){switch(a){case"\\":return"\\";case"0":return"\x00";case"":return"";default:return a}})}function envira_gallery_sortable($){$(envira_gallery_output).sortable({containment:envira_gallery_output,items:"li",cursor:"move",forcePlaceholderSize:!0,placeholder:"dropzone",helper:function(e,a){a.hasClass("selected")||a.addClass("selected").siblings().removeClass("selected");var t=a.parent().children(".selected").clone();a.data("multidrag",t).siblings(".selected").remove();var i=$("<li/>");return i.append(t)},stop:function(e,a){var t=a.item.data("multidrag");a.item.after(t).remove(),$("li.selected",$(envira_gallery_output)).removeClass("selected"),$.ajax({url:envira_gallery_metabox.ajax,type:"post",async:!0,cache:!1,dataType:"json",data:{action:"envira_gallery_sort_images",order:$(envira_gallery_output).sortable("toArray").toString(),post_id:envira_gallery_metabox.id,nonce:envira_gallery_metabox.sort},success:function(e){EnviraGalleryImagesUpdate(!1)},error:function(e,a,t){$(envira_gallery_output).before('<div class="error"><p>'+a.responseText+"</p></div>")}})}})}jQuery(document).ready(function($){$("input, select").conditional({data:"envira-conditional",value:"envira-conditional-value",displayOnEnabled:"envira-conditional-display"})}),function($){"use strict";$.fn.conditional=function(e){var a=$.extend({data:"conditional",value:"conditional-value",displayOnEnabled:"conditional-display"},e);return this.each(function(){if("undefined"==typeof $(this).data(a.data))return!0;var e,t,i,n;$(this).on("change",function(){switch(e=$(this).data(a.data).split(","),t=$(this).data(a.displayOnEnabled),"undefined"==typeof t&&(t=!0),i=$(this).data(a.value),"undefined"==typeof i&&(i=""),n=!1,$(this).attr("type")){case"checkbox":n=t?$(this).is(":checked"):$(this).is(":checked")?!1:!0;break;default:n=t?""!==i?String($(this).val())!==String(i)?!1:!0:""===$(this).val()||"0"===$(this).val()?!1:!0:""!==i?$(this).val()!==i?!0:!1:""===$(this).val()||"0"===$(this).val()?!0:!1}for(var r=0;r<e.length;r++)n?$("#"+e[r]).fadeIn(300):$("#"+e[r]).fadeOut(300)}),$(this).trigger("change")}),this}}(jQuery);var envira_video_link="p.envira-intro a.envira-video",envira_close_video_link="a.envira-video-close";jQuery(document).ready(function($){$(document).on("click",envira_video_link,function(e){e.preventDefault();var a=$(this).attr("href");-1==a.search("autoplay=1")&&(a+=-1==a.search("rel=")?"?rel=0&autoplay=1":"&autoplay=1"),$("div.envira-video-help").remove();var t=$(this).closest("p.envira-intro");$(t).append('<div class="envira-video-help"><iframe src="'+a+'" /><a href="#" class="envira-video-close dashicons dashicons-no"></a></div>')}),$(document).on("click",envira_close_video_link,function(e){e.preventDefault(),$(this).closest(".envira-video-help").remove()})}),jQuery(document).ready(function($){$(document).on("click","a.envira-gallery-images-delete",function(e){e.preventDefault();var a=confirm(envira_gallery_metabox.remove_multiple);if(!a)return!1;var t=[];$("ul#envira-gallery-output > li.selected").each(function(){t.push($(this).attr("id"))});var i=$(this).parent().attr("id");$.ajax({url:envira_gallery_metabox.ajax,type:"post",dataType:"json",data:{action:"envira_gallery_remove_images",attachment_ids:t,post_id:envira_gallery_metabox.id,nonce:envira_gallery_metabox.remove_nonce},success:function(e){$("ul#envira-gallery-output > li.selected").remove(),$("nav.envira-select-options").fadeOut(),$(".envira-gallery-load-library").attr("data-envira-gallery-offset",0).addClass("has-search").trigger("click"),EnviraGalleryImagesUpdate(!1)},error:function(e,a,t){$(envira_gallery_output).before('<div class="error"><p>'+a.responseText+"</p></div>")}})}),$(document).on("click","#envira-gallery-main .envira-gallery-remove-image",function(e){e.preventDefault();var a=confirm(envira_gallery_metabox.remove);if(a){var t=$(this).parent().attr("id");$.ajax({url:envira_gallery_metabox.ajax,type:"post",dataType:"json",data:{action:"envira_gallery_remove_image",attachment_id:t,post_id:envira_gallery_metabox.id,nonce:envira_gallery_metabox.remove_nonce},success:function(e){$("#"+t).fadeOut("normal",function(){$(this).remove(),$(".envira-gallery-load-library").attr("data-envira-gallery-offset",0).addClass("has-search").trigger("click"),EnviraGalleryImagesUpdate(!1)})},error:function(e,a,t){$(envira_gallery_output).before('<div class="error"><p>'+a.responseText+"</p></div>")}})}})});var EnviraGalleryImage=Backbone.Model.extend({defaults:{id:"",title:"",caption:"",alt:"",link:""}}),EnviraGalleryImages=new Backbone.Collection;if("undefined"==typeof EnviraGalleryModalWindow)var EnviraGalleryModalWindow=new wp.media.view.Modal({controller:{trigger:function(){}}});var EnviraGalleryEditView=wp.Backbone.View.extend({tagName:"div",className:"edit-attachment-frame mode-select hide-menu hide-router",template:wp.template("envira-meta-editor"),events:{"click .edit-media-header .left":"loadPreviousItem","click .edit-media-header .right":"loadNextItem","keyup input":"updateItem","keyup textarea":"updateItem","change input":"updateItem","change textarea":"updateItem","blur textarea":"updateItem","change select":"updateItem","click .actions a.envira-gallery-meta-submit":"saveItem","keyup input#link-search":"searchLinks","click div.query-results li":"insertLink","click button.media-file":"insertMediaFileLink","click button.attachment-page":"insertAttachmentPageLink"},initialize:function(e){this.on("loading",this.loading,this),this.on("loaded",this.loaded,this),this.is_loading=!1,this.collection=e.collection,this.child_views=e.child_views,this.attachment_id=e.attachment_id,this.attachment_index=0,this.search_timer="";var a=0;this.collection.each(function(e){return e.get("id")==this.attachment_id?(this.model=e,this.attachment_index=a,!1):void a++},this)},render:function(){return this.$el.html(this.template(this.model.attributes)),this.child_views.length>0&&this.child_views.forEach(function(e){var a=new e({model:this.model});this.$el.find("div.addons").append(a.render().el)},this),this.$el.find("textarea[name=caption]").val(this.model.get("caption")),setTimeout(function(){quicktags({id:"caption",buttons:"strong,em,link,ul,ol,li,close"}),QTags._buttonsInit()},500),"undefined"!=typeof wpLink&&wpLink.init,0==this.attachment_index&&this.$el.find("button.left").addClass("disabled"),this.attachment_index==this.collection.length-1&&this.$el.find("button.right").addClass("disabled"),this},renderError:function(e){var a={};a.error=e;var t=new wp.media.view.EnviraGalleryError({model:a});return t.render().el},loading:function(){this.is_loading=!0,this.$el.find(".spinner").css("visibility","visible")},loaded:function(e){this.is_loading=!1,this.$el.find(".spinner").css("visibility","hidden"),"undefined"!=typeof e&&this.$el.find("div.media-toolbar").after(this.renderError(e))},loadPreviousItem:function(){this.attachment_index--,this.model=this.collection.at(this.attachment_index),this.attachment_id=this.model.get("id"),this.render()},loadNextItem:function(){this.attachment_index++,this.model=this.collection.at(this.attachment_index),this.attachment_id=this.model.get("id"),this.render()},updateItem:function(e){""!=e.target.name&&("checkbox"==e.target.type?value=e.target.checked?1:0:value=e.target.value,this.model.set(e.target.name,value))},saveItem:function(){this.trigger("loading"),wp.media.ajax("envira_gallery_save_meta",{context:this,data:{nonce:envira_gallery_metabox.save_nonce,post_id:envira_gallery_metabox.id,attach_id:this.model.get("id"),meta:this.model.attributes},success:function(e){this.trigger("loaded loaded:success");var a=JSON.stringify(this.model.attributes),t=jQuery("ul#envira-gallery-output li#"+this.model.get("id"));jQuery(t).attr("data-envira-gallery-image-model",a),jQuery("div.meta div.title span",t).text(this.model.get("title")),jQuery("div.meta div.title a.hint",t).attr("title",this.model.get("title")),this.model.get("title").length>20?jQuery("div.meta div.title a.hint",t).removeClass("hidden"):jQuery("div.meta div.title a.hint",t).addClass("hidden");var i=this.$el.find(".saved");i.fadeIn(),setTimeout(function(){i.fadeOut()},1500)},error:function(e){this.trigger("loaded loaded:error",e)}})},searchLinks:function(e){},insertLink:function(e){},insertMediaFileLink:function(e){this.trigger("loading"),wp.media.ajax("envira_gallery_get_attachment_links",{context:this,data:{nonce:envira_gallery_metabox.save_nonce,attachment_id:this.model.get("id")},success:function(e){this.model.set("link",e.media_link),this.trigger("loaded loaded:success"),this.render()},error:function(e){this.trigger("loaded loaded:error",e)}})},insertAttachmentPageLink:function(e){this.trigger("loading"),wp.media.ajax("envira_gallery_get_attachment_links",{context:this,data:{nonce:envira_gallery_metabox.save_nonce,attachment_id:this.model.get("id")},success:function(e){this.model.set("link",e.attachment_page),this.trigger("loaded loaded:success"),this.render()},error:function(e){this.trigger("loaded loaded:error",e)}})}}),EnviraGalleryChildViews=[];jQuery(document).ready(function($){$(document).on("click","#envira-gallery-main a.envira-gallery-modify-image",function(e){e.preventDefault(),EnviraGalleryImagesUpdate(!1);var a=$(this).parent().data("envira-gallery-image");EnviraGalleryModalWindow.content(new EnviraGalleryEditView({collection:EnviraGalleryImages,child_views:EnviraGalleryChildViews,attachment_id:a})),EnviraGalleryModalWindow.open()})}),jQuery(document).ready(function($){$("a.envira-media-library").on("click",function(e){return e.preventDefault(),wp.media.frames.envira?void wp.media.frames.envira.open():(wp.media.frames.envira=wp.media({frame:"post",title:wp.media.view.l10n.insertIntoPost,button:{text:wp.media.view.l10n.insertIntoPost},multiple:!0}),wp.media.frames.envira.on("open",function(){var e=wp.media.frames.envira.state().get("selection");$("ul#envira-gallery-output li").each(function(){var a=wp.media.attachment($(this).attr("id"));e.add(a?[a]:[])})}),wp.media.frames.envira.on("insert",function(e){var a=wp.media.frames.envira.state(),t=[];e.each(function(e){var i=a.display(e).toJSON();switch(i.link){case"none":e.set("link",e.get("url"));break;case"file":e.set("link",e.get("url"));break;case"post":break;case"custom":e.set("link",i.linkUrl)}t.push(e.toJSON())},this),$.post(envira_gallery_metabox.ajax,{action:"envira_gallery_insert_images",nonce:envira_gallery_metabox.insert_nonce,post_id:envira_gallery_metabox.id,images:t},function(e){e&&e.success&&($("#envira-gallery-output").html(e.success),EnviraGalleryImagesUpdate(!1))},"json")}),void wp.media.frames.envira.open())})});var envira_gallery_output="#envira-gallery-output",envira_gallery_shift_key_pressed=!1,envira_gallery_last_selected_image=!1;jQuery(document).ready(function($){envira_gallery_sortable($)}),function($){$(function(){if("undefined"!=typeof uploader){$("input#plupload-browse-button").val(envira_gallery_metabox.uploader_files_computer),$("#envira-gallery .drag-drop-inside").append('<div class="envira-progress-bar"><div></div></div>');var e=$("#envira-gallery .envira-progress-bar"),a=$("#envira-gallery .envira-progress-bar div"),t=$("#envira-gallery-output"),i=$("#envira-gallery-upload-error");uploader.bind("FilesAdded",function(a,t){$(i).html(""),$(e).fadeIn()}),uploader.bind("UploadProgress",function(e,t){$(a).css({width:e.total.percent+"%"})}),uploader.bind("FileUploaded",function(e,a,i){$.post(envira_gallery_metabox.ajax,{action:"envira_gallery_load_image",nonce:envira_gallery_metabox.load_image,id:i.response,post_id:envira_gallery_metabox.id},function(e){switch(envira_gallery_metabox.media_position){case"before":$(t).prepend(e);break;case"after":default:$(t).append(e)}EnviraGalleryImagesUpdate(!1)},"json")}),uploader.bind("UploadComplete",function(){$(e).fadeOut()}),uploader.bind("Error",function(e,a){$("#envira-gallery-upload-error").html('<div class="error fade"><p>'+a.file.name+": "+a.message+"</p></div>"),e.refresh()})}})}(jQuery);
1
+ function EnviraGalleryImagesUpdate(e){EnviraGalleryImages.reset();var a="ul#envira-gallery-output li.envira-gallery-image"+(e?".selected":"");jQuery(a).each(function(){var e=jQuery.parseJSON(jQuery(this).attr("data-envira-gallery-image-model"));e.alt=EnviraGalleryStripslashes(e.alt),EnviraGalleryImages.add(new EnviraGalleryImage(e))}),jQuery("#envira-gallery-main span.count").text(jQuery("ul#envira-gallery-output li.envira-gallery-image").length)}function EnviraGalleryStripslashes(e){return(e+"").replace(/\\(.?)/g,function(e,a){switch(a){case"\\":return"\\";case"0":return"\x00";case"":return"";default:return a}})}function envira_gallery_sortable($){$(envira_gallery_output).sortable({containment:envira_gallery_output,items:"li",cursor:"move",forcePlaceholderSize:!0,placeholder:"dropzone",helper:function(e,a){a.hasClass("selected")||a.addClass("selected").siblings().removeClass("selected");var t=a.parent().children(".selected").clone();a.data("multidrag",t).siblings(".selected").remove();var i=$("<li/>");return i.append(t)},stop:function(e,a){var t=a.item.data("multidrag");a.item.after(t).remove(),$("li.selected",$(envira_gallery_output)).removeClass("selected"),$.ajax({url:envira_gallery_metabox.ajax,type:"post",async:!0,cache:!1,dataType:"json",data:{action:"envira_gallery_sort_images",order:$(envira_gallery_output).sortable("toArray").toString(),post_id:envira_gallery_metabox.id,nonce:envira_gallery_metabox.sort},success:function(e){EnviraGalleryImagesUpdate(!1)},error:function(e,a,t){$(envira_gallery_output).before('<div class="error"><p>'+a.responseText+"</p></div>")}})}})}var envira_video_link="p.envira-intro a.envira-video",envira_close_video_link="a.envira-video-close";jQuery(document).ready(function($){$(document).on("click",envira_video_link,function(e){e.preventDefault();var a=$(this).attr("href");-1==a.search("autoplay=1")&&(a+=-1==a.search("rel=")?"?rel=0&autoplay=1":"&autoplay=1"),$("div.envira-video-help").remove();var t=$(this).closest("p.envira-intro");$(t).append('<div class="envira-video-help"><iframe src="'+a+'" /><a href="#" class="envira-video-close dashicons dashicons-no"></a></div>')}),$(document).on("click",envira_close_video_link,function(e){e.preventDefault(),$(this).closest(".envira-video-help").remove()})}),jQuery(document).ready(function($){$(document).on("click","a.envira-gallery-images-delete",function(e){e.preventDefault();var a=confirm(envira_gallery_metabox.remove_multiple);if(!a)return!1;var t=[];$("ul#envira-gallery-output > li.selected").each(function(){t.push($(this).attr("id"))});var i=$(this).parent().attr("id");$.ajax({url:envira_gallery_metabox.ajax,type:"post",dataType:"json",data:{action:"envira_gallery_remove_images",attachment_ids:t,post_id:envira_gallery_metabox.id,nonce:envira_gallery_metabox.remove_nonce},success:function(e){$("ul#envira-gallery-output > li.selected").remove(),$("nav.envira-select-options").fadeOut(),$(".envira-gallery-load-library").attr("data-envira-gallery-offset",0).addClass("has-search").trigger("click"),EnviraGalleryImagesUpdate(!1)},error:function(e,a,t){$(envira_gallery_output).before('<div class="error"><p>'+a.responseText+"</p></div>")}})}),$(document).on("click","#envira-gallery-main .envira-gallery-remove-image",function(e){e.preventDefault();var a=confirm(envira_gallery_metabox.remove);if(a){var t=$(this).parent().attr("id");$.ajax({url:envira_gallery_metabox.ajax,type:"post",dataType:"json",data:{action:"envira_gallery_remove_image",attachment_id:t,post_id:envira_gallery_metabox.id,nonce:envira_gallery_metabox.remove_nonce},success:function(e){$("#"+t).fadeOut("normal",function(){$(this).remove(),$(".envira-gallery-load-library").attr("data-envira-gallery-offset",0).addClass("has-search").trigger("click"),EnviraGalleryImagesUpdate(!1)})},error:function(e,a,t){$(envira_gallery_output).before('<div class="error"><p>'+a.responseText+"</p></div>")}})}})});var EnviraGalleryImage=Backbone.Model.extend({defaults:{id:"",title:"",caption:"",alt:"",link:""}}),EnviraGalleryImages=new Backbone.Collection;if("undefined"==typeof EnviraGalleryModalWindow)var EnviraGalleryModalWindow=new wp.media.view.Modal({controller:{trigger:function(){}}});var EnviraGalleryEditView=wp.Backbone.View.extend({tagName:"div",className:"edit-attachment-frame mode-select hide-menu hide-router",template:wp.template("envira-meta-editor"),events:{"click .edit-media-header .left":"loadPreviousItem","click .edit-media-header .right":"loadNextItem","keyup input":"updateItem","keyup textarea":"updateItem","change input":"updateItem","change textarea":"updateItem","blur textarea":"updateItem","change select":"updateItem","click .actions a.envira-gallery-meta-submit":"saveItem","keyup input#link-search":"searchLinks","click div.query-results li":"insertLink","click button.media-file":"insertMediaFileLink","click button.attachment-page":"insertAttachmentPageLink"},initialize:function(e){this.on("loading",this.loading,this),this.on("loaded",this.loaded,this),this.is_loading=!1,this.collection=e.collection,this.child_views=e.child_views,this.attachment_id=e.attachment_id,this.attachment_index=0,this.search_timer="";var a=0;this.collection.each(function(e){return e.get("id")==this.attachment_id?(this.model=e,this.attachment_index=a,!1):void a++},this)},render:function(){return this.$el.html(this.template(this.model.attributes)),this.child_views.length>0&&this.child_views.forEach(function(e){var a=new e({model:this.model});this.$el.find("div.addons").append(a.render().el)},this),this.$el.find("textarea[name=caption]").val(this.model.get("caption")),setTimeout(function(){quicktags({id:"caption",buttons:"strong,em,link,ul,ol,li,close"}),QTags._buttonsInit()},500),wpLink.init,0==this.attachment_index&&this.$el.find("button.left").addClass("disabled"),this.attachment_index==this.collection.length-1&&this.$el.find("button.right").addClass("disabled"),this},renderError:function(e){var a={};a.error=e;var t=new wp.media.view.EnviraGalleryError({model:a});return t.render().el},loading:function(){this.is_loading=!0,this.$el.find(".spinner").css("visibility","visible")},loaded:function(e){this.is_loading=!1,this.$el.find(".spinner").css("visibility","hidden"),"undefined"!=typeof e&&this.$el.find("div.media-toolbar").after(this.renderError(e))},loadPreviousItem:function(){this.attachment_index--,this.model=this.collection.at(this.attachment_index),this.attachment_id=this.model.get("id"),this.render()},loadNextItem:function(){this.attachment_index++,this.model=this.collection.at(this.attachment_index),this.attachment_id=this.model.get("id"),this.render()},updateItem:function(e){""!=e.target.name&&("checkbox"==e.target.type?value=e.target.checked?e.target.value:0:value=e.target.value,this.model.set(e.target.name,value))},saveItem:function(){this.trigger("loading"),wp.media.ajax("envira_gallery_save_meta",{context:this,data:{nonce:envira_gallery_metabox.save_nonce,post_id:envira_gallery_metabox.id,attach_id:this.model.get("id"),meta:this.model.attributes},success:function(e){this.trigger("loaded loaded:success");var a=JSON.stringify(this.model.attributes),t=jQuery("ul#envira-gallery-output li#"+this.model.get("id"));jQuery(t).attr("data-envira-gallery-image-model",a),jQuery("div.meta div.title span",t).text(this.model.get("title")),jQuery("div.meta div.title a.hint",t).attr("title",this.model.get("title")),this.model.get("title").length>20?jQuery("div.meta div.title a.hint",t).removeClass("hidden"):jQuery("div.meta div.title a.hint",t).addClass("hidden");var i=this.$el.find(".saved");i.fadeIn(),setTimeout(function(){i.fadeOut()},1500)},error:function(e){this.trigger("loaded loaded:error",e)}})},searchLinks:function(e){},insertLink:function(e){},insertMediaFileLink:function(e){this.trigger("loading"),wp.media.ajax("envira_gallery_get_attachment_links",{context:this,data:{nonce:envira_gallery_metabox.save_nonce,attachment_id:this.model.get("id")},success:function(e){this.model.set("link",e.media_link),this.trigger("loaded loaded:success"),this.render()},error:function(e){this.trigger("loaded loaded:error",e)}})},insertAttachmentPageLink:function(e){this.trigger("loading"),wp.media.ajax("envira_gallery_get_attachment_links",{context:this,data:{nonce:envira_gallery_metabox.save_nonce,attachment_id:this.model.get("id")},success:function(e){this.model.set("link",e.attachment_page),this.trigger("loaded loaded:success"),this.render()},error:function(e){this.trigger("loaded loaded:error",e)}})}}),EnviraGalleryChildViews=[];jQuery(document).ready(function($){$(document).on("click","#envira-gallery-main a.envira-gallery-modify-image",function(e){e.preventDefault(),EnviraGalleryImagesUpdate(!1);var a=$(this).parent().data("envira-gallery-image");EnviraGalleryModalWindow.content(new EnviraGalleryEditView({collection:EnviraGalleryImages,child_views:EnviraGalleryChildViews,attachment_id:a})),EnviraGalleryModalWindow.open()})}),jQuery(document).ready(function($){$("a.envira-media-library").on("click",function(e){return e.preventDefault(),wp.media.frames.envira?void wp.media.frames.envira.open():(wp.media.frames.envira=wp.media({frame:"post",title:wp.media.view.l10n.insertIntoPost,button:{text:wp.media.view.l10n.insertIntoPost},multiple:!0}),wp.media.frames.envira.on("open",function(){var e=wp.media.frames.envira.state().get("selection");$("ul#envira-gallery-output li").each(function(){var a=wp.media.attachment($(this).attr("id"));e.add(a?[a]:[])})}),wp.media.frames.envira.on("insert",function(e){var a=wp.media.frames.envira.state(),t=[];e.each(function(e){var i=a.display(e).toJSON();switch(i.link){case"none":e.set("link",e.get("url"));break;case"file":e.set("link",e.get("url"));break;case"post":break;case"custom":e.set("link",i.linkUrl)}t.push(e.toJSON())},this),$.post(envira_gallery_metabox.ajax,{action:"envira_gallery_insert_images",nonce:envira_gallery_metabox.insert_nonce,post_id:envira_gallery_metabox.id,images:t},function(e){e&&e.success&&($("#envira-gallery-output").html(e.success),EnviraGalleryImagesUpdate(!1))},"json")}),void wp.media.frames.envira.open())})});var envira_gallery_output="#envira-gallery-output",envira_gallery_shift_key_pressed=!1,envira_gallery_last_selected_image=!1;jQuery(document).ready(function($){$(document).on("click","nav.envira-tab-options a",function(e){e.preventDefault();var a=$(this).closest(".envira-tab-options"),t=$(this).data("view"),i=$(this).data("view-style");$(t).hasClass(i)||($(t).removeClass("list").removeClass("grid").addClass(i),$("a",a).removeClass("selected"),$(this).addClass("selected"),$.ajax({url:envira_gallery_metabox.ajax,type:"post",dataType:"json",data:{action:"envira_gallery_set_user_setting",name:"envira_gallery_image_view",value:i,nonce:envira_gallery_metabox.set_user_setting_nonce},success:function(e){},error:function(e,a,t){$(envira_gallery_output).before('<div class="error"><p>'+a.responseText+"</p></div>")}}))}),$(document).on("change","nav.envira-tab-options input",function(e){$(this).prop("checked")?($("li",$(envira_gallery_output)).addClass("selected"),$("nav.envira-select-options").fadeIn()):($("li",$(envira_gallery_output)).removeClass("selected"),$("nav.envira-select-options").fadeOut())}),envira_gallery_sortable($),$(document).on("enviraGalleryType",function(){$(envira_gallery_output).length>0&&envira_gallery_sortable($)}),$(document).on("click","ul#envira-gallery-output li.envira-gallery-image > img, li.envira-gallery-image > div, li.envira-gallery-image > a.check",function(e){e.preventDefault();var a=$(this).parent();if($(a).hasClass("selected"))$(a).removeClass("selected"),envira_gallery_last_selected_image=!1;else{if(envira_gallery_shift_key_pressed&&envira_gallery_last_selected_image!==!1){var t=$("ul#envira-gallery-output li").index($(envira_gallery_last_selected_image)),i=$("ul#envira-gallery-output li").index($(a)),r=0;if(i>t)for(r=t;i>=r;r++)$("ul#envira-gallery-output li:eq( "+r+")").addClass("selected");else for(r=i;t>=r;r++)$("ul#envira-gallery-output li:eq( "+r+")").addClass("selected")}$(a).addClass("selected"),envira_gallery_last_selected_image=$(a)}$("ul#envira-gallery-output > li.selected").length>0?$("nav.envira-select-options").fadeIn():$("nav.envira-select-options").fadeOut()}),$(document).on("keyup keydown",function(e){envira_gallery_shift_key_pressed=e.shiftKey})}),function($){$(function(){if("undefined"!=typeof uploader){$("input#plupload-browse-button").val(envira_gallery_metabox.uploader_files_computer);var e=$("#envira-gallery .envira-progress-bar"),a=$("#envira-gallery .envira-progress-bar div.envira-progress-bar-inner"),t=$("#envira-gallery .envira-progress-bar div.envira-progress-bar-status"),i=$("#envira-gallery-output"),r=$("#envira-gallery-upload-error"),n=0;uploader.bind("Init",function(e){$("#drag-drop-area").fadeIn(),$("a.envira-media-library.button").fadeIn()}),uploader.bind("FilesAdded",function(a,i){$(r).html(""),n=i.length,$(".uploading .current",$(t)).text("1"),$(".uploading .total",$(t)).text(n),$(".uploading",$(t)).show(),$(".done",$(t)).hide(),$(e).fadeIn()}),uploader.bind("UploadProgress",function(e,i){$(".uploading .current",$(t)).text(n-e.total.queued+1),$(a).css({width:e.total.percent+"%"})}),uploader.bind("FileUploaded",function(e,a,t){$.post(envira_gallery_metabox.ajax,{action:"envira_gallery_load_image",nonce:envira_gallery_metabox.load_image,id:t.response,post_id:envira_gallery_metabox.id},function(e){switch(envira_gallery_metabox.media_position){case"before":$(i).prepend(e);break;case"after":default:$(i).append(e)}EnviraGalleryImagesUpdate(!1)},"json")}),uploader.bind("UploadComplete",function(){$(".uploading",$(t)).hide(),$(".done",$(t)).show(),setTimeout(function(){$(e).fadeOut()},1e3)}),uploader.bind("Error",function(e,a){$("#envira-gallery-upload-error").html('<div class="error fade"><p>'+a.file.name+": "+a.message+"</p></div>"),e.refresh()})}})}(jQuery),jQuery(document).ready(function($){$('select[name="_envira_gallery[image_size]"]').on("change",function(){"envira_gallery_random"==$(this).val()?$("tr#envira-config-image-sizes-random-box").show():$("tr#envira-config-image-sizes-random-box").hide()}),$('select[name="_envira_gallery[image_size]"]').trigger("change")});
envira-gallery-lite.php CHANGED
@@ -5,7 +5,7 @@
5
  * Description: Envira Gallery is best responsive WordPress gallery plugin. This is the lite version.
6
  * Author: Thomas Griffin
7
  * Author URI: http://enviragallery.com
8
- * Version: 1.5.0.1
9
  * Text Domain: envira-gallery
10
  *
11
  * Envira Gallery is free software: you can redistribute it and/or modify
@@ -53,7 +53,7 @@ class Envira_Gallery_Lite {
53
  *
54
  * @var string
55
  */
56
- public $version = '1.5.0.1';
57
 
58
  /**
59
  * The name of the plugin.
5
  * Description: Envira Gallery is best responsive WordPress gallery plugin. This is the lite version.
6
  * Author: Thomas Griffin
7
  * Author URI: http://enviragallery.com
8
+ * Version: 1.5.0.2
9
  * Text Domain: envira-gallery
10
  *
11
  * Envira Gallery is free software: you can redistribute it and/or modify
53
  *
54
  * @var string
55
  */
56
+ public $version = '1.5.0.2';
57
 
58
  /**
59
  * The name of the plugin.
includes/admin/ajax.php CHANGED
@@ -52,7 +52,7 @@ function envira_gallery_ajax_change_preview() {
52
  $type = stripslashes( $_POST['type'] );
53
 
54
  // Get the saved Gallery configuration.
55
- $data = Envira_Gallery_Lite::get_instance()->get_gallery( $post_id );
56
 
57
  // Iterate through the POSTed Gallery configuration (which comprises of index based fields),
58
  // overwriting the above with the supplied values. This gives us the most up to date,
@@ -625,7 +625,7 @@ function envira_gallery_ajax_install_addon() {
625
 
626
  // We do not need any extra credentials if we have gotten this far, so let's install the plugin.
627
  require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
628
- require_once plugin_dir_path( Envira_Gallery_Lite::get_instance()->file ) . 'includes/admin/skin.php';
629
 
630
  // Create the plugin upgrader with our custom skin.
631
  $installer = new Plugin_Upgrader( $skin = new Envira_Gallery_Skin() );
@@ -724,7 +724,7 @@ function envira_gallery_ajax_prepare_gallery_data( $gallery_data, $id, $image =
724
  } else {
725
  $image = array(
726
  'status' => 'active',
727
- 'src' => $image['url'],
728
  'title' => $image['title'],
729
  'link' => $image['link'],
730
  'alt' => $image['alt'],
@@ -833,11 +833,13 @@ function envira_gallery_editor_get_galleries() {
833
  check_ajax_referer( 'envira-gallery-editor-get-galleries', 'nonce' );
834
 
835
  // Get POSTed fields
836
- $search = (bool) $_POST['search'];
837
- $search_terms = sanitize_text_field( $_POST['search_terms'] );
 
838
 
839
  // Get galleries
840
- $galleries = Envira_Gallery_Lite::get_instance()->get_galleries( false, true, ( $search ? $search_terms : '' ) );
 
841
 
842
  // Build array of just the data we need.
843
  foreach ( ( array ) $galleries as $gallery ) {
@@ -852,13 +854,102 @@ function envira_gallery_editor_get_galleries() {
852
  // Add gallery to results
853
  $results[] = array(
854
  'id' => $gallery['id'],
 
855
  'title' => $gallery['config']['title'],
856
  'thumbnail' => ( ( isset( $thumbnail ) && is_array( $thumbnail ) ) ? $thumbnail[0] : '' ),
857
  'action' => 'gallery', // Tells the editor modal whether this is a Gallery or Album for the shortcode output
858
  );
859
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
860
 
861
  // Return galleries
862
  wp_send_json_success( $results );
863
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
864
  }
52
  $type = stripslashes( $_POST['type'] );
53
 
54
  // Get the saved Gallery configuration.
55
+ $data = ( class_exists( 'Envira_Gallery' ) ? Envira_Gallery::get_instance()->get_gallery( $post_id ) : Envira_Gallery_Lite::get_instance()->get_gallery( $post_id ) );
56
 
57
  // Iterate through the POSTed Gallery configuration (which comprises of index based fields),
58
  // overwriting the above with the supplied values. This gives us the most up to date,
625
 
626
  // We do not need any extra credentials if we have gotten this far, so let's install the plugin.
627
  require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
628
+ require_once plugin_dir_path( Envira_Gallery::get_instance()->file ) . 'includes/admin/skin.php';
629
 
630
  // Create the plugin upgrader with our custom skin.
631
  $installer = new Plugin_Upgrader( $skin = new Envira_Gallery_Skin() );
724
  } else {
725
  $image = array(
726
  'status' => 'active',
727
+ 'src' => ( isset( $image['src'] ) ? $image['src'] : $image['url'] ),
728
  'title' => $image['title'],
729
  'link' => $image['link'],
730
  'alt' => $image['alt'],
833
  check_ajax_referer( 'envira-gallery-editor-get-galleries', 'nonce' );
834
 
835
  // Get POSTed fields
836
+ $search = (bool) $_POST['search'];
837
+ $search_terms = sanitize_text_field( $_POST['search_terms'] );
838
+ $prepend_ids = stripslashes_deep( $_POST['prepend_ids'] );
839
 
840
  // Get galleries
841
+ $instance = ( class_exists( 'Envira_Gallery' ) ? Envira_Gallery::get_instance() : Envira_Gallery_Lite::get_instance() );
842
+ $galleries = $instance->get_galleries( false, true, ( $search ? $search_terms : '' ) );
843
 
844
  // Build array of just the data we need.
845
  foreach ( ( array ) $galleries as $gallery ) {
854
  // Add gallery to results
855
  $results[] = array(
856
  'id' => $gallery['id'],
857
+ 'slug' => $gallery['config']['slug'],
858
  'title' => $gallery['config']['title'],
859
  'thumbnail' => ( ( isset( $thumbnail ) && is_array( $thumbnail ) ) ? $thumbnail[0] : '' ),
860
  'action' => 'gallery', // Tells the editor modal whether this is a Gallery or Album for the shortcode output
861
  );
862
  }
863
+
864
+ // If any prepended Gallery IDs were specified, get them now
865
+ // These will typically be a Defaults Gallery, which wouldn't be included in the above get_galleries() call
866
+ if ( is_array( $prepend_ids ) && count( $prepend_ids ) > 0 ) {
867
+ $prepend_results = array();
868
+
869
+ // Get each Gallery
870
+ foreach ( $prepend_ids as $gallery_id ) {
871
+ // Get gallery
872
+ $gallery = get_post_meta( $gallery_id, '_eg_gallery_data', true );
873
+
874
+ // Get gallery first image
875
+ if ( isset( $gallery['gallery'] ) && ! empty( $gallery['gallery'] ) ) {
876
+ // Get the first image
877
+ reset( $gallery['gallery'] );
878
+ $key = key( $gallery['gallery'] );
879
+ $thumbnail = wp_get_attachment_image_src( $key, 'thumbnail' );
880
+ }
881
+
882
+ // Add gallery to results
883
+ $prepend_results[] = array(
884
+ 'id' => $gallery['id'],
885
+ 'slug' => $gallery['config']['slug'],
886
+ 'title' => $gallery['config']['title'],
887
+ 'thumbnail' => ( ( isset( $thumbnail ) && is_array( $thumbnail ) ) ? $thumbnail[0] : '' ),
888
+ 'action' => 'gallery', // Tells the editor modal whether this is a Gallery or Album for the shortcode output
889
+ );
890
+ }
891
+
892
+ // Add to results
893
+ if ( is_array( $prepend_results ) && count( $prepend_results ) > 0 ) {
894
+ $results = array_merge( $prepend_results, $results );
895
+ }
896
+ }
897
 
898
  // Return galleries
899
  wp_send_json_success( $results );
900
 
901
+ }
902
+
903
+ /**
904
+ * Moves media (images) from one Gallery to another
905
+ *
906
+ * @since 1.5.0.3
907
+ */
908
+ add_action( 'wp_ajax_envira_gallery_move_media', 'envira_gallery_move_media' );
909
+ function envira_gallery_move_media() {
910
+
911
+ // Check nonce
912
+ check_ajax_referer( 'envira-gallery-move-media', 'nonce' );
913
+
914
+ // Get POSTed fields
915
+ $from_gallery_id = absint( $_POST['from_gallery_id'] );
916
+ $to_gallery_id = absint( $_POST['to_gallery_id'] );
917
+ $image_ids = $_POST['image_ids'];
918
+
919
+ if ( ! $from_gallery_id ) {
920
+ wp_send_json_error( __( 'The From Gallery ID has not been specified.', 'envira-gallery' ) );
921
+ }
922
+ if ( ! $to_gallery_id ) {
923
+ wp_send_json_error( __( 'The From Gallery ID has not been specified.', 'envira-gallery' ) );
924
+ }
925
+ if ( count( $image_ids ) == 0 ) {
926
+ wp_send_json_error( __( 'No images were selected to be moved between Galleries.', 'envira-gallery' ) );
927
+ }
928
+
929
+ // Get from and to Galleries
930
+ $from_gallery = Envira_Gallery::get_instance()->get_gallery( $from_gallery_id );
931
+ $to_gallery = Envira_Gallery::get_instance()->get_gallery( $to_gallery_id );
932
+
933
+ // Iterate through each image ID, adding the image to $to_gallery, then removing from $from_gallery
934
+ foreach ( $image_ids as $image_id ) {
935
+ // Check the image exists in $from_gallery
936
+ // If not, skip this image
937
+ if ( ! isset( $from_gallery['gallery'][ $image_id ] ) ) {
938
+ continue;
939
+ }
940
+
941
+ // Copy the image to $to_gallery
942
+ $to_gallery['gallery'][ $image_id ] = $from_gallery['gallery'][ $image_id ];
943
+
944
+ // Remove the image from $from_gallery
945
+ unset( $from_gallery['gallery'][ $image_id ] );
946
+ }
947
+
948
+ // Save both Galleries
949
+ update_post_meta( $from_gallery_id, '_eg_gallery_data', $from_gallery );
950
+ update_post_meta( $to_gallery_id, '_eg_gallery_data', $to_gallery );
951
+
952
+ // Return success
953
+ wp_send_json_success();
954
+
955
  }
includes/admin/common.php CHANGED
@@ -53,7 +53,7 @@ class Envira_Gallery_Common_Admin {
53
  public function __construct() {
54
 
55
  // Load the base class object.
56
- $this->base = Envira_Gallery_Lite::get_instance();
57
 
58
  // Handle any necessary DB upgrades.
59
  add_action( 'admin_init', array( $this, 'db_upgrade' ) );
@@ -85,7 +85,7 @@ class Envira_Gallery_Common_Admin {
85
  // Upgrade to allow captions (v1.1.6).
86
  $captions = get_option( 'envira_gallery_116' );
87
  if ( ! $captions ) {
88
- $galleries = Envira_Gallery_Lite::get_instance()->_get_galleries();
89
  if ( $galleries ) {
90
  foreach ( $galleries as $gallery ) {
91
  foreach ( (array) $gallery['gallery'] as $id => $item ) {
@@ -102,129 +102,128 @@ class Envira_Gallery_Common_Admin {
102
  // 1.2.1: Convert all non-Envira Post Type galleries into Envira CPT galleries.
103
  $cptGalleries = get_option( 'envira_gallery_121' );
104
  if ( ! $cptGalleries ) {
105
- // Get Post Types, excluding our own
106
- // We don't use post_status => 'any', as this doesn't include CPTs where exclude_from_search = true.
107
- $postTypes = get_post_types( array(
108
- 'public' => true,
109
- ) );
110
- $excludedPostTypes = array( 'envira', 'envira_album', 'attachment' );
111
- foreach ( $postTypes as $key=>$postType ) {
112
- if ( in_array( $postType, $excludedPostTypes ) ) {
113
- unset( $postTypes[ $key ] );
114
- }
115
- }
116
-
117
- // Get all Posts that have _eg_gallery_data set
118
- $inPostGalleries = new WP_Query( array(
119
- 'post_type' => $postTypes,
120
- 'post_status' => 'any',
121
- 'posts_per_page'=> -1,
122
- 'meta_query' => array(
123
- array(
124
- 'key' => '_eg_gallery_data',
125
- 'compare' => 'EXISTS',
126
- ),
127
- )
128
- ) );
129
-
130
- // Check if any Posts with galleries exist
131
- if ( count( $inPostGalleries->posts ) > 0 ) {
132
  $migrated_galleries = 0;
133
 
134
- // Iterate through Posts with Galleries
135
- foreach ( $inPostGalleries->posts as $post ) {
136
- // Check if this is an Envira or Envira Album CPT
137
- // If so, skip it
138
- if ( $post->post_type == 'envira' || $post->post_type == 'envira_album' ) {
139
- continue;
140
- }
141
-
142
- // Get metadata
143
- $data = get_post_meta( $post->ID, '_eg_gallery_data', true);
144
- $in = get_post_meta( $post->ID, '_eg_in_gallery', true);
145
-
146
- // Check if there is at least one image in the gallery
147
- // Some Posts save Envira config data but don't have images - we don't want to migrate those,
148
- // as we would end up with blank Envira CPT galleries
149
- if ( ! isset( $data['gallery'] ) || ! is_array( $data['gallery']) ) {
150
- continue;
151
- }
152
-
153
- // If here, we need to create a new Envira CPT
154
- $cpt_args = array(
155
- 'post_title' => ( !empty( $data['config']['title'] ) ? $data['config']['title'] : $post->post_title ),
156
- 'post_status' => $post->post_status,
157
- 'post_type' => 'envira',
158
- 'post_author' => $post->post_author,
159
- );
160
- if ( ! empty( $data['config']['slug'] ) ) {
161
- $cpt_args['post_name'] = $data['config']['slug'];
162
- }
163
- $enviraGalleryID = wp_insert_post( $cpt_args );
164
-
165
- // Check gallery creation was successful
166
- if ( is_wp_error( $enviraGalleryID ) ) {
167
- // @TODO how to handle errors?
168
- continue;
169
- }
170
-
171
- // Get Envira Gallery Post
172
- $enviraPost = get_post( $enviraGalleryID );
173
-
174
- // Map the title and slug of the post object to the custom fields if no value exists yet.
175
- $data['config']['title'] = trim( strip_tags( $enviraPost->post_title ) );
176
- $data['config']['slug'] = sanitize_text_field( $enviraPost->post_name );
177
-
178
- // Store post metadata
179
- update_post_meta( $enviraGalleryID, '_eg_gallery_data', $data );
180
- update_post_meta( $enviraGalleryID, '_eg_in_gallery', $in );
181
- update_post_meta( $enviraGalleryID, '_eg_gallery_old', $post->ID );
182
- if ( ! empty( $data['config']['slug'] ) ) {
183
- update_post_meta( $enviraGalleryID, '_eg_gallery_old_slug', $data['config']['slug'] );
184
- }
185
-
186
- // Remove post metadata from the original Post
187
- delete_post_meta( $post->ID, '_eg_gallery_data' );
188
- delete_post_meta( $post->ID, '_eg_in_gallery' );
189
-
190
- // Search for the envira shortcode in the Post content, and change its ID to the new Envira Gallery ID
191
- if ( has_shortcode ( $post->post_content, 'envira-gallery' ) ) {
192
- $pattern = get_shortcode_regex();
193
- if ( preg_match_all( '/'. $pattern .'/s', $post->post_content, $matches ) ) {
194
- foreach ( $matches[2] as $key => $shortcode ) {
195
- if ( $shortcode == 'envira-gallery' ) {
196
- // Found an envira-gallery shortcode
197
- // Change the ID
198
- $originalShortcode = $matches[0][ $key ];
199
- $replacementShortcode = str_replace( 'id="' . $post->ID . '"', 'id="' . $enviraGalleryID . '"', $originalShortcode );
200
- $post->post_content = str_replace( $originalShortcode, $replacementShortcode, $post->post_content );
201
- wp_update_post( $post );
202
- }
203
- }
204
- }
205
- }
206
-
207
- // Store a relationship between the gallery and this Post
208
- update_post_meta( $post->ID, '_eg_gallery_id', $enviraGalleryID );
209
 
210
  // Increment the counter
211
  $migrated_galleries++;
212
- }
213
 
214
  // Display a one time admin notice so the user knows their in-page galleries were migrated.
215
  if ( $migrated_galleries > 0 ) {
216
  add_action( 'admin_notices', array( $this, 'notice_galleries_migrated' ) );
217
  }
218
- }
219
 
220
- // Force the tags addon to convert any tags to the new CPT system for any galleries that have been converted to Envira post type.
221
- delete_option( 'envira_tags_taxonomy_migrated' );
222
 
223
- // Mark upgrade as complete
224
- update_option( 'envira_gallery_121', true );
225
- }
226
  }
227
-
228
  /**
229
  * Displays a notice on screen when a user upgrades from Lite to Pro or Lite to Lite 1.5.x,
230
  * telling them that their in-page galleries have been migrated.
53
  public function __construct() {
54
 
55
  // Load the base class object.
56
+ $this->base = ( class_exists( 'Envira_Gallery' ) ? Envira_Gallery::get_instance() : Envira_Gallery_Lite::get_instance() );
57
 
58
  // Handle any necessary DB upgrades.
59
  add_action( 'admin_init', array( $this, 'db_upgrade' ) );
85
  // Upgrade to allow captions (v1.1.6).
86
  $captions = get_option( 'envira_gallery_116' );
87
  if ( ! $captions ) {
88
+ $galleries = ( class_exists( 'Envira_Gallery' ) ? Envira_Gallery::get_instance()->_get_galleries() : Envira_Gallery_Lite::get_instance()->_get_galleries() );
89
  if ( $galleries ) {
90
  foreach ( $galleries as $gallery ) {
91
  foreach ( (array) $gallery['gallery'] as $id => $item ) {
102
  // 1.2.1: Convert all non-Envira Post Type galleries into Envira CPT galleries.
103
  $cptGalleries = get_option( 'envira_gallery_121' );
104
  if ( ! $cptGalleries ) {
105
+ // Get Post Types, excluding our own
106
+ // We don't use post_status => 'any', as this doesn't include CPTs where exclude_from_search = true.
107
+ $postTypes = get_post_types( array(
108
+ 'public' => true,
109
+ ) );
110
+ $excludedPostTypes = array( 'envira', 'envira_album', 'attachment' );
111
+ foreach ( $postTypes as $key=>$postType ) {
112
+ if ( in_array( $postType, $excludedPostTypes ) ) {
113
+ unset( $postTypes[ $key ] );
114
+ }
115
+ }
116
+
117
+ // Get all Posts that have _eg_gallery_data set
118
+ $inPostGalleries = new WP_Query( array(
119
+ 'post_type' => $postTypes,
120
+ 'post_status' => 'any',
121
+ 'posts_per_page'=> -1,
122
+ 'meta_query' => array(
123
+ array(
124
+ 'key' => '_eg_gallery_data',
125
+ 'compare' => 'EXISTS',
126
+ ),
127
+ )
128
+ ) );
129
+
130
+ // Check if any Posts with galleries exist
131
+ if ( count( $inPostGalleries->posts ) > 0 ) {
132
  $migrated_galleries = 0;
133
 
134
+ // Iterate through Posts with Galleries
135
+ foreach ( $inPostGalleries->posts as $post ) {
136
+ // Check if this is an Envira or Envira Album CPT
137
+ // If so, skip it
138
+ if ( $post->post_type == 'envira' || $post->post_type == 'envira_album' ) {
139
+ continue;
140
+ }
141
+
142
+ // Get metadata
143
+ $data = get_post_meta( $post->ID, '_eg_gallery_data', true);
144
+ $in = get_post_meta( $post->ID, '_eg_in_gallery', true);
145
+
146
+ // Check if there is at least one image in the gallery
147
+ // Some Posts save Envira config data but don't have images - we don't want to migrate those,
148
+ // as we would end up with blank Envira CPT galleries
149
+ if ( ! isset( $data['gallery'] ) || ! is_array( $data['gallery']) ) {
150
+ continue;
151
+ }
152
+
153
+ // If here, we need to create a new Envira CPT
154
+ $cpt_args = array(
155
+ 'post_title' => ( !empty( $data['config']['title'] ) ? $data['config']['title'] : $post->post_title ),
156
+ 'post_status' => $post->post_status,
157
+ 'post_type' => 'envira',
158
+ 'post_author' => $post->post_author,
159
+ );
160
+ if ( ! empty( $data['config']['slug'] ) ) {
161
+ $cpt_args['post_name'] = $data['config']['slug'];
162
+ }
163
+ $enviraGalleryID = wp_insert_post( $cpt_args );
164
+
165
+ // Check gallery creation was successful
166
+ if ( is_wp_error( $enviraGalleryID ) ) {
167
+ // @TODO how to handle errors?
168
+ continue;
169
+ }
170
+
171
+ // Get Envira Gallery Post
172
+ $enviraPost = get_post( $enviraGalleryID );
173
+
174
+ // Map the title and slug of the post object to the custom fields if no value exists yet.
175
+ $data['config']['title'] = trim( strip_tags( $enviraPost->post_title ) );
176
+ $data['config']['slug'] = sanitize_text_field( $enviraPost->post_name );
177
+
178
+ // Store post metadata
179
+ update_post_meta( $enviraGalleryID, '_eg_gallery_data', $data );
180
+ update_post_meta( $enviraGalleryID, '_eg_in_gallery', $in );
181
+ update_post_meta( $enviraGalleryID, '_eg_gallery_old', $post->ID );
182
+ if ( ! empty( $data['config']['slug'] ) ) {
183
+ update_post_meta( $enviraGalleryID, '_eg_gallery_old_slug', $data['config']['slug'] );
184
+ }
185
+
186
+ // Remove post metadata from the original Post
187
+ delete_post_meta( $post->ID, '_eg_gallery_data' );
188
+ delete_post_meta( $post->ID, '_eg_in_gallery' );
189
+
190
+ // Search for the envira shortcode in the Post content, and change its ID to the new Envira Gallery ID
191
+ if ( has_shortcode ( $post->post_content, 'envira-gallery' ) ) {
192
+ $pattern = get_shortcode_regex();
193
+ if ( preg_match_all( '/'. $pattern .'/s', $post->post_content, $matches ) ) {
194
+ foreach ( $matches[2] as $key => $shortcode ) {
195
+ if ( $shortcode == 'envira-gallery' ) {
196
+ // Found an envira-gallery shortcode
197
+ // Change the ID
198
+ $originalShortcode = $matches[0][ $key ];
199
+ $replacementShortcode = str_replace( 'id="' . $post->ID . '"', 'id="' . $enviraGalleryID . '"', $originalShortcode );
200
+ $post->post_content = str_replace( $originalShortcode, $replacementShortcode, $post->post_content );
201
+ wp_update_post( $post );
202
+ }
203
+ }
204
+ }
205
+ }
206
+
207
+ // Store a relationship between the gallery and this Post
208
+ update_post_meta( $post->ID, '_eg_gallery_id', $enviraGalleryID );
209
 
210
  // Increment the counter
211
  $migrated_galleries++;
212
+ }
213
 
214
  // Display a one time admin notice so the user knows their in-page galleries were migrated.
215
  if ( $migrated_galleries > 0 ) {
216
  add_action( 'admin_notices', array( $this, 'notice_galleries_migrated' ) );
217
  }
218
+ }
219
 
220
+ // Force the tags addon to convert any tags to the new CPT system for any galleries that have been converted to Envira post type.
221
+ delete_option( 'envira_tags_taxonomy_migrated' );
222
 
223
+ // Mark upgrade as complete
224
+ update_option( 'envira_gallery_121', true );
225
+ }
226
  }
 
227
  /**
228
  * Displays a notice on screen when a user upgrades from Lite to Pro or Lite to Lite 1.5.x,
229
  * telling them that their in-page galleries have been migrated.
includes/admin/editor.php CHANGED
@@ -53,7 +53,7 @@ class Envira_Gallery_Editor {
53
  public function __construct() {
54
 
55
  // Load the base class object.
56
- $this->base = Envira_Gallery_Lite::get_instance();
57
 
58
  // Add a custom media button to the editor.
59
  add_filter( 'media_buttons_context', array( $this, 'media_button' ) );
@@ -73,13 +73,25 @@ class Envira_Gallery_Editor {
73
  public function media_button( $buttons ) {
74
 
75
  // Enqueue styles.
 
 
 
76
  wp_register_style( $this->base->plugin_slug . '-editor-style', plugins_url( 'assets/css/editor.css', $this->base->file ), array(), $this->base->version );
77
  wp_enqueue_style( $this->base->plugin_slug . '-editor-style' );
78
 
79
- // Enqueue the script that will trigger the editor button.
80
- wp_enqueue_script( $this->base->plugin_slug . '-editor-script', plugins_url( 'assets/js/editor.js', $this->base->file ), array( 'jquery' ), $this->base->version, true );
81
- wp_localize_script( $this->base->plugin_slug . '-editor-script', 'envira_gallery_editor', array(
82
  'get_galleries_nonce' => wp_create_nonce( 'envira-gallery-editor-get-galleries' ),
 
 
 
 
 
 
 
 
 
83
  ) );
84
 
85
  // Create the media button.
53
  public function __construct() {
54
 
55
  // Load the base class object.
56
+ $this->base = ( class_exists( 'Envira_Gallery' ) ? Envira_Gallery::get_instance() : Envira_Gallery_Lite::get_instance() );
57
 
58
  // Add a custom media button to the editor.
59
  add_filter( 'media_buttons_context', array( $this, 'media_button' ) );
73
  public function media_button( $buttons ) {
74
 
75
  // Enqueue styles.
76
+ wp_register_style( $this->base->plugin_slug . '-admin-style', plugins_url( 'assets/css/admin.css', $this->base->file ), array(), $this->base->version );
77
+ wp_enqueue_style( $this->base->plugin_slug . '-admin-style' );
78
+
79
  wp_register_style( $this->base->plugin_slug . '-editor-style', plugins_url( 'assets/css/editor.css', $this->base->file ), array(), $this->base->version );
80
  wp_enqueue_style( $this->base->plugin_slug . '-editor-style' );
81
 
82
+ // Enqueue the gallery / album selection script
83
+ wp_enqueue_script( $this->base->plugin_slug . '-gallery-select-script', plugins_url( 'assets/js/min/gallery-select-min.js', $this->base->file ), array( 'jquery' ), $this->base->version, true );
84
+ wp_localize_script( $this->base->plugin_slug . '-gallery-select-script', 'envira_gallery_select', array(
85
  'get_galleries_nonce' => wp_create_nonce( 'envira-gallery-editor-get-galleries' ),
86
+ 'modal_title' => __( 'Insert', 'envira-gallery' ),
87
+ 'insert_button_label' => __( 'Insert', 'envira-gallery' ),
88
+ ) );
89
+
90
+ // Enqueue the script that will trigger the editor button.
91
+ wp_enqueue_script( $this->base->plugin_slug . '-editor-script', plugins_url( 'assets/js/min/editor-min.js', $this->base->file ), array( 'jquery' ), $this->base->version, true );
92
+ wp_localize_script( $this->base->plugin_slug . '-gallery-select-script', 'envira_gallery_editor', array(
93
+ 'modal_title' => __( 'Insert', 'envira-gallery' ),
94
+ 'insert_button_label' => __( 'Insert', 'envira-gallery' ),
95
  ) );
96
 
97
  // Create the media button.
includes/admin/media-view.php CHANGED
@@ -44,7 +44,7 @@ class Envira_Gallery_Media_View {
44
  public function __construct() {
45
 
46
  // Base
47
- $this->base = Envira_Gallery_Lite::get_instance();
48
 
49
  // Modals
50
  add_filter( 'envira_gallery_media_view_strings', array( $this, 'media_view_strings' ) );
@@ -80,25 +80,16 @@ class Envira_Gallery_Media_View {
80
  ?>
81
  <script type="text/html" id="tmpl-envira-selection">
82
  <div class="media-frame-title">
83
- <h1><?php _e( 'Insert', 'envira-gallery' ); ?></h1>
84
  </div>
85
  <div class="media-frame-content">
86
  <div class="attachments-browser envira-gallery envira-gallery-editor">
 
87
  <ul class="attachments">
88
  </ul>
89
 
90
- <!-- Helpful Tips -->
91
- <div class="media-sidebar">
92
- <h3><?php _e( 'Helpful Tips', 'envira-gallery' ); ?></h3>
93
- <strong><?php _e( 'Choosing Your Gallery', 'envira-gallery' ); ?></strong>
94
- <p>
95
- <?php _e( 'To choose your gallery, simply click on one of the boxes to the left. The "Insert Gallery" button will be activated once you have selected a gallery.', 'envira-gallery' ); ?>
96
- </p>
97
-
98
- <strong><?php _e( 'Inserting Your Gallery', 'envira-gallery' ); ?></strong>
99
- <p>
100
- <?php _e( 'To insert your gallery into the editor, click on the "Insert Gallery" button below.', 'envira-gallery' ); ?>
101
- </p>
102
  </div>
103
 
104
  <!-- Search -->
@@ -119,7 +110,7 @@ class Envira_Gallery_Media_View {
119
  <div class="media-toolbar">
120
  <div class="media-toolbar-primary search-form">
121
  <button type="button" class="button media-button button-primary button-large media-button-insert" disabled="disabled">
122
- <?php _e( 'Insert', 'envira-gallery' ); ?>
123
  </button>
124
  </div>
125
  </div>
@@ -155,6 +146,45 @@ class Envira_Gallery_Media_View {
155
  </script>
156
  <?php
157
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  // Error
159
  // Use: wp.media.template( 'envira-gallery-error' )
160
  ?>
@@ -214,6 +244,32 @@ class Envira_Gallery_Media_View {
214
  </div>
215
  </label>
216
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  <!-- Alt Text -->
218
  <label class="setting">
219
  <span class="name"><?php _e( 'Alt Text', 'envira-gallery' ); ?></span>
@@ -237,21 +293,41 @@ class Envira_Gallery_Media_View {
237
  <?php _e( 'Enter a hyperlink if you wish to link this image to somewhere other than its full size image.', 'envira-gallery' ); ?>
238
  </span>
239
  </label>
240
-
241
- <label class="setting">
242
- <!-- Upgrade -->
 
 
 
 
 
 
 
 
 
243
  <?php
244
- Envira_Gallery_Notice_Admin::get_instance()->display_inline_notice(
245
- 'envira_gallery_edit_metadata',
246
- __( 'Want Captions and more options?', 'envira-gallery' ),
247
- __( 'By upgrading to Envira Pro, you can get access to numerous other features, including: HTML captions, open links in new windows, WooCommerce product integration and so much more!', 'envira-gallery' ),
248
- 'warning',
249
- __( 'Click here to Upgrade', 'envira-gallery' ),
250
- Envira_Gallery_Common_Admin::get_instance()->get_upgrade_link(),
251
- false
252
- );
253
  ?>
254
- </label>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  </div>
256
  <!-- /.settings -->
257
 
@@ -274,6 +350,197 @@ class Envira_Gallery_Media_View {
274
  </script>
275
 
276
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
 
278
  }
279
 
44
  public function __construct() {
45
 
46
  // Base
47
+ $this->base = ( class_exists( 'Envira_Gallery' ) ? Envira_Gallery::get_instance() : Envira_Gallery_Lite::get_instance() );
48
 
49
  // Modals
50
  add_filter( 'envira_gallery_media_view_strings', array( $this, 'media_view_strings' ) );
80
  ?>
81
  <script type="text/html" id="tmpl-envira-selection">
82
  <div class="media-frame-title">
83
+ <h1>{{data.modal_title}}</h1>
84
  </div>
85
  <div class="media-frame-content">
86
  <div class="attachments-browser envira-gallery envira-gallery-editor">
87
+ <!-- Galleries -->
88
  <ul class="attachments">
89
  </ul>
90
 
91
+ <!-- Sidebar -->
92
+ <div class="media-sidebar attachment-info">
 
 
 
 
 
 
 
 
 
 
93
  </div>
94
 
95
  <!-- Search -->
110
  <div class="media-toolbar">
111
  <div class="media-toolbar-primary search-form">
112
  <button type="button" class="button media-button button-primary button-large media-button-insert" disabled="disabled">
113
+ {{data.insert_button_label}}
114
  </button>
115
  </div>
116
  </div>
146
  </script>
147
  <?php
148
 
149
+ // Selection Sidebar
150
+ // Use: wp.media.template( 'envira-selection-sidebar' )
151
+ ?>
152
+ <script type="text/html" id="tmpl-envira-selection-sidebar">
153
+ <!-- Helpful Tips -->
154
+ <h3><?php _e( 'Helpful Tips', 'envira-gallery' ); ?></h3>
155
+ <strong><?php _e( 'Choosing Your Gallery', 'envira-gallery' ); ?></strong>
156
+ <p>
157
+ <?php _e( 'To choose your gallery, simply click on one of the boxes to the left. Ctrl / cmd and click to select multiple Galleries. The "Insert Gallery" button will be activated once you have selected a gallery.', 'envira-gallery' ); ?>
158
+ </p>
159
+ <strong><?php _e( 'Inserting Your Gallery', 'envira-gallery' ); ?></strong>
160
+ <p>
161
+ <?php _e( 'To insert your gallery into the editor, click on the "Insert Gallery" button below.', 'envira-gallery' ); ?>
162
+ </p>
163
+
164
+ <!-- Insert Options -->
165
+ <h3><?php _e( 'Insert Options', 'envira-gallery' ); ?></h3>
166
+ <div class="settings">
167
+ <!-- Display Title -->
168
+ <label class="setting">
169
+ <span class="name"><?php _e( 'Display Title', 'envira-gallery' ); ?></span>
170
+ <select name="title" size="1">
171
+ <option value="0" selected><?php _e( 'No', 'envira-gallery' ); ?></option>
172
+ <?php
173
+ for( $i = 1; $i <= 6; $i++ ) {
174
+ ?>
175
+ <option value="h<?php echo $i; ?>"><?php echo sprintf( __( 'Yes, as Heading H%s', 'envira-gallery'), $i ); ?></option>
176
+ <?php
177
+ }
178
+ ?>
179
+ </select>
180
+ </label>
181
+ <p class="description">
182
+ <?php _e( 'Prepends each inserted Gallery with the Gallery Title.', 'envira-gallery' ); ?>
183
+ </p>
184
+ </div>
185
+ </script>
186
+
187
+ <?php
188
  // Error
189
  // Use: wp.media.template( 'envira-gallery-error' )
190
  ?>
244
  </div>
245
  </label>
246
 
247
+ <?php
248
+ if ( class_exists( 'Envira_Gallery' ) ) {
249
+ ?>
250
+ <!-- Caption -->
251
+ <div class="setting">
252
+ <span class="name"><?php _e( 'Caption', 'envira-gallery' ); ?></span>
253
+ <?php
254
+ wp_editor( '', 'caption', array(
255
+ 'media_buttons' => false,
256
+ 'wpautop' => false,
257
+ 'tinymce' => false,
258
+ 'textarea_name' => 'caption',
259
+ 'quicktags' => array(
260
+ 'buttons' => 'strong,em,link,ul,ol,li,close'
261
+ ),
262
+ 'editor_height' => 100,
263
+ ) );
264
+ ?>
265
+ <div class="description">
266
+ <?php _e( 'Captions can take any type of HTML, and are displayed when an image is clicked.', 'envira-gallery' ); ?>
267
+ </div>
268
+ </div>
269
+ <?php
270
+ }
271
+ ?>
272
+
273
  <!-- Alt Text -->
274
  <label class="setting">
275
  <span class="name"><?php _e( 'Alt Text', 'envira-gallery' ); ?></span>
293
  <?php _e( 'Enter a hyperlink if you wish to link this image to somewhere other than its full size image.', 'envira-gallery' ); ?>
294
  </span>
295
  </label>
296
+
297
+ <?php
298
+ if ( class_exists( 'Envira_Gallery' ) ) {
299
+ ?>
300
+ <!-- Link in New Window -->
301
+ <label class="setting">
302
+ <span class="name"><?php _e( 'Open URL in New Window?', 'envira-gallery' ); ?></span>
303
+ <input type="checkbox" name="link_new_window" value="1"<# if ( data.link_new_window == '1' ) { #> checked <# } #> />
304
+ <span class="description">
305
+ <?php _e( 'Opens your image links in a new browser window / tab.', 'envira-gallery' ); ?>
306
+ </span>
307
+ </label>
308
  <?php
309
+ } else {
 
 
 
 
 
 
 
 
310
  ?>
311
+ <label class="setting">
312
+ <!-- Upgrade -->
313
+ <?php
314
+ Envira_Gallery_Notice_Admin::get_instance()->display_inline_notice(
315
+ 'envira_gallery_edit_metadata',
316
+ __( 'Want Captions and more options?', 'envira-gallery' ),
317
+ __( 'By upgrading to Envira Pro, you can get access to numerous other features, including: HTML captions, open links in new windows, WooCommerce product integration and so much more!', 'envira-gallery' ),
318
+ 'warning',
319
+ __( 'Click here to Upgrade', 'envira-gallery' ),
320
+ Envira_Gallery_Common_Admin::get_instance()->get_upgrade_link(),
321
+ false
322
+ );
323
+ ?>
324
+ </label>
325
+ <?php
326
+ }
327
+ ?>
328
+
329
+ <!-- Addons can populate the UI here -->
330
+ <div class="addons"></div>
331
  </div>
332
  <!-- /.settings -->
333
 
350
  </script>
351
 
352
  <?php
353
+ // Bulk Image Editor
354
+ // Use: wp.media.template( 'envira-meta-bulk-editor' )
355
+ ?>
356
+ <script type="text/html" id="tmpl-envira-meta-bulk-editor">
357
+ <div class="media-frame-title">
358
+ <h1><?php _e( 'Bulk Edit', 'envira-gallery' ); ?></h1>
359
+ </div>
360
+ <div class="media-frame-content">
361
+ <div class="attachment-details save-ready">
362
+ <!-- Left -->
363
+ <div class="attachment-media-view portrait">
364
+ <ul class="attachments envira-bulk-edit">
365
+ </ul>
366
+ </div>
367
+
368
+ <!-- Right -->
369
+ <div class="attachment-info">
370
+ <!-- Settings -->
371
+ <div class="settings">
372
+ <!-- Image Title -->
373
+ <label class="setting">
374
+ <span class="name"><?php _e( 'Title', 'envira-gallery' ); ?></span>
375
+ <input type="text" name="title" value="" />
376
+ <div class="description">
377
+ <?php _e( 'Image titles can take any type of HTML. You can adjust the position of the titles in the main Lightbox settings.', 'envira-gallery' ); ?>
378
+ </div>
379
+ </label>
380
+
381
+ <!-- Caption -->
382
+ <div class="setting">
383
+ <span class="name"><?php _e( 'Caption', 'envira-gallery' ); ?></span>
384
+ <?php
385
+ wp_editor( '', 'caption', array(
386
+ 'media_buttons' => false,
387
+ 'wpautop' => false,
388
+ 'tinymce' => false,
389
+ 'textarea_name' => 'caption',
390
+ 'quicktags' => array(
391
+ 'buttons' => 'strong,em,link,ul,ol,li,close'
392
+ ),
393
+ 'editor_height' => 100,
394
+ ) );
395
+ ?>
396
+ <div class="description">
397
+ <?php _e( 'Captions can take any type of HTML, and are displayed when an image is clicked.', 'envira-gallery' ); ?>
398
+ </div>
399
+ </div>
400
+
401
+ <!-- Alt Text -->
402
+ <label class="setting">
403
+ <span class="name"><?php _e( 'Alt Text', 'envira-gallery' ); ?></span>
404
+ <input type="text" name="alt" value="" />
405
+ <div class="description">
406
+ <?php _e( 'Very important for SEO, the Alt Text describes the image.', 'envira-gallery' ); ?>
407
+ </div>
408
+ </label>
409
+
410
+ <!-- Link -->
411
+ <label class="setting">
412
+ <span class="name"><?php _e( 'URL', 'envira-gallery' ); ?></span>
413
+ <input type="text" name="link" value="" />
414
+ <# if ( typeof( data.id ) === 'number' ) { #>
415
+ <span class="buttons">
416
+ <button class="button button-small media-file"><?php _e( 'Media File', 'envira-gallery' ); ?></button>
417
+ <button class="button button-small attachment-page"><?php _e( 'Attachment Page', 'envira-gallery' ); ?></button>
418
+ </span>
419
+ <# } #>
420
+ <span class="description">
421
+ <?php _e( 'Enter a hyperlink if you wish to link this image to somewhere other than its full size image.', 'envira-gallery' ); ?>
422
+ </span>
423
+ </label>
424
+
425
+ <!-- Link in New Window -->
426
+ <label class="setting">
427
+ <span class="name"><?php _e( 'Open URL in New Window?', 'envira-gallery' ); ?></span>
428
+ <input type="checkbox" name="link_new_window" value="1" />
429
+ <span class="description">
430
+ <?php _e( 'Opens your image links in a new browser window / tab.', 'envira-gallery' ); ?>
431
+ </span>
432
+ </label>
433
+
434
+ <!-- Addons can populate the UI here -->
435
+ <div class="addons"></div>
436
+ </div>
437
+ <!-- /.settings -->
438
+
439
+ <!-- Actions -->
440
+ <div class="actions">
441
+ <a href="#" class="envira-gallery-meta-submit button media-button button-large button-primary media-button-insert" title="<?php esc_attr_e( 'Save Metadata to Items', 'envira-gallery' ); ?>">
442
+ <?php _e( 'Save Metadata', 'envira-gallery' ); ?>
443
+ </a>
444
+
445
+ <!-- Save Spinner -->
446
+ <span class="settings-save-status">
447
+ <span class="spinner"></span>
448
+ <span class="saved"><?php _e( 'Saved.', 'envira-gallery' ); ?></span>
449
+ </span>
450
+ </div>
451
+ <!-- /.actions -->
452
+ </div>
453
+ </div>
454
+ </div>
455
+ </script>
456
+
457
+ <?php
458
+ // Bulk Image Editor Image
459
+ // Use: wp.media.template( 'envira-meta-bulk-editor-image' )
460
+ ?>
461
+ <script type="text/html" id="tmpl-envira-meta-bulk-editor-image">
462
+ <div class="attachment-preview">
463
+ <div class="thumbnail">
464
+ <div class="centered">
465
+ <img src={{ data._thumbnail }} />
466
+ </div>
467
+ </div>
468
+ </div>
469
+ </script>
470
+
471
+ <?php
472
+
473
+ /**
474
+ * Move Images to Gallery
475
+ */
476
+ // Selection Sidebar
477
+ // Use: wp.media.template( 'envira-meta-move-media-sidebar' )
478
+ ?>
479
+ <script type="text/html" id="tmpl-envira-meta-move-media-sidebar">
480
+ <!-- Helpful Tips -->
481
+ <h3><?php _e( 'Helpful Tips', 'envira-gallery' ); ?></h3>
482
+ <p>
483
+ <?php _e( 'Select the Gallery to move the selected images to by clicking on one of the boxes to the left.', 'envira-gallery' ); ?>
484
+ </p>
485
+ <p>
486
+ <?php _e( 'Once done, click the Move button, and the selected images will be moved to the chosen Gallery.', 'envira-gallery' ); ?>
487
+ </p>
488
+ </script>
489
+
490
+ <?php
491
+ /**
492
+ * Insert from Third Party Sources
493
+ */
494
+
495
+ // Search
496
+ // Use: wp.media.template( 'envira-gallery-search-bar' )
497
+ ?>
498
+ <script type="text/html" id="tmpl-envira-gallery-search-bar">
499
+ <div class="media-toolbar">
500
+ <div class="media-toolbar-secondary">
501
+ <span class="spinner"></span>
502
+ </div>
503
+ <div class="media-toolbar-primary search-form">
504
+ <label for="envira-gallery-search" class="screen-reader-text"><?php _e( 'Search', 'envira-gallery' ); ?></label>
505
+ <input type="search" placeholder="<?php _e( 'Search', 'envira-gallery' ); ?>" id="envira-gallery-search" class="search" />
506
+ </div>
507
+ </div>
508
+ </script>
509
+
510
+ <?php
511
+ // Folders and Items
512
+ // Use: wp.media.template( 'envira-gallery-items' )
513
+ ?>
514
+ <script type="text/html" id="tmpl-envira-gallery-items">
515
+ <ul class="attachments envira-gallery-attachments"></ul>
516
+ </script>
517
+
518
+ <?php
519
+ // Single Folder or Image (Item)
520
+ // Use: wp.media.template( 'envira-gallery-item' )
521
+ ?>
522
+ <script type="text/html" id="tmpl-envira-gallery-item">
523
+ <# if ( ! data.is_dir ) { #>
524
+ <div class="attachment-preview js--select-attachment type-image subtype-<# data.mime_type #>" data-id="{{ data.id }}" data-is-dir="{{ data.is_dir }}">
525
+ <div class="thumbnail">
526
+ <div class="centered">
527
+ <img src="{{ data.thumbnail }}" draggable="false" alt="{{ data.title }}" />
528
+ </div>
529
+ </div>
530
+ </div>
531
+ <button type="button" class="button-link check" tabindex="-1">
532
+ <span class="media-modal-icon"></span>
533
+ </button>
534
+ <# } else { #>
535
+ <div class="attachment-preview" data-id="{{ data.id }}" data-is-dir="{{ data.is_dir }}">
536
+ <div class="thumbnail">
537
+ <span class="dashicons dashicons-portfolio"></span>
538
+ <span>{{ data.title }}</span>
539
+ </div>
540
+ </div>
541
+ <# } #>
542
+ </script>
543
+ <?php
544
 
545
  }
546
 
includes/admin/media.php CHANGED
@@ -44,7 +44,7 @@ class Envira_Gallery_Media {
44
  public function __construct() {
45
 
46
  // Load the base class object.
47
- $this->base = Envira_Gallery_Lite::get_instance();
48
 
49
  add_filter( 'wp_handle_upload', array( $this, 'fix_image_orientation' ) );
50
 
44
  public function __construct() {
45
 
46
  // Load the base class object.
47
+ $this->base = ( class_exists( 'Envira_Gallery' ) ? Envira_Gallery::get_instance() : Envira_Gallery_Lite::get_instance() );
48
 
49
  add_filter( 'wp_handle_upload', array( $this, 'fix_image_orientation' ) );
50
 
includes/admin/metaboxes.php CHANGED
@@ -44,7 +44,7 @@ class Envira_Gallery_Metaboxes {
44
  public function __construct() {
45
 
46
  // Load the base class object.
47
- $this->base = Envira_Gallery_Lite::get_instance();
48
 
49
  // Output a notice if missing cropping extensions because Envira needs them.
50
  if ( ! $this->has_gd_extension() && ! $this->has_imagick_extension() ) {
@@ -68,10 +68,12 @@ class Envira_Gallery_Metaboxes {
68
  add_action( 'envira_gallery_tab_images', array( $this, 'images_tab' ) );
69
  add_action( 'envira_gallery_tab_config', array( $this, 'config_tab' ) );
70
  add_action( 'envira_gallery_tab_lightbox', array( $this, 'lightbox_tab' ) );
 
71
  add_action( 'envira_gallery_tab_misc', array( $this, 'misc_tab' ) );
72
 
73
  // Load some tabs for Envira Gallery Lite.
74
  if ( 'Envira_Gallery_Lite' == get_class( $this->base ) ) {
 
75
  add_filter( 'envira_gallery_tab_nav', array( $this, 'lite_tabs' ) );
76
  add_action( 'envira_gallery_tab_mobile', array( $this, 'lite_mobile_tab' ) );
77
  add_action( 'envira_gallery_tab_videos', array( $this, 'lite_videos_tab' ) );
@@ -142,7 +144,10 @@ class Envira_Gallery_Metaboxes {
142
 
143
  /**
144
  * Appends the "Select Files From Other Sources" button to the Media Uploader, which is called using WordPress'
145
- * media_upload_form() function
 
 
 
146
  *
147
  * CSS positions this button to improve the layout.
148
  *
@@ -155,6 +160,21 @@ class Envira_Gallery_Metaboxes {
155
  <a href="#" class="envira-media-library button" title="<?php _e( 'Click Here to Insert from Other Image Sources', 'envira-gallery' ); ?>" style="vertical-align: baseline;">
156
  <?php _e( 'Select Files from Other Sources', 'envira-gallery' ); ?>
157
  </a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  <?php
159
 
160
  }
@@ -205,7 +225,7 @@ class Envira_Gallery_Metaboxes {
205
 
206
  // Get current screen.
207
  $screen = get_current_screen();
208
-
209
  // Bail if we're not on the Envira Post Type screen.
210
  if ( 'envira' !== $screen->post_type ) {
211
  return;
@@ -229,12 +249,24 @@ class Envira_Gallery_Metaboxes {
229
  add_filter( 'plupload_init', array( $this, 'plupload_init' ) );
230
 
231
  // Tabs
232
- wp_register_script( $this->base->plugin_slug . '-tabs-script', plugins_url( 'assets/js/tabs.js', $this->base->file ), array( 'jquery' ), $this->base->version, true );
233
  wp_enqueue_script( $this->base->plugin_slug . '-tabs-script' );
234
 
235
  // Clipboard
236
- wp_register_script( $this->base->plugin_slug . '-clipboard-script', plugins_url( 'assets/js/min/clipboard-min.js', $this->base->file ), array( 'jquery' ), $this->base->version );
237
  wp_enqueue_script( $this->base->plugin_slug . '-clipboard-script' );
 
 
 
 
 
 
 
 
 
 
 
 
238
 
239
  // Metaboxes
240
  wp_register_script( $this->base->plugin_slug . '-metabox-script', plugins_url( 'assets/js/min/metabox-min.js', $this->base->file ), array( 'jquery', 'plupload-handlers', 'quicktags', 'jquery-ui-sortable' ), $this->base->version, true );
@@ -252,6 +284,10 @@ class Envira_Gallery_Metaboxes {
252
  'library_search' => wp_create_nonce( 'envira-gallery-library-search' ),
253
  'load_gallery' => wp_create_nonce( 'envira-gallery-load-gallery' ),
254
  'load_image' => wp_create_nonce( 'envira-gallery-load-image' ),
 
 
 
 
255
  'preview_nonce' => wp_create_nonce( 'envira-gallery-change-preview' ),
256
  'refresh_nonce' => wp_create_nonce( 'envira-gallery-refresh' ),
257
  'remove' => __( 'Are you sure you want to remove this image from the gallery?', 'envira-gallery' ),
@@ -266,6 +302,23 @@ class Envira_Gallery_Metaboxes {
266
  )
267
  );
268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  // Link Search
270
  wp_enqueue_script( 'wp-link' );
271
 
@@ -550,6 +603,7 @@ class Envira_Gallery_Metaboxes {
550
  'images' => __( 'Images', 'envira-gallery' ),
551
  'config' => __( 'Config', 'envira-gallery' ),
552
  'lightbox' => __( 'Lightbox', 'envira-gallery' ),
 
553
  );
554
  $tabs = apply_filters( 'envira_gallery_tab_nav', $tabs );
555
 
@@ -662,8 +716,36 @@ class Envira_Gallery_Metaboxes {
662
  </p>
663
 
664
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
665
  do_action( 'envira_gallery_do_default_display', $post );
666
  ?>
 
667
  <ul id="envira-gallery-output" class="envira-gallery-images-output <?php echo $layout; ?>">
668
  <?php
669
  if ( ! empty( $gallery_data['gallery'] ) ) {
@@ -672,19 +754,30 @@ class Envira_Gallery_Metaboxes {
672
  }
673
  }
674
  ?>
675
- </ul>
676
-
677
  <?php
678
- // Output an upgrade notice
679
- Envira_Gallery_Notice_Admin::get_instance()->display_inline_notice(
680
- 'envira_gallery_images_tab',
681
- __( 'Want to make your gallery workflow even better?', 'envira-gallery' ),
682
- __( 'By upgrading to Envira Pro, you can get access to numerous other features, including: a fully featured gallery widget, complete gallery API, powerful gallery documentation, full mobile and Retina support, dedicated customer support and so much more!', 'envira-gallery' ),
683
- 'warning',
684
- __( 'Click here to Upgrade', 'envira-gallery' ),
685
- Envira_Gallery_Common_Admin::get_instance()->get_upgrade_link(),
686
- false
687
- );
 
 
 
 
 
 
 
 
 
 
 
688
 
689
  }
690
 
@@ -703,8 +796,7 @@ class Envira_Gallery_Metaboxes {
703
  <p class="envira-intro">
704
  <?php _e( 'Gallery Settings', 'envira-gallery' ); ?>
705
  <small>
706
- <?php _e( 'The settings below adjust the basic configuration options for the gallery.', 'envira-gallery' ); ?>
707
- <br />
708
  <?php _e( 'Need some help?', 'envira-gallery' ); ?>
709
  <a href="http://enviragallery.com/docs/creating-first-envira-gallery/" class="envira-doc" target="_blank">
710
  <?php _e( 'Read the Documentation', 'envira-gallery' ); ?>
@@ -730,7 +822,6 @@ class Envira_Gallery_Metaboxes {
730
  <p class="description"><?php _e( 'Determines the number of columns in the gallery. Automatic will attempt to fill each row as much as possible before moving on to the next row.', 'envira-gallery' ); ?></p>
731
  </td>
732
  </tr>
733
-
734
  <tr id="envira-config-gallery-theme-box">
735
  <th scope="row">
736
  <label for="envira-config-gallery-theme"><?php _e( 'Gallery Theme', 'envira-gallery' ); ?></label>
@@ -745,7 +836,53 @@ class Envira_Gallery_Metaboxes {
745
  </td>
746
  </tr>
747
 
748
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
749
  <tr id="envira-config-gutter-box">
750
  <th scope="row">
751
  <label for="envira-config-gutter"><?php _e( 'Column Gutter Width', 'envira-gallery' ); ?></label>
@@ -755,7 +892,6 @@ class Envira_Gallery_Metaboxes {
755
  <p class="description"><?php _e( 'Sets the space between the columns (defaults to 10).', 'envira-gallery' ); ?></p>
756
  </td>
757
  </tr>
758
-
759
  <tr id="envira-config-margin-box">
760
  <th scope="row">
761
  <label for="envira-config-margin"><?php _e( 'Margin Below Each Image', 'envira-gallery' ); ?></label>
@@ -766,6 +902,47 @@ class Envira_Gallery_Metaboxes {
766
  </td>
767
  </tr>
768
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
769
  <!-- Dimensions -->
770
  <tr id="envira-config-image-size-box">
771
  <th scope="row">
@@ -781,9 +958,38 @@ class Envira_Gallery_Metaboxes {
781
  }
782
  ?>
783
  </select>
784
- <p class="description"><?php _e( 'Define the maximum image size for the Gallery view. Default will use the below Image Dimensions.', 'envira-gallery' ); ?></p>
785
  </td>
786
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
787
  <tr id="envira-config-crop-size-box">
788
  <th scope="row">
789
  <label for="envira-config-crop-width"><?php _e( 'Image Dimensions', 'envira-gallery' ); ?></label>
@@ -799,28 +1005,75 @@ class Envira_Gallery_Metaboxes {
799
  </th>
800
  <td>
801
  <input id="envira-config-crop" type="checkbox" name="_envira_gallery[crop]" value="<?php echo $this->get_config( 'crop', $this->get_config_default( 'crop' ) ); ?>" <?php checked( $this->get_config( 'crop', $this->get_config_default( 'crop' ) ), 1 ); ?> />
802
- <span class="description"><?php _e( 'If enabled, forces images to exactly match the sizes defined above for Image Dimensions.', 'envira-gallery' ); ?></span>
803
  <span class="description"><?php _e( 'If disabled, images will be resized to maintain their aspect ratio.', 'envira-gallery' ); ?></span>
804
 
805
  </td>
806
  </tr>
807
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
808
  <?php do_action( 'envira_gallery_config_box', $post ); ?>
809
  </tbody>
810
  </table>
811
  </div>
812
- <?php
813
 
 
814
  // Output an upgrade notice
815
- Envira_Gallery_Notice_Admin::get_instance()->display_inline_notice(
816
- 'envira_gallery_config_tab',
817
- __( 'Want to do even more with your gallery display?', 'envira-gallery' ),
818
- __( 'By upgrading to Envira Pro, you can get access to numerous other gallery display features, including: custom image tagging and filtering, mobile specific image assets for blazing fast load times, dedicated and unique gallery URLs, custom gallery themes, gallery thumbnail support and so much more!', 'envira-gallery' ),
819
- 'warning',
820
- __( 'Click here to Upgrade', 'envira-gallery' ),
821
- Envira_Gallery_Common_Admin::get_instance()->get_upgrade_link(),
822
- false
823
- );
 
 
824
 
825
  }
826
 
@@ -909,24 +1162,371 @@ class Envira_Gallery_Metaboxes {
909
  <p class="description"><?php _e( 'Sets the display of the lightbox image\'s caption.', 'envira-gallery' ); ?></p>
910
  </td>
911
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
912
 
913
  <?php do_action( 'envira_gallery_lightbox_box', $post ); ?>
914
  </tbody>
915
  </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
916
  </div>
917
  </div>
918
  <?php
919
 
920
  // Output an upgrade notice
921
- Envira_Gallery_Notice_Admin::get_instance()->display_inline_notice(
922
- 'envira_gallery_lightbox_tab',
923
- __( 'Want even more fine tuned control over your lightbox display?', 'envira-gallery' ),
924
- __( 'By upgrading to Envira Pro, you can get access to numerous other lightbox features, including: custom lightbox titles, enable/disable lightbox controls (arrow, keyboard and mousehweel navigation), custom lightbox transition effects, native fullscreen support, gallery deeplinking, image protection, lightbox supersize effects, lightbox slideshows and so much more!', 'envira-gallery' ),
925
- 'warning',
926
- __( 'Click here to Upgrade', 'envira-gallery' ),
927
- Envira_Gallery_Common_Admin::get_instance()->get_upgrade_link(),
928
- false
929
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
930
 
931
  }
932
 
@@ -944,7 +1544,7 @@ class Envira_Gallery_Metaboxes {
944
  <p class="envira-intro">
945
  <?php _e( 'Miscellaneous Settings', 'envira-gallery' ); ?>
946
  <small>
947
- <?php _e( 'The settings below adjust miscellaneous settings for the gallery.', 'envira-gallery' ); ?>
948
  <br />
949
  <?php _e( 'Need some help?', 'envira-gallery' ); ?>
950
  <a href="http://enviragallery.com/docs/creating-first-envira-gallery/" class="envira-doc" target="_blank">
@@ -985,6 +1585,40 @@ class Envira_Gallery_Metaboxes {
985
  <p class="description"><?php _e( 'Adds custom CSS classes to this gallery. Enter one class per line.', 'envira-gallery' ); ?></p>
986
  </td>
987
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
988
  <tr id="envira-config-rtl-box">
989
  <th scope="row">
990
  <label for="envira-config-rtl"><?php _e( 'Enable RTL Support?', 'envira-gallery' ); ?></label>
@@ -999,17 +1633,18 @@ class Envira_Gallery_Metaboxes {
999
  </table>
1000
  </div>
1001
  <?php
1002
-
1003
  // Output an upgrade notice
1004
- Envira_Gallery_Notice_Admin::get_instance()->display_inline_notice(
1005
- 'envira_gallery_misc_tab',
1006
- __( 'Want to take your galleries further?', 'envira-gallery' ),
1007
- __( 'By upgrading to Envira Pro, you can get access to numerous other features, including: a fully-integrated import/export module for your galleries, custom CSS controls for each gallery and so much more!', 'envira-gallery' ),
1008
- 'warning',
1009
- __( 'Click here to Upgrade', 'envira-gallery' ),
1010
- Envira_Gallery_Common_Admin::get_instance()->get_upgrade_link(),
1011
- false
1012
- );
 
 
1013
 
1014
  }
1015
 
@@ -1163,35 +1798,35 @@ class Envira_Gallery_Metaboxes {
1163
  }
1164
 
1165
  if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
1166
- // Check if this is a Quick Edit request
1167
- if ( isset( $_POST['_inline_edit'] ) ) {
1168
-
1169
- // Just update specific fields in the Quick Edit screen
1170
-
1171
- // Get settings
1172
- $settings = get_post_meta( $post_id, '_eg_gallery_data', true );
1173
- if ( empty( $settings ) ) {
1174
- return;
1175
- }
1176
 
1177
- // Update Settings
1178
- $settings['config']['columns'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['columns'] );
1179
  $settings['config']['gallery_theme'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['gallery_theme'] );
1180
  $settings['config']['gutter'] = absint( $_POST['_envira_gallery']['gutter'] );
1181
  $settings['config']['margin'] = absint( $_POST['_envira_gallery']['margin'] );
1182
  $settings['config']['crop_width'] = absint( $_POST['_envira_gallery']['crop_width'] );
1183
  $settings['config']['crop_height'] = absint( $_POST['_envira_gallery']['crop_height'] );
1184
-
1185
- // Provide a filter to override settings.
1186
- $settings = apply_filters( 'envira_gallery_quick_edit_save_settings', $settings, $post_id, $post );
1187
-
1188
- // Update the post meta.
1189
- update_post_meta( $post_id, '_eg_gallery_data', $settings );
1190
-
1191
- // Finally, flush all gallery caches to ensure everything is up to date.
1192
  Envira_Gallery_Common::get_instance()->flush_gallery_caches( $post_id, $settings['config']['slug'] );
1193
-
1194
- }
1195
 
1196
  return;
1197
  }
@@ -1235,12 +1870,57 @@ class Envira_Gallery_Metaboxes {
1235
  $settings['config']['crop_height'] = absint( $_POST['_envira_gallery']['crop_height'] );
1236
  $settings['config']['crop'] = isset( $_POST['_envira_gallery']['crop'] ) ? 1 : 0;
1237
 
 
 
 
 
 
 
 
 
 
 
 
 
1238
  // Lightbox
1239
  $settings['config']['lightbox_enabled'] = isset( $_POST['_envira_gallery']['lightbox_enabled'] ) ? 1 : 0;
1240
  $settings['config']['lightbox_theme'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['lightbox_theme'] );
1241
  $settings['config']['lightbox_image_size'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['lightbox_image_size'] );
1242
  $settings['config']['title_display'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['title_display'] );
1243
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1244
  // Misc
1245
  $settings['config']['classes'] = explode( "\n", $_POST['_envira_gallery']['classes'] );
1246
  $settings['config']['rtl'] = isset( $_POST['_envira_gallery']['rtl'] ) ? 1 : 0;
@@ -1266,6 +1946,19 @@ class Envira_Gallery_Metaboxes {
1266
  // Change states of images in gallery from pending to active.
1267
  $this->change_gallery_states( $post_id );
1268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1269
  // If the crop option is checked, crop images accordingly.
1270
  if ( isset( $settings['config']['crop'] ) && $settings['config']['crop'] ) {
1271
  $args = array(
@@ -1279,6 +1972,19 @@ class Envira_Gallery_Metaboxes {
1279
  $this->crop_images( $args, $post_id );
1280
  }
1281
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1282
  // Fire a hook for addons that need to utilize the cropping feature.
1283
  do_action( 'envira_gallery_saved_settings', $settings, $post_id, $post );
1284
 
@@ -1628,12 +2334,13 @@ class Envira_Gallery_Metaboxes {
1628
  *
1629
  * @since 1.3.6
1630
  *
 
1631
  * @return array Array of image size data.
1632
  */
1633
- public function get_image_sizes() {
1634
 
1635
  $instance = Envira_Gallery_Common::get_instance();
1636
- return $instance->get_image_sizes();
1637
 
1638
  }
1639
 
44
  public function __construct() {
45
 
46
  // Load the base class object.
47
+ $this->base = ( class_exists( 'Envira_Gallery' ) ? Envira_Gallery::get_instance() : Envira_Gallery_Lite::get_instance() );
48
 
49
  // Output a notice if missing cropping extensions because Envira needs them.
50
  if ( ! $this->has_gd_extension() && ! $this->has_imagick_extension() ) {
68
  add_action( 'envira_gallery_tab_images', array( $this, 'images_tab' ) );
69
  add_action( 'envira_gallery_tab_config', array( $this, 'config_tab' ) );
70
  add_action( 'envira_gallery_tab_lightbox', array( $this, 'lightbox_tab' ) );
71
+ add_action( 'envira_gallery_tab_mobile', array( $this, 'mobile_tab' ) );
72
  add_action( 'envira_gallery_tab_misc', array( $this, 'misc_tab' ) );
73
 
74
  // Load some tabs for Envira Gallery Lite.
75
  if ( 'Envira_Gallery_Lite' == get_class( $this->base ) ) {
76
+ remove_action( 'envira_gallery_tab_mobile', array( $this, 'mobile_tab' ) );
77
  add_filter( 'envira_gallery_tab_nav', array( $this, 'lite_tabs' ) );
78
  add_action( 'envira_gallery_tab_mobile', array( $this, 'lite_mobile_tab' ) );
79
  add_action( 'envira_gallery_tab_videos', array( $this, 'lite_videos_tab' ) );
144
 
145
  /**
146
  * Appends the "Select Files From Other Sources" button to the Media Uploader, which is called using WordPress'
147
+ * media_upload_form() function.
148
+ *
149
+ * Also appends a hidden upload progress bar, which is displayed by js/media-upload.js when the user uploads images
150
+ * from their computer.
151
  *
152
  * CSS positions this button to improve the layout.
153
  *
160
  <a href="#" class="envira-media-library button" title="<?php _e( 'Click Here to Insert from Other Image Sources', 'envira-gallery' ); ?>" style="vertical-align: baseline;">
161
  <?php _e( 'Select Files from Other Sources', 'envira-gallery' ); ?>
162
  </a>
163
+
164
+ <!-- Progress Bar -->
165
+ <div class="envira-progress-bar">
166
+ <div class="envira-progress-bar-inner"></div>
167
+ <div class="envira-progress-bar-status">
168
+ <span class="uploading">
169
+ <?php _e( 'Uploading Image', 'envira-gallery' ); ?>
170
+ <span class="current">1</span>
171
+ <?php _e( 'of', 'envira-gallery' ); ?>
172
+ <span class="total">3</span>
173
+ </span>
174
+
175
+ <span class="done"><?php _e( 'All images uploaded.', 'envira-gallery' ); ?></span>
176
+ </div>
177
+ </div>
178
  <?php
179
 
180
  }
225
 
226
  // Get current screen.
227
  $screen = get_current_screen();
228
+
229
  // Bail if we're not on the Envira Post Type screen.
230
  if ( 'envira' !== $screen->post_type ) {
231
  return;
249
  add_filter( 'plupload_init', array( $this, 'plupload_init' ) );
250
 
251
  // Tabs
252
+ wp_register_script( $this->base->plugin_slug . '-tabs-script', plugins_url( 'assets/js/min/tabs-min.js', $this->base->file ), array( 'jquery' ), $this->base->version, true );
253
  wp_enqueue_script( $this->base->plugin_slug . '-tabs-script' );
254
 
255
  // Clipboard
256
+ wp_register_script( $this->base->plugin_slug . '-clipboard-script', plugins_url( 'assets/js/min/clipboard-min.js', $this->base->file ), array( 'jquery' ), $this->base->version, true );
257
  wp_enqueue_script( $this->base->plugin_slug . '-clipboard-script' );
258
+
259
+ // Conditional Fields
260
+ wp_register_script( $this->base->plugin_slug . '-conditional-fields-script', plugins_url( 'assets/js/min/conditional-fields-min.js', $this->base->file ), array( 'jquery' ), $this->base->version, true );
261
+ wp_enqueue_script( $this->base->plugin_slug . '-conditional-fields-script' );
262
+
263
+ // Gallery / Album Selection
264
+ wp_enqueue_script( $this->base->plugin_slug . '-gallery-select-script', plugins_url( 'assets/js/gallery-select.js', $this->base->file ), array( 'jquery' ), $this->base->version, true );
265
+ wp_localize_script( $this->base->plugin_slug . '-gallery-select-script', 'envira_gallery_select', array(
266
+ 'get_galleries_nonce' => wp_create_nonce( 'envira-gallery-editor-get-galleries' ),
267
+ 'modal_title' => __( 'Insert', 'envira-gallery' ),
268
+ 'insert_button_label' => __( 'Insert', 'envira-gallery' ),
269
+ ) );
270
 
271
  // Metaboxes
272
  wp_register_script( $this->base->plugin_slug . '-metabox-script', plugins_url( 'assets/js/min/metabox-min.js', $this->base->file ), array( 'jquery', 'plupload-handlers', 'quicktags', 'jquery-ui-sortable' ), $this->base->version, true );
284
  'library_search' => wp_create_nonce( 'envira-gallery-library-search' ),
285
  'load_gallery' => wp_create_nonce( 'envira-gallery-load-gallery' ),
286
  'load_image' => wp_create_nonce( 'envira-gallery-load-image' ),
287
+ 'media_position' => Envira_Gallery_Settings::get_instance()->get_setting( 'media_position' ),
288
+ 'move_media_nonce' => wp_create_nonce( 'envira-gallery-move-media' ),
289
+ 'move_media_modal_title'=> __( 'Move Media to Gallery', 'envira-gallery' ),
290
+ 'move_media_insert_button_label' => __( 'Move Media to Selected Gallery', 'envira-gallery' ),
291
  'preview_nonce' => wp_create_nonce( 'envira-gallery-change-preview' ),
292
  'refresh_nonce' => wp_create_nonce( 'envira-gallery-refresh' ),
293
  'remove' => __( 'Are you sure you want to remove this image from the gallery?', 'envira-gallery' ),
302
  )
303
  );
304
 
305
+ // Insert from Third Party Sources
306
+ if ( class_exists( 'Envira_Gallery' ) ) {
307
+ wp_register_script( $this->base->plugin_slug . '-media-insert-third-party', plugins_url( 'assets/js/media-insert-third-party.js', $this->base->file ), array( 'jquery' ), $this->base->version, true );
308
+ wp_enqueue_script( $this->base->plugin_slug . '-media-insert-third-party' );
309
+ wp_localize_script(
310
+ $this->base->plugin_slug . '-media-insert-third-party',
311
+ 'envira_gallery_media_insert',
312
+ array(
313
+ 'nonce' => wp_create_nonce( 'envira-gallery-media-insert' ),
314
+ 'post_id' => $post_id,
315
+
316
+ // Addons must add their slug/base key/value pair to this array to appear within the "Insert from Other Sources" modal
317
+ 'addons' => apply_filters( 'envira_gallery_media_insert_third_party_sources', array(), $post_id ),
318
+ )
319
+ );
320
+ }
321
+
322
  // Link Search
323
  wp_enqueue_script( 'wp-link' );
324
 
603
  'images' => __( 'Images', 'envira-gallery' ),
604
  'config' => __( 'Config', 'envira-gallery' ),
605
  'lightbox' => __( 'Lightbox', 'envira-gallery' ),
606
+ 'mobile' => __( 'Mobile', 'envira-gallery' ),
607
  );
608
  $tabs = apply_filters( 'envira_gallery_tab_nav', $tabs );
609
 
716
  </p>
717
 
718
  <?php
719
+ if ( 'Envira_Gallery' == get_class( $this->base ) ) {
720
+ ?>
721
+ <nav class="envira-tab-options">
722
+ <!-- Select All -->
723
+ <label for="select-all">
724
+ <input type="checkbox" name="cb" id="select-all" />
725
+ <?php echo sprintf( __( 'Select All (<span class="count">%d</span>)', 'envira-gallery' ), $this->base->get_gallery_image_count( $post->ID ) ); ?>
726
+ </label>
727
+
728
+ <!-- List / Grid View -->
729
+ <a href="#" class="dashicons dashicons-grid-view<?php echo ( $layout == 'grid' ? ' selected' : '' ); ?>" data-view="#envira-gallery-output" data-view-style="grid">
730
+ <span><?php _e( 'Grid View', 'envira-gallery' ); ?></span>
731
+ </a>
732
+ <a href="#" class="dashicons dashicons-list-view<?php echo ( $layout == 'list' ? ' selected' : '' ); ?>" data-view="#envira-gallery-output" data-view-style="list">
733
+ <span><?php _e( 'List View', 'envira-gallery' ); ?></span>
734
+ </a>
735
+ </nav>
736
+
737
+ <!-- Bulk Edit / Delete Buttons -->
738
+ <nav class="envira-select-options">
739
+ <a href="#" class="button envira-gallery-images-edit"><?php _e( 'Edit Selected Images', 'envira-gallery' ); ?></a>
740
+ <a href="#" class="button envira-gallery-images-move" data-action="gallery"><?php _e( 'Move Selected Images to another Gallery', 'envira-gallery' ); ?></a>
741
+ <a href="#" class="button button-danger envira-gallery-images-delete"><?php _e( 'Delete Selected Images from Gallery', 'envira-gallery' ); ?></a>
742
+ </nav>
743
+ <?php
744
+ }
745
+
746
  do_action( 'envira_gallery_do_default_display', $post );
747
  ?>
748
+
749
  <ul id="envira-gallery-output" class="envira-gallery-images-output <?php echo $layout; ?>">
750
  <?php
751
  if ( ! empty( $gallery_data['gallery'] ) ) {
754
  }
755
  }
756
  ?>
757
+ </ul>
758
+
759
  <?php
760
+ if ( 'Envira_Gallery' == get_class( $this->base ) ) {
761
+ ?>
762
+ <!-- Bulk Edit / Delete Buttons -->
763
+ <nav class="envira-select-options">
764
+ <a href="#" class="button envira-gallery-images-edit"><?php _e( 'Edit Selected Images', 'envira-gallery' ); ?></a>
765
+ <a href="#" class="button envira-gallery-images-move" data-action="gallery"><?php _e( 'Move Selected Images to another Gallery', 'envira-gallery' ); ?></a>
766
+ <a href="#" class="button button-danger envira-gallery-images-delete"><?php _e( 'Delete Selected Images from Gallery', 'envira-gallery' ); ?></a>
767
+ </nav>
768
+ <?php
769
+ } else {
770
+ // Output an upgrade notice
771
+ Envira_Gallery_Notice_Admin::get_instance()->display_inline_notice(
772
+ 'envira_gallery_images_tab',
773
+ __( 'Want to make your gallery workflow even better?', 'envira-gallery' ),
774
+ __( 'By upgrading to Envira Pro, you can get access to numerous other features, including: a fully featured gallery widget, complete gallery API, powerful gallery documentation, full mobile and Retina support, dedicated customer support and so much more!', 'envira-gallery' ),
775
+ 'warning',
776
+ __( 'Click here to Upgrade', 'envira-gallery' ),
777
+ Envira_Gallery_Common_Admin::get_instance()->get_upgrade_link(),
778
+ false
779
+ );
780
+ }
781
 
782
  }
783
 
796
  <p class="envira-intro">
797
  <?php _e( 'Gallery Settings', 'envira-gallery' ); ?>
798
  <small>
799
+ <?php _e( 'The settings below adjust the basic configuration options for the gallery.', 'envira-gallery' ); ?><br />
 
800
  <?php _e( 'Need some help?', 'envira-gallery' ); ?>
801
  <a href="http://enviragallery.com/docs/creating-first-envira-gallery/" class="envira-doc" target="_blank">
802
  <?php _e( 'Read the Documentation', 'envira-gallery' ); ?>
822
  <p class="description"><?php _e( 'Determines the number of columns in the gallery. Automatic will attempt to fill each row as much as possible before moving on to the next row.', 'envira-gallery' ); ?></p>
823
  </td>
824
  </tr>
 
825
  <tr id="envira-config-gallery-theme-box">
826
  <th scope="row">
827
  <label for="envira-config-gallery-theme"><?php _e( 'Gallery Theme', 'envira-gallery' ); ?></label>
836
  </td>
837
  </tr>
838
 
839
+ <?php
840
+ if ( class_exists( 'Envira_Gallery' ) ) {
841
+ ?>
842
+ <!-- Display Description -->
843
+ <tr id="envira-config-display-description-box">
844
+ <th scope="row">
845
+ <label for="envira-config-display-description"><?php _e( 'Display Gallery Description?', 'envira-gallery' ); ?></label>
846
+ </th>
847
+ <td>
848
+ <select id="envira-config-display-description" name="_envira_gallery[description_position]" data-envira-conditional="envira-config-description-box">
849
+ <?php
850
+ foreach ( (array) $this->get_display_description_options() as $i => $data ) {
851
+ ?>
852
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'description_position', $this->get_config_default( 'description_position' ) ) ); ?>><?php echo $data['name']; ?></option>
853
+ <?php
854
+ }
855
+ ?>
856
+ </select>
857
+ <p class="description"><?php _e( 'Choose to display a description above or below this gallery\'s images.', 'envira-gallery' ); ?></p>
858
+ </td>
859
+ </tr>
860
+
861
+ <!-- Description -->
862
+ <tr id="envira-config-description-box">
863
+ <th scope="row">
864
+ <label for="envira-config-gallery-description"><?php _e( 'Gallery Description', 'envira-gallery' ); ?></label>
865
+ </th>
866
+ <td>
867
+ <?php
868
+ $description = $this->get_config( 'description' );
869
+ if ( empty( $description ) ) {
870
+ $description = $this->get_config_default( 'description' );
871
+ }
872
+ wp_editor( $description, 'envira-gallery-description', array(
873
+ 'media_buttons' => false,
874
+ 'wpautop' => true,
875
+ 'tinymce' => true,
876
+ 'textarea_name' => '_envira_gallery[description]',
877
+ ) );
878
+ ?>
879
+ <p class="description"><?php _e( 'The description to display for this gallery.', 'envira-gallery' ); ?></p>
880
+ </td>
881
+ </tr>
882
+ <?php
883
+ }
884
+ ?>
885
+
886
  <tr id="envira-config-gutter-box">
887
  <th scope="row">
888
  <label for="envira-config-gutter"><?php _e( 'Column Gutter Width', 'envira-gallery' ); ?></label>
892
  <p class="description"><?php _e( 'Sets the space between the columns (defaults to 10).', 'envira-gallery' ); ?></p>
893
  </td>
894
  </tr>
 
895
  <tr id="envira-config-margin-box">
896
  <th scope="row">
897
  <label for="envira-config-margin"><?php _e( 'Margin Below Each Image', 'envira-gallery' ); ?></label>
902
  </td>
903
  </tr>
904
 
905
+ <?php
906
+ if ( class_exists( 'Envira_Gallery' ) ) {
907
+ ?>
908
+ <!-- Sorting -->
909
+ <tr id="envira-config-sorting-box">
910
+ <th scope="row">
911
+ <label for="envira-config-sorting"><?php _e( 'Sorting', 'envira-gallery' ); ?></label>
912
+ </th>
913
+ <td>
914
+ <select id="envira-config-sorting" name="_envira_gallery[random]" data-envira-conditional="envira-config-sorting-direction-box">
915
+ <?php
916
+ foreach ( (array) $this->get_sorting_options() as $i => $data ) {
917
+ ?>
918
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'random', $this->get_config_default( 'random' ) ) ); ?>><?php echo $data['name']; ?></option>
919
+ <?php
920
+ }
921
+ ?>
922
+ </select>
923
+ <p class="description"><?php _e( 'Choose to sort the images in a different order than displayed on the Images tab.', 'envira-gallery' ); ?></p>
924
+ </td>
925
+ </tr>
926
+ <tr id="envira-config-sorting-direction-box">
927
+ <th scope="row">
928
+ <label for="envira-config-sorting-direction"><?php _e( 'Direction', 'envira-gallery' ); ?></label>
929
+ </th>
930
+ <td>
931
+ <select id="envira-config-sorting-direction" name="_envira_gallery[sorting_direction]">
932
+ <?php
933
+ foreach ( (array) $this->get_sorting_directions() as $i => $data ) {
934
+ ?>
935
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'sorting_direction', $this->get_config_default( 'sorting_direction' ) ) ); ?>><?php echo $data['name']; ?></option>
936
+ <?php
937
+ }
938
+ ?>
939
+ </select>
940
+ </td>
941
+ </tr>
942
+ <?php
943
+ }
944
+ ?>
945
+
946
  <!-- Dimensions -->
947
  <tr id="envira-config-image-size-box">
948
  <th scope="row">
958
  }
959
  ?>
960
  </select>
961
+ <p class="description"><?php _e( 'Define the maximum image size for the Gallery view. Default will use the below Image Dimensions; Random will allow you to choose one or more WordPress image sizes, which will be used for the gallery output.', 'envira-gallery' ); ?></p>
962
  </td>
963
  </tr>
964
+
965
+ <?php
966
+ if ( class_exists( 'Envira_Gallery' ) ) {
967
+ ?>
968
+ <tr id="envira-config-image-sizes-random-box">
969
+ <th scope="row">
970
+ <label for="envira-config-image-sizes-random"><?php _e( 'Random Image Sizes', 'envira-gallery' ); ?></label>
971
+ </th>
972
+ <td>
973
+ <?php
974
+ // Get random image sizes that have been selected, if any.
975
+ $image_sizes_random = (array) $this->get_config( 'image_sizes_random', $this->get_config_default( 'image_sizes_random' ) );
976
+
977
+ foreach ( (array) $this->get_image_sizes( true ) as $i => $data ) {
978
+ ?>
979
+ <label for="envira-config-image-sizes-random-<?php echo $data['value']; ?>">
980
+ <input id="envira-config-image-sizes-random-<?php echo $data['value']; ?>" type="checkbox" name="_envira_gallery[image_sizes_random][]" value="<?php echo $data['value']; ?>"<?php echo ( in_array( $data['value'], $image_sizes_random ) ? ' checked' : '' ); ?> />
981
+ <?php echo $data['name']; ?>
982
+ </label><br />
983
+ <?php
984
+ }
985
+ ?>
986
+ <p class="description"><?php _e( 'Define the WordPress registered image sizes to include when randomly assigning an image size to each image in your Gallery.', 'envira-gallery' ); ?></p>
987
+ </td>
988
+ </tr>
989
+ <?php
990
+ }
991
+ ?>
992
+
993
  <tr id="envira-config-crop-size-box">
994
  <th scope="row">
995
  <label for="envira-config-crop-width"><?php _e( 'Image Dimensions', 'envira-gallery' ); ?></label>
1005
  </th>
1006
  <td>
1007
  <input id="envira-config-crop" type="checkbox" name="_envira_gallery[crop]" value="<?php echo $this->get_config( 'crop', $this->get_config_default( 'crop' ) ); ?>" <?php checked( $this->get_config( 'crop', $this->get_config_default( 'crop' ) ), 1 ); ?> />
1008
+ <span class="description"><?php _e( 'If enabled, forces images to exactly match the sizes defined above for Image Dimensions and Mobile Dimensions.', 'envira-gallery' ); ?></span>
1009
  <span class="description"><?php _e( 'If disabled, images will be resized to maintain their aspect ratio.', 'envira-gallery' ); ?></span>
1010
 
1011
  </td>
1012
  </tr>
1013
+
1014
+ <?php
1015
+ if ( class_exists( 'Envira_Gallery' ) ) {
1016
+ ?>
1017
+ <tr id="envira-config-dimensions-box">
1018
+ <th scope="row">
1019
+ <label for="envira-config-dimensions"><?php _e( 'Set Dimensions on Images?', 'envira-gallery' ); ?></label>
1020
+ </th>
1021
+ <td>
1022
+ <input id="envira-config-dimensions" type="checkbox" name="_envira_gallery[dimensions]" value="<?php echo $this->get_config( 'dimensions', $this->get_config_default( 'dimensions' ) ); ?>" <?php checked( $this->get_config( 'dimensions', $this->get_config_default( 'dimensions' ) ), 1 ); ?> />
1023
+ <span class="description"><?php _e( 'Enables or disables the width and height attributes on the img element. Only needs to be enabled if you need to meet Google Pagespeeds requirements.', 'envira-gallery' ); ?></span>
1024
+ </td>
1025
+ </tr>
1026
+ <tr id="envira-config-isotope-box">
1027
+ <th scope="row">
1028
+ <label for="envira-config-isotope"><?php _e( 'Enable Isotope?', 'envira-gallery' ); ?></label>
1029
+ </th>
1030
+ <td>
1031
+ <input id="envira-config-isotope" type="checkbox" name="_envira_gallery[isotope]" value="<?php echo $this->get_config( 'isotope', $this->get_config_default( 'isotope' ) ); ?>" <?php checked( $this->get_config( 'isotope', $this->get_config_default( 'isotope' ) ), 1 ); ?> />
1032
+ <span class="description"><?php _e( 'Enables or disables isotope/masonry layout support for the main gallery images.', 'envira-gallery' ); ?></span>
1033
+ </td>
1034
+ </tr>
1035
+
1036
+ <tr id="envira-config-css-animations-box">
1037
+ <th scope="row">
1038
+ <label for="envira-config-css-animations"><?php _e( 'Enable CSS Animations?', 'envira-gallery' ); ?></label>
1039
+ </th>
1040
+ <td>
1041
+ <input id="envira-config-css-animations" type="checkbox" name="_envira_gallery[css_animations]" value="<?php echo $this->get_config( 'css_animations', $this->get_config_default( 'css_animations' ) ); ?>" <?php checked( $this->get_config( 'css_animations', $this->get_config_default( 'css_animations' ) ), 1 ); ?> data-envira-conditional="envira-config-css-opacity-box" />
1042
+ <span class="description"><?php _e( 'Enables CSS animations when loading the main gallery images.', 'envira-gallery' ); ?></span>
1043
+ </td>
1044
+ </tr>
1045
+
1046
+ <tr id="envira-config-css-opacity-box">
1047
+ <th scope="row">
1048
+ <label for="envira-config-css-opacity"><?php _e( 'Image Opacity', 'envira-gallery' ); ?></label>
1049
+ </th>
1050
+ <td>
1051
+ <input id="envira-config-css-opacity" type="number" name="_envira_gallery[css_opacity]" min="0" max="100" step="1" value="<?php echo $this->get_config( 'css_opacity', $this->get_config_default( 'css_opacity' ) ); ?>" /><span class="envira-unit">%</span>
1052
+ <p class="description"><?php _e( 'The opacity to display images at when loading the main gallery images using CSS animations (between 1 and 100%).', 'envira-gallery' ); ?></p>
1053
+ </td>
1054
+ </tr>
1055
+ <?php
1056
+ }
1057
+ ?>
1058
+
1059
  <?php do_action( 'envira_gallery_config_box', $post ); ?>
1060
  </tbody>
1061
  </table>
1062
  </div>
 
1063
 
1064
+ <?php
1065
  // Output an upgrade notice
1066
+ if ( class_exists( 'Envira_Gallery_Lite' ) ) {
1067
+ Envira_Gallery_Notice_Admin::get_instance()->display_inline_notice(
1068
+ 'envira_gallery_config_tab',
1069
+ __( 'Want to do even more with your gallery display?', 'envira-gallery' ),
1070
+ __( 'By upgrading to Envira Pro, you can get access to numerous other gallery display features, including: custom image tagging and filtering, mobile specific image assets for blazing fast load times, dedicated and unique gallery URLs, custom gallery themes, gallery thumbnail support and so much more!', 'envira-gallery' ),
1071
+ 'warning',
1072
+ __( 'Click here to Upgrade', 'envira-gallery' ),
1073
+ Envira_Gallery_Common_Admin::get_instance()->get_upgrade_link(),
1074
+ false
1075
+ );
1076
+ }
1077
 
1078
  }
1079
 
1162
  <p class="description"><?php _e( 'Sets the display of the lightbox image\'s caption.', 'envira-gallery' ); ?></p>
1163
  </td>
1164
  </tr>
1165
+
1166
+ <?php
1167
+ if ( class_exists( 'Envira_Gallery' ) ) {
1168
+ ?>
1169
+ <tr id="envira-config-lightbox-arrows-box">
1170
+ <th scope="row">
1171
+ <label for="envira-config-lightbox-arrows"><?php _e( 'Enable Gallery Arrows?', 'envira-gallery' ); ?></label>
1172
+ </th>
1173
+ <td>
1174
+ <input id="envira-config-lightbox-arrows" type="checkbox" name="_envira_gallery[arrows]" value="<?php echo $this->get_config( 'arrows', $this->get_config_default( 'arrows' ) ); ?>" <?php checked( $this->get_config( 'arrows', $this->get_config_default( 'arrows' ) ), 1 ); ?> data-envira-conditional="envira-config-lightbox-arrows-position-box" />
1175
+ <span class="description"><?php _e( 'Enables or disables the gallery lightbox navigation arrows.', 'envira-gallery' ); ?></span>
1176
+ </td>
1177
+ </tr>
1178
+ <tr id="envira-config-lightbox-arrows-position-box">
1179
+ <th scope="row">
1180
+ <label for="envira-config-lightbox-arrows-position"><?php _e( 'Gallery Arrow Position', 'envira-gallery' ); ?></label>
1181
+ </th>
1182
+ <td>
1183
+ <select id="envira-config-lightbox-arrows-position" name="_envira_gallery[arrows_position]">
1184
+ <?php foreach ( (array) $this->get_arrows_positions() as $i => $data ) : ?>
1185
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'arrows_position', $this->get_config_default( 'arrows_position' ) ) ); ?>><?php echo $data['name']; ?></option>
1186
+ <?php endforeach; ?>
1187
+ </select>
1188
+ <p class="description"><?php _e( 'Sets the position of the gallery lightbox navigation arrows.', 'envira-gallery' ); ?></p>
1189
+ </td>
1190
+ </tr>
1191
+ <tr id="envira-config-lightbox-keyboard-box">
1192
+ <th scope="row">
1193
+ <label for="envira-config-lightbox-keyboard"><?php _e( 'Enable Keyboard Navigation?', 'envira-gallery' ); ?></label>
1194
+ </th>
1195
+ <td>
1196
+ <input id="envira-config-lightbox-keyboard" type="checkbox" name="_envira_gallery[keyboard]" value="<?php echo $this->get_config( 'keyboard', $this->get_config_default( 'keyboard' ) ); ?>" <?php checked( $this->get_config( 'keyboard', $this->get_config_default( 'keyboard' ) ), 1 ); ?> />
1197
+ <span class="description"><?php _e( 'Enables or disables keyboard navigation in the gallery lightbox.', 'envira-gallery' ); ?></span>
1198
+ </td>
1199
+ </tr>
1200
+ <tr id="envira-config-lightbox-mousewheel-box">
1201
+ <th scope="row">
1202
+ <label for="envira-config-lightbox-mousewheel"><?php _e( 'Enable Mousewheel Navigation?', 'envira-gallery' ); ?></label>
1203
+ </th>
1204
+ <td>
1205
+ <input id="envira-config-lightbox-mousewheel" type="checkbox" name="_envira_gallery[mousewheel]" value="<?php echo $this->get_config( 'mousewheel', $this->get_config_default( 'mousewheel' ) ); ?>" <?php checked( $this->get_config( 'mousewheel', $this->get_config_default( 'mousewheel' ) ), 1 ); ?> />
1206
+ <span class="description"><?php _e( 'Enables or disables mousewheel navigation in the gallery.', 'envira-gallery' ); ?></span>
1207
+ </td>
1208
+ </tr>
1209
+ <tr id="envira-config-lightbox-toolbar-box">
1210
+ <th scope="row">
1211
+ <label for="envira-config-lightbox-toolbar"><?php _e( 'Enable Gallery Toolbar?', 'envira-gallery' ); ?></label>
1212
+ </th>
1213
+ <td>
1214
+ <input id="envira-config-lightbox-toolbar" type="checkbox" name="_envira_gallery[toolbar]" value="<?php echo $this->get_config( 'toolbar', $this->get_config_default( 'toolbar' ) ); ?>" <?php checked( $this->get_config( 'toolbar', $this->get_config_default( 'toolbar' ) ), 1 ); ?> data-envira-conditional="envira-config-lightbox-toolbar-title-box,envira-config-lightbox-toolbar-position-box" />
1215
+ <span class="description"><?php _e( 'Enables or disables the gallery lightbox toolbar.', 'envira-gallery' ); ?></span>
1216
+ </td>
1217
+ </tr>
1218
+ <tr id="envira-config-lightbox-toolbar-title-box">
1219
+ <th scope="row">
1220
+ <label for="envira-config-lightbox-toolbar-title"><?php _e( 'Display Gallery Title in Toolbar?', 'envira-gallery' ); ?></label>
1221
+ </th>
1222
+ <td>
1223
+ <input id="envira-config-lightbox-toolbar-title" type="checkbox" name="_envira_gallery[toolbar_title]" value="<?php echo $this->get_config( 'toolbar_title', $this->get_config_default( 'toolbar_title' ) ); ?>" <?php checked( $this->get_config( 'toolbar_title', $this->get_config_default( 'toolbar_title' ) ), 1 ); ?> data-envira-conditional="envira-config-lightbox-toolbar-position-box" />
1224
+ <span class="description"><?php _e( 'Display the gallery title in the lightbox toolbar.', 'envira-gallery' ); ?></span>
1225
+ </td>
1226
+ </tr>
1227
+ <tr id="envira-config-lightbox-toolbar-position-box">
1228
+ <th scope="row">
1229
+ <label for="envira-config-lightbox-toolbar-position"><?php _e( 'Gallery Toolbar Position', 'envira-gallery' ); ?></label>
1230
+ </th>
1231
+ <td>
1232
+ <select id="envira-config-lightbox-toolbar-position" name="_envira_gallery[toolbar_position]">
1233
+ <?php foreach ( (array) $this->get_toolbar_positions() as $i => $data ) : ?>
1234
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'toolbar_position', $this->get_config_default( 'toolbar_position' ) ) ); ?>><?php echo $data['name']; ?></option>
1235
+ <?php endforeach; ?>
1236
+ </select>
1237
+ <p class="description"><?php _e( 'Sets the position of the lightbox toolbar.', 'envira-gallery' ); ?></p>
1238
+ </td>
1239
+ </tr>
1240
+ <tr id="envira-config-lightbox-aspect-box">
1241
+ <th scope="row">
1242
+ <label for="envira-config-lightbox-aspect"><?php _e( 'Keep Aspect Ratio?', 'envira-gallery' ); ?></label>
1243
+ </th>
1244
+ <td>
1245
+ <input id="envira-config-lightbox-toolbar" type="checkbox" name="_envira_gallery[aspect]" value="<?php echo $this->get_config( 'aspect', $this->get_config_default( 'aspect' ) ); ?>" <?php checked( $this->get_config( 'aspect', $this->get_config_default( 'aspect' ) ), 1 ); ?> />
1246
+ <span class="description"><?php _e( 'If enabled, images will always resize based on the original aspect ratio.', 'envira-gallery' ); ?></span>
1247
+ </td>
1248
+ </tr>
1249
+ <tr id="envira-config-lightbox-loop-box">
1250
+ <th scope="row">
1251
+ <label for="envira-config-lightbox-loop"><?php _e( 'Loop Gallery Navigation?', 'envira-gallery' ); ?></label>
1252
+ </th>
1253
+ <td>
1254
+ <input id="envira-config-lightbox-loop" type="checkbox" name="_envira_gallery[loop]" value="<?php echo $this->get_config( 'loop', $this->get_config_default( 'loop' ) ); ?>" <?php checked( $this->get_config( 'loop', $this->get_config_default( 'loop' ) ), 1 ); ?> />
1255
+ <span class="description"><?php _e( 'Enables or disables infinite navigation cycling of the lightbox gallery.', 'envira-gallery' ); ?></span>
1256
+ </td>
1257
+ </tr>
1258
+ <tr id="envira-config-lightbox-open-close-effect-box">
1259
+ <th scope="row">
1260
+ <label for="envira-config-lightbox-open-close-effect"><?php _e( 'Lightbox Open/Close Effect', 'envira-gallery' ); ?></label>
1261
+ </th>
1262
+ <td>
1263
+ <select id="envira-config-lightbox-open-close-effect" name="_envira_gallery[lightbox_open_close_effect]">
1264
+ <?php
1265
+ // Standard Effects
1266
+ foreach ( (array) $this->get_transition_effects() as $i => $data ) {
1267
+ ?>
1268
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'lightbox_open_close_effect', $this->get_config_default( 'lightbox_open_close_effect' ) ) ); ?>><?php echo $data['name']; ?></option>
1269
+ <?php
1270
+ }
1271
+
1272
+ // Easing Effects
1273
+ foreach ( (array) $this->get_easing_transition_effects() as $i => $data ) {
1274
+ ?>
1275
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'lightbox_open_close_effect', $this->get_config_default( 'lightbox_open_close_effect' ) ) ); ?>><?php echo $data['name']; ?></option>
1276
+ <?php
1277
+ }
1278
+ ?>
1279
+ </select>
1280
+ <p class="description"><?php _e( 'Type of transition when opening and closing the lightbox.', 'envira-gallery' ); ?></p>
1281
+ </td>
1282
+ </tr>
1283
+ <tr id="envira-config-lightbox-effect-box">
1284
+ <th scope="row">
1285
+ <label for="envira-config-lightbox-effect"><?php _e( 'Lightbox Transition Effect', 'envira-gallery' ); ?></label>
1286
+ </th>
1287
+ <td>
1288
+ <select id="envira-config-lightbox-effect" name="_envira_gallery[effect]">
1289
+ <?php
1290
+ // Standard Effects
1291
+ foreach ( (array) $this->get_transition_effects() as $i => $data ) {
1292
+ ?>
1293
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'effect', $this->get_config_default( 'effect' ) ) ); ?>><?php echo $data['name']; ?></option>
1294
+ <?php
1295
+ }
1296
+
1297
+ // Easing Effects
1298
+ foreach ( (array) $this->get_easing_transition_effects() as $i => $data ) {
1299
+ ?>
1300
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'effect', $this->get_config_default( 'effect' ) ) ); ?>><?php echo $data['name']; ?></option>
1301
+ <?php
1302
+ }
1303
+ ?>
1304
+ </select>
1305
+ <p class="description"><?php _e( 'Type of transition between images in the lightbox view.', 'envira-gallery' ); ?></p>
1306
+ </td>
1307
+ </tr>
1308
+ <tr id="envira-config-lightbox-html5-box">
1309
+ <th scope="row">
1310
+ <label for="envira-config-lightbox-html5"><?php _e( 'HTML5 Output?', 'envira-gallery' ); ?></label>
1311
+ </th>
1312
+ <td>
1313
+ <input id="envira-config-lightbox-html5" type="checkbox" name="_envira_gallery[html5]" value="<?php echo $this->get_config( 'html5', $this->get_config_default( 'html5' ) ); ?>" <?php checked( $this->get_config( 'html5', $this->get_config_default( 'html5' ) ), 1 ); ?> />
1314
+ <span class="description"><?php _e( 'If enabled, uses data-envirabox-gallery instead of rel attributes for W3C HTML5 validation.', 'envira-gallery' ); ?></span>
1315
+ </td>
1316
+ </tr>
1317
+ <?php
1318
+ }
1319
+ ?>
1320
 
1321
  <?php do_action( 'envira_gallery_lightbox_box', $post ); ?>
1322
  </tbody>
1323
  </table>
1324
+
1325
+ <?php
1326
+ if ( class_exists( 'Envira_Gallery' ) ) {
1327
+ ?>
1328
+ <p class="envira-intro"><?php _e( 'The settings below adjust the thumbnail views for the gallery lightbox display.', 'envira-gallery' ); ?></p>
1329
+ <table class="form-table">
1330
+ <tbody>
1331
+ <tr id="envira-config-thumbnails-box">
1332
+ <th scope="row">
1333
+ <label for="envira-config-thumbnails"><?php _e( 'Enable Gallery Thumbnails?', 'envira-gallery' ); ?></label>
1334
+ </th>
1335
+ <td>
1336
+ <input id="envira-config-thumbnails" type="checkbox" name="_envira_gallery[thumbnails]" value="<?php echo $this->get_config( 'thumbnails', $this->get_config_default( 'thumbnails' ) ); ?>" <?php checked( $this->get_config( 'thumbnails', $this->get_config_default( 'thumbnails' ) ), 1 ); ?> data-envira-conditional="envira-config-thumbnails-width-box,envira-config-thumbnails-height-box,envira-config-thumbnails-position-box" />
1337
+ <span class="description"><?php _e( 'Enables or disables the gallery lightbox thumbnails.', 'envira-gallery' ); ?></span>
1338
+ </td>
1339
+ </tr>
1340
+ <tr id="envira-config-thumbnails-width-box">
1341
+ <th scope="row">
1342
+ <label for="envira-config-thumbnails-width"><?php _e( 'Gallery Thumbnails Width', 'envira-gallery' ); ?></label>
1343
+ </th>
1344
+ <td>
1345
+ <input id="envira-config-thumbnails-width" type="number" name="_envira_gallery[thumbnails_width]" value="<?php echo $this->get_config( 'thumbnails_width', $this->get_config_default( 'thumbnails_width' ) ); ?>" /> <span class="envira-unit"><?php _e( 'px', 'envira-gallery' ); ?></span>
1346
+ <p class="description"><?php _e( 'Sets the width of each lightbox thumbnail.', 'envira-gallery' ); ?></p>
1347
+ </td>
1348
+ </tr>
1349
+ <tr id="envira-config-thumbnails-height-box">
1350
+ <th scope="row">
1351
+ <label for="envira-config-thumbnails-height"><?php _e( 'Gallery Thumbnails Height', 'envira-gallery' ); ?></label>
1352
+ </th>
1353
+ <td>
1354
+ <input id="envira-config-thumbnails-height" type="number" name="_envira_gallery[thumbnails_height]" value="<?php echo $this->get_config( 'thumbnails_height', $this->get_config_default( 'thumbnails_height' ) ); ?>" /> <span class="envira-unit"><?php _e( 'px', 'envira-gallery' ); ?></span>
1355
+ <p class="description"><?php _e( 'Sets the height of each lightbox thumbnail.', 'envira-gallery' ); ?></p>
1356
+ </td>
1357
+ </tr>
1358
+ <tr id="envira-config-thumbnails-position-box">
1359
+ <th scope="row">
1360
+ <label for="envira-config-thumbnails-position"><?php _e( 'Gallery Thumbnails Position', 'envira-gallery' ); ?></label>
1361
+ </th>
1362
+ <td>
1363
+ <select id="envira-config-thumbnails-position" name="_envira_gallery[thumbnails_position]">
1364
+ <?php foreach ( (array) $this->get_thumbnail_positions() as $i => $data ) : ?>
1365
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'thumbnails_position', $this->get_config_default( 'thumbnails_position' ) ) ); ?>><?php echo $data['name']; ?></option>
1366
+ <?php endforeach; ?>
1367
+ </select>
1368
+ <p class="description"><?php _e( 'Sets the position of the lightbox thumbnails.', 'envira-gallery' ); ?></p>
1369
+ </td>
1370
+ </tr>
1371
+ <?php do_action( 'envira_gallery_thumbnails_box', $post ); ?>
1372
+ </tbody>
1373
+ </table>
1374
+ <?php
1375
+ }
1376
+ ?>
1377
  </div>
1378
  </div>
1379
  <?php
1380
 
1381
  // Output an upgrade notice
1382
+ if ( class_exists( 'Envira_Gallery_Lite' ) ) {
1383
+ Envira_Gallery_Notice_Admin::get_instance()->display_inline_notice(
1384
+ 'envira_gallery_lightbox_tab',
1385
+ __( 'Want even more fine tuned control over your lightbox display?', 'envira-gallery' ),
1386
+ __( 'By upgrading to Envira Pro, you can get access to numerous other lightbox features, including: custom lightbox titles, enable/disable lightbox controls (arrow, keyboard and mousehweel navigation), custom lightbox transition effects, native fullscreen support, gallery deeplinking, image protection, lightbox supersize effects, lightbox slideshows and so much more!', 'envira-gallery' ),
1387
+ 'warning',
1388
+ __( 'Click here to Upgrade', 'envira-gallery' ),
1389
+ Envira_Gallery_Common_Admin::get_instance()->get_upgrade_link(),
1390
+ false
1391
+ );
1392
+ }
1393
+
1394
+ }
1395
+
1396
+ /**
1397
+ * Callback for displaying the settings UI for the Mobile tab.
1398
+ *
1399
+ * @since 1.3.2
1400
+ *
1401
+ * @param object $post The current post object.
1402
+ */
1403
+ public function mobile_tab( $post ) {
1404
+
1405
+ ?>
1406
+ <div id="envira-mobile">
1407
+ <p class="envira-intro">
1408
+ <?php _e( 'Mobile Gallery Settings', 'envira-gallery' ); ?>
1409
+ <small>
1410
+ <?php _e( 'The settings below adjust configuration options for the Gallery when viewed on a mobile device.', 'envira-gallery' ); ?><br />
1411
+ <?php _e( 'Need some help?', 'envira-gallery' ); ?>
1412
+ <a href="http://enviragallery.com/docs/creating-first-envira-gallery/" class="envira-doc" target="_blank">
1413
+ <?php _e( 'Read the Documentation', 'envira-gallery' ); ?>
1414
+ </a>
1415
+ or
1416
+ <a href="https://www.youtube.com/embed/4jHG3LOmV-c?autoplay=1&amp;rel=0" class="envira-video" target="_blank">
1417
+ <?php _e( 'Watch a Video', 'envira-gallery' ); ?>
1418
+ </a>
1419
+ </small>
1420
+ </p>
1421
+ <table class="form-table">
1422
+ <tbody>
1423
+ <tr id="envira-config-mobile-columns-box">
1424
+ <th scope="row">
1425
+ <label for="envira-config-mobile-columns"><?php _e( 'Number of Gallery Columns', 'envira-gallery' ); ?></label>
1426
+ </th>
1427
+ <td>
1428
+ <select id="envira-config-mobile-columns" name="_envira_gallery[mobile_columns]">
1429
+ <?php foreach ( (array) $this->get_columns() as $i => $data ) : ?>
1430
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'mobile_columns', $this->get_config_default( 'mobile_columns' ) ) ); ?>><?php echo $data['name']; ?></option>
1431
+ <?php endforeach; ?>
1432
+ </select>
1433
+ <p class="description"><?php _e( 'Determines the number of columns in the gallery on mobile devices. Automatic will attempt to fill each row as much as possible before moving on to the next row.', 'envira-gallery' ); ?></p>
1434
+ </td>
1435
+ </tr>
1436
+
1437
+ <tr id="envira-config-mobile-box">
1438
+ <th scope="row">
1439
+ <label for="envira-config-mobile"><?php _e( 'Create Mobile Gallery Images?', 'envira-gallery' ); ?></label>
1440
+ </th>
1441
+ <td>
1442
+ <input id="envira-config-mobile" type="checkbox" name="_envira_gallery[mobile]" value="<?php echo $this->get_config( 'mobile', $this->get_config_default( 'mobile' ) ); ?>" <?php checked( $this->get_config( 'mobile', $this->get_config_default( 'mobile' ) ), 1 ); ?> data-envira-conditional="envira-config-mobile-size-box" />
1443
+ <span class="description"><?php _e( 'Enables or disables creating specific images for mobile devices.', 'envira-gallery' ); ?></span>
1444
+ </td>
1445
+ </tr>
1446
+
1447
+ <tr id="envira-config-mobile-size-box">
1448
+ <th scope="row">
1449
+ <label for="envira-config-mobile-width"><?php _e( 'Mobile Dimensions', 'envira-gallery' ); ?></label>
1450
+ </th>
1451
+ <td>
1452
+ <input id="envira-config-mobile-width" type="number" name="_envira_gallery[mobile_width]" value="<?php echo $this->get_config( 'mobile_width', $this->get_config_default( 'mobile_width' ) ); ?>" /> &#215; <input id="envira-config-mobile-height" type="number" name="_envira_gallery[mobile_height]" value="<?php echo $this->get_config( 'mobile_height', $this->get_config_default( 'mobile_height' ) ); ?>" /> <span class="envira-unit"><?php _e( 'px', 'envira-gallery' ); ?></span>
1453
+ <p class="description"><?php _e( 'These will be the sizes used for images displayed on mobile devices.', 'envira-gallery' ); ?></p>
1454
+ </td>
1455
+ </tr>
1456
+
1457
+ <?php do_action( 'envira_gallery_mobile_box', $post ); ?>
1458
+ </tbody>
1459
+ </table>
1460
+
1461
+ <!-- Lightbox -->
1462
+ <p class="envira-intro">
1463
+ <?php _e( 'Mobile Lightbox Settings', 'envira-gallery' ); ?>
1464
+ <small>
1465
+ <?php _e( 'The settings below adjust configuration options for the Lightbox when viewed on a mobile device.', 'envira-gallery' ); ?><br />
1466
+ </small>
1467
+ </p>
1468
+ <table class="form-table">
1469
+ <tbody>
1470
+ <tr id="envira-config-mobile-lightbox-box">
1471
+ <th scope="row">
1472
+ <label for="envira-config-mobile-lightbox"><?php _e( 'Enable Lightbox?', 'envira-gallery' ); ?></label>
1473
+ </th>
1474
+ <td>
1475
+ <input id="envira-config-mobile-lightbox" type="checkbox" name="_envira_gallery[mobile_lightbox]" value="<?php echo $this->get_config( 'mobile_lightbox', $this->get_config_default( 'mobile_lightbox' ) ); ?>" <?php checked( $this->get_config( 'mobile_lightbox', $this->get_config_default( 'mobile_lightbox' ) ), 1 ); ?> data-envira-conditional="envira-config-mobile-touchwipe-box,envira-config-mobile-touchwipe-close-box,envira-config-mobile-arrows-box,envira-config-mobile-toolbar-box,envira-config-mobile-thumbnails-box,envira-config-exif-mobile-box" />
1476
+ <span class="description"><?php _e( 'Enables or disables the gallery lightbox on mobile devices.', 'envira-gallery' ); ?></span>
1477
+ </td>
1478
+ </tr>
1479
+ <tr id="envira-config-mobile-touchwipe-box">
1480
+ <th scope="row">
1481
+ <label for="envira-config-mobile-touchwipe"><?php _e( 'Enable Gallery Touchwipe?', 'envira-gallery' ); ?></label>
1482
+ </th>
1483
+ <td>
1484
+ <input id="envira-config-mobile-touchwipe" type="checkbox" name="_envira_gallery[mobile_touchwipe]" value="<?php echo $this->get_config( 'mobile_touchwipe', $this->get_config_default( 'mobile_touchwipe' ) ); ?>" <?php checked( $this->get_config( 'mobile_touchwipe', $this->get_config_default( 'mobile_touchwipe' ) ), 1 ); ?> data-envira-conditional="envira-config-mobile-touchwipe-close-box" />
1485
+ <span class="description"><?php _e( 'Enables or disables touchwipe support for the gallery lightbox on mobile devices.', 'envira-gallery' ); ?></span>
1486
+ </td>
1487
+ </tr>
1488
+ <tr id="envira-config-mobile-touchwipe-close-box">
1489
+ <th scope="row">
1490
+ <label for="envira-config-mobile-touchwipe-close"><?php _e( 'Close Lightbox on Swipe Up?', 'envira-gallery' ); ?></label>
1491
+ </th>
1492
+ <td>
1493
+ <input id="envira-config-mobile-touchwipe-close" type="checkbox" name="_envira_gallery[mobile_touchwipe_close]" value="<?php echo $this->get_config( 'mobile_touchwipe_close', $this->get_config_default( 'mobile_touchwipe_close' ) ); ?>" <?php checked( $this->get_config( 'mobile_touchwipe_close', $this->get_config_default( 'mobile_touchwipe_close' ) ), 1 ); ?> />
1494
+ <span class="description"><?php _e( 'Enables or disables closing the Lightbox when the user swipes up on mobile devices.', 'envira-gallery' ); ?></span>
1495
+ </td>
1496
+ </tr>
1497
+ <tr id="envira-config-mobile-arrows-box">
1498
+ <th scope="row">
1499
+ <label for="envira-config-mobile-arrows"><?php _e( 'Enable Gallery Arrows?', 'envira-gallery' ); ?></label>
1500
+ </th>
1501
+ <td>
1502
+ <input id="envira-config-mobile-arrows" type="checkbox" name="_envira_gallery[mobile_arrows]" value="<?php echo $this->get_config( 'mobile_arrows', $this->get_config_default( 'mobile_arrows' ) ); ?>" <?php checked( $this->get_config( 'mobile_arrows', $this->get_config_default( 'mobile_arrows' ) ), 1 ); ?> />
1503
+ <span class="description"><?php _e( 'Enables or disables the gallery lightbox navigation arrows on mobile devices.', 'envira-gallery' ); ?></span>
1504
+ </td>
1505
+ </tr>
1506
+ <tr id="envira-config-mobile-toolbar-box">
1507
+ <th scope="row">
1508
+ <label for="envira-config-mobile-toolbar"><?php _e( 'Enable Gallery Toolbar?', 'envira-gallery' ); ?></label>
1509
+ </th>
1510
+ <td>
1511
+ <input id="envira-config-mobile-toolbar" type="checkbox" name="_envira_gallery[mobile_toolbar]" value="<?php echo $this->get_config( 'mobile_toolbar', $this->get_config_default( 'mobile_toolbar' ) ); ?>" <?php checked( $this->get_config( 'mobile_toolbar', $this->get_config_default( 'mobile_toolbar' ) ), 1 ); ?> />
1512
+ <span class="description"><?php _e( 'Enables or disables the gallery lightbox toolbar on mobile devices.', 'envira-gallery' ); ?></span>
1513
+ </td>
1514
+ </tr>
1515
+ <tr id="envira-config-mobile-thumbnails-box">
1516
+ <th scope="row">
1517
+ <label for="envira-config-mobile-thumbnails"><?php _e( 'Enable Gallery Thumbnails?', 'envira-gallery' ); ?></label>
1518
+ </th>
1519
+ <td>
1520
+ <input id="envira-config-mobile-thumbnails" type="checkbox" name="_envira_gallery[mobile_thumbnails]" value="<?php echo $this->get_config( 'mobile_thumbnails', $this->get_config_default( 'mobile_toolbar' ) ); ?>" <?php checked( $this->get_config( 'mobile_thumbnails', $this->get_config_default( 'mobile_thumbnails' ) ), 1 ); ?> />
1521
+ <span class="description"><?php _e( 'Enables or disables the gallery lightbox thumbnails on mobile devices.', 'envira-gallery' ); ?></span>
1522
+ </td>
1523
+ </tr>
1524
+
1525
+ <?php do_action( 'envira_gallery_mobile_lightbox_box', $post ); ?>
1526
+ </tbody>
1527
+ </table>
1528
+ </div>
1529
+ <?php
1530
 
1531
  }
1532
 
1544
  <p class="envira-intro">
1545
  <?php _e( 'Miscellaneous Settings', 'envira-gallery' ); ?>
1546
  <small>
1547
+ <?php _e( 'The settings below adjust miscellaneous options for the Gallery.', 'envira-gallery' ); ?>
1548
  <br />
1549
  <?php _e( 'Need some help?', 'envira-gallery' ); ?>
1550
  <a href="http://enviragallery.com/docs/creating-first-envira-gallery/" class="envira-doc" target="_blank">
1585
  <p class="description"><?php _e( 'Adds custom CSS classes to this gallery. Enter one class per line.', 'envira-gallery' ); ?></p>
1586
  </td>
1587
  </tr>
1588
+
1589
+ <?php
1590
+ if ( class_exists( 'Envira_Gallery' ) ) {
1591
+ ?>
1592
+ <tr id="envira-config-import-export-box">
1593
+ <th scope="row">
1594
+ <label for="envira-config-import-gallery"><?php _e( 'Import/Export Gallery', 'envira-gallery' ); ?></label>
1595
+ </th>
1596
+ <td>
1597
+ <form></form>
1598
+ <?php
1599
+ $import_url = 'auto-draft' == $post->post_status ? add_query_arg( array( 'post' => $post->ID, 'action' => 'edit', 'envira-gallery-imported' => true ), admin_url( 'post.php' ) ) : add_query_arg( 'envira-gallery-imported', true );
1600
+ $import_url = esc_url( $import_url );
1601
+ ?>
1602
+ <form action="<?php echo $import_url; ?>" id="envira-config-import-gallery-form" class="envira-gallery-import-form" method="post" enctype="multipart/form-data">
1603
+ <input id="envira-config-import-gallery" type="file" name="envira_import_gallery" />
1604
+ <input type="hidden" name="envira_import" value="1" />
1605
+ <input type="hidden" name="envira_post_id" value="<?php echo $post->ID; ?>" />
1606
+ <?php wp_nonce_field( 'envira-gallery-import', 'envira-gallery-import' ); ?>
1607
+ <?php submit_button( __( 'Import Gallery', 'envira-gallery' ), 'secondary', 'envira-gallery-import-submit', false ); ?>
1608
+ <span class="spinner envira-gallery-spinner"></span>
1609
+ </form>
1610
+ <form id="envira-config-export-gallery-form" method="post">
1611
+ <input type="hidden" name="envira_export" value="1" />
1612
+ <input type="hidden" name="envira_post_id" value="<?php echo $post->ID; ?>" />
1613
+ <?php wp_nonce_field( 'envira-gallery-export', 'envira-gallery-export' ); ?>
1614
+ <?php submit_button( __( 'Export Gallery', 'envira-gallery' ), 'secondary', 'envira-gallery-export-submit', false ); ?>
1615
+ </form>
1616
+ </td>
1617
+ </tr>
1618
+ <?php
1619
+ }
1620
+ ?>
1621
+
1622
  <tr id="envira-config-rtl-box">
1623
  <th scope="row">
1624
  <label for="envira-config-rtl"><?php _e( 'Enable RTL Support?', 'envira-gallery' ); ?></label>
1633
  </table>
1634
  </div>
1635
  <?php
 
1636
  // Output an upgrade notice
1637
+ if ( class_exists( 'Envira_Gallery_Lite' ) ) {
1638
+ Envira_Gallery_Notice_Admin::get_instance()->display_inline_notice(
1639
+ 'envira_gallery_misc_tab',
1640
+ __( 'Want to take your galleries further?', 'envira-gallery' ),
1641
+ __( 'By upgrading to Envira Pro, you can get access to numerous other features, including: a fully-integrated import/export module for your galleries, custom CSS controls for each gallery and so much more!', 'envira-gallery' ),
1642
+ 'warning',
1643
+ __( 'Click here to Upgrade', 'envira-gallery' ),
1644
+ Envira_Gallery_Common_Admin::get_instance()->get_upgrade_link(),
1645
+ false
1646
+ );
1647
+ }
1648
 
1649
  }
1650
 
1798
  }
1799
 
1800
  if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
1801
+ // Check if this is a Quick Edit request
1802
+ if ( isset( $_POST['_inline_edit'] ) ) {
1803
+
1804
+ // Just update specific fields in the Quick Edit screen
1805
+
1806
+ // Get settings
1807
+ $settings = get_post_meta( $post_id, '_eg_gallery_data', true );
1808
+ if ( empty( $settings ) ) {
1809
+ return;
1810
+ }
1811
 
1812
+ // Update Settings
1813
+ $settings['config']['columns'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['columns'] );
1814
  $settings['config']['gallery_theme'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['gallery_theme'] );
1815
  $settings['config']['gutter'] = absint( $_POST['_envira_gallery']['gutter'] );
1816
  $settings['config']['margin'] = absint( $_POST['_envira_gallery']['margin'] );
1817
  $settings['config']['crop_width'] = absint( $_POST['_envira_gallery']['crop_width'] );
1818
  $settings['config']['crop_height'] = absint( $_POST['_envira_gallery']['crop_height'] );
1819
+
1820
+ // Provide a filter to override settings.
1821
+ $settings = apply_filters( 'envira_gallery_quick_edit_save_settings', $settings, $post_id, $post );
1822
+
1823
+ // Update the post meta.
1824
+ update_post_meta( $post_id, '_eg_gallery_data', $settings );
1825
+
1826
+ // Finally, flush all gallery caches to ensure everything is up to date.
1827
  Envira_Gallery_Common::get_instance()->flush_gallery_caches( $post_id, $settings['config']['slug'] );
1828
+
1829
+ }
1830
 
1831
  return;
1832
  }
1870
  $settings['config']['crop_height'] = absint( $_POST['_envira_gallery']['crop_height'] );
1871
  $settings['config']['crop'] = isset( $_POST['_envira_gallery']['crop'] ) ? 1 : 0;
1872
 
1873
+ if ( 'Envira_Gallery' == get_class( $this->base ) ) {
1874
+ $settings['config']['description_position'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['description_position'] );
1875
+ $settings['config']['description'] = trim( $_POST['_envira_gallery']['description'] );
1876
+ $settings['config']['random'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['random'] );
1877
+ $settings['config']['sorting_direction'] = preg_replace( '#[^A-Z]#', '', $_POST['_envira_gallery']['sorting_direction'] );
1878
+ $settings['config']['image_sizes_random'] = ( isset( $_POST['_envira_gallery']['image_sizes_random'] ) ? stripslashes_deep( $_POST['_envira_gallery']['image_sizes_random'] ) : array() );
1879
+ $settings['config']['dimensions'] = isset( $_POST['_envira_gallery']['dimensions'] ) ? 1 : 0;
1880
+ $settings['config']['isotope'] = isset( $_POST['_envira_gallery']['isotope'] ) ? 1 : 0;
1881
+ $settings['config']['css_animations'] = isset( $_POST['_envira_gallery']['css_animations'] ) ? 1 : 0;
1882
+ $settings['config']['css_opacity'] = absint( $_POST['_envira_gallery']['css_opacity'] );
1883
+ }
1884
+
1885
  // Lightbox
1886
  $settings['config']['lightbox_enabled'] = isset( $_POST['_envira_gallery']['lightbox_enabled'] ) ? 1 : 0;
1887
  $settings['config']['lightbox_theme'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['lightbox_theme'] );
1888
  $settings['config']['lightbox_image_size'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['lightbox_image_size'] );
1889
  $settings['config']['title_display'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['title_display'] );
1890
 
1891
+ if ( 'Envira_Gallery' == get_class( $this->base ) ) {
1892
+ $settings['config']['arrows'] = isset( $_POST['_envira_gallery']['arrows'] ) ? 1 : 0;
1893
+ $settings['config']['arrows_position'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['arrows_position'] );
1894
+ $settings['config']['keyboard'] = isset( $_POST['_envira_gallery']['keyboard'] ) ? 1 : 0;
1895
+ $settings['config']['mousewheel'] = isset( $_POST['_envira_gallery']['mousewheel'] ) ? 1 : 0;
1896
+ $settings['config']['aspect'] = isset( $_POST['_envira_gallery']['aspect'] ) ? 1 : 0;
1897
+ $settings['config']['toolbar'] = isset( $_POST['_envira_gallery']['toolbar'] ) ? 1 : 0;
1898
+ $settings['config']['toolbar_title'] = isset( $_POST['_envira_gallery']['toolbar_title'] ) ? 1 : 0;
1899
+ $settings['config']['toolbar_position'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['toolbar_position'] );
1900
+ $settings['config']['loop'] = isset( $_POST['_envira_gallery']['loop'] ) ? 1 : 0;
1901
+ $settings['config']['lightbox_open_close_effect'] = preg_replace( '#[^A-Za-z0-9-_]#', '', $_POST['_envira_gallery']['lightbox_open_close_effect'] );
1902
+ $settings['config']['effect'] = preg_replace( '#[^A-Za-z0-9-_]#', '', $_POST['_envira_gallery']['effect'] );
1903
+ $settings['config']['html5'] = isset( $_POST['_envira_gallery']['html5'] ) ? 1 : 0;
1904
+
1905
+ // Lightbox Thumbnails
1906
+ $settings['config']['thumbnails'] = isset( $_POST['_envira_gallery']['thumbnails'] ) ? 1 : 0;
1907
+ $settings['config']['thumbnails_width'] = absint( $_POST['_envira_gallery']['thumbnails_width'] );
1908
+ $settings['config']['thumbnails_height'] = absint( $_POST['_envira_gallery']['thumbnails_height'] );
1909
+ $settings['config']['thumbnails_position'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['thumbnails_position'] );
1910
+
1911
+ // Mobile
1912
+ $settings['config']['mobile_columns'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['mobile_columns'] );
1913
+ $settings['config']['mobile'] = isset( $_POST['_envira_gallery']['mobile'] ) ? 1 : 0;
1914
+ $settings['config']['mobile_width'] = absint( $_POST['_envira_gallery']['mobile_width'] );
1915
+ $settings['config']['mobile_height'] = absint( $_POST['_envira_gallery']['mobile_height'] );
1916
+ $settings['config']['mobile_lightbox'] = isset( $_POST['_envira_gallery']['mobile_lightbox'] ) ? 1 : 0;
1917
+ $settings['config']['mobile_touchwipe'] = isset( $_POST['_envira_gallery']['mobile_touchwipe'] ) ? 1 : 0;
1918
+ $settings['config']['mobile_touchwipe_close'] = isset( $_POST['_envira_gallery']['mobile_touchwipe_close'] ) ? 1 : 0;
1919
+ $settings['config']['mobile_arrows'] = isset( $_POST['_envira_gallery']['mobile_arrows'] ) ? 1 : 0;
1920
+ $settings['config']['mobile_toolbar'] = isset( $_POST['_envira_gallery']['mobile_toolbar'] ) ? 1 : 0;
1921
+ $settings['config']['mobile_thumbnails'] = isset( $_POST['_envira_gallery']['mobile_thumbnails'] ) ? 1 : 0;
1922
+ }
1923
+
1924
  // Misc
1925
  $settings['config']['classes'] = explode( "\n", $_POST['_envira_gallery']['classes'] );
1926
  $settings['config']['rtl'] = isset( $_POST['_envira_gallery']['rtl'] ) ? 1 : 0;
1946
  // Change states of images in gallery from pending to active.
1947
  $this->change_gallery_states( $post_id );
1948
 
1949
+ // If the thumbnails option is checked, crop images accordingly.
1950
+ if ( isset( $settings['config']['thumbnails'] ) && $settings['config']['thumbnails'] ) {
1951
+ $args = array(
1952
+ 'position' => 'c',
1953
+ 'width' => $this->get_config( 'thumbnails_width', $this->get_config_default( 'thumbnails_width' ) ),
1954
+ 'height' => $this->get_config( 'thumbnails_height', $this->get_config_default( 'thumbnails_height' ) ),
1955
+ 'quality' => 100,
1956
+ 'retina' => false
1957
+ );
1958
+ $args = apply_filters( 'envira_gallery_crop_image_args', $args );
1959
+ $this->crop_thumbnails( $args, $post_id );
1960
+ }
1961
+
1962
  // If the crop option is checked, crop images accordingly.
1963
  if ( isset( $settings['config']['crop'] ) && $settings['config']['crop'] ) {
1964
  $args = array(
1972
  $this->crop_images( $args, $post_id );
1973
  }
1974
 
1975
+ // If the mobile option is checked, crop images accordingly.
1976
+ if ( isset( $settings['config']['mobile'] ) && $settings['config']['mobile'] ) {
1977
+ $args = array(
1978
+ 'position' => 'c',
1979
+ 'width' => $this->get_config( 'mobile_width', $this->get_config_default( 'mobile_width' ) ),
1980
+ 'height' => $this->get_config( 'mobile_height', $this->get_config_default( 'mobile_height' ) ),
1981
+ 'quality' => 100,
1982
+ 'retina' => false
1983
+ );
1984
+ $args = apply_filters( 'envira_gallery_crop_image_args', $args );
1985
+ $this->crop_images( $args, $post_id );
1986
+ }
1987
+
1988
  // Fire a hook for addons that need to utilize the cropping feature.
1989
  do_action( 'envira_gallery_saved_settings', $settings, $post_id, $post );
1990
 
2334
  *
2335
  * @since 1.3.6
2336
  *
2337
+ * @param bool $wordpress_only WordPress Only image sizes (default: false)
2338
  * @return array Array of image size data.
2339
  */
2340
+ public function get_image_sizes( $wordpress_only = false ) {
2341
 
2342
  $instance = Envira_Gallery_Common::get_instance();
2343
+ return $instance->get_image_sizes( $wordpress_only );
2344
 
2345
  }
2346
 
includes/admin/partials/header.php CHANGED
@@ -8,6 +8,7 @@
8
  * @author David Bisset, Tim Carr
9
  */
10
  ?>
 
11
  <div id="envira-header" class="envira-header">
12
  <h1 class="envira-logo" id="envira-logo">
13
  <img src="<?php echo $data['logo']; ?>" alt="<?php _e( 'Envira Gallery', 'envira-gallery' ); ?>" width="339" height="26" />
8
  * @author David Bisset, Tim Carr
9
  */
10
  ?>
11
+ <div id="envira-header-temp"></div>
12
  <div id="envira-header" class="envira-header">
13
  <h1 class="envira-logo" id="envira-logo">
14
  <img src="<?php echo $data['logo']; ?>" alt="<?php _e( 'Envira Gallery', 'envira-gallery' ); ?>" width="339" height="26" />
includes/admin/partials/metabox-gallery-type.php CHANGED
@@ -29,7 +29,7 @@
29
 
30
  <!-- WP Media Upload Form -->
31
  <?php
32
- media_upload_form();
33
  ?>
34
  <script type="text/javascript">
35
  var post_id = <?php echo $data['post']->ID; ?>, shortform = 3;
@@ -40,15 +40,48 @@
40
  <!-- External Gallery -->
41
  <div id="envira-gallery-external" class="envira-tab envira-clear<?php echo ( ( $data['instance']->get_config( 'type', $data['instance']->get_config_default( 'type' ) ) != 'default' ) ? ' envira-active' : '' ); ?>">
42
  <?php
43
- Envira_Gallery_Notice_Admin::get_instance()->display_inline_notice(
44
- 'envira_gallery_external',
45
- __( 'Want to display Instagram or Post Images?', 'envira-gallery' ),
46
- __( 'By upgrading to Envira Pro, you can build Galleries based on Instagram images and/or Post images.', 'envira-gallery' ),
47
- 'warning',
48
- 'Click here to Upgrade',
49
- 'http://enviragallery.com/lite/?utm_source=liteplugin&utm_medium=link&utm_campaign=WordPress',
50
- false
51
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  ?>
53
  </div>
54
  </div>
29
 
30
  <!-- WP Media Upload Form -->
31
  <?php
32
+ media_upload_form();
33
  ?>
34
  <script type="text/javascript">
35
  var post_id = <?php echo $data['post']->ID; ?>, shortform = 3;
40
  <!-- External Gallery -->
41
  <div id="envira-gallery-external" class="envira-tab envira-clear<?php echo ( ( $data['instance']->get_config( 'type', $data['instance']->get_config_default( 'type' ) ) != 'default' ) ? ' envira-active' : '' ); ?>">
42
  <?php
43
+ if ( count( $data['types'] ) > 1 ) {
44
+ ?>
45
+ <p class="envira-intro"><?php _e( 'Select Your Service', 'envira-gallery' ); ?></p>
46
+ <ul id="envira-gallery-types-nav">
47
+ <?php
48
+ foreach ( $data['types'] as $id => $title ) {
49
+ // Don't output the default type as an option here
50
+ if ( 'default' == $id ) {
51
+ continue;
52
+ }
53
+
54
+ // Output the type as a radio option
55
+ ?>
56
+ <li id="envira-gallery-type-<?php echo sanitize_html_class( $id ); ?>"<?php echo ( ( $data['instance']->get_config( 'type', $data['instance']->get_config_default( 'type' ) ) == $id ) ? ' class="envira-active"' : '' ); ?>>
57
+ <label for="envira-gallery-type-<?php echo $id; ?>">
58
+ <input id="envira-gallery-type-<?php echo sanitize_html_class( $id ); ?>" type="radio" name="_envira_gallery[type]" value="<?php echo $id; ?>" <?php checked( $data['instance']->get_config( 'type', $data['instance']->get_config_default( 'type' ) ), $id ); ?> />
59
+ <div class="icon"></div>
60
+ <div class="title"><?php echo $title; ?></div>
61
+ </label>
62
+ </li>
63
+ <?php
64
+ }
65
+ ?>
66
+ </ul>
67
+ <?php
68
+ } else {
69
+ if ( class_exists( 'Envira_Gallery_Lite' ) ) {
70
+ Envira_Gallery_Notice_Admin::get_instance()->display_inline_notice(
71
+ 'envira_gallery_external',
72
+ __( 'Want to display Instagram or Post Images?', 'envira-gallery' ),
73
+ __( 'By upgrading to Envira Pro, you can build Galleries based on Instagram images and/or Post images.', 'envira-gallery' ),
74
+ 'warning',
75
+ __( 'Click here to Upgrade', 'envira-gallery' ),
76
+ Envira_Gallery_Common_Admin::get_instance()->get_upgrade_link(),
77
+ false
78
+ );
79
+ } else {
80
+ ?>
81
+ <p><?php _e( 'It doesn\'t look like you have any Addons activated which import images from external sources.', 'envira-gallery' ); ?></p>
82
+ <?php
83
+ }
84
+ }
85
  ?>
86
  </div>
87
  </div>
includes/admin/posttype.php CHANGED
@@ -44,7 +44,7 @@ class Envira_Gallery_Posttype_Admin {
44
  public function __construct() {
45
 
46
  // Load the base class object.
47
- $this->base = Envira_Gallery_Lite::get_instance();
48
  $this->metabox = Envira_Gallery_Metaboxes::get_instance();
49
 
50
  // Update post type messages.
@@ -54,7 +54,7 @@ class Envira_Gallery_Posttype_Admin {
54
  add_action( 'admin_head', array( $this, 'menu_icon' ) );
55
 
56
  // Add the Universal Header.
57
- add_action( 'all_admin_notices', array( $this, 'admin_header' ) );
58
 
59
  }
60
 
44
  public function __construct() {
45
 
46
  // Load the base class object.
47
+ $this->base = ( class_exists( 'Envira_Gallery' ) ? Envira_Gallery::get_instance() : Envira_Gallery_Lite::get_instance() );
48
  $this->metabox = Envira_Gallery_Metaboxes::get_instance();
49
 
50
  // Update post type messages.
54
  add_action( 'admin_head', array( $this, 'menu_icon' ) );
55
 
56
  // Add the Universal Header.
57
+ add_action( 'in_admin_header', array( $this, 'admin_header' ), 100 );
58
 
59
  }
60
 
includes/admin/settings.php CHANGED
@@ -52,6 +52,234 @@ class Envira_Gallery_Settings {
52
  */
53
  public function __construct() {
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  }
56
 
57
  /**
@@ -122,6 +350,323 @@ class Envira_Gallery_Settings {
122
 
123
  }
124
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  /**
126
  * Returns the singleton instance of the class.
127
  *
52
  */
53
  public function __construct() {
54
 
55
+ // Load the base class object.
56
+ $this->base = ( class_exists( 'Envira_Gallery' ) ? Envira_Gallery::get_instance() : Envira_Gallery_Lite::get_instance() );
57
+
58
+ // Only load the Settings submenu item and admin page if we're running Envira Gallery, and not Envira Gallery Lite.
59
+ if ( class_exists( 'Envira_Gallery' ) ) {
60
+ // Add custom settings submenu.
61
+ add_action( 'admin_menu', array( $this, 'admin_menu' ), 11 );
62
+
63
+ // Add callbacks for settings tabs.
64
+ add_action( 'envira_gallery_tab_settings_general', array( $this, 'settings_general_tab' ) );
65
+
66
+ // Add the settings menu item to the Plugins table.
67
+ add_filter( 'plugin_action_links_' . plugin_basename( plugin_dir_path( dirname( dirname( __FILE__ ) ) ) . 'envira-gallery.php' ), array( $this, 'settings_link' ) );
68
+ }
69
+
70
+ }
71
+
72
+ /**
73
+ * Register the Settings submenu item for Envira.
74
+ *
75
+ * @since 1.0.0
76
+ */
77
+ public function admin_menu() {
78
+
79
+ // Register the submenu.
80
+ $this->hook = add_submenu_page(
81
+ 'edit.php?post_type=envira',
82
+ __( 'Envira Gallery Settings', 'envira-gallery' ),
83
+ __( 'Settings', 'envira-gallery' ),
84
+ apply_filters( 'envira_gallery_menu_cap', 'manage_options' ),
85
+ $this->base->plugin_slug . '-settings',
86
+ array( $this, 'settings_page' )
87
+ );
88
+
89
+ // If successful, load admin assets only on that page and check for addons refresh.
90
+ if ( $this->hook ) {
91
+ add_action( 'load-' . $this->hook, array( $this, 'maybe_fix_migration' ) );
92
+ add_action( 'load-' . $this->hook, array( $this, 'update_image_settings' ) );
93
+ add_action( 'load-' . $this->hook, array( $this, 'settings_page_assets' ) );
94
+ }
95
+
96
+ }
97
+
98
+ /**
99
+ * Maybe fixes the broken migration.
100
+ *
101
+ * @since 1.3.1.6
102
+ *
103
+ * @return null Return early if not fixing the broken migration
104
+ */
105
+ public function maybe_fix_migration() {
106
+
107
+ // Check if user pressed 'Fix' button and nonce is valid
108
+ if ( ! isset( $_POST['envira-serialization-submit'] ) ) {
109
+ return;
110
+ }
111
+ if ( ! wp_verify_nonce( $_POST['envira-serialization-nonce'], 'envira-serialization-nonce' ) ) {
112
+ return;
113
+ }
114
+
115
+ // If here, fix potentially broken migration
116
+ // Get WPDB and serialization class
117
+ global $wpdb, $fixedGalleries;
118
+ require plugin_dir_path( __FILE__ ) . 'serialization.php';
119
+ $instance = Envira_Serialization_Admin::get_instance();
120
+
121
+ // Keep count of the number of galleries that get fixed
122
+ $fixedGalleries = 0;
123
+
124
+ // Query to get all Envira CPTs
125
+ $galleries = new WP_Query( array (
126
+ 'post_type' => 'envira',
127
+ 'post_status' => 'any',
128
+ 'posts_per_page'=> -1,
129
+ ) );
130
+
131
+ // Iterate through galleries
132
+ if ( $galleries->posts ) {
133
+ foreach ( $galleries->posts as $gallery ) {
134
+
135
+ $fixed = false;
136
+
137
+ // Attempt to get gallery data
138
+ $gallery_data = get_post_meta( $gallery->ID, '_eg_gallery_data', true );
139
+
140
+ // Skip empty galleries
141
+ if ( empty( $gallery_data ) ) {
142
+ continue;
143
+ }
144
+
145
+ // If gallery data isn't an array, something broke
146
+ if ( ! is_array( $gallery_data ) ) {
147
+ // Need to fix the broken serialized string for this gallery
148
+ // Get raw string from DB
149
+ $query = $wpdb->prepare( " SELECT meta_value
150
+ FROM ".$wpdb->prefix."postmeta
151
+ WHERE post_id = %d
152
+ AND meta_key = %s
153
+ LIMIT 1",
154
+ $gallery->ID,
155
+ '_eg_gallery_data' );
156
+ $raw_gallery_data = $wpdb->get_row( $query );
157
+
158
+ // Do the fix, which returns an unserialized array
159
+ $gallery_data = $instance->fix_serialized_string( $raw_gallery_data->meta_value );
160
+
161
+ // Check we now have an array of unserialized data
162
+ if ( ! is_array ( $gallery_data ) ) {
163
+ continue;
164
+ }
165
+
166
+ // Mark as fixed
167
+ $fixed = true;
168
+ }
169
+
170
+ // Next, check each gallery image has a valid URL
171
+ // Some migrations seem to strip the leading HTTP URL, which causes us problems with thumbnail generation.
172
+ if ( isset( $gallery_data['gallery'] ) ) {
173
+ foreach ( $gallery_data['gallery'] as $id => $item ) {
174
+ // Source
175
+ if ( isset( $item['src'] ) ) {
176
+ if ( ! empty( $item['src'] ) && ! filter_var( $item['src'], FILTER_VALIDATE_URL ) ) {
177
+ // Image isn't a valid URL - fix
178
+ $gallery_data['gallery'][ $id ]['src'] = get_bloginfo( 'url' ) . '/' . $item['src'];
179
+ $fixed = true;
180
+ }
181
+ }
182
+
183
+ // Link
184
+ if ( isset( $item['link'] ) ) {
185
+ if ( ! empty( $item['link'] ) && ! filter_var( $item['link'], FILTER_VALIDATE_URL ) ) {
186
+ // Image isn't a valid URL - fix
187
+ $gallery_data['gallery'][ $id ]['link'] = get_bloginfo( 'url' ) . '/' . $item['link'];
188
+ $fixed = true;
189
+ }
190
+ }
191
+
192
+ // Thumbnail
193
+ if ( isset( $item['thumb'] ) ) {
194
+ if ( ! empty( $item['thumb'] ) && ! filter_var( $item['thumb'], FILTER_VALIDATE_URL ) ) {
195
+ // Thumbnail isn't a valid URL - fix
196
+ $gallery_data['gallery'][ $id ]['thumb'] = get_bloginfo( 'url' ) . '/' . $item['thumb'];
197
+ $fixed = true;
198
+ }
199
+ }
200
+ }
201
+ }
202
+
203
+ // Finally, store the post meta if a fix was applied
204
+ if ( $fixed ) {
205
+ update_post_meta( $gallery->ID, '_eg_gallery_data', $gallery_data );
206
+ $fixedGalleries++;
207
+ }
208
+
209
+ }
210
+ }
211
+
212
+ // Output an admin notice so the user knows what happened
213
+ add_action( 'envira_gallery_settings_general_tab_notice', array( $this, 'fixed_migration' ) );
214
+
215
+ }
216
+
217
+ /**
218
+ * Outputs a WordPress style notification to tell the user how many galleries were
219
+ * fixed after running the migration fixer
220
+ *
221
+ * @since 1.3.1.6
222
+ */
223
+ public function fixed_migration() {
224
+ global $fixedGalleries;
225
+
226
+ ?>
227
+ <div class="notice updated below-h2">
228
+ <p><strong><?php echo $fixedGalleries . __( ' galleries(s) fixed successfully.', 'envira-gallery' ); ?></strong></p>
229
+ </div>
230
+ <?php
231
+
232
+ }
233
+
234
+ /**
235
+ * Saves images Settings:
236
+ * - Add New Images
237
+ * - Delete Images on Gallery Deletion
238
+ *
239
+ * @since 1.3.3.6
240
+ *
241
+ * @return null Return early if not fixing the broken migration
242
+ */
243
+ public function update_image_settings() {
244
+
245
+ // Check if user pressed the 'Update' button and nonce is valid
246
+ if ( ! isset( $_POST['envira-gallery-settings-submit'] ) ) {
247
+ return;
248
+ }
249
+ if ( ! wp_verify_nonce( $_POST['envira-gallery-settings-nonce'], 'envira-gallery-settings-nonce' ) ) {
250
+ return;
251
+ }
252
+
253
+ // Update settings
254
+ $this->update_setting( 'media_position', $_POST['envira_media_position'] );
255
+ $this->update_setting( 'image_delete', $_POST['envira_image_delete'] );
256
+ $this->update_setting( 'media_delete', $_POST['envira_media_delete'] );
257
+
258
+ // Output an admin notice so the user knows what happened
259
+ add_action( 'envira_gallery_settings_general_tab_notice', array( $this, 'updated_settings' ) );
260
+
261
+ }
262
+
263
+ /**
264
+ * Helper method for updating a setting's value.
265
+ *
266
+ * @since 1.3.3.6
267
+ *
268
+ * @param string $key The setting key
269
+ * @param string $value The value to set for the key
270
+ * @return null
271
+ */
272
+ public function update_setting( $key, $value ) {
273
+
274
+ // Prefix the key
275
+ $key = 'envira_gallery_' . $key;
276
+
277
+ // Allow devs to filter
278
+ $value = apply_filters( 'envira_gallery_get_setting', $value, $key );
279
+
280
+ // Update option
281
+ update_option( $key, $value );
282
+
283
  }
284
 
285
  /**
350
 
351
  }
352
 
353
+ /**
354
+ * Outputs a WordPress style notification to tell the user settings were saved
355
+ *
356
+ * @since 1.3.3.6
357
+ */
358
+ public function updated_settings() {
359
+
360
+ ?>
361
+ <div class="notice updated below-h2">
362
+ <p><strong><?php _e( 'Settings saved successfully.', 'envira-gallery' ); ?></strong></p>
363
+ </div>
364
+ <?php
365
+
366
+ }
367
+
368
+ /**
369
+ * Loads assets for the settings page.
370
+ *
371
+ * @since 1.0.0
372
+ */
373
+ public function settings_page_assets() {
374
+
375
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_styles' ) );
376
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
377
+
378
+ }
379
+
380
+ /**
381
+ * Register and enqueue settings page specific CSS.
382
+ *
383
+ * @since 1.0.0
384
+ */
385
+ public function enqueue_admin_styles() {
386
+
387
+ wp_register_style( $this->base->plugin_slug . '-settings-style', plugins_url( 'assets/css/settings.css', $this->base->file ), array(), $this->base->version );
388
+ wp_enqueue_style( $this->base->plugin_slug . '-settings-style' );
389
+
390
+ // Run a hook to load in custom styles.
391
+ do_action( 'envira_gallery_settings_styles' );
392
+
393
+ }
394
+
395
+ /**
396
+ * Register and enqueue settings page specific JS.
397
+ *
398
+ * @since 1.0.0
399
+ */
400
+ public function enqueue_admin_scripts() {
401
+
402
+ // Tabs
403
+ wp_register_script( $this->base->plugin_slug . '-tabs-script', plugins_url( 'assets/js/tabs.js', $this->base->file ), array( 'jquery' ), $this->base->version, true );
404
+ wp_enqueue_script( $this->base->plugin_slug . '-tabs-script' );
405
+
406
+ // Settings
407
+ wp_register_script( $this->base->plugin_slug . '-settings-script', plugins_url( 'assets/js/settings.js', $this->base->file ), array( 'jquery', 'jquery-ui-tabs' ), $this->base->version, true );
408
+ wp_enqueue_script( $this->base->plugin_slug . '-settings-script' );
409
+ wp_localize_script(
410
+ $this->base->plugin_slug . '-settings-script',
411
+ 'envira_gallery_settings',
412
+ array(
413
+ 'active' => __( 'Status: Active', 'envira-gallery' ),
414
+ 'activate' => __( 'Activate', 'envira-gallery' ),
415
+ 'activate_nonce' => wp_create_nonce( 'envira-gallery-activate' ),
416
+ 'activating' => __( 'Activating...', 'envira-gallery' ),
417
+ 'ajax' => admin_url( 'admin-ajax.php' ),
418
+ 'deactivate' => __( 'Deactivate', 'envira-gallery' ),
419
+ 'deactivate_nonce' => wp_create_nonce( 'envira-gallery-deactivate' ),
420
+ 'deactivating' => __( 'Deactivating...', 'envira-gallery' ),
421
+ 'inactive' => __( 'Status: Inactive', 'envira-gallery' ),
422
+ 'install' => __( 'Install', 'envira-gallery' ),
423
+ 'install_nonce' => wp_create_nonce( 'envira-gallery-install' ),
424
+ 'installing' => __( 'Installing...', 'envira-gallery' ),
425
+ 'proceed' => __( 'Proceed', 'envira-gallery' )
426
+ )
427
+ );
428
+
429
+ // Run a hook to load in custom scripts.
430
+ do_action( 'envira_gallery_settings_scripts' );
431
+
432
+ }
433
+
434
+ /**
435
+ * Callback to output the Envira settings page.
436
+ *
437
+ * @since 1.0.0
438
+ */
439
+ public function settings_page() {
440
+
441
+ do_action('envira_head');
442
+
443
+ ?>
444
+
445
+ <!-- Tabs -->
446
+ <h1 id="envira-tabs-nav" class="envira-tabs-nav" data-container="#envira-gallery-settings" data-update-hashbang="1">
447
+ <?php
448
+ $i = 0;
449
+ foreach ( (array) $this->get_envira_settings_tab_nav() as $id => $title ) {
450
+ $class = ( 0 === $i ? 'envira-active' : '' );
451
+ ?>
452
+ <a class="nav-tab <?php echo $class; ?>" href="#envira-tab-<?php echo $id; ?>" title="<?php echo $title; ?>"><?php echo $title; ?></a>
453
+ <?php
454
+ $i++;
455
+ }
456
+ ?>
457
+ </h1>
458
+
459
+ <!-- Tab Panels -->
460
+ <div id="envira-gallery-settings" class="wrap">
461
+ <h1 class="envira-hideme"></h1>
462
+ <div class="envira-gallery envira-clear">
463
+ <div id="envira-tabs" class="envira-clear" data-navigation="#envira-tabs-nav">
464
+ <?php
465
+ $i = 0;
466
+ foreach ( (array) $this->get_envira_settings_tab_nav() as $id => $title ) {
467
+ $class = ( 0 === $i ? 'envira-active' : '' );
468
+ ?>
469
+ <div id="envira-tab-<?php echo $id; ?>" class="envira-tab envira-clear <?php echo $class; ?>">
470
+ <?php do_action( 'envira_gallery_tab_settings_' . $id ); ?>
471
+ </div>
472
+ <?php
473
+ $i++;
474
+ }
475
+ ?>
476
+ </div>
477
+ </div>
478
+ </div>
479
+
480
+ <?php
481
+
482
+ }
483
+
484
+ /**
485
+ * Callback for getting all of the settings tabs for Envira.
486
+ *
487
+ * @since 1.0.0
488
+ *
489
+ * @return array Array of tab information.
490
+ */
491
+ public function get_envira_settings_tab_nav() {
492
+
493
+ $tabs = array(
494
+ 'general' => __( 'General', 'envira-gallery' ), // This tab is required. DO NOT REMOVE VIA FILTERING.
495
+ );
496
+ $tabs = apply_filters( 'envira_gallery_settings_tab_nav', $tabs );
497
+
498
+ return $tabs;
499
+
500
+ }
501
+
502
+ /**
503
+ * Callback for displaying the UI for general settings tab.
504
+ *
505
+ * @since 1.0.0
506
+ */
507
+ public function settings_general_tab() {
508
+
509
+ // Get settings
510
+ $media_position = $this->get_setting( 'media_position' );
511
+ $image_delete = $this->get_setting( 'image_delete' );
512
+ $media_delete = $this->get_setting( 'media_delete' );
513
+ ?>
514
+ <div id="envira-settings-general">
515
+ <?php
516
+ // Output any notices now
517
+ do_action( 'envira_gallery_settings_general_tab_notice' );
518
+ ?>
519
+
520
+ <table class="form-table">
521
+ <tbody>
522
+ <tr id="envira-settings-key-box">
523
+ <th scope="row">
524
+ <label for="envira-settings-key"><?php _e( 'Envira License Key', 'envira-gallery' ); ?></label>
525
+ </th>
526
+ <td>
527
+ <form id="envira-settings-verify-key" method="post">
528
+ <input type="password" name="envira-license-key" id="envira-settings-key" value="<?php echo ( $this->base->get_license_key() ? $this->base->get_license_key() : '' ); ?>" />
529
+ <?php wp_nonce_field( 'envira-gallery-key-nonce', 'envira-gallery-key-nonce' ); ?>
530
+ <?php submit_button( __( 'Verify Key', 'envira-gallery' ), 'primary', 'envira-gallery-verify-submit', false ); ?>
531
+ <?php submit_button( __( 'Deactivate Key', 'envira-gallery' ), 'secondary', 'envira-gallery-deactivate-submit', false ); ?>
532
+ <p class="description"><?php _e( 'License key to enable automatic updates for Envira.', 'envira-gallery' ); ?></p>
533
+ </form>
534
+ </td>
535
+ </tr>
536
+ <?php $type = $this->base->get_license_key_type(); if ( ! empty( $type ) ) : ?>
537
+ <tr id="envira-settings-key-type-box">
538
+ <th scope="row">
539
+ <label for="envira-settings-key-type"><?php _e( 'Envira License Key Type', 'envira-gallery' ); ?></label>
540
+ </th>
541
+ <td>
542
+ <form id="envira-settings-key-type" method="post">
543
+ <span class="envira-license-type"><?php printf( __( 'Your license key type for this site is <strong>%s.</strong>', 'envira-gallery' ), $this->base->get_license_key_type() ); ?>
544
+ <input type="hidden" name="envira-license-key" value="<?php echo $this->base->get_license_key(); ?>" />
545
+ <?php wp_nonce_field( 'envira-gallery-key-nonce', 'envira-gallery-key-nonce' ); ?>
546
+ <?php submit_button( __( 'Refresh Key', 'envira-gallery' ), 'primary', 'envira-gallery-refresh-submit', false ); ?>
547
+ <p class="description"><?php _e( 'Your license key type (handles updates and Addons). Click refresh if your license has been upgraded or the type is incorrect.', 'envira-gallery' ); ?></p>
548
+ </form>
549
+ </td>
550
+ </tr>
551
+ <?php endif; ?>
552
+
553
+ <!-- Fix Broken Migration -->
554
+ <tr id="envira-serialization-box">
555
+ <th scope="row">
556
+ <label for="envira-serialization"><?php _e( 'Fix Broken Migration', 'envira-gallery' ); ?></label>
557
+ </th>
558
+ <td>
559
+ <form id="envira-serialization" method="post">
560
+ <?php wp_nonce_field( 'envira-serialization-nonce', 'envira-serialization-nonce' ); ?>
561
+ <?php submit_button( __( 'Fix', 'envira-gallery' ), 'primary', 'envira-serialization-submit', false ); ?>
562
+ <p class="description"><?php _e( 'If you have changed the URL of your WordPress web site, and manually executed a search/replace query on URLs in your WordPress database, your galleries will probably no longer show any images. If this is the case, click the button above to fix this. We recommend using a migration plugin or script next time :)', 'envira-gallery' ); ?></p>
563
+ </form>
564
+ </td>
565
+ </tr>
566
+ </tbody>
567
+ </table>
568
+
569
+ <!-- <hr /> -->
570
+
571
+ <!-- Settings Form -->
572
+ <form id="envira-media-delete" method="post">
573
+ <table class="form-table">
574
+ <tbody>
575
+ <!-- Media Position -->
576
+ <tr id="envira-media-position-box">
577
+ <th scope="row">
578
+ <label for="envira-media-position"><?php _e( 'Add New Images', 'envira-gallery' ); ?></label>
579
+ </th>
580
+ <td>
581
+ <select id="envira-media-position" name="envira_media_position">
582
+ <?php foreach ( (array) Envira_Gallery_Common::get_instance()->get_media_positions() as $i => $data ) : ?>
583
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $media_position ); ?>><?php echo $data['name']; ?></option>
584
+ <?php endforeach; ?>
585
+ </select>
586
+ <p class="description"><?php _e( 'When adding media to a Gallery, choose whether to add this media before or after any existing images.', 'envira-gallery' ); ?></p>
587
+ </td>
588
+ </tr>
589
+
590
+ <!-- Delete Media -->
591
+ <tr id="envira-image-delete-box">
592
+ <th scope="row">
593
+ <label for="envira-image-delete"><?php _e( 'Delete Image on Gallery Image Deletion', 'envira-gallery' ); ?></label>
594
+ </th>
595
+ <td>
596
+ <select id="envira-image-delete" name="envira_image_delete">
597
+ <?php foreach ( (array) Envira_Gallery_Common::get_instance()->get_media_delete_options() as $i => $data ) : ?>
598
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $image_delete ); ?>><?php echo $data['name']; ?></option>
599
+ <?php endforeach; ?>
600
+ </select>
601
+ <p class="description"><?php _e( 'When deleting an Image from a Gallery, choose whether to delete all media associated with that image. Note: If image(s) in the Media Library are attached to other Posts, they will not be deleted.', 'envira-gallery' ); ?></p>
602
+ </td>
603
+ </tr>
604
+
605
+ <tr id="envira-media-delete-box">
606
+ <th scope="row">
607
+ <label for="envira-media-delete"><?php _e( 'Delete Images on Gallery Deletion', 'envira-gallery' ); ?></label>
608
+ </th>
609
+ <td>
610
+ <select id="envira-media-delete" name="envira_media_delete">
611
+ <?php foreach ( (array) Envira_Gallery_Common::get_instance()->get_media_delete_options() as $i => $data ) : ?>
612
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $media_delete ); ?>><?php echo $data['name']; ?></option>
613
+ <?php endforeach; ?>
614
+ </select>
615
+ <p class="description"><?php _e( 'When deleting a Gallery, choose whether to delete all media associated with the gallery. Note: If image(s) in the Media Library are attached to other Posts, they will not be deleted.', 'envira-gallery' ); ?></p>
616
+ </td>
617
+ </tr>
618
+
619
+ <?php do_action( 'envira_gallery_settings_general_box' ); ?>
620
+ </tbody>
621
+ </table>
622
+
623
+ <?php wp_nonce_field( 'envira-gallery-settings-nonce', 'envira-gallery-settings-nonce' ); ?>
624
+ <?php submit_button( __( 'Save Settings', 'envira-gallery' ), 'primary', 'envira-gallery-settings-submit', false ); ?>
625
+ </form>
626
+ </div>
627
+ <?php
628
+
629
+ }
630
+
631
+ /**
632
+ * Retrieve the plugin basename from the plugin slug.
633
+ *
634
+ * @since 1.0.0
635
+ *
636
+ * @param string $slug The plugin slug.
637
+ * @return string The plugin basename if found, else the plugin slug.
638
+ */
639
+ public function get_plugin_basename_from_slug( $slug ) {
640
+
641
+ $keys = array_keys( get_plugins() );
642
+
643
+ foreach ( $keys as $key ) {
644
+ if ( preg_match( '|^' . $slug . '|', $key ) ) {
645
+ return $key;
646
+ }
647
+ }
648
+
649
+ return $slug;
650
+
651
+ }
652
+
653
+ /**
654
+ * Add Settings page to plugin action links in the Plugins table.
655
+ *
656
+ * @since 1.0.0
657
+ *
658
+ * @param array $links Default plugin action links.
659
+ * @return array $links Amended plugin action links.
660
+ */
661
+ public function settings_link( $links ) {
662
+
663
+ $settings_link = sprintf( '<a href="%s">%s</a>', esc_url( add_query_arg( array( 'post_type' => 'envira', 'page' => 'envira-gallery-settings' ), admin_url( 'edit.php' ) ) ), __( 'Settings', 'envira-gallery' ) );
664
+ array_unshift( $links, $settings_link );
665
+
666
+ return $links;
667
+
668
+ }
669
+
670
  /**
671
  * Returns the singleton instance of the class.
672
  *
includes/admin/table.php CHANGED
@@ -53,7 +53,7 @@ class Envira_Gallery_Table_Admin {
53
  public function __construct() {
54
 
55
  // Load the base class object.
56
- $this->base = Envira_Gallery_Lite::get_instance();
57
 
58
  // Load the metabox class object.
59
  $this->metabox = Envira_Gallery_Metaboxes::get_instance();
@@ -66,6 +66,13 @@ class Envira_Gallery_Table_Admin {
66
  add_filter( 'manage_edit-envira_columns', array( &$this, 'envira_columns' ) );
67
  add_action( 'manage_envira_posts_custom_column', array( &$this, 'envira_custom_columns'), 10, 2 );
68
 
 
 
 
 
 
 
 
69
  }
70
 
71
  /**
@@ -125,6 +132,22 @@ class Envira_Gallery_Table_Admin {
125
  wp_register_script( $this->base->plugin_slug . '-clipboard-script', plugins_url( 'assets/js/min/clipboard-min.js', $this->base->file ), array( 'jquery' ), $this->base->version );
126
  wp_enqueue_script( $this->base->plugin_slug . '-clipboard-script' );
127
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  // Fire a hook to load in custom admin scripts.
129
  do_action( 'envira_gallery_admin_scripts' );
130
 
@@ -240,6 +263,233 @@ class Envira_Gallery_Table_Admin {
240
  }
241
 
242
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
 
244
  /**
245
  * Returns the singleton instance of the class.
53
  public function __construct() {
54
 
55
  // Load the base class object.
56
+ $this->base = ( class_exists( 'Envira_Gallery' ) ? Envira_Gallery::get_instance() : Envira_Gallery_Lite::get_instance() );
57
 
58
  // Load the metabox class object.
59
  $this->metabox = Envira_Gallery_Metaboxes::get_instance();
66
  add_filter( 'manage_edit-envira_columns', array( &$this, 'envira_columns' ) );
67
  add_action( 'manage_envira_posts_custom_column', array( &$this, 'envira_custom_columns'), 10, 2 );
68
 
69
+ // Only load Quick and Bulk Editing support if we're running Envira Gallery, and not Envira Gallery Lite.
70
+ if ( class_exists( 'Envira_Gallery' ) ) {
71
+ add_action( 'quick_edit_custom_box', array( $this, 'quick_edit_custom_box' ), 10, 2 ); // Single Item.
72
+ add_action( 'bulk_edit_custom_box', array( $this, 'bulk_edit_custom_box' ), 10, 2 ); // Multiple Items.
73
+ add_action( 'post_updated', array( $this, 'bulk_edit_save' ) );
74
+ }
75
+
76
  }
77
 
78
  /**
132
  wp_register_script( $this->base->plugin_slug . '-clipboard-script', plugins_url( 'assets/js/min/clipboard-min.js', $this->base->file ), array( 'jquery' ), $this->base->version );
133
  wp_enqueue_script( $this->base->plugin_slug . '-clipboard-script' );
134
 
135
+ // Gallery / Album Selection
136
+ // Just register and localize the script; if a third party Addon wants to use this, they can use both functions:
137
+ // wp_enqueue_media();
138
+ // wp_enqueue_script( 'envira-gallery-gallery-select-script' );
139
+ wp_register_script( $this->base->plugin_slug . '-gallery-select-script', plugins_url( 'assets/js/gallery-select.js', $this->base->file ), array( 'jquery' ), $this->base->version, true );
140
+ wp_localize_script( $this->base->plugin_slug . '-gallery-select-script', 'envira_gallery_select', array(
141
+ 'get_galleries_nonce' => wp_create_nonce( 'envira-gallery-editor-get-galleries' ),
142
+ 'modal_title' => __( 'Insert', 'envira-gallery' ),
143
+ 'insert_button_label' => __( 'Insert', 'envira-gallery' ),
144
+ ) );
145
+
146
+ if ( class_exists( 'Envira_Gallery' ) ) {
147
+ wp_register_script( $this->base->plugin_slug . '-table-script', plugins_url( 'assets/js/min/table-min.js', $this->base->file ), array( 'jquery' ), $this->base->version );
148
+ wp_enqueue_script( $this->base->plugin_slug . '-table-script' );
149
+ }
150
+
151
  // Fire a hook to load in custom admin scripts.
152
  do_action( 'envira_gallery_admin_scripts' );
153
 
263
  }
264
 
265
  }
266
+
267
+ /**
268
+ * Adds Envira fields to the quick editing and bulk editing screens
269
+ *
270
+ * @since 1.3.1
271
+ *
272
+ * @param string $column_name Column Name
273
+ * @param string $post_type Post Type
274
+ * @return HTML
275
+ */
276
+ public function quick_edit_custom_box( $column_name, $post_type ) {
277
+
278
+ // Check post type is Envira
279
+ if ( 'envira' !== $post_type ) {
280
+ return;
281
+ }
282
+
283
+ // Only apply to shortcode column
284
+ //if ( 'shortcode' !== $column_name ) {
285
+ // return;
286
+ //}
287
+
288
+ // Get metabox instance
289
+ $this->metabox = Envira_Gallery_Metaboxes::get_instance();
290
+
291
+ // Depending on the column we're on, output some additional fields.
292
+ switch ( $column_name ) {
293
+ case 'shortcode':
294
+ ?>
295
+ <fieldset class="inline-edit-col-left inline-edit-envira-gallery">
296
+ <div class="inline-edit-col inline-edit-<?php echo $column_name ?>">
297
+ <label class="inline-edit-group">
298
+ <span class="title"><?php _e( 'Number of Columns', 'envira-gallery'); ?></span>
299
+ <select name="_envira_gallery[columns]">
300
+ <?php foreach ( (array) $this->metabox->get_columns() as $i => $data ) : ?>
301
+ <option value="<?php echo $data['value']; ?>"><?php echo $data['name']; ?></option>
302
+ <?php endforeach; ?>
303
+ </select>
304
+ </label>
305
+
306
+ <label class="inline-edit-group">
307
+ <span class="title"><?php _e( 'Gallery Theme', 'envira-gallery'); ?></span>
308
+ <select name="_envira_gallery[gallery_theme]">
309
+ <?php foreach ( (array) $this->metabox->get_gallery_themes() as $i => $data ) : ?>
310
+ <option value="<?php echo $data['value']; ?>"><?php echo $data['name']; ?></option>
311
+ <?php endforeach; ?>
312
+ </select>
313
+ </label>
314
+
315
+ <label class="inline-edit-group">
316
+ <span class="title"><?php _e( 'Column Gutter Width', 'envira-gallery'); ?></span>
317
+ <input type="number" name="_envira_gallery[gutter]" value="" />
318
+ </label>
319
+
320
+ <label class="inline-edit-group">
321
+ <span class="title"><?php _e( 'Margin Below Each Image', 'envira-gallery'); ?></span>
322
+ <input type="number" name="_envira_gallery[margin]" value="" />
323
+ px
324
+ </label>
325
+
326
+ <label class="inline-edit-group">
327
+ <span class="title"><?php _e( 'Image Dimensions', 'envira-gallery'); ?></span>
328
+ <input type="number" name="_envira_gallery[crop_width]" value="" />
329
+ x
330
+ <input type="number" name="_envira_gallery[crop_height]" value="" />
331
+ px
332
+ </label>
333
+ </div>
334
+ </fieldset>
335
+ <?php
336
+ break;
337
+ }
338
+
339
+ wp_nonce_field( 'envira-gallery', 'envira-gallery' );
340
+
341
+ }
342
+
343
+ /**
344
+ * Adds Envira fields to the bulk editing screens
345
+ *
346
+ * @since 1.3.1
347
+ *
348
+ * @param string $column_name Column Name
349
+ * @param string $post_type Post Type
350
+ * @return HTML
351
+ */
352
+ public function bulk_edit_custom_box( $column_name, $post_type ) {
353
+
354
+ // Check post type is Envira
355
+ if ( 'envira' !== $post_type ) {
356
+ return;
357
+ }
358
+
359
+ // Only apply to shortcode column
360
+ if ( 'shortcode' !== $column_name ) {
361
+ return;
362
+ }
363
+
364
+ // Get metabox instance
365
+ $this->metabox = Envira_Gallery_Metaboxes::get_instance();
366
+
367
+ switch ( $column_name ) {
368
+ case 'shortcode':
369
+ ?>
370
+ <fieldset class="inline-edit-col-left inline-edit-envira-gallery">
371
+ <div class="inline-edit-col inline-edit-<?php echo $column_name ?>">
372
+ <label class="inline-edit-group">
373
+ <span class="title"><?php _e( 'Number of Columns', 'envira-gallery'); ?></span>
374
+ <select name="_envira_gallery[columns]">
375
+ <option value="-1" selected><?php _e( '— No Change —', 'envira-gallery' ); ?></option>
376
+
377
+ <?php foreach ( (array) $this->metabox->get_columns() as $i => $data ) : ?>
378
+ <option value="<?php echo $data['value']; ?>"><?php echo $data['name']; ?></option>
379
+ <?php endforeach; ?>
380
+ </select>
381
+ </label>
382
+
383
+ <label class="inline-edit-group">
384
+ <span class="title"><?php _e( 'Gallery Theme', 'envira-gallery'); ?></span>
385
+ <select name="_envira_gallery[gallery_theme]">
386
+ <option value="-1" selected><?php _e( '— No Change —', 'envira-gallery' ); ?></option>
387
+
388
+ <?php foreach ( (array) $this->metabox->get_gallery_themes() as $i => $data ) : ?>
389
+ <option value="<?php echo $data['value']; ?>"><?php echo $data['name']; ?></option>
390
+ <?php endforeach; ?>
391
+ </select>
392
+ </label>
393
+
394
+ <label class="inline-edit-group">
395
+ <span class="title"><?php _e( 'Column Gutter Width', 'envira-gallery'); ?></span>
396
+ <input type="number" name="_envira_gallery[gutter]" value="" placeholder="<?php _e( '— No Change —', 'envira-gallery' ); ?>" />
397
+ </label>
398
+
399
+ <label class="inline-edit-group">
400
+ <span class="title"><?php _e( 'Margin Below Each Image', 'envira-gallery'); ?></span>
401
+ <input type="number" name="_envira_gallery[margin]" value="" placeholder="<?php _e( '— No Change —', 'envira-gallery' ); ?>" />
402
+ </label>
403
+
404
+ <label class="inline-edit-group">
405
+ <span class="title"><?php _e( 'Image Dimensions', 'envira-gallery'); ?></span>
406
+ <input type="number" name="_envira_gallery[crop_width]" value="" placeholder="<?php _e( '— No Change —', 'envira-gallery' ); ?>" />
407
+ x
408
+ <input type="number" name="_envira_gallery[crop_height]" value="" placeholder="<?php _e( '— No Change —', 'envira-gallery' ); ?>" />
409
+ px
410
+ </label>
411
+ </div>
412
+ </fieldset>
413
+ <?php
414
+ break;
415
+ }
416
+
417
+ wp_nonce_field( 'envira-gallery', 'envira-gallery' );
418
+
419
+ }
420
+
421
+ /**
422
+ * Called every time a WordPress Post is updated
423
+ *
424
+ * Checks to see if the request came from submitting the Bulk Editor form,
425
+ * and if so applies the updates. This is because there is no direct action
426
+ * or filter fired for bulk saving
427
+ *
428
+ * @since 1.3.1
429
+ *
430
+ * @param int $post_ID Post ID
431
+ */
432
+ public function bulk_edit_save( $post_ID ) {
433
+
434
+ // Check we are performing a Bulk Edit
435
+ if ( !isset( $_REQUEST['bulk_edit'] ) ) {
436
+ return;
437
+ }
438
+
439
+ // Bail out if we fail a security check.
440
+ if ( ! isset( $_REQUEST['envira-gallery'] ) || ! wp_verify_nonce( $_REQUEST['envira-gallery'], 'envira-gallery' ) || ! isset( $_REQUEST['_envira_gallery'] ) ) {
441
+ return;
442
+ }
443
+
444
+ // Check Post IDs have been submitted
445
+ $post_ids = ( ! empty( $_REQUEST[ 'post' ] ) ) ? $_REQUEST[ 'post' ] : array();
446
+ if ( empty( $post_ids ) || !is_array( $post_ids ) ) {
447
+ return;
448
+ }
449
+
450
+ // Get metabox instance
451
+ $this->metabox = Envira_Gallery_Metaboxes::get_instance();
452
+
453
+ // Iterate through post IDs, updating settings
454
+ foreach ( $post_ids as $post_id ) {
455
+ // Get settings
456
+ $settings = get_post_meta( $post_id, '_eg_gallery_data', true );
457
+ if ( empty( $settings ) ) {
458
+ continue;
459
+ }
460
+
461
+ // Update Settings, if they have values
462
+ if ( ! empty( $_REQUEST['_envira_gallery']['columns'] ) && $_REQUEST['_envira_gallery']['columns'] != -1 ) {
463
+ $settings['config']['columns'] = preg_replace( '#[^a-z0-9-_]#', '', $_REQUEST['_envira_gallery']['columns'] );
464
+ }
465
+ if ( ! empty( $_REQUEST['_envira_gallery']['gallery_theme'] ) && $_REQUEST['_envira_gallery']['gallery_theme'] != -1 ) {
466
+ $settings['config']['gallery_theme'] = preg_replace( '#[^a-z0-9-_]#', '', $_REQUEST['_envira_gallery']['gallery_theme'] );
467
+ }
468
+ if ( ! empty( $_REQUEST['_envira_gallery']['gutter'] ) ) {
469
+ $settings['config']['gutter'] = absint( $_REQUEST['_envira_gallery']['gutter'] );
470
+ }
471
+ if ( ! empty( $_REQUEST['_envira_gallery']['margin'] ) ) {
472
+ $settings['config']['margin'] = absint( $_REQUEST['_envira_gallery']['margin'] );
473
+ }
474
+ if ( ! empty( $_REQUEST['_envira_gallery']['crop_width'] ) ) {
475
+ $settings['config']['crop_width'] = absint( $_REQUEST['_envira_gallery']['crop_width'] );
476
+ }
477
+ if ( ! empty( $_REQUEST['_envira_gallery']['crop_height'] ) ) {
478
+ $settings['config']['crop_height'] = absint( $_REQUEST['_envira_gallery']['crop_height'] );
479
+ }
480
+
481
+ // Provide a filter to override settings.
482
+ $settings = apply_filters( 'envira_gallery_bulk_edit_save_settings', $settings, $post_id );
483
+
484
+ // Update the post meta.
485
+ update_post_meta( $post_id, '_eg_gallery_data', $settings );
486
+
487
+ // Finally, flush all gallery caches to ensure everything is up to date.
488
+ $this->metabox->flush_gallery_caches( $post_id, $settings['config']['slug'] );
489
+
490
+ }
491
+
492
+ }
493
 
494
  /**
495
  * Returns the singleton instance of the class.
includes/global/common.php CHANGED
@@ -44,7 +44,7 @@ class Envira_Gallery_Common {
44
  public function __construct() {
45
 
46
  // Load the base class object.
47
- $this->base = Envira_Gallery_Lite::get_instance();
48
 
49
  }
50
 
@@ -240,16 +240,20 @@ class Envira_Gallery_Common {
240
  * @since 1.3.6
241
  *
242
  * @global array $_wp_additional_image_sizes Array of registered image sizes.
243
- * @return array Array of image size data.
 
 
244
  */
245
- public function get_image_sizes() {
246
-
247
- $sizes = array(
248
- array(
249
- 'value' => 'default',
250
- 'name' => __( 'Default', 'envira-gallery' ),
251
- )
252
- );
 
 
253
 
254
  global $_wp_additional_image_sizes;
255
  $wp_sizes = get_intermediate_image_sizes();
@@ -271,10 +275,20 @@ class Envira_Gallery_Common {
271
  $sizes[] = array(
272
  'value' => $size,
273
  'name' => ucwords( str_replace( array( '-', '_' ), ' ', $size ) ) . ' (' . $width . ' &#215; ' . $height . ')',
 
 
274
  );
275
  }
276
  }
277
 
 
 
 
 
 
 
 
 
278
  return apply_filters( 'envira_gallery_image_sizes', $sizes );
279
 
280
  }
@@ -553,6 +567,7 @@ class Envira_Gallery_Common {
553
  'random' => 0,
554
  'sorting_direction' => 'ASC',
555
  'image_size' => 'default', // Default = uses the below crop_width and crop_height
 
556
  'crop_width' => 640,
557
  'crop_height' => 480,
558
  'crop' => 0,
@@ -586,6 +601,7 @@ class Envira_Gallery_Common {
586
  'thumbnails_position' => 'bottom',
587
 
588
  // Mobile
 
589
  'mobile' => 1,
590
  'mobile_width' => 320,
591
  'mobile_height' => 240,
44
  public function __construct() {
45
 
46
  // Load the base class object.
47
+ $this->base = ( class_exists( 'Envira_Gallery' ) ? Envira_Gallery::get_instance() : Envira_Gallery_Lite::get_instance() );
48
 
49
  }
50
 
240
  * @since 1.3.6
241
  *
242
  * @global array $_wp_additional_image_sizes Array of registered image sizes.
243
+ *
244
+ * @param bool $wordpress_only WordPress Only (excludes the default and envira_gallery_random options)
245
+ * @return array Array of image size data.
246
  */
247
+ public function get_image_sizes( $wordpress_only = false ) {
248
+
249
+ if ( ! $wordpress_only ) {
250
+ $sizes = array(
251
+ array(
252
+ 'value' => 'default',
253
+ 'name' => __( 'Default', 'envira-gallery' ),
254
+ )
255
+ );
256
+ }
257
 
258
  global $_wp_additional_image_sizes;
259
  $wp_sizes = get_intermediate_image_sizes();
275
  $sizes[] = array(
276
  'value' => $size,
277
  'name' => ucwords( str_replace( array( '-', '_' ), ' ', $size ) ) . ' (' . $width . ' &#215; ' . $height . ')',
278
+ 'width' => $width,
279
+ 'height' => $height,
280
  );
281
  }
282
  }
283
 
284
+ // Add Random option
285
+ if ( ! $wordpress_only ) {
286
+ $sizes[] = array(
287
+ 'value' => 'envira_gallery_random',
288
+ 'name' => __( 'Random', 'envira-gallery' ),
289
+ );
290
+ }
291
+
292
  return apply_filters( 'envira_gallery_image_sizes', $sizes );
293
 
294
  }
567
  'random' => 0,
568
  'sorting_direction' => 'ASC',
569
  'image_size' => 'default', // Default = uses the below crop_width and crop_height
570
+ 'image_sizes_random' => array(),
571
  'crop_width' => 640,
572
  'crop_height' => 480,
573
  'crop' => 0,
601
  'thumbnails_position' => 'bottom',
602
 
603
  // Mobile
604
+ 'mobile_columns' => 1,
605
  'mobile' => 1,
606
  'mobile_width' => 320,
607
  'mobile_height' => 240,
includes/global/posttype.php CHANGED
@@ -44,7 +44,7 @@ class Envira_Gallery_Posttype {
44
  public function __construct() {
45
 
46
  // Load the base class object.
47
- $this->base = Envira_Gallery_Lite::get_instance();
48
 
49
  // Build the labels for the post type.
50
  $labels = array(
@@ -77,6 +77,34 @@ class Envira_Gallery_Posttype {
77
  'menu_icon' => plugins_url( 'assets/css/images/menu-icon@2x.png', $this->base->file ),
78
  'supports' => array( 'title' ),
79
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  $args = apply_filters( 'envira_gallery_post_type_args', $args );
81
 
82
  // Register the post type with WordPress.
44
  public function __construct() {
45
 
46
  // Load the base class object.
47
+ $this->base = ( class_exists( 'Envira_Gallery' ) ? Envira_Gallery::get_instance() : Envira_Gallery_Lite::get_instance() );
48
 
49
  // Build the labels for the post type.
50
  $labels = array(
77
  'menu_icon' => plugins_url( 'assets/css/images/menu-icon@2x.png', $this->base->file ),
78
  'supports' => array( 'title' ),
79
  );
80
+
81
+ // Define custom capaibilities if we're running Envira Gallery.
82
+ if ( class_exists( 'Envira_Gallery' ) ) {
83
+ $args['capaibilities'] = array(
84
+ // Meta caps
85
+ 'edit_post' => 'edit_envira_gallery',
86
+ 'read_post' => 'read_envira_gallery',
87
+ 'delete_post' => 'delete_envira_gallery',
88
+
89
+ // Primitive caps outside map_meta_cap()
90
+ 'edit_posts' => 'edit_envira_galleries',
91
+ 'edit_others_posts' => 'edit_other_envira_galleries',
92
+ 'publish_posts' => 'publish_envira_galleries',
93
+ 'read_private_posts' => 'read_private_envira_galleries',
94
+
95
+ // Primitive caps used within map_meta_cap()
96
+ 'read' => 'read',
97
+ 'delete_posts' => 'delete_envira_galleries',
98
+ 'delete_private_posts' => 'delete_private_envira_galleries',
99
+ 'delete_published_posts'=> 'delete_published_envira_galleries',
100
+ 'delete_others_posts' => 'delete_others_envira_galleries',
101
+ 'edit_private_posts' => 'edit_private_envira_galleries',
102
+ 'edit_published_posts' => 'edit_published_envira_galleries',
103
+ 'edit_posts' => 'create_envira_galleries',
104
+ );
105
+ }
106
+
107
+ // Filter arguments.
108
  $args = apply_filters( 'envira_gallery_post_type_args', $args );
109
 
110
  // Register the post type with WordPress.
includes/global/shortcode.php CHANGED
@@ -80,7 +80,7 @@ class Envira_Gallery_Shortcode {
80
  public function __construct() {
81
 
82
  // Load the base class object.
83
- $this->base = Envira_Gallery_Lite::get_instance();
84
 
85
  // Register main gallery style.
86
  wp_register_style( $this->base->plugin_slug . '-style', plugins_url( 'assets/css/envira.css', $this->base->file ), array(), $this->base->version );
@@ -184,7 +184,7 @@ class Envira_Gallery_Shortcode {
184
  $gallery = apply_filters( 'envira_gallery_output_start', $gallery, $data );
185
 
186
  // Build out the gallery HTML.
187
- $gallery .= '<div id="envira-gallery-wrap-' . sanitize_html_class( $data['id'] ) . '" class="' . $this->get_gallery_classes( $data ) . '">';
188
  $gallery = apply_filters( 'envira_gallery_output_before_container', $gallery, $data );
189
 
190
  // Description
@@ -261,7 +261,13 @@ class Envira_Gallery_Shortcode {
261
  }
262
 
263
  $item = apply_filters( 'envira_gallery_output_item_data', $item, $id, $data, $i );
 
 
 
264
  $imagesrc = $this->get_image_src( $id, $item, $data );
 
 
 
265
  $gallery = apply_filters( 'envira_gallery_output_before_item', $gallery, $id, $item, $data, $i );
266
 
267
  // Maybe change the item's link if it is an image and we have an image size defined for the Lightbox
@@ -274,23 +280,27 @@ class Envira_Gallery_Shortcode {
274
  $item['thumb'] = str_replace( $thumbnail_start_url, get_bloginfo( 'url' ) . '/', $item['thumb'] );
275
  }
276
 
277
- $output = '<div id="envira-gallery-item-' . sanitize_html_class( $id ) . '" class="' . $this->get_gallery_item_classes( $item, $i, $data ) . '" style="padding-left: ' . $padding . 'px; padding-bottom: ' . $this->get_config( 'margin', $data ) . 'px; padding-right: ' . $padding . 'px;" ' . apply_filters( 'envira_gallery_output_item_attr', '', $id, $item, $data, $i ) . '>';
278
 
279
  $output .= '<div class="envira-gallery-item-inner">';
280
  $output = apply_filters( 'envira_gallery_output_before_link', $output, $id, $item, $data, $i );
281
 
282
  // Caption
283
- // Envira Lite doesn't have the concept of a caption as such, so we use the Image Title.
284
- $caption = do_shortcode( str_replace( "\n", '<br />', esc_attr( $item['title'] ) ) );
 
 
 
 
285
 
286
  if ( ! empty( $item['link'] ) ) {
287
- $output .= '<a href="' . esc_url( $item['link'] ) . '" class="envira-gallery-' . sanitize_html_class( $data['id'] ) . ' envira-gallery-link" ' . $html5_attribute . '="enviragallery' . sanitize_html_class( $data['id'] ) . '" title="' . strip_tags( html_entity_decode( $item['title'] ) ) . '" data-envira-caption="' . $caption . '" data-thumbnail="' . esc_url( $item['thumb'] ) . '"' . ( ( isset($item['link_new_window']) && $item['link_new_window'] == 1 ) ? ' target="_blank"' : '' ) . ' ' . apply_filters( 'envira_gallery_output_link_attr', '', $id, $item, $data, $i ) . '>';
288
  }
289
 
290
  $output = apply_filters( 'envira_gallery_output_before_image', $output, $id, $item, $data, $i );
291
 
292
  // Build the image and allow filtering
293
- $output_item = '<img id="envira-gallery-image-' . sanitize_html_class( $id ) . '" class="envira-gallery-image envira-gallery-image-' . $i . '" data-envira-index="' . $i . '" src="' . esc_url( $imagesrc ) . '"' . ( $this->get_config( 'dimensions', $data ) ? ' width="' . $this->get_config( 'crop_width', $data ) . '" height="' . $this->get_config( 'crop_height', $data ) . '"' : '' ) . ' data-envira-src="' . esc_url( $imagesrc ) . '" data-envira-gallery-id="' . $data['id'] . '" data-envira-item-id="' . $id . '" alt="' . esc_attr( $item['alt'] ) . '" title="' . strip_tags( html_entity_decode( $item['title'] ) ) . '" ' . apply_filters( 'envira_gallery_output_image_attr', '', $id, $item, $data, $i ) . ' />';
294
  $output_item = apply_filters( 'envira_gallery_output_image', $output_item, $id, $item, $data, $i );
295
 
296
  // Add image to output
@@ -571,9 +581,15 @@ class Envira_Gallery_Shortcode {
571
  */
572
  public function gallery_init() {
573
 
 
 
 
574
  ?>
575
  <script type="text/javascript">
576
- var envira_galleries = [];
 
 
 
577
  jQuery(document).ready(function($){<?php ob_start();
578
  do_action( 'envira_gallery_api_start_global' );
579
  foreach ( $this->data as $data ) {
@@ -592,8 +608,9 @@ class Envira_Gallery_Shortcode {
592
  <?php
593
  // Isotope: Start
594
  if ( $this->get_config( 'isotope', $data ) ) {
 
595
  ?>
596
- envira_container_<?php echo $data['id']; ?> = $('#envira-gallery-<?php echo $data['id']; ?>').enviratope( {
597
  <?php do_action( 'envira_gallery_api_enviratope_config', $data ); ?>
598
  itemSelector: '.envira-gallery-item',
599
  <?php
@@ -610,12 +627,22 @@ class Envira_Gallery_Shortcode {
610
  <?php
611
  }
612
  ?>
613
- });
614
-
615
- // Reload again once all images have loaded, so everything is placed correctly
616
- envira_container_<?php echo $data['id']; ?>.imagesLoaded( function() {
617
- envira_container_<?php echo $data['id']; ?>.enviratope('layout');
618
- });
 
 
 
 
 
 
 
 
 
 
619
  <?php
620
  do_action( 'envira_gallery_api_enviratope', $data );
621
  }
@@ -642,8 +669,59 @@ class Envira_Gallery_Shortcode {
642
 
643
  // Fancybox: Start
644
  if ( $this->get_config( 'lightbox_enabled', $data ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
645
  ?>
646
- envira_galleries['<?php echo $data['id']; ?>'] = $('.envira-gallery-<?php echo $data['id']; ?>').envirabox({
647
  <?php do_action( 'envira_gallery_api_config', $data ); // Depreciated ?>
648
  <?php do_action( 'envira_gallery_api_envirabox_config', $data ); ?>
649
  <?php if ( ! $this->get_config( 'keyboard', $data ) ) : ?>
@@ -720,7 +798,11 @@ class Envira_Gallery_Shortcode {
720
  width: <?php echo $this->get_config( 'thumbnails_width', $data ); ?>,
721
  height: <?php echo $this->get_config( 'thumbnails_height', $data ); ?>,
722
  source: function(current) {
723
- return $(current.element).data('thumbnail');
 
 
 
 
724
  },
725
  position: '<?php echo $this->get_config( 'thumbnails_position', $data ); ?>'
726
  },
@@ -748,15 +830,38 @@ class Envira_Gallery_Shortcode {
748
  }
749
  });
750
 
751
- // Get a bunch of data attributes from clicked image link
752
- var gallery_id = this.element.find('img').data('envira-gallery-id');
753
- var gallery_item_id = this.element.find('img').data('envira-item-id');
754
- var alt = this.element.find('img').attr('alt');
755
- var title = this.element.find('img').parent().attr('title');
756
- var caption = this.element.find('img').parent().data('envira-caption');
757
- var index = this.element.find('img').data('envira-index');
758
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
759
  // Set alt, data-envira-title, data-envira-caption and data-envira-index attributes on Lightbox image
 
760
  this.inner.find('img').attr('alt', alt)
761
  .attr('data-envira-gallery-id', gallery_id)
762
  .attr('data-envira-item-id', gallery_item_id)
@@ -764,6 +869,13 @@ class Envira_Gallery_Shortcode {
764
  .attr('data-envira-caption', caption)
765
  .attr('data-envira-index', index);
766
 
 
 
 
 
 
 
 
767
  <?php do_action( 'envira_gallery_api_before_show', $data ); ?>
768
  },
769
  afterShow: function(){
@@ -838,6 +950,13 @@ class Envira_Gallery_Shortcode {
838
  });
839
 
840
  <?php
 
 
 
 
 
 
 
841
  do_action( 'envira_gallery_api_lightbox', $data );
842
  // Fancybox: End
843
  }
@@ -966,10 +1085,10 @@ class Envira_Gallery_Shortcode {
966
  public function maybe_change_link( $id, $item, $data ) {
967
 
968
  // Check gallery config
969
- $size = $this->get_config( 'lightbox_image_size', $data );
970
 
971
  // Return if we are serving a full size image
972
- if ( $size == 'default' || $size == 'full_width' ) {
973
  return $item;
974
  }
975
 
@@ -986,13 +1105,39 @@ class Envira_Gallery_Shortcode {
986
  }
987
 
988
  // Get media library attachment at requested size
989
- $image = wp_get_attachment_image_src( $id, $size );
990
  if ( ! is_array( $image ) ) {
991
  return $item;
992
  }
993
 
994
  // Inject new image size into $item
995
  $item['link'] = $image[0];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
996
 
997
  // Return
998
  return $item;
@@ -1004,13 +1149,14 @@ class Envira_Gallery_Shortcode {
1004
  *
1005
  * @since 1.0.0
1006
  *
1007
- * @param int $id The image attachment ID to use.
1008
- * @param array $item Gallery item data.
1009
- * @param array $data The gallery data to use for retrieval.
1010
- * @param bool $mobile Whether or not to retrieve the mobile image.
1011
- * @return string The proper image src attribute for the image.
 
1012
  */
1013
- public function get_image_src( $id, $item, $data, $mobile = false ) {
1014
 
1015
  // Detect if user is on a mobile device - if so, override $mobile flag which may be manually set
1016
  // by out of date addons or plugins
@@ -1020,9 +1166,29 @@ class Envira_Gallery_Shortcode {
1020
 
1021
  // Check if this Gallery uses a WordPress defined image size
1022
  $image_size = $this->get_config( 'image_size', $data );
1023
- if ( $image_size != 'default' ) {
1024
- // Get the requested image size
1025
- $src = wp_get_attachment_image_src( $id, $image_size );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1026
  } else {
1027
  // Get the full image
1028
  $src = wp_get_attachment_image_src( $id, 'full' );
@@ -1043,14 +1209,15 @@ class Envira_Gallery_Shortcode {
1043
 
1044
  // Prep our indexable images.
1045
  if ( $image && ! $mobile ) {
1046
- $this->index[$data['id']][$id] = array(
1047
  'src' => $image,
1048
  'alt' => ! empty( $item['alt'] ) ? $item['alt'] : ''
1049
  );
1050
  }
1051
 
1052
- // If the image size is a WordPress size, we don't need to resize or crop anything
1053
- if ( $image_size != 'default' ) {
 
1054
  // Return the image
1055
  return apply_filters( 'envira_gallery_image_src', $image, $id, $item, $data );
1056
  }
@@ -1066,9 +1233,31 @@ class Envira_Gallery_Shortcode {
1066
  'width' => $this->get_config( $type . '_width', $data ),
1067
  'height' => $this->get_config( $type . '_height', $data ),
1068
  'quality' => 100,
1069
- 'retina' => false
1070
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1071
  $args = apply_filters( 'envira_gallery_crop_image_args', $args);
 
1072
  $resized_image = $common->resize_image( $image, $args['width'], $args['height'], $this->get_config( 'crop', $data ), $args['position'], $args['quality'], $args['retina'], $data );
1073
 
1074
  // If there is an error, possibly output error message and return the default image src.
@@ -1165,6 +1354,7 @@ class Envira_Gallery_Shortcode {
1165
  // If we are on a mobile device, some config keys have mobile equivalents, which we need to check instead
1166
  if ( wp_is_mobile() ) {
1167
  $mobile_keys = array(
 
1168
  'lightbox_enabled' => 'mobile_lightbox',
1169
  'arrows' => 'mobile_arrows',
1170
  'toolbar' => 'mobile_toolbar',
@@ -1192,6 +1382,8 @@ class Envira_Gallery_Shortcode {
1192
  */
1193
  public function minify( $string, $stripDoubleForwardslashes = true ) {
1194
 
 
 
1195
  // Added a switch for stripping double forwardslashes
1196
  // This can be disabled when using URLs in JS, to ensure http:// doesn't get removed
1197
  // All other comment removal and minification will take place
80
  public function __construct() {
81
 
82
  // Load the base class object.
83
+ $this->base = ( class_exists( 'Envira_Gallery' ) ? Envira_Gallery::get_instance() : Envira_Gallery_Lite::get_instance() );
84
 
85
  // Register main gallery style.
86
  wp_register_style( $this->base->plugin_slug . '-style', plugins_url( 'assets/css/envira.css', $this->base->file ), array(), $this->base->version );
184
  $gallery = apply_filters( 'envira_gallery_output_start', $gallery, $data );
185
 
186
  // Build out the gallery HTML.
187
+ $gallery .= '<div id="envira-gallery-wrap-' . sanitize_html_class( $data['id'] ) . '" class="' . $this->get_gallery_classes( $data ) . '" itemscope itemtype="http://schema.org/ImageGallery">';
188
  $gallery = apply_filters( 'envira_gallery_output_before_container', $gallery, $data );
189
 
190
  // Description
261
  }
262
 
263
  $item = apply_filters( 'envira_gallery_output_item_data', $item, $id, $data, $i );
264
+
265
+ // Get image and image retina URLs
266
+ // These calls will generate thumbnails as necessary for us.
267
  $imagesrc = $this->get_image_src( $id, $item, $data );
268
+ $image_src_retina = $this->get_image_src( $id, $item, $data, false, true );
269
+
270
+ // Filter output before starting this gallery item.
271
  $gallery = apply_filters( 'envira_gallery_output_before_item', $gallery, $id, $item, $data, $i );
272
 
273
  // Maybe change the item's link if it is an image and we have an image size defined for the Lightbox
280
  $item['thumb'] = str_replace( $thumbnail_start_url, get_bloginfo( 'url' ) . '/', $item['thumb'] );
281
  }
282
 
283
+ $output = '<div id="envira-gallery-item-' . sanitize_html_class( $id ) . '" class="' . $this->get_gallery_item_classes( $item, $i, $data ) . '" style="padding-left: ' . $padding . 'px; padding-bottom: ' . $this->get_config( 'margin', $data ) . 'px; padding-right: ' . $padding . 'px;" ' . apply_filters( 'envira_gallery_output_item_attr', '', $id, $item, $data, $i ) . ' itemscope itemtype="http://schema.org/ImageObject">';
284
 
285
  $output .= '<div class="envira-gallery-item-inner">';
286
  $output = apply_filters( 'envira_gallery_output_before_link', $output, $id, $item, $data, $i );
287
 
288
  // Caption
289
+ // Lite doesn't support captions, so we fallback to the title.
290
+ if ( isset( $item['caption'] ) ) {
291
+ $caption = do_shortcode( str_replace( "\n", '<br />', esc_attr( $item['caption'] ) ) );
292
+ } else {
293
+ $caption = $item['title'];
294
+ }
295
 
296
  if ( ! empty( $item['link'] ) ) {
297
+ $output .= '<a href="' . esc_url( $item['link'] ) . '" class="envira-gallery-' . sanitize_html_class( $data['id'] ) . ' envira-gallery-link" ' . $html5_attribute . '="enviragallery' . sanitize_html_class( $data['id'] ) . '" title="' . strip_tags( html_entity_decode( $item['title'] ) ) . '" data-envira-caption="' . $caption . '" data-envira-retina="' . ( isset( $item['lightbox_retina_image'] ) ? $item['lightbox_retina_image'] : '' ) . '" data-thumbnail="' . esc_url( $item['thumb'] ) . '"' . ( ( isset($item['link_new_window']) && $item['link_new_window'] == 1 ) ? ' target="_blank"' : '' ) . ' ' . apply_filters( 'envira_gallery_output_link_attr', '', $id, $item, $data, $i ) . ' itemprop="contentUrl">';
298
  }
299
 
300
  $output = apply_filters( 'envira_gallery_output_before_image', $output, $id, $item, $data, $i );
301
 
302
  // Build the image and allow filtering
303
+ $output_item = '<img id="envira-gallery-image-' . sanitize_html_class( $id ) . '" class="envira-gallery-image envira-gallery-image-' . $i . '" data-envira-index="' . $i . '" src="' . esc_url( $imagesrc ) . '"' . ( $this->get_config( 'dimensions', $data ) ? ' width="' . $this->get_config( 'crop_width', $data ) . '" height="' . $this->get_config( 'crop_height', $data ) . '"' : '' ) . ' data-envira-src="' . esc_url( $imagesrc ) . '" data-envira-gallery-id="' . $data['id'] . '" data-envira-item-id="' . $id . '" alt="' . esc_attr( $item['alt'] ) . '" title="' . strip_tags( html_entity_decode( $item['title'] ) ) . '" ' . apply_filters( 'envira_gallery_output_image_attr', '', $id, $item, $data, $i ) . ' itemprop="thumbnailUrl" srcset="' . esc_url( $image_src_retina ) . ' 2x" />';
304
  $output_item = apply_filters( 'envira_gallery_output_image', $output_item, $id, $item, $data, $i );
305
 
306
  // Add image to output
581
  */
582
  public function gallery_init() {
583
 
584
+ // envira_galleries stores all Fancybox instances
585
+ // envira_isotopes stores all Isotope instances
586
+ // envira_isotopes_config stores Isotope configs for each Gallery
587
  ?>
588
  <script type="text/javascript">
589
+ var envira_galleries = [],
590
+ envira_isotopes = [],
591
+ envira_isotopes_config = [];
592
+
593
  jQuery(document).ready(function($){<?php ob_start();
594
  do_action( 'envira_gallery_api_start_global' );
595
  foreach ( $this->data as $data ) {
608
  <?php
609
  // Isotope: Start
610
  if ( $this->get_config( 'isotope', $data ) ) {
611
+ // Define config for this Isotope Gallery
612
  ?>
613
+ envira_isotopes_config[<?php echo $data['id']; ?>] = {
614
  <?php do_action( 'envira_gallery_api_enviratope_config', $data ); ?>
615
  itemSelector: '.envira-gallery-item',
616
  <?php
627
  <?php
628
  }
629
  ?>
630
+ };
631
+ <?php
632
+ // Initialize Isotope
633
+ ?>
634
+ envira_isotopes[<?php echo $data['id']; ?>] = envira_container_<?php echo $data['id']; ?>
635
+ = $('#envira-gallery-<?php echo $data['id']; ?>').enviratope(envira_isotopes_config[<?php echo $data['id']; ?>]);
636
+ <?php
637
+ // Re-layout Isotope when each image loads
638
+ ?>
639
+ envira_isotopes[<?php echo $data['id']; ?>].imagesLoaded()
640
+ .done(function() {
641
+ envira_isotopes[<?php echo $data['id']; ?>].enviratope('layout');
642
+ })
643
+ .progress(function() {
644
+ envira_isotopes[<?php echo $data['id']; ?>].enviratope('layout');
645
+ });
646
  <?php
647
  do_action( 'envira_gallery_api_enviratope', $data );
648
  }
669
 
670
  // Fancybox: Start
671
  if ( $this->get_config( 'lightbox_enabled', $data ) ) {
672
+ // By default, we'll use the images in the Gallery DOM to populate the lightbox.
673
+ // However, Addons (e.g. Pagination) may require us to give access to all images
674
+ // in a Gallery, not just the paginated subset on screen.
675
+ // Those Addons can populate this array now which will tell envirabox which images to use.
676
+ $lightbox_images = apply_filters( 'envira_gallery_lightbox_images', false, $data );
677
+
678
+ if ( ! $lightbox_images ) {
679
+ // No lightbox images specified, so use images from DOM
680
+ ?>
681
+ envira_galleries['<?php echo $data['id']; ?>'] = $('.envira-gallery-<?php echo $data['id']; ?>').envirabox({
682
+ <?php
683
+ } else {
684
+ // Use images from $lightbox_images
685
+ add_filter( 'envira_minify_strip_double_forward_slashes', '__return_false' );
686
+ ?>
687
+ var envira_gallery_images_<?php echo $data['id']; ?> = [];
688
+ <?php
689
+ // Build a JS array of all images
690
+ $count = 0;
691
+ foreach ( $lightbox_images as $image_id => $image ) {
692
+ // If no image ID exists, skip
693
+ if ( empty( $image_id ) ) {
694
+ continue;
695
+ }
696
+ ?>
697
+ envira_gallery_images_<?php echo $data['id']; ?>.push({
698
+ href: '<?php echo $image['src']; ?>',
699
+ gallery_id: <?php echo $data['id']; ?>,
700
+ id: <?php echo $image_id; ?>,
701
+ alt: '<?php echo addslashes( str_replace( "\n", '<br />', $image['alt'] ) ); ?>',
702
+ caption: '<?php echo addslashes( str_replace( "\n", '<br />', $image['caption'] ) ); ?>',
703
+ title: '<?php echo addslashes( str_replace( "\n", '<br />', $image['title'] ) ); ?>',
704
+ index: <?php echo $count; ?>,
705
+ thumbnail: '<?php echo ( isset( $image['thumb'] ) ? $image['thumb'] : '' ); ?>'
706
+ <?php do_action( 'envira_gallery_api_lightbox_image_attributes', $image, $image_id, $lightbox_images, $data ); ?>
707
+ });
708
+ <?php
709
+ $count++;
710
+ }
711
+
712
+ // Open envirabox when an image is clicked, telling envirabox which images are available to it.
713
+ ?>
714
+ $('#envira-gallery-wrap-<?php echo $data['id']; ?>').on('click', 'a.envira-gallery-link', function(e) {
715
+ e.preventDefault();
716
+ var envirabox_page = ( $('#envira-gallery-wrap-<?php echo $data['id']; ?> div.envira-pagination').data('page') - 1 );
717
+ var envirabox_per_page = $('#envira-gallery-wrap-<?php echo $data['id']; ?> div.envira-pagination').data('per-page');
718
+ var envirabox_index = ( Number($('img', $(this)).data('envira-index')) - 1 );
719
+ envira_galleries['<?php echo $data['id']; ?>'] = $.envirabox( envira_gallery_images_<?php echo $data['id']; ?>, {
720
+ index: ((envirabox_page * envirabox_per_page) + envirabox_index),
721
+ <?php
722
+ }
723
  ?>
724
+
725
  <?php do_action( 'envira_gallery_api_config', $data ); // Depreciated ?>
726
  <?php do_action( 'envira_gallery_api_envirabox_config', $data ); ?>
727
  <?php if ( ! $this->get_config( 'keyboard', $data ) ) : ?>
798
  width: <?php echo $this->get_config( 'thumbnails_width', $data ); ?>,
799
  height: <?php echo $this->get_config( 'thumbnails_height', $data ); ?>,
800
  source: function(current) {
801
+ if ( typeof current.element == 'undefined' ) {
802
+ return current.thumbnail;
803
+ } else {
804
+ return $(current.element).data('thumbnail');
805
+ }
806
  },
807
  position: '<?php echo $this->get_config( 'thumbnails_position', $data ); ?>'
808
  },
830
  }
831
  });
832
 
833
+ <?php
834
+ // Set data attributes on the lightbox image, based on either
835
+ // the image in the DOM or (if $lightbox_images defined) the image
836
+ // from $lightbox_images
837
+ ?>
838
+ if ( typeof this.element === 'undefined' ) {
839
+ <?php
840
+ // Using $lightbox_images
841
+ ?>
842
+ var gallery_id = this.group[ this.index ].gallery_id;
843
+ var gallery_item_id = this.group[ this.index ].id;
844
+ var alt = this.group[ this.index ].alt;
845
+ var title = this.group[ this.index ].title;
846
+ var caption = this.group[ this.index ].caption;
847
+ var index = this.index;
848
+ } else {
849
+ <?php
850
+ // Using image from DOM
851
+ // Get a bunch of data attributes from clicked image link
852
+ ?>
853
+ var gallery_id = this.element.find('img').data('envira-gallery-id');
854
+ var gallery_item_id = this.element.find('img').data('envira-item-id');
855
+ var alt = this.element.find('img').attr('alt');
856
+ var title = this.element.find('img').parent().attr('title');
857
+ var caption = this.element.find('img').parent().data('envira-caption');
858
+ var retina_image = this.element.find('img').parent().data('envira-retina');
859
+ var index = this.element.find('img').data('envira-index');
860
+ }
861
+
862
+ <?php
863
  // Set alt, data-envira-title, data-envira-caption and data-envira-index attributes on Lightbox image
864
+ ?>
865
  this.inner.find('img').attr('alt', alt)
866
  .attr('data-envira-gallery-id', gallery_id)
867
  .attr('data-envira-item-id', gallery_item_id)
869
  .attr('data-envira-caption', caption)
870
  .attr('data-envira-index', index);
871
 
872
+ <?php
873
+ // Set retina image srcset if specified
874
+ ?>
875
+ if ( typeof retina_image !== 'undefined' && retina_image !== '' ) {
876
+ this.inner.find('img').attr('srcset', retina_image + ' 2x');
877
+ }
878
+
879
  <?php do_action( 'envira_gallery_api_before_show', $data ); ?>
880
  },
881
  afterShow: function(){
950
  });
951
 
952
  <?php
953
+ // If lightbox images were specified, we need to close the click handler now
954
+ if ( $lightbox_images !== false ) {
955
+ ?>
956
+ });
957
+ <?php
958
+ }
959
+
960
  do_action( 'envira_gallery_api_lightbox', $data );
961
  // Fancybox: End
962
  }
1085
  public function maybe_change_link( $id, $item, $data ) {
1086
 
1087
  // Check gallery config
1088
+ $image_size = $this->get_config( 'lightbox_image_size', $data );
1089
 
1090
  // Return if we are serving a full size image
1091
+ if ( $image_size == 'default' || $image_size == 'full_width' ) {
1092
  return $item;
1093
  }
1094
 
1105
  }
1106
 
1107
  // Get media library attachment at requested size
1108
+ $image = wp_get_attachment_image_src( $id, $image_size );
1109
  if ( ! is_array( $image ) ) {
1110
  return $item;
1111
  }
1112
 
1113
  // Inject new image size into $item
1114
  $item['link'] = $image[0];
1115
+
1116
+ /*
1117
+ // Generate a retina version of the image
1118
+ $common = Envira_Gallery_Common::get_instance();
1119
+ $wordpress_image_sizes = $common->get_image_sizes();
1120
+ foreach ( $wordpress_image_sizes as $size ) {
1121
+ if ( $size['value'] !== $image_size ) {
1122
+ continue;
1123
+ }
1124
+
1125
+ // We found the image size. Use its dimensions
1126
+ $args = array(
1127
+ 'position' => 'c',
1128
+ 'width' => $size['width'],
1129
+ 'height' => $size['height'],
1130
+ 'quality' => 100,
1131
+ 'retina' => true,
1132
+ );
1133
+
1134
+ // Get full image
1135
+ $full_image = wp_get_attachment_image_src( $id, 'full' );
1136
+ $item['lightbox_retina_image'] = $common->resize_image( $full_image[0], $args['width'], $args['height'], false, $args['position'], $args['quality'], $args['retina'] );
1137
+ break;
1138
+
1139
+ }
1140
+ */
1141
 
1142
  // Return
1143
  return $item;
1149
  *
1150
  * @since 1.0.0
1151
  *
1152
+ * @param int $id The image attachment ID to use.
1153
+ * @param array $item Gallery item data.
1154
+ * @param array $data The gallery data to use for retrieval.
1155
+ * @param bool $mobile Whether or not to retrieve the mobile image.
1156
+ * @param bool $retina Whether to return a retina sized image.
1157
+ * @return string The proper image src attribute for the image.
1158
  */
1159
+ public function get_image_src( $id, $item, $data, $mobile = false, $retina = false ) {
1160
 
1161
  // Detect if user is on a mobile device - if so, override $mobile flag which may be manually set
1162
  // by out of date addons or plugins
1166
 
1167
  // Check if this Gallery uses a WordPress defined image size
1168
  $image_size = $this->get_config( 'image_size', $data );
1169
+ if ( $image_size != 'default' && ! $retina ) {
1170
+ // If image size is envira_gallery_random, get a random image size.
1171
+ if ( $image_size == 'envira_gallery_random' ) {
1172
+
1173
+ // Get random image sizes that have been chosen for this Gallery.
1174
+ $image_sizes_random = (array) $this->get_config( 'image_sizes_random', $data );
1175
+
1176
+ if ( count( $image_sizes_random ) == 0 ) {
1177
+ // The user didn't choose any image sizes - use them all.
1178
+ $wordpress_image_sizes = Envira_Gallery_Common::get_instance()->get_image_sizes( true );
1179
+ $wordpress_image_size_random_key = array_rand( $wordpress_image_sizes, 1 );
1180
+ $image_size = $wordpress_image_sizes[ $wordpress_image_size_random_key ]['value'];
1181
+ } else {
1182
+ $wordpress_image_size_random_key = array_rand( $image_sizes_random, 1 );
1183
+ $image_size = $image_sizes_random[ $wordpress_image_size_random_key ];
1184
+ }
1185
+
1186
+ // Get the random WordPress defined image size
1187
+ $src = wp_get_attachment_image_src( $id, $image_size );
1188
+ } else {
1189
+ // Get the requested WordPress defined image size
1190
+ $src = wp_get_attachment_image_src( $id, $image_size );
1191
+ }
1192
  } else {
1193
  // Get the full image
1194
  $src = wp_get_attachment_image_src( $id, 'full' );
1209
 
1210
  // Prep our indexable images.
1211
  if ( $image && ! $mobile ) {
1212
+ $this->index[ $data['id'] ][ $id ] = array(
1213
  'src' => $image,
1214
  'alt' => ! empty( $item['alt'] ) ? $item['alt'] : ''
1215
  );
1216
  }
1217
 
1218
+ // If the image size is a WordPress size and we're not requesting a retina image
1219
+ // we don't need to resize or crop anything.
1220
+ if ( $image_size != 'default' && ! $retina ) {
1221
  // Return the image
1222
  return apply_filters( 'envira_gallery_image_src', $image, $id, $item, $data );
1223
  }
1233
  'width' => $this->get_config( $type . '_width', $data ),
1234
  'height' => $this->get_config( $type . '_height', $data ),
1235
  'quality' => 100,
1236
+ 'retina' => $retina,
1237
  );
1238
+
1239
+ // If we're requesting a retina image, and the gallery uses a registered WordPress image size,
1240
+ // we need use the width and height of that registered WordPress image size - not the gallery's
1241
+ // image width and height, which are hidden settings.
1242
+ if ( $image_size != 'default' && $retina ) {
1243
+ // Find WordPress registered image size
1244
+ $wordpress_image_sizes = $common->get_image_sizes();
1245
+ foreach ( $wordpress_image_sizes as $size ) {
1246
+ if ( $size['value'] !== $image_size ) {
1247
+ continue;
1248
+ }
1249
+
1250
+ // We found the image size. Use its dimensions
1251
+ $args['width'] = $size['width'];
1252
+ $args['height'] = $size['height'];
1253
+ break;
1254
+
1255
+ }
1256
+ }
1257
+
1258
+ // Filter
1259
  $args = apply_filters( 'envira_gallery_crop_image_args', $args);
1260
+
1261
  $resized_image = $common->resize_image( $image, $args['width'], $args['height'], $this->get_config( 'crop', $data ), $args['position'], $args['quality'], $args['retina'], $data );
1262
 
1263
  // If there is an error, possibly output error message and return the default image src.
1354
  // If we are on a mobile device, some config keys have mobile equivalents, which we need to check instead
1355
  if ( wp_is_mobile() ) {
1356
  $mobile_keys = array(
1357
+ 'columns' => 'mobile_columns',
1358
  'lightbox_enabled' => 'mobile_lightbox',
1359
  'arrows' => 'mobile_arrows',
1360
  'toolbar' => 'mobile_toolbar',
1382
  */
1383
  public function minify( $string, $stripDoubleForwardslashes = true ) {
1384
 
1385
+ return $string;
1386
+
1387
  // Added a switch for stripping double forwardslashes
1388
  // This can be disabled when using URLs in JS, to ensure http:// doesn't get removed
1389
  // All other comment removal and minification will take place
readme.txt CHANGED
@@ -2,7 +2,7 @@
2
  Contributors: griffinjt, smub
3
  Tags: wordpress gallery, gallery, wordpress gallery plugin, gallery plugin, responsive, responsive gallery, image gallery, image gallery plugin, responsive gallery plugin, responsive image gallery, responsive image gallery plugin, custom post types, slideshow, responsive slideshow, slideshow plugin, responsive slideshow plugin, rotator, image rotator, responsive rotator, jquery gallery, javascript gallery, jquery rotator, javascript rotator, picture gallery, photo gallery, photo rotator, shortcode, template tag, custom post type, media uploader, ajax, wordpress galleries, responsive galleries, fullscreen, deeplinking, best wordpress gallery, best wordpress gallery plugin, best gallery plugin, best gallery, best responsive gallery, best responsive wordpress gallery, best wp gallery, portfolio, design portfolio, lightroom, adobe lightroom, masonry gallery, polaroid gallery
4
  Requires at least: 4.0
5
- Tested up to: 4.5.1
6
  Stable tag: trunk
7
  License: GNU General Public License v2.0 or later
8
 
@@ -185,6 +185,23 @@ Also, I'm an <a href="https://thomasgriffin.io" rel="me" title="WordPress Develo
185
 
186
  == Changelog ==
187
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  = 1.5.0.1 =
189
  * Updated: Standardised edit screen titles and descriptions
190
  * Updated: Screenshots
2
  Contributors: griffinjt, smub
3
  Tags: wordpress gallery, gallery, wordpress gallery plugin, gallery plugin, responsive, responsive gallery, image gallery, image gallery plugin, responsive gallery plugin, responsive image gallery, responsive image gallery plugin, custom post types, slideshow, responsive slideshow, slideshow plugin, responsive slideshow plugin, rotator, image rotator, responsive rotator, jquery gallery, javascript gallery, jquery rotator, javascript rotator, picture gallery, photo gallery, photo rotator, shortcode, template tag, custom post type, media uploader, ajax, wordpress galleries, responsive galleries, fullscreen, deeplinking, best wordpress gallery, best wordpress gallery plugin, best gallery plugin, best gallery, best responsive gallery, best responsive wordpress gallery, best wp gallery, portfolio, design portfolio, lightroom, adobe lightroom, masonry gallery, polaroid gallery
4
  Requires at least: 4.0
5
+ Tested up to: 4.5.2
6
  Stable tag: trunk
7
  License: GNU General Public License v2.0 or later
8
 
185
 
186
  == Changelog ==
187
 
188
+ = 1.5.0.2 =
189
+ * Added: ImageGallery and ImageObject Schema Markup to Galleries
190
+ * Added: Option to insert Gallery Title as heading when using the Add Gallery button in a Visual Editor
191
+ * Added: More detailed on screen progress bars when uploading multiple images
192
+ * Added: envira_isotopes and envira_isotopes_config JS arrays for developers
193
+ * Updated: Isotope to 3.0.0
194
+ * Updated: ImagesLoaded to 4.1.0
195
+ * Updated: Standardised edit screen titles and descriptions
196
+ * Fix: Better rendering of Isotope layouts using imagesLoaded
197
+ * Fix: Image uploader on Gallery Add/Edit screen not displaying on some tablet and mobile devices
198
+ * Fix: Checkmark icon wrongly displaying on modal close when editing images.
199
+ * Fix: Display text in warning when Envira Lite and Envira Gallery are both activated.
200
+ * Fix: Ensure that third party notification plugins don’t remove the Envira Gallery logo and header from Envira’s screens
201
+ * Fix: Various resets for images and captions to prevent themes overriding default behaviour
202
+ * Fix: Minified admin CSS for faster load times
203
+ * Fix: When editing an image, store any checkbox values if checked, instead of assuming 1 or 0 for better Addon compatibility.
204
+
205
  = 1.5.0.1 =
206
  * Updated: Standardised edit screen titles and descriptions
207
  * Updated: Screenshots