BackUpWordPress - Version 3.0-beta

Version Description

Download this release

Release Info

Developer pauldewouters
Plugin Icon 128x128 BackUpWordPress
Version 3.0-beta
Comparing to
See all releases

Code changes from version 2.6.2 to 3.0-beta

Files changed (143) hide show
  1. admin/actions.php +381 -301
  2. admin/backups-table.php +42 -0
  3. admin/backups.php +28 -106
  4. admin/enable-support.php +2 -15
  5. admin/faq.php +58 -0
  6. admin/menu.php +7 -22
  7. admin/page.php +5 -23
  8. admin/schedule-form-excludes.php +287 -66
  9. admin/schedule-form.php +128 -75
  10. admin/{schedule.php → schedule-sentence.php} +42 -20
  11. admin/schedule-settings.php +87 -0
  12. admin/server-info.php +2 -1
  13. admin/upsell.php +17 -0
  14. assets/colorbox/README.md +527 -0
  15. assets/colorbox/bower.json +31 -0
  16. assets/colorbox/colorbox.ai +1814 -3
  17. assets/colorbox/colorbox.jquery.json +30 -0
  18. assets/colorbox/content/ajax.html +11 -0
  19. assets/colorbox/content/daisy.jpg +0 -0
  20. assets/colorbox/content/daisy@2x.jpg +0 -0
  21. assets/colorbox/content/homer.jpg +0 -0
  22. assets/colorbox/content/marylou.jpg +0 -0
  23. assets/colorbox/content/ohoopee1.jpg +0 -0
  24. assets/colorbox/content/ohoopee2.jpg +0 -0
  25. assets/colorbox/content/ohoopee3.jpg +0 -0
  26. assets/colorbox/example1/index.html +95 -0
  27. assets/colorbox/example2/colorbox.css +50 -0
  28. assets/colorbox/example2/images/controls.png +0 -0
  29. assets/colorbox/example2/images/loading.gif +0 -0
  30. assets/colorbox/example2/index.html +95 -0
  31. assets/colorbox/example3/colorbox.css +45 -0
  32. assets/colorbox/example3/images/controls.png +0 -0
  33. assets/colorbox/example3/images/loading.gif +0 -0
  34. assets/colorbox/example3/index.html +95 -0
  35. assets/colorbox/example4/colorbox.css +66 -0
  36. assets/colorbox/example4/images/border1.png +0 -0
  37. assets/colorbox/example4/images/border2.png +0 -0
  38. assets/colorbox/example4/images/loading.gif +0 -0
  39. assets/colorbox/example4/index.html +95 -0
  40. assets/colorbox/example5/colorbox.css +58 -0
  41. assets/colorbox/example5/images/border.png +0 -0
  42. assets/colorbox/example5/images/controls.png +0 -0
  43. assets/colorbox/example5/images/loading.gif +0 -0
  44. assets/colorbox/example5/images/loading_background.png +0 -0
  45. assets/colorbox/example5/index.html +95 -0
  46. assets/colorbox/i18n/jquery.colorbox-ar.js +15 -0
  47. assets/colorbox/i18n/jquery.colorbox-bg.js +16 -0
  48. assets/colorbox/i18n/jquery.colorbox-ca.js +13 -0
  49. assets/colorbox/i18n/jquery.colorbox-cs.js +16 -0
  50. assets/colorbox/i18n/jquery.colorbox-da.js +16 -0
  51. assets/colorbox/i18n/jquery.colorbox-de.js +15 -0
  52. assets/colorbox/i18n/jquery.colorbox-es.js +13 -0
  53. assets/colorbox/i18n/jquery.colorbox-et.js +15 -0
  54. assets/colorbox/i18n/jquery.colorbox-fa.js +18 -0
  55. assets/colorbox/i18n/jquery.colorbox-fi.js +15 -0
  56. assets/colorbox/i18n/jquery.colorbox-fr.js +15 -0
  57. assets/colorbox/i18n/jquery.colorbox-gl.js +13 -0
  58. assets/colorbox/i18n/jquery.colorbox-he.js +16 -0
  59. assets/colorbox/i18n/jquery.colorbox-hr.js +15 -0
  60. assets/colorbox/i18n/jquery.colorbox-hu.js +15 -0
  61. assets/colorbox/i18n/jquery.colorbox-id.js +15 -0
  62. assets/colorbox/i18n/jquery.colorbox-it.js +15 -0
  63. assets/colorbox/i18n/jquery.colorbox-ja.js +15 -0
  64. assets/colorbox/i18n/jquery.colorbox-kr.js +15 -0
  65. assets/colorbox/i18n/jquery.colorbox-lv.js +16 -0
  66. assets/colorbox/i18n/jquery.colorbox-nl.js +15 -0
  67. assets/colorbox/i18n/jquery.colorbox-no.js +16 -0
  68. assets/colorbox/i18n/jquery.colorbox-pl.js +16 -0
  69. assets/colorbox/i18n/jquery.colorbox-pt-br.js +15 -0
  70. assets/colorbox/i18n/jquery.colorbox-ro.js +15 -0
  71. assets/colorbox/i18n/jquery.colorbox-ru.js +16 -0
  72. assets/colorbox/i18n/jquery.colorbox-si.js +15 -0
  73. assets/colorbox/i18n/jquery.colorbox-sk.js +15 -0
  74. assets/colorbox/i18n/jquery.colorbox-sr.js +15 -0
  75. assets/colorbox/i18n/jquery.colorbox-sv.js +15 -0
  76. assets/colorbox/i18n/jquery.colorbox-tr.js +19 -0
  77. assets/colorbox/i18n/jquery.colorbox-uk.js +16 -0
  78. assets/colorbox/i18n/jquery.colorbox-zh-CN.js +15 -0
  79. assets/colorbox/i18n/jquery.colorbox-zh-TW.js +15 -0
  80. assets/colorbox/jquery.colorbox.js +1084 -0
  81. assets/d-azure-alt.png +0 -0
  82. assets/d-azure.png +0 -0
  83. assets/d-dream-alt.png +0 -0
  84. assets/d-dream.png +0 -0
  85. assets/d-drive-alt.png +0 -0
  86. assets/d-drive.png +0 -0
  87. assets/d-dropbox-alt.png +0 -0
  88. assets/d-dropbox.png +0 -0
  89. assets/d-ftp-alt.png +0 -0
  90. assets/d-ftp.png +0 -0
  91. assets/d-rack-alt.png +0 -0
  92. assets/d-rack.png +0 -0
  93. assets/d-s3-alt.png +0 -0
  94. assets/d-s3.png +0 -0
  95. assets/hmbkp.css +81 -84
  96. assets/hmbkp.js +56 -296
  97. assets/hmbkp.min.css +1 -0
  98. assets/hmbkp.min.js +1 -0
  99. assets/icon_backupwordpress_16x16.png +0 -0
  100. assets/icon_backupwordpress_16x16_hover.png +0 -0
  101. assets/icon_backupwordpress_32x32.png +0 -0
  102. backdrop/README.md +114 -0
  103. backdrop/hm-backdrop.php +12 -0
  104. backdrop/license.txt +340 -0
  105. backdrop/namespace.php +6 -0
  106. backdrop/server.php +38 -0
  107. backdrop/task.php +71 -0
  108. backupwordpress.php +75 -41
  109. bin/install-wp-tests.sh +78 -0
  110. classes/class-email.php +14 -16
  111. classes/class-requirements.php +58 -70
  112. classes/class-schedule.php +262 -103
  113. classes/class-schedules.php +5 -3
  114. classes/class-services.php +21 -7
  115. functions/core.php +42 -13
  116. functions/interface.php +118 -106
  117. hm-backup/CONTRIBUTING.md +13 -0
  118. hm-backup/README.md +8 -0
  119. hm-backup/composer.json +20 -0
  120. hm-backup/hm-backup.php +10 -200
  121. hm-backup/tests/test-data-symlink/test-data-symlink.txt +1 -0
  122. hm-backup/tests/test-data/exclude/exclude.exclude +1 -0
  123. hm-backup/tests/test-data/test-data.txt +1 -0
  124. hm-backup/tests/testBackUpProcessTest.php +205 -0
  125. hm-backup/tests/testBackupPropertiesTest.php +115 -0
  126. hm-backup/tests/testBrokenSymlinkTest.php +143 -0
  127. hm-backup/tests/testConformDirTest.php +70 -0
  128. hm-backup/tests/testDatabaseDumpTest.php +80 -0
  129. hm-backup/tests/testExcludesTest.php +567 -0
  130. hm-backup/tests/testHiddenFileTest.php +127 -0
  131. hm-backup/tests/testSafeModeTest.php +156 -0
  132. hm-backup/tests/testSymlinkDirTest.php +136 -0
  133. hm-backup/tests/testSymlinkFileTest.php +133 -0
  134. hm-backup/tests/testUnreadableFileTest.php +122 -0
  135. languages/backupwordpress.pot +1172 -0
  136. languages/hmbkp.mo +0 -0
  137. languages/hmbkp.po +0 -910
  138. languages/hmbkp.pot +0 -846
  139. readme.md +733 -0
  140. readme.txt +143 -16
  141. readme/readme-footer.txt +660 -0
  142. readme/readme-header.txt +42 -0
  143. uninstall.php +11 -3
admin/actions.php CHANGED
@@ -1,78 +1,82 @@
1
  <?php
2
 
3
  /**
4
- * Delete the backup and then redirect
5
- * back to the backups page
6
  */
7
  function hmbkp_request_delete_backup() {
8
 
9
- if ( empty( $_GET['hmbkp_delete_backup'] ) || ! check_admin_referer( 'hmbkp-delete_backup' ) )
10
- return;
11
 
12
  $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( urldecode( $_GET['hmbkp_schedule_id'] ) ) );
13
 
14
- $deleted = $schedule->delete_backup( sanitize_text_field( base64_decode( $_GET['hmbkp_delete_backup'] ) ) );
15
 
16
- if ( is_wp_error( $deleted ) )
17
  wp_die( $deleted->get_error_message() );
 
18
 
19
- wp_safe_redirect( remove_query_arg( array( 'hmbkp_delete_backup', '_wpnonce' ) ), 303 );
20
 
21
  die;
22
 
23
  }
24
- add_action( 'load-' . HMBKP_ADMIN_PAGE, 'hmbkp_request_delete_backup' );
25
 
26
  /**
27
  * Enable support and then redirect back to the backups page
28
- * @return void
29
  */
30
  function hmbkp_request_enable_support() {
31
 
32
- if ( empty( $_POST['hmbkp_enable_support'] ) || ! check_admin_referer( 'enable-support', 'hmbkp' ) )
33
- return;
34
 
35
  update_option( 'hmbkp_enable_support', true );
36
 
37
- wp_safe_redirect( remove_query_arg( 'null' ) , 303 );
38
 
39
  die;
40
 
41
  }
42
- add_action( 'load-' . HMBKP_ADMIN_PAGE, 'hmbkp_request_enable_support' );
43
 
44
  /**
45
- * Delete a schedule and all it's backups and then redirect
46
- * back to the backups page
47
  */
48
  function hmbkp_request_delete_schedule() {
49
 
50
- if ( empty( $_GET['action'] ) || $_GET['action'] !== 'hmbkp_delete_schedule' || ! check_admin_referer( 'hmbkp-delete_schedule' ) )
51
- return;
52
 
53
  $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( urldecode( $_GET['hmbkp_schedule_id'] ) ) );
54
  $schedule->cancel( true );
55
 
56
- wp_safe_redirect( remove_query_arg( array( 'hmbkp_schedule_id', 'action', '_wpnonce' ) ), 303 );
57
 
58
  die;
59
 
60
  }
61
- add_action( 'load-' . HMBKP_ADMIN_PAGE, 'hmbkp_request_delete_schedule' );
62
 
63
  /**
64
- * Perform a manual backup via ajax
 
 
65
  */
66
- function hmbkp_ajax_request_do_backup() {
 
 
 
 
 
 
 
 
 
 
 
67
 
68
- check_ajax_referer( 'hmbkp_nonce', 'nonce' );
69
 
70
  // Fixes an issue on servers which only allow a single session per client
71
  session_write_close();
72
 
73
- if ( empty( $_POST['hmbkp_schedule_id'] ) )
74
- die;
75
-
76
  // We want to display any fatal errors in this ajax request so we can catch them on the other side.
77
  error_reporting( E_ERROR | E_USER_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_RECOVERABLE_ERROR );
78
  @ini_set( 'display_errors', 'On' );
@@ -89,7 +93,7 @@ function hmbkp_ajax_request_do_backup() {
89
 
90
  hmbkp_cleanup();
91
 
92
- $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( urldecode( $_POST['hmbkp_schedule_id'] ) ) );
93
 
94
  $schedule->run();
95
 
@@ -97,32 +101,46 @@ function hmbkp_ajax_request_do_backup() {
97
 
98
  $error_message = '';
99
 
100
- foreach ( $errors as $error_set )
101
  $error_message .= implode( "\n\r", $error_set );
 
102
 
103
- if ( $error_message && file_exists( $schedule->get_archive_filepath() ) )
104
  $error_message .= 'HMBKP_SUCCESS';
 
105
 
106
- if ( trim( $error_message ) )
107
  echo $error_message;
 
 
 
 
 
 
 
 
 
108
 
109
  die;
110
 
111
  }
112
- add_action( 'wp_ajax_hmbkp_run_schedule', 'hmbkp_ajax_request_do_backup' );
 
113
 
114
  /**
115
- * Send the download file to the browser and
116
- * then redirect back to the backups page
117
  */
118
  function hmbkp_request_download_backup() {
119
 
120
- global $is_apache;
121
 
122
- if ( empty( $_GET['hmbkp_download_backup'] ) || ! check_admin_referer( 'hmbkp-download_backup' ) || ! file_exists( sanitize_text_field( base64_decode( $_GET['hmbkp_download_backup'] ) ) ) )
123
  return;
 
124
 
125
- $url = str_replace( HM_Backup::conform_dir( HM_Backup::get_home_path() ), home_url(), trailingslashit( dirname( sanitize_text_field( base64_decode( $_GET['hmbkp_download_backup'] ) ) ) ) ) . urlencode( pathinfo( sanitize_text_field( base64_decode( $_GET['hmbkp_download_backup'] ) ), PATHINFO_BASENAME ) );
 
 
126
 
127
  if ( $is_apache ) {
128
 
@@ -141,47 +159,49 @@ function hmbkp_request_download_backup() {
141
  die;
142
 
143
  }
144
- add_action( 'load-' . HMBKP_ADMIN_PAGE, 'hmbkp_request_download_backup' );
145
 
146
  /**
147
- * Cancels a running backup then redirect
148
- * back to the backups page
149
  */
150
  function hmbkp_request_cancel_backup() {
151
 
152
- if ( ! isset( $_GET['action'] ) || $_GET['action'] !== 'hmbkp_cancel' )
153
- return;
154
 
155
  $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( urldecode( $_GET['hmbkp_schedule_id'] ) ) );
156
 
157
  // Delete the running backup
158
- if ( $schedule->get_running_backup_filename() && file_exists( trailingslashit( hmbkp_path() ) . $schedule->get_running_backup_filename() ) )
159
  unlink( trailingslashit( hmbkp_path() ) . $schedule->get_running_backup_filename() );
 
160
 
161
- if ( $schedule->get_schedule_running_path() && file_exists( $schedule->get_schedule_running_path() ) )
162
  unlink( $schedule->get_schedule_running_path() );
 
163
 
164
  hmbkp_cleanup();
165
 
166
- wp_safe_redirect( remove_query_arg( array( 'action' ) ), 303 );
167
 
168
  die;
169
 
170
  }
171
- add_action( 'load-' . HMBKP_ADMIN_PAGE, 'hmbkp_request_cancel_backup' );
172
 
173
  /**
174
- * Dismiss an error and then redirect
175
- * back to the backups page
176
  */
177
  function hmbkp_dismiss_error() {
178
 
179
- if ( empty( $_GET['action'] ) || $_GET['action'] !== 'hmbkp_dismiss_error' )
 
 
180
  return;
 
181
 
182
  hmbkp_cleanup();
183
 
184
- wp_safe_redirect( remove_query_arg( 'action' ), 303 );
185
 
186
  die;
187
 
@@ -189,312 +209,249 @@ function hmbkp_dismiss_error() {
189
  add_action( 'admin_init', 'hmbkp_dismiss_error' );
190
 
191
  /**
192
- * Display the running status via ajax
193
- */
194
- function hmbkp_ajax_is_backup_in_progress() {
195
-
196
- check_ajax_referer( 'hmbkp_nonce', 'nonce' );
197
-
198
- if ( empty( $_POST['hmbkp_schedule_id'] ) )
199
- die;
200
-
201
- $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( urldecode( $_POST['hmbkp_schedule_id'] ) ) );
202
-
203
- if ( ! $schedule->get_status() )
204
- echo 0;
205
-
206
- else
207
- hmbkp_schedule_actions( $schedule );
208
-
209
- die;
210
-
211
- }
212
- add_action( 'wp_ajax_hmbkp_is_in_progress', 'hmbkp_ajax_is_backup_in_progress' );
213
-
214
- /**
215
- * Display the calculated size via ajax
216
- */
217
- function hmbkp_ajax_calculate_backup_size() {
218
-
219
- check_ajax_referer( 'hmbkp_nonce', 'nonce' );
220
-
221
- if ( empty( $_POST['hmbkp_schedule_id'] ) )
222
- die;
223
-
224
- $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( urldecode( $_POST['hmbkp_schedule_id'] ) ) );
225
-
226
- $recalculate_filesize = true;
227
-
228
- include_once( HMBKP_PLUGIN_PATH . '/admin/schedule.php' );
229
-
230
- die;
231
-
232
- }
233
- add_action( 'wp_ajax_hmbkp_calculate', 'hmbkp_ajax_calculate_backup_size' );
234
-
235
- /**
236
- * Test the cron response and if it's not 200 show a warning message
237
  */
238
- function hmbkp_ajax_cron_test() {
239
-
240
- check_ajax_referer( 'hmbkp_nonce', 'nonce' );
241
-
242
- if ( defined( 'ALTERNATE_WP_CRON' ) ) {
243
 
244
- delete_option( 'hmbkp_wp_cron_test_failed' );
245
-
246
- echo 1;
247
-
248
- die;
249
 
 
 
250
  }
251
 
252
- $response = wp_remote_head( site_url( 'wp-cron.php' ), array( 'timeout' => 30 ) );
253
-
254
- if ( is_wp_error( $response ) ) {
255
-
256
- echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . sprintf( __( '%1$s is returning a %2$s response which could mean cron jobs aren\'t getting fired properly. BackUpWordPress relies on wp-cron to run scheduled backups. See the %3$s for more details.', 'hmbkp' ), '<code>wp-cron.php</code>', '<code>' . $response->get_error_message() . '</code>', '<a href="http://wordpress.org/extend/plugins/backupwordpress/faq/">FAQ</a>' ) . '</p></div>';
257
-
258
- update_option( 'hmbkp_wp_cron_test_failed', true );
259
-
260
- } elseif ( wp_remote_retrieve_response_code( $response ) != 200 ) {
261
-
262
- echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . sprintf( __( '%1$s is returning a %2$s response which could mean cron jobs aren\'t getting fired properly. BackUpWordPress relies on wp-cron to run scheduled backups. See the %3$s for more details.', 'hmbkp' ), '<code>wp-cron.php</code>', '<code>' . esc_html( wp_remote_retrieve_response_code( $response ) ) . ' ' . esc_html( get_status_header_desc( wp_remote_retrieve_response_code( $response ) ) ) . '</code>', '<a href="http://wordpress.org/extend/plugins/backupwordpress/faq/">FAQ</a>' ) . '</p></div>';
263
-
264
- update_option( 'hmbkp_wp_cron_test_failed', true );
265
-
266
- } else {
267
 
268
- echo 1;
269
 
270
- delete_option( 'hmbkp_wp_cron_test_failed' );
271
 
 
 
 
272
  }
273
 
274
- die;
275
-
276
- }
277
- add_action( 'wp_ajax_hmbkp_cron_test', 'hmbkp_ajax_cron_test' );
278
-
279
- /**
280
- * Load the edit schedule form
281
- */
282
- function hmbkp_edit_schedule_load() {
283
-
284
- if ( empty( $_GET['hmbkp_schedule_id'] ) )
285
- die;
286
-
287
- $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( $_GET['hmbkp_schedule_id'] ) );
288
-
289
- require( HMBKP_PLUGIN_PATH . '/admin/schedule-form.php' );
290
-
291
- die;
292
-
293
- }
294
- add_action( 'wp_ajax_hmbkp_edit_schedule_load', 'hmbkp_edit_schedule_load' );
295
 
296
- /**
297
- * Load the edit schedule excludes form
298
- */
299
- function hmbkp_edit_schedule_excludes_load() {
300
 
301
- if ( empty( $_GET['hmbkp_schedule_id'] ) )
302
- die;
303
-
304
- $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( $_GET['hmbkp_schedule_id'] ) );
305
 
306
- require( HMBKP_PLUGIN_PATH . '/admin/schedule-form-excludes.php' );
307
 
 
308
  die;
309
 
310
- }
311
- add_action( 'wp_ajax_hmbkp_edit_schedule_excludes_load', 'hmbkp_edit_schedule_excludes_load' );
312
-
313
- /**
314
- * Load the add schedule form
315
- */
316
- function hmbkp_add_schedule_load() {
317
-
318
- $schedule = new HMBKP_Scheduled_Backup( date( 'U' ) );
319
- $is_new_schedule = true;
320
-
321
- require( HMBKP_PLUGIN_PATH . '/admin/schedule-form.php' );
322
-
323
- die;
324
 
325
  }
326
- add_action( 'wp_ajax_hmbkp_add_schedule_load', 'hmbkp_add_schedule_load' );
327
 
328
  /**
329
- * Catch the edit schedule form
330
  *
331
  * Validate and either return errors or update the schedule
332
  */
333
  function hmbkp_edit_schedule_submit() {
334
 
335
- check_ajax_referer( 'hmbkp_schedule_submit_action', 'hmbkp_schedule_submit_nonce' );
336
 
337
- if ( empty( $_GET['hmbkp_schedule_id'] ) )
338
  die;
 
339
 
340
- $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( $_GET['hmbkp_schedule_id'] ) );
 
 
341
 
342
  $errors = array();
343
 
344
- // called from an extension
345
- if ( isset( $_GET['is_destination_form'] ) ) {
346
 
347
- // Save the service options
348
- foreach ( HMBKP_Services::get_services( $schedule ) as $service )
349
- $errors = array_merge( $errors, $service->save() );
350
 
351
- $schedule->save();
352
 
353
- if ( empty( $errors ) )
354
- wp_send_json_success();
355
- else
356
- wp_send_json_error( $errors );
357
 
358
- } else {
 
 
359
 
360
- $schedule_settings = array();
 
 
361
 
362
- if ( isset( $_GET['hmbkp_schedule_recurrence'] ) ) {
363
 
364
- $hmbkp_schedule_recurrence = $_GET['hmbkp_schedule_recurrence'];
365
 
366
- if ( isset( $_GET['hmbkp_schedule_type'] ) ) {
367
 
368
- $schedule_type = sanitize_text_field( $_GET['hmbkp_schedule_type'] );
 
 
369
 
370
- if ( ! trim( $schedule_type ) )
371
- $errors['hmbkp_schedule_type'] = __( 'Backup type cannot be empty', 'hmbkp' );
 
372
 
373
- elseif ( ! in_array( $schedule_type, array( 'complete', 'file', 'database' ) ) )
374
- $errors['hmbkp_schedule_type'] = __( 'Invalid backup type', 'hmbkp' );
 
375
 
376
- else
377
- $schedule_settings['schedule_type'] = $schedule_type;
378
 
379
- }
380
 
381
- if ( isset( $_GET['hmbkp_schedule_recurrence']['hmbkp_type'] ) ) {
382
- $hmbkp_schedule_recurrence_type = sanitize_text_field( $_GET['hmbkp_schedule_recurrence']['hmbkp_type'] );
383
 
384
- if ( empty( $hmbkp_schedule_recurrence_type ) )
385
- $errors['hmbkp_schedule_recurrence']['hmbkp_type'] = __( 'Schedule cannot be empty', 'hmbkp' );
 
386
 
387
- elseif ( ! in_array( $hmbkp_schedule_recurrence_type, array_keys( hmbkp_get_cron_schedules() ) ) && $hmbkp_schedule_recurrence_type !== 'manually' )
388
- $errors['hmbkp_schedule_recurrence']['hmbkp_type'] = __( 'Invalid schedule', 'hmbkp' );
 
389
 
390
- }
391
 
392
- if ( 'manually' !== $hmbkp_schedule_recurrence_type ) {
393
 
394
- if ( isset( $_GET['hmbkp_schedule_recurrence']['hmbkp_schedule_start_day_of_week'] ) ) {
395
 
396
- $hmbkp_schedule_time['day_of_week'] = sanitize_text_field( $_GET['hmbkp_schedule_recurrence']['hmbkp_schedule_start_day_of_week'] );
 
 
 
397
 
398
- if ( ! in_array( $hmbkp_schedule_time['day_of_week'], array( 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday' ) ) )
399
- $errors['hmbkp_schedule_start_day_of_week'] = __( 'Day of week must be an integer between 1 and 7', 'backupwordpress' );
 
400
 
401
- }
 
 
402
 
403
- if ( isset( $_GET['hmbkp_schedule_recurrence']['hmbkp_schedule_start_day_of_month'] ) ) {
404
 
405
- $hmbkp_schedule_time['day_of_month'] = absint( $_GET['hmbkp_schedule_recurrence']['hmbkp_schedule_start_day_of_month'] );
406
 
407
- $options = array(
408
- 'min_range' => 1,
409
- 'max_range' => 31
410
- );
411
 
412
- if ( false === filter_var( $hmbkp_schedule_time['day_of_month'], FILTER_VALIDATE_INT, array( 'options' => $options ) ) )
413
- $errors['hmbkp_schedule_start_day_of_month'] = __( 'Day of month must be between 1 and 31', 'backupwordpress' );
 
 
414
 
415
- }
 
 
416
 
417
- if ( isset( $_GET['hmbkp_schedule_recurrence']['hmbkp_schedule_start_hours'] ) ) {
 
 
418
 
419
- $hmbkp_schedule_time['hours'] = absint( $_GET['hmbkp_schedule_recurrence']['hmbkp_schedule_start_hours'] );
420
 
421
- $options = array(
422
- 'min_range' => 1,
423
- 'max_range' => 23
424
- );
425
 
426
- if ( false === filter_var( $hmbkp_schedule_time['hours'], FILTER_VALIDATE_INT, array( 'options' => $options ) ) )
427
- $errors['hmbkp_schedule_start_hours'] = __( 'Hours must be between 1 and 23', 'backupwordpress' );
428
 
429
- }
 
 
 
430
 
431
- if ( isset( $_GET['hmbkp_schedule_recurrence']['hmbkp_schedule_start_minutes'] ) ) {
 
 
432
 
433
- $hmbkp_schedule_time['minutes'] = absint( $_GET['hmbkp_schedule_recurrence']['hmbkp_schedule_start_minutes'] );
 
 
434
 
435
- $options = array(
436
- 'min_range' => 0,
437
- 'max_range' => 59
438
- );
439
 
440
- if ( false === filter_var( $hmbkp_schedule_time['minutes'], FILTER_VALIDATE_INT, array( 'options' => $options ) ) )
441
- $errors['hmbkp_schedule_start_minutes'] = __( 'Minutes must be between 0 and 59', 'backupwordpress' );
442
 
443
- }
444
 
445
- }
 
446
  }
447
 
448
- if ( isset( $_GET['hmbkp_schedule_max_backups'] ) ) {
 
 
449
 
450
- $schedule_max_backups = sanitize_text_field( $_GET['hmbkp_schedule_max_backups'] );
 
 
451
 
452
- if ( empty( $schedule_max_backups ) )
453
- $errors['hmbkp_schedule_max_backups'] = __( 'Max backups can\'t be empty', 'hmbkp' );
 
454
 
455
- elseif ( ! is_numeric( $schedule_max_backups ) )
456
- $errors['hmbkp_schedule_max_backups'] = __( 'Max backups must be a number', 'hmbkp' );
457
 
458
- elseif ( ! ( $schedule_max_backups >= 1 ) )
459
- $errors['hmbkp_schedule_max_backups'] = __( 'Max backups must be greater than 0', 'hmbkp' );
 
 
460
 
461
- else
462
- $schedule_settings['schedule_max_backups'] = absint( $schedule_max_backups );
463
 
464
- }
 
465
 
466
- // Save the service options
467
- foreach ( HMBKP_Services::get_services( $schedule ) as $service ) {
468
- $errors = array_merge( $errors, $service->save() );
469
  }
470
 
471
- if ( $errors ) {
472
- wp_send_json_error( $errors );
473
 
474
- } else {
 
 
475
 
476
- if ( isset( $hmbkp_schedule_time ) )
477
- $schedule->set_schedule_start_time( hmbkp_determine_start_time( $hmbkp_schedule_recurrence_type, $hmbkp_schedule_time ) );
 
478
 
479
- $schedule->set_reoccurrence( $hmbkp_schedule_recurrence_type );
480
- $schedule->set_type( $schedule_type );
481
- $schedule->set_max_backups( $schedule_settings['schedule_max_backups'] );
482
 
483
- $schedule->save();
 
484
 
485
- // Remove any old backups in-case max backups was reduced
486
- $schedule->delete_old_backups();
487
 
488
- wp_send_json_success();
489
 
 
 
490
  }
491
 
492
  }
493
 
494
- die();
 
 
 
 
 
 
 
495
 
496
  }
497
- add_action( 'wp_ajax_hmbkp_edit_schedule_submit', 'hmbkp_edit_schedule_submit' );
498
 
499
  /**
500
  * Add an exclude rule
@@ -504,23 +461,32 @@ add_action( 'wp_ajax_hmbkp_edit_schedule_submit', 'hmbkp_edit_schedule_submit' )
504
  */
505
  function hmbkp_add_exclude_rule() {
506
 
507
- check_ajax_referer( 'hmbkp_nonce', 'nonce' );
508
 
509
- if ( empty( $_POST['hmbkp_schedule_id'] ) )
510
- die;
 
511
 
512
- $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( $_POST['hmbkp_schedule_id'] ) );
513
 
514
- $schedule->set_excludes( sanitize_text_field( $_POST['hmbkp_exclude_rule'] ), true );
 
 
515
 
516
  $schedule->save();
517
 
518
- require( HMBKP_PLUGIN_PATH . '/admin/schedule-form-excludes.php' );
 
 
 
 
 
 
519
 
520
  die;
521
 
522
  }
523
- add_action( 'wp_ajax_hmbkp_add_exclude_rule', 'hmbkp_add_exclude_rule' );
524
 
525
  /**
526
  * Delete an exclude rule
@@ -528,73 +494,96 @@ add_action( 'wp_ajax_hmbkp_add_exclude_rule', 'hmbkp_add_exclude_rule' );
528
  * @access public
529
  * @return void
530
  */
531
- function hmbkp_delete_exclude_rule() {
532
 
533
- if ( empty( $_GET['hmbkp_schedule_id'] ) )
 
 
534
  die;
 
535
 
536
  $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( $_GET['hmbkp_schedule_id'] ) );
537
 
538
  $excludes = $schedule->get_excludes();
539
 
540
- $schedule->set_excludes( array_diff( $excludes, (array) stripslashes( sanitize_text_field( $_GET['hmbkp_exclude_rule'] ) ) ) );
541
 
542
  $schedule->save();
543
 
544
- require( HMBKP_PLUGIN_PATH . '/admin/schedule-form-excludes.php' );
 
 
 
 
 
 
545
 
546
  die;
547
 
548
  }
549
- add_action( 'wp_ajax_hmbkp_delete_exclude_rule', 'hmbkp_delete_exclude_rule' );
550
 
551
  /**
552
- * Ajax action for previewing an exclude rule.
553
  *
554
- * @access public
555
- * @return void
556
  */
557
- function hmbkp_preview_exclude_rule() {
558
 
559
- check_ajax_referer( 'hmbkp_nonce', 'nonce' );
 
 
560
 
561
- if ( empty( $_POST['hmbkp_schedule_id'] ) || empty( $_POST['hmbkp_schedule_excludes'] ) )
562
- die;
563
 
564
- $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( $_POST['hmbkp_schedule_id'] ) );
565
 
566
- $excludes = explode( ',', sanitize_text_field( $_POST['hmbkp_schedule_excludes'] ) );
 
567
 
568
- hmbkp_file_list( $schedule, $excludes, 'get_excluded_files' );
569
 
570
- $schedule->set_excludes( $excludes );
 
 
571
 
572
- if ( $schedule->get_excluded_file_count() ) { ?>
 
573
 
574
- <p><?php printf( _n( '%s matches 1 file.', '%1$s matches %2$d files.', $schedule->get_excluded_file_count(), 'hmbkp' ), '<code>' . implode( '</code>, <code>', array_map( 'esc_html', $excludes ) ) . '</code>', $schedule->get_excluded_file_count() ); ?></p>
 
575
 
576
- <?php } else { ?>
 
 
 
577
 
578
- <p><?php printf( __( '%s didn\'t match any files.', 'hmbkp' ), '<code>' . implode( '</code>, <code>', array_map( 'esc_html', $excludes ) ) . '</code>' ); ?></p>
579
 
580
- <?php } ?>
581
 
582
- <p>
583
- <button type="button" class="button-primary hmbkp_save_exclude_rule"><?php _e( 'Exclude', 'hmbkp' ); ?></button>
584
- <button type="button" class="button-secondary hmbkp_cancel_save_exclude_rule"><?php _e( 'Cancel', 'hmbkp' ); ?></button>
585
- </p>
586
 
587
- <?php die;
 
 
 
 
 
 
 
588
 
589
  }
590
- add_action( 'wp_ajax_hmbkp_file_list', 'hmbkp_preview_exclude_rule', 10, 0 );
591
 
 
592
  function hmbkp_display_error_and_offer_to_email_it() {
593
 
594
  check_ajax_referer( 'hmbkp_nonce', 'nonce' );
595
 
596
- if ( empty( $_POST['hmbkp_error'] ) )
597
  die;
 
598
 
599
  $error = wp_strip_all_tags( stripslashes( $_POST['hmbkp_error'] ) );
600
 
@@ -614,8 +603,7 @@ function hmbkp_display_error_and_offer_to_email_it() {
614
 
615
  <pre><?php esc_html_e( $error ); ?></pre>
616
 
617
- <p class="description"><?php printf( __( 'You can email details of this error to %s so they can look into the issue.', 'hmbkp' ), '<a href="http://hmn.md">Human Made Limited</a>' ); ?>
618
- <br /><br /></p>
619
 
620
  <button class="button hmbkp-colorbox-close"><?php _e( 'Close', 'hmbkp' ); ?></button>
621
  <button class="button-primary hmbkp_send_error_via_email right"><?php _e( 'Email to Support', 'hmbkp' ); ?></button>
@@ -625,12 +613,14 @@ function hmbkp_display_error_and_offer_to_email_it() {
625
  }
626
  add_action( 'wp_ajax_hmbkp_backup_error', 'hmbkp_display_error_and_offer_to_email_it' );
627
 
 
628
  function hmbkp_send_error_via_email() {
629
 
630
  check_ajax_referer( 'hmbkp_nonce', 'nonce' );
631
 
632
- if ( empty( $_POST['hmbkp_error'] ) )
633
  die;
 
634
 
635
  $error = wp_strip_all_tags( $_POST['hmbkp_error'] );
636
 
@@ -652,7 +642,97 @@ function hmbkp_load_enable_support() {
652
 
653
  require_once HMBKP_PLUGIN_PATH . 'admin/enable-support.php';
654
 
655
- die();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
656
 
657
  }
658
- add_action( 'wp_ajax_load_enable_support', 'hmbkp_load_enable_support' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
 
3
  /**
4
+ * Delete the backup and then redirect back to the backups page
 
5
  */
6
  function hmbkp_request_delete_backup() {
7
 
8
+ check_admin_referer( 'hmbkp_delete_backup', 'hmbkp_delete_backup_nonce' );
 
9
 
10
  $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( urldecode( $_GET['hmbkp_schedule_id'] ) ) );
11
 
12
+ $deleted = $schedule->delete_backup( sanitize_text_field( base64_decode( $_GET['hmbkp_backup_archive'] ) ) );
13
 
14
+ if ( is_wp_error( $deleted ) ) {
15
  wp_die( $deleted->get_error_message() );
16
+ }
17
 
18
+ wp_safe_redirect( hmbkp_get_settings_url(), 303 );
19
 
20
  die;
21
 
22
  }
23
+ add_action( 'admin_post_hmbkp_request_delete_backup', 'hmbkp_request_delete_backup' );
24
 
25
  /**
26
  * Enable support and then redirect back to the backups page
 
27
  */
28
  function hmbkp_request_enable_support() {
29
 
30
+ check_admin_referer( 'hmbkp_enable_support', 'hmbkp_enable_support_nonce' );
 
31
 
32
  update_option( 'hmbkp_enable_support', true );
33
 
34
+ wp_safe_redirect( hmbkp_get_settings_url(), 303 );
35
 
36
  die;
37
 
38
  }
39
+ add_action( 'admin_post_hmbkp_request_enable_support', 'hmbkp_request_enable_support' );
40
 
41
  /**
42
+ * Delete a schedule and all it's backups and then redirect back to the backups page
 
43
  */
44
  function hmbkp_request_delete_schedule() {
45
 
46
+ check_admin_referer( 'hmbkp_delete_schedule', 'hmbkp_delete_schedule_nonce' );
 
47
 
48
  $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( urldecode( $_GET['hmbkp_schedule_id'] ) ) );
49
  $schedule->cancel( true );
50
 
51
+ wp_safe_redirect( hmbkp_get_settings_url(), 303 );
52
 
53
  die;
54
 
55
  }
56
+ add_action( 'admin_post_hmbkp_request_delete_schedule', 'hmbkp_request_delete_schedule' );
57
 
58
  /**
59
+ * Perform a manual backup
60
+ *
61
+ * Handles ajax requests as well as standard GET requests
62
  */
63
+ function hmbkp_request_do_backup() {
64
+
65
+ if ( empty( $_GET['hmbkp_schedule_id'] ) ) {
66
+ die;
67
+ }
68
+
69
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
70
+ check_ajax_referer( 'hmbkp_run_schedule', 'hmbkp_run_schedule_nonce' );
71
+ } else {
72
+ check_admin_referer( 'hmbkp-run-schedule', 'hmbkp-run-schedule' );
73
+ }
74
+
75
 
 
76
 
77
  // Fixes an issue on servers which only allow a single session per client
78
  session_write_close();
79
 
 
 
 
80
  // We want to display any fatal errors in this ajax request so we can catch them on the other side.
81
  error_reporting( E_ERROR | E_USER_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_RECOVERABLE_ERROR );
82
  @ini_set( 'display_errors', 'On' );
93
 
94
  hmbkp_cleanup();
95
 
96
+ $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( urldecode( $_GET['hmbkp_schedule_id'] ) ) );
97
 
98
  $schedule->run();
99
 
101
 
102
  $error_message = '';
103
 
104
+ foreach ( $errors as $error_set ) {
105
  $error_message .= implode( "\n\r", $error_set );
106
+ }
107
 
108
+ if ( $error_message && file_exists( $schedule->get_archive_filepath() ) && defined( 'DOING_AJAX' ) && DOING_AJAX ) {
109
  $error_message .= 'HMBKP_SUCCESS';
110
+ }
111
 
112
+ if ( trim( $error_message ) && defined( 'DOING_AJAX' ) && DOING_AJAX ) {
113
  echo $error_message;
114
+ }
115
+
116
+ if ( trim( $error_message ) && defined( 'DOING_AJAX' ) ) {
117
+ wp_die( $error_message );
118
+ }
119
+
120
+ if ( ! defined( 'DOING_AJAX' ) ) {
121
+ wp_safe_redirect( hmbkp_get_settings_url(), '303' );
122
+ }
123
 
124
  die;
125
 
126
  }
127
+ add_action( 'wp_ajax_hmbkp_run_schedule', 'hmbkp_request_do_backup' );
128
+ add_action( 'admin_post_hmbkp_request_do_backup', 'hmbkp_request_do_backup' );
129
 
130
  /**
131
+ * Send the download file to the browser and then redirect back to the backups page
 
132
  */
133
  function hmbkp_request_download_backup() {
134
 
135
+ check_admin_referer( 'hmbkp_download_backup', 'hmbkp_download_backup_nonce' );
136
 
137
+ if ( ! file_exists( sanitize_text_field( base64_decode( $_GET['hmbkp_backup_archive'] ) ) ) ) {
138
  return;
139
+ }
140
 
141
+ $url = str_replace( HM_Backup::conform_dir( HM_Backup::get_home_path() ), home_url(), trailingslashit( dirname( sanitize_text_field( base64_decode( $_GET['hmbkp_backup_archive'] ) ) ) ) ) . urlencode( pathinfo( sanitize_text_field( base64_decode( $_GET['hmbkp_backup_archive'] ) ), PATHINFO_BASENAME ) );
142
+
143
+ global $is_apache;
144
 
145
  if ( $is_apache ) {
146
 
159
  die;
160
 
161
  }
162
+ add_action( 'admin_post_hmbkp_request_download_backup', 'hmbkp_request_download_backup' );
163
 
164
  /**
165
+ * Cancels a running backup then redirect back to the backups page
 
166
  */
167
  function hmbkp_request_cancel_backup() {
168
 
169
+ check_admin_referer( 'hmbkp_request_cancel_backup', 'hmbkp_request_cancel_backup_nonce' );
 
170
 
171
  $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( urldecode( $_GET['hmbkp_schedule_id'] ) ) );
172
 
173
  // Delete the running backup
174
+ if ( $schedule->get_running_backup_filename() && file_exists( trailingslashit( hmbkp_path() ) . $schedule->get_running_backup_filename() ) ) {
175
  unlink( trailingslashit( hmbkp_path() ) . $schedule->get_running_backup_filename() );
176
+ }
177
 
178
+ if ( $schedule->get_schedule_running_path() && file_exists( $schedule->get_schedule_running_path() ) ) {
179
  unlink( $schedule->get_schedule_running_path() );
180
+ }
181
 
182
  hmbkp_cleanup();
183
 
184
+ wp_safe_redirect( hmbkp_get_settings_url(), 303 );
185
 
186
  die;
187
 
188
  }
189
+ add_action( 'admin_post_hmbkp_request_cancel_backup', 'hmbkp_request_cancel_backup' );
190
 
191
  /**
192
+ * Dismiss an error and then redirect back to the backups page
 
193
  */
194
  function hmbkp_dismiss_error() {
195
 
196
+ // TODO Should really be nonced
197
+
198
+ if ( empty( $_GET['action'] ) || $_GET['action'] !== 'hmbkp_dismiss_error' ) {
199
  return;
200
+ }
201
 
202
  hmbkp_cleanup();
203
 
204
+ wp_safe_redirect( hmbkp_get_settings_url(), 303 );
205
 
206
  die;
207
 
209
  add_action( 'admin_init', 'hmbkp_dismiss_error' );
210
 
211
  /**
212
+ * Catch the schedule service settings form submission
213
+ *
214
+ * Validate and either return errors or update the schedule
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
  */
216
+ function hmbkp_edit_schedule_services_submit() {
 
 
 
 
217
 
218
+ check_admin_referer( 'hmbkp-edit-schedule-services', 'hmbkp-edit-schedule-services-nonce' );
 
 
 
 
219
 
220
+ if ( empty( $_POST['hmbkp_schedule_id'] ) ) {
221
+ wp_die( __( 'The schedule ID was not provided. Aborting.', 'hmbkp' ) );
222
  }
223
 
224
+ $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( $_POST['hmbkp_schedule_id'] ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
 
226
+ hmbkp_clear_settings_errors();
227
 
228
+ $errors = array();
229
 
230
+ // Save the service options
231
+ foreach ( HMBKP_Services::get_services( $schedule ) as $service ) {
232
+ $errors = array_merge( $errors, $service->save() );
233
  }
234
 
235
+ $schedule->save();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
 
237
+ if ( $errors ) {
 
 
 
238
 
239
+ foreach ( $errors as $error ) {
240
+ hmbkp_add_settings_error( $error );
241
+ }
 
242
 
243
+ }
244
 
245
+ wp_safe_redirect( wp_get_referer(), '303' );
246
  die;
247
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
 
249
  }
250
+ add_action( 'admin_post_hmbkp_edit_schedule_services_submit', 'hmbkp_edit_schedule_services_submit' );
251
 
252
  /**
253
+ * Catch the schedule settings form submission
254
  *
255
  * Validate and either return errors or update the schedule
256
  */
257
  function hmbkp_edit_schedule_submit() {
258
 
259
+ check_admin_referer( 'hmbkp-edit-schedule', 'hmbkp-edit-schedule-nonce' );
260
 
261
+ if ( empty( $_POST['hmbkp_schedule_id'] ) ) {
262
  die;
263
+ }
264
 
265
+ $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( $_POST['hmbkp_schedule_id'] ) );
266
+
267
+ hmbkp_clear_settings_errors();
268
 
269
  $errors = array();
270
 
271
+ $settings = array();
 
272
 
273
+ if ( isset( $_POST['hmbkp_schedule_type'] ) ) {
 
 
274
 
275
+ $schedule_type = sanitize_text_field( $_POST['hmbkp_schedule_type'] );
276
 
277
+ if ( ! trim( $schedule_type ) ) {
278
+ $errors['hmbkp_schedule_type'] = __( 'Backup type cannot be empty', 'hmbkp' );
279
+ }
 
280
 
281
+ elseif ( ! in_array( $schedule_type, array( 'complete', 'file', 'database' ) ) ) {
282
+ $errors['hmbkp_schedule_type'] = __( 'Invalid backup type', 'hmbkp' );
283
+ }
284
 
285
+ else {
286
+ $settings['type'] = $schedule_type;
287
+ }
288
 
289
+ }
290
 
291
+ if ( isset( $_POST['hmbkp_schedule_recurrence']['hmbkp_type'] ) ) {
292
 
293
+ $schedule_recurrence_type = sanitize_text_field( $_POST['hmbkp_schedule_recurrence']['hmbkp_type'] );
294
 
295
+ if ( empty( $schedule_recurrence_type ) ) {
296
+ $errors['hmbkp_schedule_recurrence']['hmbkp_type'] = __( 'Schedule cannot be empty', 'hmbkp' );
297
+ }
298
 
299
+ elseif ( ! in_array( $schedule_recurrence_type, array_keys( hmbkp_get_cron_schedules() ) ) && $schedule_recurrence_type !== 'manually' ) {
300
+ $errors['hmbkp_schedule_recurrence']['hmbkp_type'] = __( 'Invalid schedule', 'hmbkp' );
301
+ }
302
 
303
+ else {
304
+ $settings['recurrence'] = $schedule_recurrence_type;
305
+ }
306
 
307
+ }
 
308
 
309
+ if ( isset( $_POST['hmbkp_schedule_recurrence']['hmbkp_schedule_start_day_of_week'] ) ) {
310
 
311
+ $day_of_week = sanitize_text_field( $_POST['hmbkp_schedule_recurrence']['hmbkp_schedule_start_day_of_week'] );
 
312
 
313
+ if ( ! in_array( $day_of_week, array( 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday' ) ) ) {
314
+ $errors['hmbkp_schedule_start_day_of_week'] = __( 'Day of the week must be a valid lowercase day name', 'hmbkp' );
315
+ }
316
 
317
+ else {
318
+ $settings['start_time']['day_of_week'] = $day_of_week;
319
+ }
320
 
321
+ }
322
 
323
+ if ( isset( $_POST['hmbkp_schedule_recurrence']['hmbkp_schedule_start_day_of_month'] ) ) {
324
 
325
+ $day_of_month = absint( $_POST['hmbkp_schedule_recurrence']['hmbkp_schedule_start_day_of_month'] );
326
 
327
+ $options = array(
328
+ 'min_range' => 1,
329
+ 'max_range' => 31
330
+ );
331
 
332
+ if ( false === filter_var( $day_of_month, FILTER_VALIDATE_INT, array( 'options' => $options ) ) ) {
333
+ $errors['hmbkp_schedule_start_day_of_month'] = __( 'Day of month must be between 1 and 31', 'hmbkp' );
334
+ }
335
 
336
+ else {
337
+ $settings['start_time']['day_of_month'] = $day_of_month;
338
+ }
339
 
340
+ }
341
 
342
+ if ( isset( $_POST['hmbkp_schedule_recurrence']['hmbkp_schedule_start_hours'] ) ) {
343
 
344
+ $hours = absint( $_POST['hmbkp_schedule_recurrence']['hmbkp_schedule_start_hours'] );
 
 
 
345
 
346
+ $options = array(
347
+ 'min_range' => 0,
348
+ 'max_range' => 23
349
+ );
350
 
351
+ if ( false === filter_var( $hours, FILTER_VALIDATE_INT, array( 'options' => $options ) ) ) {
352
+ $errors['hmbkp_schedule_start_hours'] = __( 'Hours must be between 0 and 23', 'hmbkp' );
353
+ }
354
 
355
+ else {
356
+ $settings['start_time']['hours'] = $hours;
357
+ }
358
 
359
+ }
360
 
361
+ if ( isset( $_POST['hmbkp_schedule_recurrence']['hmbkp_schedule_start_minutes'] ) ) {
 
 
 
362
 
363
+ $minutes = absint( $_POST['hmbkp_schedule_recurrence']['hmbkp_schedule_start_minutes'] );
 
364
 
365
+ $options = array(
366
+ 'min_range' => 0,
367
+ 'max_range' => 59
368
+ );
369
 
370
+ if ( false === filter_var( $minutes, FILTER_VALIDATE_INT, array( 'options' => $options ) ) ) {
371
+ $errors['hmbkp_schedule_start_minutes'] = __( 'Minutes must be between 0 and 59', 'hmbkp' );
372
+ }
373
 
374
+ else {
375
+ $settings['start_time']['minutes'] = $minutes;
376
+ }
377
 
378
+ }
 
 
 
379
 
380
+ if ( isset( $_POST['hmbkp_schedule_max_backups'] ) ) {
 
381
 
382
+ $max_backups = sanitize_text_field( $_POST['hmbkp_schedule_max_backups'] );
383
 
384
+ if ( empty( $max_backups ) ) {
385
+ $errors['hmbkp_schedule_max_backups'] = __( 'Max backups can\'t be empty', 'hmbkp' );
386
  }
387
 
388
+ elseif ( ! is_numeric( $max_backups ) ) {
389
+ $errors['hmbkp_schedule_max_backups'] = __( 'Max backups must be a number', 'hmbkp' );
390
+ }
391
 
392
+ elseif ( ! ( $max_backups >= 1 ) ) {
393
+ $errors['hmbkp_schedule_max_backups'] = __( 'Max backups must be greater than 0', 'hmbkp' );
394
+ }
395
 
396
+ else {
397
+ $settings['max_backups'] = absint( $max_backups );
398
+ }
399
 
400
+ }
 
401
 
402
+ // Save the service options
403
+ foreach ( HMBKP_Services::get_services( $schedule ) as $service ) {
404
+ $errors = array_merge( $errors, $service->save() );
405
+ }
406
 
407
+ if ( ! empty( $settings['recurrence'] ) && ! empty( $settings['start_time'] ) ) {
 
408
 
409
+ // Calculate the start time depending on the recurrence
410
+ $start_time = hmbkp_determine_start_time( $settings['recurrence'], $settings['start_time'] );
411
 
412
+ if ( $start_time ) {
413
+ $schedule->set_schedule_start_time( $start_time );
 
414
  }
415
 
416
+ }
 
417
 
418
+ if ( ! empty( $settings['recurrence'] ) ) {
419
+ $schedule->set_reoccurrence( $settings['recurrence'] );
420
+ }
421
 
422
+ if ( ! empty( $settings['type'] ) ) {
423
+ $schedule->set_type( $settings['type'] );
424
+ }
425
 
426
+ if ( ! empty( $settings['max_backups'] ) ) {
427
+ $schedule->set_max_backups( $settings['max_backups'] );
428
+ }
429
 
430
+ // Save the new settings
431
+ $schedule->save();
432
 
433
+ // Remove any old backups in-case max backups was reduced
434
+ $schedule->delete_old_backups();
435
 
436
+ if ( $errors ) {
437
 
438
+ foreach ( $errors as $error ) {
439
+ hmbkp_add_settings_error( $error );
440
  }
441
 
442
  }
443
 
444
+ $redirect = remove_query_arg( array( 'hmbkp_panel', 'action' ), wp_get_referer() );
445
+
446
+ if ( $errors ) {
447
+ $redirect = wp_get_referer();
448
+ }
449
+
450
+ wp_safe_redirect( $redirect, '303' );
451
+ die;
452
 
453
  }
454
+ add_action( 'admin_post_hmbkp_edit_schedule_submit', 'hmbkp_edit_schedule_submit' );
455
 
456
  /**
457
  * Add an exclude rule
461
  */
462
  function hmbkp_add_exclude_rule() {
463
 
464
+ check_admin_referer( 'hmbkp-add-exclude-rule', 'hmbkp-add-exclude-rule-nonce' );
465
 
466
+ if ( ! isset( $_GET['hmbkp_exclude_pathname'] ) ) {
467
+ return;
468
+ }
469
 
470
+ $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( $_GET['hmbkp_schedule_id'] ) );
471
 
472
+ $exclude_rule = str_ireplace( $schedule->get_root(), '', sanitize_text_field( $_GET['hmbkp_exclude_pathname'] ) );
473
+
474
+ $schedule->set_excludes( $exclude_rule, true );
475
 
476
  $schedule->save();
477
 
478
+ $url = add_query_arg( array( 'action' => 'hmbkp_edit_schedule', 'hmbkp_panel' => 'hmbkp_edit_schedule_excludes#directory-listing' ), hmbkp_get_settings_url() );
479
+
480
+ if ( isset( $_GET['hmbkp_directory_browse'] ) ) {
481
+ $url = add_query_arg( 'hmbkp_directory_browse', sanitize_text_field( $_GET['hmbkp_directory_browse'] ), $url );
482
+ }
483
+
484
+ wp_safe_redirect( $url, '303' );
485
 
486
  die;
487
 
488
  }
489
+ add_action( 'admin_post_hmbkp_add_exclude_rule', 'hmbkp_add_exclude_rule' );
490
 
491
  /**
492
  * Delete an exclude rule
494
  * @access public
495
  * @return void
496
  */
497
+ function hmbkp_remove_exclude_rule() {
498
 
499
+ check_admin_referer( 'hmbkp_remove_exclude_rule', 'hmbkp-remove_exclude_rule_nonce' );
500
+
501
+ if ( ! isset( $_GET['hmbkp_remove_exclude'] ) ) {
502
  die;
503
+ }
504
 
505
  $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( $_GET['hmbkp_schedule_id'] ) );
506
 
507
  $excludes = $schedule->get_excludes();
508
 
509
+ $schedule->set_excludes( array_diff( $excludes, (array) stripslashes( sanitize_text_field( $_GET['hmbkp_remove_exclude'] ) ) ) );
510
 
511
  $schedule->save();
512
 
513
+ $url = add_query_arg( array( 'action' => 'hmbkp_edit_schedule', 'hmbkp_panel' => 'hmbkp_edit_schedule_excludes' ), hmbkp_get_settings_url() );
514
+
515
+ if ( isset( $_GET['hmbkp_directory_browse'] ) ) {
516
+ $url = add_query_arg( 'hmbkp_directory_browse', sanitize_text_field( $_GET['hmbkp_directory_browse'] ), $url );
517
+ }
518
+
519
+ wp_safe_redirect( $url, '303' );
520
 
521
  die;
522
 
523
  }
524
+ add_action( 'admin_post_hmbkp_remove_exclude_rule', 'hmbkp_remove_exclude_rule' );
525
 
526
  /**
 
527
  *
528
+ * @param null $pathname
 
529
  */
530
+ function hmbkp_recalculate_directory_filesize() {
531
 
532
+ if ( ! isset( $_GET['hmbkp_recalculate_directory_filesize'] ) || ! check_admin_referer( 'hmbkp-recalculate_directory_filesize' ) ) {
533
+ return;
534
+ }
535
 
536
+ $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( $_GET['hmbkp_schedule_id'] ) );
 
537
 
538
+ $directory = sanitize_text_field( $_GET['hmbkp_recalculate_directory_filesize'] );
539
 
540
+ // Delete the cached directory size
541
+ delete_transient( 'hmbkp_directory_filesizes' );
542
 
543
+ $url = add_query_arg( array( 'action' => 'hmbkp_edit_schedule', 'hmbkp_panel' => 'hmbkp_edit_schedule_excludes' ), hmbkp_get_settings_url() );
544
 
545
+ if ( isset( $_GET['hmbkp_directory_browse'] ) ) {
546
+ $url = add_query_arg( 'hmbkp_directory_browse', sanitize_text_field( $_GET['hmbkp_directory_browse'] ), $url );
547
+ }
548
 
549
+ wp_safe_redirect( $url, '303' );
550
+ die;
551
 
552
+ }
553
+ add_action( 'load-' . HMBKP_ADMIN_PAGE, 'hmbkp_recalculate_directory_filesize' );
554
 
555
+ /**
556
+ * Receive the heartbeat and return backup status
557
+ */
558
+ function hmbkp_heartbeat_received( $response, $data ) {
559
 
560
+ if ( ! empty( $data['hmbkp_is_in_progress'] ) ) {
561
 
562
+ $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( urldecode( $data['hmbkp_is_in_progress'] ) ) );
563
 
564
+ if ( ! $schedule->get_status() ) {
565
+ $response['hmbkp_schedule_status'] = 0;
 
 
566
 
567
+ } else {
568
+ $response['hmbkp_schedule_status'] = hmbkp_schedule_status( $schedule, false );
569
+
570
+ }
571
+
572
+ }
573
+
574
+ return $response;
575
 
576
  }
577
+ add_filter( 'heartbeat_received', 'hmbkp_heartbeat_received', 10, 2 );
578
 
579
+ // TODO needs work
580
  function hmbkp_display_error_and_offer_to_email_it() {
581
 
582
  check_ajax_referer( 'hmbkp_nonce', 'nonce' );
583
 
584
+ if ( empty( $_POST['hmbkp_error'] ) ) {
585
  die;
586
+ }
587
 
588
  $error = wp_strip_all_tags( stripslashes( $_POST['hmbkp_error'] ) );
589
 
603
 
604
  <pre><?php esc_html_e( $error ); ?></pre>
605
 
606
+ <p class="description"><?php printf( __( 'You can email details of this error to %s so they can look into the issue.', 'hmbkp' ), '<a href="http://hmn.md">Human Made Limited</a>' ); ?><br /><br /></p>
 
607
 
608
  <button class="button hmbkp-colorbox-close"><?php _e( 'Close', 'hmbkp' ); ?></button>
609
  <button class="button-primary hmbkp_send_error_via_email right"><?php _e( 'Email to Support', 'hmbkp' ); ?></button>
613
  }
614
  add_action( 'wp_ajax_hmbkp_backup_error', 'hmbkp_display_error_and_offer_to_email_it' );
615
 
616
+ // TODO needs work
617
  function hmbkp_send_error_via_email() {
618
 
619
  check_ajax_referer( 'hmbkp_nonce', 'nonce' );
620
 
621
+ if ( empty( $_POST['hmbkp_error'] ) ) {
622
  die;
623
+ }
624
 
625
  $error = wp_strip_all_tags( $_POST['hmbkp_error'] );
626
 
642
 
643
  require_once HMBKP_PLUGIN_PATH . 'admin/enable-support.php';
644
 
645
+ die;
646
+
647
+ }
648
+ add_action( 'wp_ajax_load_enable_support', 'hmbkp_load_enable_support' );
649
+
650
+ /**
651
+ * Display the running status via ajax
652
+ */
653
+ function hmbkp_ajax_is_backup_in_progress() {
654
+
655
+ check_ajax_referer( 'hmbkp_nonce', 'nonce' );
656
+
657
+ if ( empty( $_POST['hmbkp_schedule_id'] ) ) {
658
+ die;
659
+ }
660
+
661
+ $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( urldecode( $_POST['hmbkp_schedule_id'] ) ) );
662
+
663
+ if ( ! $schedule->get_status() ) {
664
+ echo 0;
665
+ } else {
666
+ hmbkp_schedule_status( $schedule );
667
+ }
668
+
669
+ die;
670
+
671
+ }
672
+ add_action( 'wp_ajax_hmbkp_is_in_progress', 'hmbkp_ajax_is_backup_in_progress' );
673
+
674
+ /**
675
+ * Display the calculated size via ajax
676
+ */
677
+ function hmbkp_ajax_calculate_backup_size() {
678
+
679
+ check_ajax_referer( 'hmbkp_nonce', 'nonce' );
680
+
681
+ if ( empty( $_POST['hmbkp_schedule_id'] ) ) {
682
+ die;
683
+ }
684
+
685
+ $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( urldecode( $_POST['hmbkp_schedule_id'] ) ) );
686
+
687
+ $recalculate_filesize = true;
688
+
689
+ require( HMBKP_PLUGIN_PATH . 'admin/schedule-sentence.php' );
690
+
691
+ die;
692
 
693
  }
694
+ add_action( 'wp_ajax_hmbkp_calculate', 'hmbkp_ajax_calculate_backup_size' );
695
+
696
+ /**
697
+ * Test the cron response and if it's not 200 show a warning message
698
+ */
699
+ function hmbkp_ajax_cron_test() {
700
+
701
+ check_ajax_referer( 'hmbkp_nonce', 'nonce' );
702
+
703
+ if ( defined( 'ALTERNATE_WP_CRON' ) ) {
704
+
705
+ delete_option( 'hmbkp_wp_cron_test_failed' );
706
+
707
+ echo 1;
708
+
709
+ die;
710
+
711
+ }
712
+
713
+ $response = wp_remote_head( site_url( 'wp-cron.php' ), array( 'timeout' => 30 ) );
714
+
715
+ if ( is_wp_error( $response ) ) {
716
+
717
+ echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . sprintf( __( '%1$s is returning a %2$s response which could mean cron jobs aren\'t getting fired properly. BackUpWordPress relies on wp-cron to run scheduled backups. See the %3$s for more details.', 'hmbkp' ), '<code>wp-cron.php</code>', '<code>' . $response->get_error_message() . '</code>', '<a href="http://wordpress.org/extend/plugins/backupwordpress/faq/">FAQ</a>' ) . '</p></div>';
718
+
719
+ update_option( 'hmbkp_wp_cron_test_failed', true );
720
+
721
+ } elseif ( wp_remote_retrieve_response_code( $response ) !== 200 ) {
722
+
723
+ echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . sprintf( __( '%1$s is returning a %2$s response which could mean cron jobs aren\'t getting fired properly. BackUpWordPress relies on wp-cron to run scheduled backups. See the %3$s for more details.', 'hmbkp' ), '<code>wp-cron.php</code>', '<code>' . esc_html( wp_remote_retrieve_response_code( $response ) ) . ' ' . esc_html( get_status_header_desc( wp_remote_retrieve_response_code( $response ) ) ) . '</code>', '<a href="http://wordpress.org/extend/plugins/backupwordpress/faq/">FAQ</a>' ) . '</p></div>';
724
+
725
+ update_option( 'hmbkp_wp_cron_test_failed', true );
726
+
727
+ } else {
728
+
729
+ echo 1;
730
+
731
+ delete_option( 'hmbkp_wp_cron_test_failed' );
732
+
733
+ }
734
+
735
+ die;
736
+
737
+ }
738
+ add_action( 'wp_ajax_hmbkp_cron_test', 'hmbkp_ajax_cron_test' );
admin/backups-table.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <table class="widefat">
2
+
3
+ <thead>
4
+
5
+ <tr>
6
+
7
+ <th scope="col"><?php hmbkp_backups_number( $schedule ); ?></th>
8
+ <th scope="col"><?php _e( 'Size', 'hmbkp' ); ?></th>
9
+ <th scope="col"><?php _e( 'Type', 'hmbkp' ); ?></th>
10
+ <th scope="col"><?php _e( 'Actions', 'hmbkp' ); ?></th>
11
+
12
+ </tr>
13
+
14
+ </thead>
15
+
16
+ <tbody>
17
+
18
+ <?php if ( $schedule->get_backups() ) {
19
+
20
+ $schedule->delete_old_backups();
21
+
22
+ foreach ( $schedule->get_backups() as $file ) {
23
+
24
+ if ( ! file_exists( $file ) ) {
25
+ continue;
26
+ }
27
+
28
+ hmbkp_get_backup_row( $file, $schedule );
29
+
30
+ }
31
+
32
+ } else { ?>
33
+
34
+ <tr>
35
+ <td class="hmbkp-no-backups" colspan="4"><?php _e( 'This is where your backups will appear once you have some.', 'hmbkp' ); ?></td>
36
+ </tr>
37
+
38
+ <?php } ?>
39
+
40
+ </tbody>
41
+
42
+ </table>
admin/backups.php CHANGED
@@ -1,127 +1,49 @@
1
- <?php $schedules = HMBKP_Schedules::get_instance(); ?>
2
-
3
- <div>
4
-
5
- <ul class="subsubsub">
6
-
7
- <?php
8
- // possible titles
9
- $titles = array(
10
- 'complete-hourly' => esc_html__( 'Complete Hourly', 'hmbkp' ),
11
- 'file-hourly' => esc_html__( 'File Hourly', 'hmbkp' ),
12
- 'database-hourly' => esc_html__( 'Database Hourly', 'hmbkp' ),
13
- 'complete-twicedaily' => esc_html__( 'Complete Twicedaily', 'hmbkp' ),
14
- 'file-twicedaily' => esc_html__( 'File Twicedaily', 'hmbkp' ),
15
- 'database-twicedaily' => esc_html__( 'Database Twicedaily', 'hmbkp' ),
16
- 'complete-daily' => esc_html__( 'Complete Daily', 'hmbkp' ),
17
- 'file-daily' => esc_html__( 'File Daily', 'hmbkp' ),
18
- 'database-daily' => esc_html__( 'Database Daily', 'hmbkp' ),
19
- 'complete-weekly' => esc_html__( 'Complete Weekly', 'hmbkp' ),
20
- 'file-weekly' => esc_html__( 'File Weekly', 'hmbkp' ),
21
- 'database-weekly' => esc_html__( 'Database Weekly', 'hmbkp' ),
22
- 'complete-fortnightly' => esc_html__( 'Complete Fortnightly', 'hmbkp' ),
23
- 'file-fortnightly' => esc_html__( 'File Fortnightly', 'hmbkp' ),
24
- 'database-fortnightly' => esc_html__( 'Database Fortnightly', 'hmbkp' ),
25
- 'complete-monthly' => esc_html__( 'Complete Monthly', 'hmbkp' ),
26
- 'file-monthly' => esc_html__( 'File Monthly', 'hmbkp' ),
27
- 'database-monthly' => esc_html__( 'Database Monthly', 'hmbkp' ),
28
- 'complete-manually' => esc_html__( 'Complete Manually', 'hmbkp' ),
29
- 'file-manually' => esc_html__( 'File Manually', 'hmbkp' ),
30
- 'database-manually' => esc_html__( 'Database Manually', 'hmbkp' )
31
- );
32
-
33
-
34
- ?>
35
- <?php foreach ( $schedules->get_schedules() as $schedule ) : ?>
36
- <li<?php if ( $schedule->get_status() ) { ?> class="hmbkp-running" title="<?php echo esc_attr( strip_tags( $schedule->get_status() ) ); ?>"<?php } ?>><a<?php if ( ! empty ( $_GET['hmbkp_schedule_id'] ) && $schedule->get_id() == $_GET['hmbkp_schedule_id'] ) { ?> class="current"<?php } ?> href="<?php echo esc_url( add_query_arg( 'hmbkp_schedule_id', $schedule->get_id(), HMBKP_ADMIN_URL ) ); ?> "><?php printf( $titles[$schedule->get_slug()] ); ?> <span class="count">(<?php echo esc_html( count( $schedule->get_backups() ) ); ?>)</span></a></li>
37
-
38
- <?php endforeach; ?>
39
-
40
- <li><a class="colorbox" href="<?php esc_attr_e( esc_url( add_query_arg( array( 'action' => 'hmbkp_add_schedule_load' ), is_multisite() ? network_admin_url( 'admin-ajax.php' ) : admin_url( 'admin-ajax.php' ) ) ) ); ?>"> + <?php _e( 'add schedule', 'hmbkp' ); ?></a></li>
41
-
42
- </ul>
43
-
44
  <?php
45
 
46
- if ( ! empty( $_GET['hmbkp_schedule_id'] ) )
47
- $schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( $_GET['hmbkp_schedule_id'] ) );
48
-
49
- else {
50
-
51
- $schedules = $schedules->get_schedules();
52
-
53
- $schedule = reset( $schedules );
54
-
55
- }
56
-
57
- if ( ! $schedule )
58
- return; ?>
59
-
60
- <div data-hmbkp-schedule-id="<?php echo esc_attr( $schedule->get_id() ); ?>" class="hmbkp_schedule">
61
 
62
- <?php require( HMBKP_PLUGIN_PATH . '/admin/schedule.php' ); ?>
63
 
64
- <table class="widefat">
 
 
 
 
65
 
66
- <thead>
67
 
68
- <tr>
69
 
70
- <th scope="col"><?php hmbkp_backups_number( $schedule ); ?></th>
71
- <th scope="col"><?php _e( 'Size', 'hmbkp' ); ?></th>
72
- <th scope="col"><?php _e( 'Type', 'hmbkp' ); ?></th>
73
- <th scope="col"><?php _e( 'Actions', 'hmbkp' ); ?></th>
74
 
75
- </tr>
76
-
77
- </thead>
78
-
79
- <tbody>
80
-
81
- <?php
82
-
83
- if ( $schedule->get_backups() ) :
84
-
85
- $schedule->delete_old_backups();
86
-
87
- foreach ( $schedule->get_backups() as $file ) :
88
-
89
- if ( ! file_exists( $file ) )
90
- continue;
91
-
92
- hmbkp_get_backup_row( $file, $schedule );
93
-
94
- endforeach;
95
 
96
- else : ?>
97
 
98
- <tr>
99
 
100
- <td class="hmbkp-no-backups" colspan="4"><?php _e( 'This is where your backups will appear once you have some.', 'hmbkp' ); ?></td>
101
 
102
- </tr>
103
 
104
- <?php endif; ?>
105
 
106
- </tbody>
107
 
108
- </table>
109
 
110
- </div>
111
 
112
- </div>
 
 
 
113
 
114
- <?php
115
- function hmbkp_backups_number( $schedule, $zero = false, $one = false, $more = false ) {
116
 
117
- $number = count( $schedule->get_backups() );
118
 
119
- if ( $number > 1 )
120
- $output = str_replace( '%', number_format_i18n( $number ), ( false === $more ) ? __( '% Backups Completed', 'hmbkp' ) : $more );
121
- elseif ( $number == 0 )
122
- $output = ( false === $zero ) ? __( 'No Backups Completed', 'hmbkp' ) : $zero;
123
- else // must be one
124
- $output = ( false === $one ) ? __( '1 Backup Completed', 'hmbkp' ) : $one;
125
 
126
- echo apply_filters( 'hmbkp_backups_number', $output, $number );
127
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
 
3
+ // Refresh the schedules from the database to make sure we have the latest changes
4
+ HMBKP_Schedules::get_instance()->refresh_schedules();
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
+ $schedules = HMBKP_Schedules::get_instance()->get_schedules();
7
 
8
+ if ( ! empty( $_GET['hmbkp_schedule_id'] ) ) {
9
+ $current_schedule = new HMBKP_Scheduled_Backup( sanitize_text_field( $_GET['hmbkp_schedule_id'] ) );
10
+ } else {
11
+ $current_schedule = reset( $schedules );
12
+ } ?>
13
 
14
+ <h2 class="nav-tab-wrapper">
15
 
16
+ <?php foreach ( $schedules as $schedule ) : ?>
17
 
18
+ <a class="nav-tab<?php if ( $schedule->get_status() ) { ?> hmbkp-running<?php } ?><?php if ( $schedule->get_id() === $current_schedule->get_id() ) { ?> nav-tab-active<?php } ?>" <?php if ( $schedule->get_status() ) { ?>title="<?php echo esc_attr( strip_tags( $schedule->get_status() ) ); ?>"<?php } ?> href="<?php echo esc_url( add_query_arg( 'hmbkp_schedule_id', $schedule->get_id(), HMBKP_ADMIN_URL ) ); ?> "><?php echo esc_html( hmbkp_translated_schedule_title( $schedule->get_slug(), $schedule->get_name() ) ); ?> <span class="count">(<?php echo esc_html( count( $schedule->get_backups() ) ); ?>)</span></a>
 
 
 
19
 
20
+ <?php endforeach; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
+ <a class="nav-tab<?php if ( ! HMBKP_Schedules::get_instance()->get_schedule( $current_schedule->get_id() ) ) { ?> nav-tab-active<?php } ?>" href="<?php echo esc_url( add_query_arg( array( 'hmbkp_add_schedule' => '1', 'action' => 'hmbkp_edit_schedule', 'hmbkp_schedule_id' => time(), 'hmbkp_panel' => 'hmbkp_edit_schedule_settings' ), HMBKP_ADMIN_URL ) ); ?>"> + <?php _e( 'add schedule', 'hmbkp' ); ?></a>
23
 
24
+ <?php if ( get_option( 'hmbkp_enable_support' ) ) { ?>
25
 
26
+ <a id="intercom" class="add-new-h2" href="mailto:support@hmn.md"><?php _e( 'Support', 'hmbkp' ); ?></a>
27
 
28
+ <?php } else {
29
 
30
+ add_thickbox(); ?>
31
 
32
+ <a id="intercom-info" class="thickbox add-new-h2" href="<?php echo wp_nonce_url( add_query_arg( array( 'action' => 'load_enable_support', 'width' => '600', 'height' => '420' ), is_multisite() ? admin_url( 'admin-ajax.php' ) : network_admin_url( 'admin-ajax.php' ) ), 'hmbkp_nonce' ); ?>"><span class="dashicons dashicons-admin-users"></span>&nbsp;<?php _e( 'Enable Support', 'hmbkp' ); ?></a>
33
 
34
+ <?php } ?>
35
 
36
+ </h2>
37
 
38
+ <?php // Don't continue if we don't have a schedule
39
+ if ( ! $schedule = $current_schedule ) {
40
+ return;
41
+ } ?>
42
 
43
+ <div data-hmbkp-schedule-id="<?php echo esc_attr( $schedule->get_id() ); ?>" class="hmbkp_schedule">
 
44
 
45
+ <?php require( HMBKP_PLUGIN_PATH . 'admin/schedule-sentence.php' ); ?>
46
 
47
+ <?php require( HMBKP_PLUGIN_PATH . 'admin/backups-table.php'); ?>
 
 
 
 
 
48
 
49
+ </div>
 
admin/enable-support.php CHANGED
@@ -57,18 +57,5 @@
57
 
58
  <p class="howto"><?php _e( 'You can disable support in the future by deactivating BackUpWordPress.', 'hmbkp' ); ?></p>
59
 
60
- <form class="hmbkp-form" method="POST">
61
-
62
- <?php wp_nonce_field( 'enable-support', 'hmbkp' ); ?>
63
-
64
- <input type="hidden" name="hmbkp_enable_support" value="1" />
65
-
66
- <p class="submit">
67
-
68
- <button type="button" class="button-secondary hmbkp-colorbox-close"><?php _e( 'No thanks', 'hmbkp' ); ?></button>
69
-
70
- <button type="submit" class="button-primary"><?php _e( 'Yes I want to enable support', 'hmbkp' ); ?></button>
71
-
72
- </p>
73
-
74
- </form>
57
 
58
  <p class="howto"><?php _e( 'You can disable support in the future by deactivating BackUpWordPress.', 'hmbkp' ); ?></p>
59
 
60
+ <a href="#" class="button-secondary hmbkp-colorbox-close"><?php _e( 'No thanks', 'hmbkp' ); ?></a>
61
+ <a href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'action' => 'hmbkp_request_enable_support' ), admin_url( 'admin-post.php' ) ), 'hmbkp_enable_support', 'hmbkp_enable_support_nonce' ) ); ?>" class="button-primary right"><?php _e( 'Yes I want to enable support', 'hmbkp' ); ?></a>
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/faq.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ echo '<p><strong>' . __( 'Where does BackUpWordPress store the backup files?', 'hmbkp' ) . '</strong></p>' .
3
+
4
+ '<p>' . __( 'Backups are stored on your server in <code>/wp-content/backups</code>, you can change the directory.', 'hmbkp' ). '</p>' .
5
+
6
+ '<p>' . __( 'Important: By default BackUpWordPress backs up everything in your site root as well as your database, this includes any non WordPress folders that happen to be in your site root. This does mean that your backup directory can get quite large.', 'hmbkp' ) . '</p>' .
7
+
8
+ '<p><strong>' . __( 'What if I want to back up my site to another destination?', 'hmbkp' ) . '</strong></p>' .
9
+
10
+ '<p>' . __( 'BackUpWordPress Pro supports Dropbox, Google Drive, Amazon S3, Rackspace, Azure, DreamObjects and FTP/SFTP. Check it out here: <a href="http://bwp.hmn.md/?utm_source=wordpress-org&utm_medium=plugin-page&utm_campaign=freeplugin" title="BackUpWordPress Homepage" target="_blank">https://bwp.hmn.md</a>', 'hmbkp' ) . '</p>' .
11
+
12
+ '<p><strong>' . __( 'How do I restore my site from a backup?', 'hmbkp' ) . '</strong></p>' .
13
+
14
+ '<p>' . __( 'You need to download the latest backup file either by clicking download on the backups page or via <code>FTP</code>. <code>Unzip</code> the files and upload all the files to your server overwriting your site. You can then import the database using your hosts database management tool (likely <code>phpMyAdmin</code>).', 'hmbkp' ) . '</p>' .
15
+
16
+ '<p>' . __( 'See this guide for more details - <a href="https://bwp.hmn.md/support-center/restore-backup/" title="Go to support center" target="_blank">How to restore from backup</a>.', 'hmbkp' ) . '</p>' .
17
+
18
+ '<p><strong>' . __( 'Does BackUpWordPress back up the backups directory?', 'hmbkp' ) . '</strong></p>' .
19
+
20
+ '<p>' . __( 'No.', 'hmbkp' ) . '</p>' .
21
+
22
+ '<p><strong>' . __( 'I\'m not receiving my backups by email?', 'hmbkp' ) . '</strong></p>' .
23
+
24
+ '<p>' . __( 'Most servers have a filesize limit on email attachments, it\'s generally about 10mb. If your backup file is over that limit it won\'t be sent attached to the email, instead you should receive an email with a link to download the backup, if you aren\'t even receiving that then you likely have a mail issue on your server that you\'ll need to contact your host about.', 'hmbkp' ) . '</p>' .
25
+
26
+ '<p><strong>' . __( 'How many backups are stored by default?', 'hmbkp' ) . '</strong></p>' .
27
+
28
+ '<p>' . __( 'BackUpWordPress stores the last 10 backups by default.', 'hmbkp' ) . '</p>' .
29
+
30
+ '<p><strong>' . __( 'How long should a backup take?', 'hmbkp' ) . '</strong></p>' .
31
+
32
+ '<p>' . __( 'Unless your site is very large (many gigabytes) it should only take a few minutes to perform a back up, if your back up has been running for longer than an hour it\'s safe to assume that something has gone wrong, try de-activating and re-activating the plugin, if it keeps happening, contact support.', 'hmbkp' ) . '</p>' .
33
+
34
+ '<p><strong>' . __( 'What do I do if I get the wp-cron error message?', 'hmbkp' ) . '</strong></p>' .
35
+
36
+ '<p>' . __( 'The issue is that your <code>wp-cron.php</code> is not returning a <code>200</code> response when hit with a HTTP request originating from your own server, it could be several things, in most cases, it\'s an issue with the server / site.', 'hmbkp' ) . '</p>' .
37
+
38
+ '<p>' . __( 'There are some things you can test to confirm this is the issue.', 'hmbkp' ) . '</p>' .
39
+
40
+ '<ul><li>' . __( 'Are scheduled posts working? (They use wp-cron as well ). ', 'hmbkp' ) . '</li>' .
41
+
42
+ '<li>' . __( 'Are you hosted on Heart Internet? (wp-cron may not be supported by Heart Internet, see below for work-around).', 'hmbkp' ) . '</li>' .
43
+
44
+ '<li>' . __( 'If you click manual backup does it work?', 'hmbkp' ) . '</li>' .
45
+
46
+ '<li>' . __( 'Try adding <code>define( \'ALTERNATE_WP_CRON\', true );</code> to your <code>wp-config.php</code>, do automatic backups work?', 'hmbkp' ) . '</li>' .
47
+
48
+ '<li>' . __( 'Is your site private (I.E. is it behind some kind of authentication, maintenance plugin, .htaccess) if so wp-cron won\'t work until you remove it, if you are and you temporarily remove the authentication, do backups start working?', 'hmbkp' ) . '</li></ul>' .
49
+
50
+ '<p>' . __( 'Report the results to our support team for further help. To do this, either enable suport from your Admin Dashboard (recommended), or email support@hmn.md', 'hmbkp' ) . '</p>' .
51
+
52
+ '<p><strong>' . __( 'How to get BackUpWordPress working in Heart Internet', 'hmbkp' ) . '</strong></p>' .
53
+
54
+ '<p>' . __( 'The script to be entered into the Heart Internet cPanel is: <code>/usr/bin/php5 /home/sites/yourdomain.com/public_html/wp-cron.php</code> (note the space between php5 and the location of the file). The file <code>wp-cron.php</code> <code>chmod</code> must be set to <code>711</code>.', 'hmbkp' ) . '</p>' .
55
+
56
+ '<p><strong>' . __( 'My backups seem to be failing?', 'hmbkp' ) . '</strong></p>' .
57
+
58
+ '<p>' . __( 'If your backups are failing - it\'s commonly caused by lack of available resources on your server. The easiest way to establish this to exclude some [of] or your entire uploades folder, running a backup an if that succeeds. If so, we know it\'s probably a server issue. If not, report the results to our support team for further help. To do this, either enable suport from your Admin Dashboard (recommended), or email support@hmn.md', 'hmbkp' ) . '</p>';
admin/menu.php CHANGED
@@ -23,7 +23,7 @@ add_action( 'admin_menu', 'hmbkp_admin_menu' );
23
  * @return null
24
  */
25
  function hmbkp_manage_backups() {
26
- require_once( HMBKP_PLUGIN_PATH . '/admin/page.php' );
27
  }
28
 
29
  /**
@@ -56,31 +56,16 @@ function hmbkp_contextual_help() {
56
  if ( ! method_exists( get_current_screen(), 'add_help_tab' ) )
57
  return;
58
 
59
- require_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
60
-
61
- if ( ! $plugin = get_transient( 'hmbkp_plugin_data' ) ) {
62
-
63
- $plugin = plugins_api( 'plugin_information', array( 'slug' => HMBKP_PLUGIN_SLUG ) );
64
-
65
- // Cache for one day
66
- set_transient( 'hmbkp_plugin_data', $plugin, 86400 );
67
-
68
- }
69
-
70
- $warning = '';
71
-
72
- // Check if help is for the right version.
73
- if ( ! empty( $plugin->version ) && version_compare( HMBKP_VERSION, $plugin->version, '!=' ) )
74
- $warning = sprintf( '<div id="message" class="updated inline"><p><strong>' . __( 'You are not using the latest stable version of BackUpWordPress', 'hmbkp' ) . '</strong> &mdash; ' . __( 'The information below is for version %1$s. View the %2$s file for help specific to version %3$s.', 'hmbkp' ) . '</p></div>', '<code>' . esc_attr( $plugin->version ) . '</code>', '<code>readme.txt</code>', '<code>' . esc_attr( HMBKP_VERSION ) . '</code>' );
75
-
76
  ob_start();
77
- require_once( HMBKP_PLUGIN_PATH . '/admin/constants.php' );
78
  $constants = ob_get_clean();
79
 
 
 
 
 
 
80
 
81
- if ( $plugin && ! is_wp_error( $plugin ) )
82
- get_current_screen()->add_help_tab( array( 'title' => __( 'FAQ', 'hmbkp' ), 'id' => 'hmbkp_faq', 'content' => wp_kses_post( $warning . $plugin->sections['faq'] ) ) );
83
-
84
  get_current_screen()->add_help_tab( array( 'title' => __( 'Constants', 'hmbkp' ), 'id' => 'hmbkp_constants', 'content' => wp_kses_post( $constants ) ) );
85
 
86
  get_current_screen()->set_help_sidebar(
23
  * @return null
24
  */
25
  function hmbkp_manage_backups() {
26
+ require_once( HMBKP_PLUGIN_PATH . 'admin/page.php' );
27
  }
28
 
29
  /**
56
  if ( ! method_exists( get_current_screen(), 'add_help_tab' ) )
57
  return;
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  ob_start();
60
+ require_once( HMBKP_PLUGIN_PATH . 'admin/constants.php' );
61
  $constants = ob_get_clean();
62
 
63
+ ob_start();
64
+ include_once( HMBKP_PLUGIN_PATH . 'admin/faq.php' );
65
+ $faq = ob_get_clean();
66
+
67
+ get_current_screen()->add_help_tab( array( 'title' => __( 'FAQ', 'hmbkp' ), 'id' => 'hmbkp_faq', 'content' => wp_kses_post( $faq ) ) );
68
 
 
 
 
69
  get_current_screen()->add_help_tab( array( 'title' => __( 'Constants', 'hmbkp' ), 'id' => 'hmbkp_constants', 'content' => wp_kses_post( $constants ) ) );
70
 
71
  get_current_screen()->set_help_sidebar(
admin/page.php CHANGED
@@ -1,31 +1,13 @@
1
  <div class="wrap">
2
 
3
- <h2>
4
- <?php _e( 'Manage Backups', 'hmbkp' ); ?>
5
 
6
- <?php if ( get_option( 'hmbkp_enable_support' ) ) { ?>
7
 
8
- <a id="intercom" class="add-new-h2" href="mailto:support@hmn.md"><?php _e( 'Support', 'hmbkp' ); ?></a>
9
 
10
- <?php } else { ?>
11
 
12
- <a id="intercom-info" class="colorbox add-new-h2" href="<?php echo wp_nonce_url( add_query_arg( array( 'action' => 'load_enable_support' ), is_multisite() ? admin_url( 'admin-ajax.php' ) : network_admin_url( 'admin-ajax.php' ) ), 'hmbkp_nonce' ); ?>"><?php _e( 'Enable Support', 'hmbkp' ); ?></a>
13
-
14
- <?php } ?>
15
-
16
-
17
- </h2>
18
-
19
- <?php if ( hmbkp_possible() ) : ?>
20
-
21
- <?php include_once( HMBKP_PLUGIN_PATH . '/admin/backups.php' ); ?>
22
-
23
- <p class="howto"><?php printf( __( 'If you\'re finding BackUpWordPress useful, please %1$s rate it on the plugin directory. %2$s', 'hmbkp' ), '<a href="http://wordpress.org/support/view/plugin-reviews/backupwordpress">', '</a>' ); ?></p>
24
-
25
- <p class="howto"><?php _e( 'If you need help getting things working then check the FAQ by clicking on help in the top right hand corner of this page.', 'hmbkp' ); ?></p>
26
-
27
- <p class="howto"><strong><?php printf( __( 'Wish you could store your backups in a safer place? Our %1$spremium extensions%2$s enable automatic backups to Dropbox, FTP, Google Drive and more.', 'hmbkp' ), '<a href="https://bwp.hmn.md/?utm_source=wordpress-org&utm_medium=wp-admin&utm_campaign=freeplugin">', '</a>' ); ?></strong></p>
28
-
29
- <?php endif; ?>
30
 
31
  </div>
1
  <div class="wrap">
2
 
3
+ <?php if ( hmbkp_possible() ) : ?>
 
4
 
5
+ <?php include_once( HMBKP_PLUGIN_PATH . 'admin/backups.php' ); ?>
6
 
7
+ <p class="howto"><?php printf( __( 'If you\'re finding BackUpWordPress useful, please %1$s rate it on the plugin directory%2$s.', 'hmbkp' ), '<a target="_blank" href="http://wordpress.org/support/view/plugin-reviews/backupwordpress">', '</a>' ); ?></p>
8
 
9
+ <?php include_once( HMBKP_PLUGIN_PATH . 'admin/upsell.php' ); ?>
10
 
11
+ <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
  </div>
admin/schedule-form-excludes.php CHANGED
@@ -1,125 +1,346 @@
1
- <form method="post" class="hmbkp-form">
2
 
3
- <input type="hidden" name="hmbkp_schedule_id" value="<?php echo esc_attr( $schedule->get_id() ); ?>" />
4
 
5
- <fieldset class="hmbkp-edit-schedule-excludes-form">
6
 
7
- <legend><?php _e( 'Manage Excludes', 'hmbkp' ); ?></legend>
8
 
9
- <div class="hmbkp_add_exclude_rule">
10
 
11
- <label for="hmbkp-new-exclude-rule">
12
 
13
- <?php _e( 'New Exclude Rule[s]', 'hmbkp' ); ?>
14
 
15
- <input id="hmbkp-new-exclude-rule" type="text" class="code" placeholder="" />
16
 
17
- <button type="button" class="button-secondary hmbkp_preview_exclude_rule"><?php _e( 'Preview', 'hmbkp' ); ?></button>
18
 
19
- <span class="howto"><?php printf( __( 'Enter new exclude rules as a comma separated list, e.g. %s', 'hmbkp' ), '<code>.git/, *.mp3, wp-content/uploads/</code>' ); ?></span>
20
 
21
- </label>
22
 
23
- </div>
24
 
25
- <table class="widefat">
26
 
27
- <thead>
28
- <tr>
29
- <th><?php _e( 'Exclude Rules', 'hmbkp' ); ?></th>
30
- </tr>
31
- </thead>
32
 
33
- <tbody>
34
 
35
- <?php foreach ( $schedule->get_excludes() as $key => $exclude ) : ?>
 
36
 
37
- <tr>
38
- <td data-hmbkp-exclude-rule="<?php echo esc_attr( $exclude ); ?>">
39
 
40
- <span class="code"><?php echo esc_attr( str_ireplace( untrailingslashit( $schedule->get_root() ), '', $exclude ) ); ?></span>
41
 
42
- <?php if ( ( $schedule->get_path() === untrailingslashit( $exclude ) ) || ( in_array( $exclude, $schedule->default_excludes() ) ) ) : ?>
43
 
44
- <span class="reason"><?php _e( 'default', 'hmbkp' ); ?></span>
45
 
46
- <?php elseif ( defined( 'HMBKP_EXCLUDE' ) && strpos( HMBKP_EXCLUDE, $exclude ) !== false ) : ?>
47
 
48
- <span class="reason"><?php _e( 'defined', 'hmbkp' ); ?></span>
49
 
50
- <?php else : ?>
51
 
52
- <a href="#" class="delete-action"><?php _e( 'Remove', 'hmbkp' ); ?></a>
53
 
54
- <?php endif; ?>
55
 
56
- </td>
57
- </tr>
58
 
59
- <?php endforeach; ?>
60
 
61
- </tbody>
62
 
63
- </table>
64
 
65
- <div class="hmbkp-tabs">
66
 
67
- <ul class="subsubsub">
68
 
69
- <?php if ( $schedule->get_excluded_file_count() ) : ?>
70
 
71
- <li><a href="#hmbkp_excluded_files"><?php _e( 'Excluded', 'hmbkp' ); ?></a>(<?php esc_html_e( $schedule->get_excluded_file_count() ); ?>)</li>
72
 
73
- <?php endif; ?>
74
 
75
- <li><a href="#hmbkp_included_files"><?php _e( 'Included', 'hmbkp' ); ?></a>(<?php esc_html_e( $schedule->get_included_file_count() ); ?>)</li>
 
76
 
77
- <?php if ( $schedule->get_unreadable_file_count() ) : ?>
78
 
79
- <li><a href="#hmbkp_unreadable_files"><?php _e( 'Unreadable', 'hmbkp' ); ?></a>(<?php esc_html_e( $schedule->get_unreadable_file_count() ); ?>)</li>
80
 
81
- <?php endif; ?>
 
 
 
82
 
83
- </ul>
84
 
85
- <?php if ( $schedule->get_excluded_file_count() ) : ?>
86
 
87
- <div id="hmbkp_excluded_files">
 
88
 
89
- <?php hmbkp_file_list( $schedule, null, 'get_excluded_files' ); ?>
90
 
91
- </div>
92
 
93
- <?php endif; ?>
94
 
95
- <div id="hmbkp_included_files">
 
 
 
 
 
 
 
96
 
97
- <?php hmbkp_file_list( $schedule, null, 'get_included_files' ); ?>
98
 
99
- </div>
 
 
100
 
101
- <?php if ( $schedule->get_unreadable_file_count() ) : ?>
102
 
103
- <div id="hmbkp_unreadable_files">
104
 
105
- <?php hmbkp_file_list( $schedule, null, 'get_unreadable_files' ); ?>
106
 
107
- <p class="description"><?php _e( 'Unreadable files can\'t be backed up', 'hmbkp' ); ?></p>
108
 
109
- </div>
110
 
111
- <?php endif; ?>
112
 
113
- <p><?php printf( __( 'Your site is %s. Backups will be compressed and so will be smaller.', 'hmbkp' ), '<code>' . esc_html( $schedule->get_formatted_file_size( false ) ) . '</code>' ); ?></p>
114
 
115
- </div>
116
 
117
- <p class="submit">
118
 
119
- <button type="submit" class="button-primary"><?php _e( 'Close', 'hmbkp' ); ?></button>
120
 
121
- </p>
122
 
123
- </fieldset>
124
 
125
- </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="hmbkp-exclude-settings">
2
 
3
+ <?php if ( $schedule->get_excludes() ) : ?>
4
 
5
+ <h3><?php _e( 'Currently Excluded', 'hmbkp' ); ?></h3>
6
 
7
+ <table class="widefat">
8
 
9
+ <tbody>
10
 
11
+ <?php foreach ( $schedule->get_excludes() as $key => $exclude ) :
12
 
13
+ $exclude_path = new SplFileInfo( trailingslashit( $schedule->get_root() ) . ltrim( str_ireplace( $schedule->get_root(), '', $exclude ), '/' ) ); ?>
14
 
15
+ <tr>
16
 
17
+ <th scope="row">
18
 
19
+ <?php if ( $exclude_path->isFile() ) { ?>
20
 
21
+ <div class="dashicons dashicons-media-default"></div>
22
 
23
+ <?php } elseif ( $exclude_path->isDir() ) { ?>
24
 
25
+ <div class="dashicons dashicons-portfolio"></div>
26
 
27
+ <?php } ?>
 
 
 
 
28
 
29
+ </th>
30
 
31
+ <td>
32
+ <code><?php echo esc_html( str_ireplace( $schedule->get_root(), '', $exclude ) ); ?></code>
33
 
34
+ </td>
 
35
 
36
+ <td>
37
 
38
+ <?php if ( ( $schedule->get_path() === untrailingslashit( $exclude ) ) || ( in_array( $exclude, $schedule->default_excludes() ) ) ) : ?>
39
 
40
+ <?php _e( 'Default rule', 'hmbkp' ); ?>
41
 
42
+ <?php elseif ( defined( 'HMBKP_EXCLUDE' ) && strpos( HMBKP_EXCLUDE, $exclude ) !== false ) : ?>
43
 
44
+ <?php _e( 'Defined in wp-config.php', 'hmbkp' ); ?>
45
 
46
+ <?php else : ?>
47
 
48
+ <a href="<?php echo hmbkp_admin_action_url( 'remove_exclude_rule', array( 'hmbkp_remove_exclude' => $exclude, 'hmbkp_schedule_id' => $schedule->get_id() ) ); ?>" class="delete-action"><?php _e( 'Remove', 'hmbkp' ); ?></a>
49
 
50
+ <?php endif; ?>
51
 
52
+ </td>
 
53
 
54
+ </tr>
55
 
56
+ <?php endforeach; ?>
57
 
58
+ </tbody>
59
 
60
+ </table>
61
 
62
+ <?php endif; ?>
63
 
64
+ <h3 id="directory-listing"><?php _e( 'Directory Listing', 'hmbkp' ); ?></h3>
65
 
66
+ <p><?php _e( 'Here\'s a directory listing of all files on your site, you can browse through and exclude files or folders that you don\'t want included in your backup.', 'hmbkp' ); ?></p>
67
 
68
+ <?php
69
 
70
+ // The directory to display
71
+ $directory = $schedule->get_root();
72
 
73
+ if ( isset( $_GET['hmbkp_directory_browse'] ) ) {
74
 
75
+ $untrusted_directory = urldecode( $_GET['hmbkp_directory_browse'] );
76
 
77
+ // Only allow real sub directories of the site root to be browsed
78
+ if ( strpos( $untrusted_directory, $schedule->get_root() ) !== false && is_dir( $untrusted_directory ) ) {
79
+ $directory = $untrusted_directory;
80
+ }
81
 
82
+ }
83
 
84
+ $exclude_string = $schedule->exclude_string( 'regex' );
85
 
86
+ // Kick off a recursive filesize scan
87
+ $files = $schedule->list_directory_by_total_filesize( $directory );
88
 
89
+ if ( $files ) { ?>
90
 
91
+ <table class="widefat">
92
 
93
+ <thead>
94
 
95
+ <tr>
96
+ <th></th>
97
+ <th scope="col"><?php _e( 'Name', 'hmbkp' ); ?></th>
98
+ <th scope="col" class="column-format"><?php _e( 'Size', 'hmbkp' ); ?></th>
99
+ <th scope="col" class="column-format"><?php _e( 'Permissions', 'hmbkp' ); ?></th>
100
+ <th scope="col" class="column-format"><?php _e( 'Type', 'hmbkp' ); ?></th>
101
+ <th scope="col" class="column-format"><?php _e( 'Status', 'hmbkp' ); ?></th>
102
+ </tr>
103
 
104
+ <tr>
105
 
106
+ <th scope="row">
107
+ <div class="dashicons dashicons-admin-home"></div>
108
+ </th>
109
 
110
+ <th scope="col">
111
 
112
+ <?php if ( $schedule->get_root() !== $directory ) { ?>
113
 
114
+ <a href="<?php echo remove_query_arg( 'hmbkp_directory_browse' ); ?>"><?php echo esc_html( $schedule->get_root() ); ?></a> <code>/</code>
115
 
116
+ <?php $parents = array_filter( explode( '/', str_replace( trailingslashit( $schedule->get_root() ), '', trailingslashit( dirname( $directory ) ) ) ) );
117
 
118
+ foreach ( $parents as $directory_basename ) { ?>
119
 
120
+ <a href="<?php echo add_query_arg( 'hmbkp_directory_browse', urlencode( substr( $directory, 0, strpos( $directory, $directory_basename ) ) . $directory_basename ) ); ?>"><?php echo esc_html( $directory_basename ); ?></a> <code>/</code>
121
 
122
+ <?php } ?>
123
 
124
+ <?php echo esc_html( basename( $directory ) ); ?>
125
 
126
+ <?php } else { ?>
127
 
128
+ <?php echo esc_html( $schedule->get_root() ); ?>
129
 
130
+ <?php } ?>
131
 
132
+ </th>
133
 
134
+ <td class="column-filesize">
135
+
136
+ <?php if ( $schedule->is_site_size_being_calculated() ) { ?>
137
+
138
+ <span class="spinner"></span>
139
+
140
+ <?php } else {
141
+
142
+ $root = new SplFileInfo( $schedule->get_root() );
143
+
144
+ $size = $schedule->filesize( $root );
145
+
146
+ if ( $size !== false ) {
147
+
148
+ $size = size_format( $size );
149
+
150
+ if ( ! $size ) {
151
+ $size = '0 B';
152
+ } ?>
153
+
154
+ <code>
155
+
156
+ <?php echo esc_html( $size ); ?>
157
+
158
+ <a class="dashicons dashicons-update" href="<?php echo wp_nonce_url( add_query_arg( 'hmbkp_recalculate_directory_filesize', urlencode( $schedule->get_root() ) ), 'hmbkp-recalculate_directory_filesize' ); ?>"><span><?php _e( 'Refresh', 'hmbkp' ); ?></span></a>
159
+
160
+ </code>
161
+
162
+
163
+ <?php } ?>
164
+
165
+ <?php } ?>
166
+
167
+ <td>
168
+ <?php echo esc_html( substr( sprintf( '%o', fileperms( $schedule->get_root() ) ), -4 ) ); ?>
169
+ </td>
170
+
171
+ <td>
172
+
173
+ <?php if ( is_link( $schedule->get_root() ) ) {
174
+
175
+ _e( 'Symlink', 'hmbkp' );
176
+
177
+ } elseif ( is_dir( $schedule->get_root() ) ) {
178
+
179
+ _e( 'Folder', 'hmbkp' );
180
+
181
+ } ?>
182
+
183
+ </td>
184
+
185
+ <td></td>
186
+
187
+ </tr>
188
+
189
+ </thead>
190
+
191
+ <tbody>
192
+
193
+ <?php foreach ( $files as $size => $file ) {
194
+
195
+ $is_excluded = $is_unreadable = false;
196
+
197
+ // Check if the file is excluded
198
+ if ( $exclude_string && preg_match( '(' . $exclude_string . ')', str_ireplace( trailingslashit( $schedule->get_root() ), '', HM_Backup::conform_dir( $file->getPathname() ) ) ) ) {
199
+ $is_excluded = true;
200
+ }
201
+
202
+ // Skip unreadable files
203
+ if ( ! @realpath( $file->getPathname() ) || ! $file->isReadable() ) {
204
+ $is_unreadable = true;
205
+ } ?>
206
+
207
+ <tr>
208
+
209
+ <td>
210
+
211
+ <?php if ( $is_unreadable ) { ?>
212
+
213
+ <div class="dashicons dashicons-dismiss"></div>
214
+
215
+ <?php } elseif ( $file->isFile() ) { ?>
216
+
217
+ <div class="dashicons dashicons-media-default"></div>
218
+
219
+ <?php } elseif ( $file->isDir() ) { ?>
220
+
221
+ <div class="dashicons dashicons-portfolio"></div>
222
+
223
+ <?php } ?>
224
+
225
+ </td>
226
+
227
+ <td>
228
+
229
+ <?php if ( $is_unreadable ) { ?>
230
+
231
+ <code class="strikethrough" title="<?php echo esc_attr( $file->getRealPath() ); ?>"><?php echo esc_html( $file->getBasename() ); ?></code>
232
+
233
+ <?php } elseif ( $file->isFile() ) { ?>
234
+
235
+ <code title="<?php echo esc_attr( $file->getRealPath() ); ?>"><?php echo esc_html( $file->getBasename() ); ?></code>
236
+
237
+ <?php } elseif ( $file->isDir() ) { ?>
238
+
239
+ <code title="<?php echo esc_attr( $file->getRealPath() ); ?>"><a href="<?php echo add_query_arg( 'hmbkp_directory_browse', urlencode( $file->getPathname() ) ); ?>"><?php echo esc_html( $file->getBasename() ); ?></a></code>
240
+
241
+ <?php } ?>
242
+
243
+ </td>
244
+
245
+ <td class="column-format column-filesize">
246
+
247
+ <?php if ( $file->isDir() && $schedule->is_site_size_being_calculated() ) { ?>
248
+
249
+ <span class="spinner"></span>
250
+
251
+ <?php } else {
252
+
253
+ $size = $schedule->filesize( $file );
254
+
255
+ if ( $size !== false ) {
256
+
257
+ $size = size_format( $size );
258
+
259
+ if ( ! $size ) {
260
+ $size = '0 B';
261
+ } ?>
262
+
263
+ <code>
264
+
265
+ <?php echo esc_html( $size ); ?>
266
+
267
+ <?php if ( $file->isDir() ) { ?>
268
+
269
+ <a title="<?php _e( 'Recalculate the size of this directory', 'hmbkp' ); ?>" class="dashicons dashicons-update" href="<?php echo wp_nonce_url( add_query_arg( 'hmbkp_recalculate_directory_filesize', urlencode( $file->getPathname() ) ), 'hmbkp-recalculate_directory_filesize' ); ?>"><span><?php _e( 'Refresh', 'hmbkp' ); ?></span></a>
270
+
271
+ <?php } ?>
272
+
273
+ </code>
274
+
275
+
276
+ <?php } else { ?>
277
+
278
+ <code>--</code>
279
+
280
+ <?php }
281
+ } ?>
282
+
283
+ </td>
284
+
285
+ <td>
286
+ <?php echo esc_html( substr( sprintf( '%o', $file->getPerms() ), -4 ) ); ?>
287
+ </td>
288
+
289
+ <td>
290
+
291
+ <?php if ( $file->isLink() ) { ?>
292
+
293
+ <span title="<?php echo esc_attr( $file->GetRealPath() ); ?>"><?php _e( 'Symlink', 'hmbkp' ); ?></span>
294
+
295
+ <?php } elseif ( $file->isDir() ) {
296
+
297
+ _e( 'Folder', 'hmbkp' );
298
+
299
+ } else {
300
+
301
+ _e( 'File', 'hmbkp' );
302
+
303
+ } ?>
304
+
305
+ </td>
306
+
307
+ <td class="column-format">
308
+
309
+ <?php if ( $is_unreadable ) { ?>
310
+
311
+ <strong title="<?php _e( 'Unreadable files won\'t be backed up.', 'hmbkp' ); ?>"><?php _e( 'Unreadable', 'hmbkp' ); ?></strong>
312
+
313
+ <?php } elseif ( $is_excluded ) { ?>
314
+
315
+ <strong><?php _e( 'Excluded', 'hmbkp' ); ?></strong>
316
+
317
+ <?php } else {
318
+
319
+ $exclude_path = $file->getPathname();
320
+
321
+ // Excluded directories need to be trailingslashed
322
+ if ( $file->isDir() ) {
323
+ $exclude_path = trailingslashit( $file->getPathname() );
324
+ } ?>
325
+
326
+ <a href="<?php echo wp_nonce_url( add_query_arg( array( 'hmbkp_schedule_id' => $schedule->get_id(), 'action' => 'hmbkp_add_exclude_rule', 'hmbkp_exclude_pathname' => urlencode( $exclude_path ) ), admin_url( 'admin-post.php' ) ), 'hmbkp-add-exclude-rule', 'hmbkp-add-exclude-rule-nonce' ); ?>" class="button-secondary"><?php _e( 'Exclude &rarr;', 'hmbkp' ); ?></a>
327
+
328
+ <?php } ?>
329
+
330
+ </td>
331
+
332
+ </tr>
333
+
334
+ <?php } ?>
335
+
336
+ </tbody>
337
+
338
+ </table>
339
+
340
+ <?php } ?>
341
+
342
+ </div>
343
+
344
+ <p class="submit">
345
+ <a href="<?php echo esc_url( hmbkp_get_settings_url() ) ?>" class="button-primary"><?php _e( 'Done', 'hmbkp' ); ?></a>
346
+ </p>
admin/schedule-form.php CHANGED
@@ -1,136 +1,189 @@
1
- <form method="post" class="hmbkp-form" novalidate data-schedule-action="<?php if ( isset( $is_new_schedule ) ) { ?>add<?php } else { ?>edit<?php } ?>">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  <input type="hidden" name="hmbkp_schedule_id" value="<?php echo esc_attr( $schedule->get_id() ); ?>" />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
- <fieldset class="hmbkp-edit-schedule-form">
6
 
7
- <legend><?php _e( 'Schedule Settings', 'hmbkp' ); ?></legend>
8
 
9
- <div>
10
 
11
- <label for="hmbkp_schedule_type"><?php _e( 'Backup', 'hmbkp' ); ?></label>
 
 
12
 
13
- <select name="hmbkp_schedule_type" id="hmbkp_schedule_type">
14
 
15
- <option<?php selected( $schedule->get_type(), 'complete' ); ?> value="complete"><?php _e( 'Both Database &amp; files', 'hmbkp' ); ?></option>
16
 
17
- <option<?php selected( $schedule->get_type(), 'file' ); ?> value="file"><?php _e( 'Files only', 'hmbkp' ); ?></option>
18
 
19
- <option<?php selected( $schedule->get_type(), 'database' ); ?> value="database"><?php _e( 'Database only', 'hmbkp' ); ?></option>
20
 
21
- </select>
22
 
23
- </div>
24
 
25
- <div>
26
 
27
- <label for="hmbkp_schedule_recurrence_type"><?php _e( 'Schedule', 'hmbkp' ); ?></label>
28
 
29
- <select name="hmbkp_schedule_recurrence[hmbkp_type]" id="hmbkp_schedule_recurrence_type">
30
 
31
- <option value="manually"><?php _e( 'Manual Only', 'hmbkp' ); ?></option>
32
 
33
- <?php foreach ( $schedule->get_cron_schedules() as $cron_schedule => $cron_details ) : ?>
34
 
35
- <option <?php selected( $schedule->get_reoccurrence(), $cron_schedule ); ?> value="<?php echo esc_attr( $cron_schedule ); ?>">
 
 
36
 
37
- <?php esc_html_e( $cron_details['display'], 'hmbkp' ); ?>
38
 
39
- </option>
 
 
40
 
41
- <?php endforeach; ?>
42
 
43
- </select>
44
 
45
- </div>
 
 
 
 
 
 
 
 
46
 
47
- <?php if ( ! $start_time = $schedule->get_schedule_start_time() )
48
- $start_time = time();
49
 
50
- $start_time += get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
51
- ?>
52
 
53
- <div id="start-day" class="recurring-setting">
54
 
55
- <label for="hmbkp_schedule_start_day_of_week"><?php _e( 'Start Day', 'hmbkp' ); ?></label>
56
 
57
- <select id="hmbkp_schedule_start_day_of_week" name="hmbkp_schedule_recurrence[hmbkp_schedule_start_day_of_week]">
58
 
59
- <?php $weekdays = array(
60
- 'monday' => __( 'Monday', 'hmbkp' ),
61
- 'tuesday' => __( 'Tuesday', 'hmbkp' ),
62
- 'wednesday' => __( 'Wednesday', 'hmbkp' ),
63
- 'thursday' => __( 'Thursday', 'hmbkp' ),
64
- 'friday' => __( 'Friday', 'hmbkp' ),
65
- 'saturday' => __( 'Saturday', 'hmbkp' ),
66
- 'sunday' => __( 'Sunday', 'hmbkp' )
67
- );
68
 
69
- foreach ( $weekdays as $key => $day ) : ?>
70
 
71
- <option value="<?php echo esc_attr( $key ) ?>" <?php selected( strtolower( date( 'l', $start_time ) ), $key ); ?>><?php echo esc_html( $day ); ?></option>
 
 
72
 
73
- <?php endforeach; ?>
 
 
74
 
75
- </select>
76
 
77
- </div>
78
 
79
- <div id="start-date" class="recurring-setting">
 
 
80
 
81
- <label for="hmbkp_schedule_start_day_of_month"><?php _e( 'Start Day of Month', 'hmbkp' ); ?></label>
82
 
83
- <input type="number" min="0" max="31" step="1" id="hmbkp_schedule_start_day_of_month" name="hmbkp_schedule_recurrence[hmbkp_schedule_start_day_of_month]" value="<?php echo esc_attr( date( 'j', $start_time ) ); ?>">
84
 
85
- </div>
86
 
87
- <div id="schedule-start" class="recurring-setting">
88
 
89
- <label for="hmbkp_schedule_start_hours"><?php _e( 'Start time', 'hmbkp' ); ?></label>
90
 
91
- <span class="field-group">
92
 
93
- <label for="hmbkp_schedule_start_hours"><input type="number" min="0" max="23" step="1" name="hmbkp_schedule_recurrence[hmbkp_schedule_start_hours]" id="hmbkp_schedule_start_hours" value="<?php echo esc_attr( date( 'G', $start_time ) ); ?>">
94
 
95
- <?php _e( 'Hours', 'hmbkp' ); ?></label>
96
 
97
- <label for="hmbkp_schedule_start_minutes"><input type="number" min="0" max="59" step="1" name="hmbkp_schedule_recurrence[hmbkp_schedule_start_minutes]" id="hmbkp_schedule_start_minutes" value="<?php echo esc_attr( (float) date( 'i', $start_time ) ); ?>">
98
 
99
- <?php _e( 'Minutes', 'hmbkp' ); ?></label>
100
 
101
- </span>
102
 
103
- <p class="twice-js description"><?php _e( 'The second backup will run 12 hours after the first', 'hmbkp' ); ?></p>
 
 
104
 
105
- </div>
106
 
107
- <div>
108
 
109
- <label for="hmbkp_schedule_max_backups"><?php _e( 'Number of backups to store on this server', 'hmbkp' ); ?></label>
110
 
111
- <input type="number" id="hmbkp_schedule_max_backups" name="hmbkp_schedule_max_backups" min="1" step="1" value="<?php echo esc_attr( $schedule->get_max_backups() ); ?>" />
112
 
113
- <p class="description">
 
 
114
 
115
- <?php printf( __( 'Past this limit older backups will be deleted automatically.', 'hmbkp' ) ); ?>
116
 
117
- <?php if ( $schedule->is_filesize_cached() ) {
118
- printf( __( 'This schedule will store a maximum of %s of backups', 'hmbkp' ), '<code>' . size_format( $schedule->get_filesize() * $schedule->get_max_backups() ) . '</code>' );
119
- } ?>
120
 
121
- </p>
122
 
123
- </div>
 
 
124
 
125
- <?php foreach ( HMBKP_Services::get_services( $schedule ) as $service )
126
- $service->field(); ?>
127
 
128
- <p class="submit">
129
- <?php wp_nonce_field( 'hmbkp_schedule_submit_action', 'hmbkp_schedule_submit_nonce' ); ?>
130
- <button type="submit" class="button-primary"><?php _e( 'Update', 'hmbkp' ); ?></button>
131
 
132
- </p>
 
 
133
 
134
- </fieldset>
135
 
136
- </form>
1
+ <h3>Settings</h3>
2
+
3
+ <?php $hmbkp_form_errors = hmbkp_get_settings_errors(); ?>
4
+
5
+ <?php if ( ! empty( $hmbkp_form_errors ) ) { ?>
6
+
7
+ <div id="hmbkp-warning" class="error settings-error">
8
+
9
+ <?php foreach ( $hmbkp_form_errors as $error ) { ?>
10
+ <p><strong><?php echo esc_html( $error ); ?></strong></p>
11
+ <?php } ?>
12
+
13
+ </div>
14
+
15
+ <?php } ?>
16
+
17
+ <form method="post" action="<?php echo admin_url( 'admin-post.php' ); ?>">
18
 
19
  <input type="hidden" name="hmbkp_schedule_id" value="<?php echo esc_attr( $schedule->get_id() ); ?>" />
20
+ <input type="hidden" name="action" value="hmbkp_edit_schedule_submit" />
21
+
22
+ <?php wp_nonce_field( 'hmbkp-edit-schedule', 'hmbkp-edit-schedule-nonce' ); ?>
23
+
24
+ <table class="form-table">
25
+
26
+ <tbody>
27
+
28
+ <tr valign="top">
29
+
30
+ <th scope="row">
31
+ <label for="hmbkp_schedule_type"><?php _e( 'Backup', 'hmbkp' ); ?></label>
32
+ </th>
33
+
34
+ <td>
35
+
36
+ <select name="hmbkp_schedule_type" id="hmbkp_schedule_type">
37
+
38
+ <option<?php selected( $schedule->get_type(), 'complete' ); ?> value="complete"><?php _e( 'Both Database &amp; files', 'hmbkp' ); ?></option>
39
+
40
+ <option<?php selected( $schedule->get_type(), 'file' ); ?> value="file"><?php _e( 'Files only', 'hmbkp' ); ?></option>
41
+
42
+ <option<?php selected( $schedule->get_type(), 'database' ); ?> value="database"><?php _e( 'Database only', 'hmbkp' ); ?></option>
43
+
44
+ </select>
45
 
46
+ </td>
47
 
48
+ </tr>
49
 
50
+ <tr>
51
 
52
+ <th scope="row">
53
+ <label for="hmbkp_schedule_recurrence_type"><?php _e( 'Schedule', 'hmbkp' ); ?></label>
54
+ </th>
55
 
56
+ <td>
57
 
58
+ <select name="hmbkp_schedule_recurrence[hmbkp_type]" id="hmbkp_schedule_recurrence_type">
59
 
60
+ <option value="manually"><?php _e( 'Manual Only', 'hmbkp' ); ?></option>
61
 
62
+ <?php foreach ( $schedule->get_cron_schedules() as $cron_schedule => $cron_details ) : ?>
63
 
64
+ <option <?php selected( $schedule->get_reoccurrence(), $cron_schedule ); ?> value="<?php echo esc_attr( $cron_schedule ); ?>">
65
 
66
+ <?php esc_html_e( $cron_details['display'], 'hmbkp' ); ?>
67
 
68
+ </option>
69
 
70
+ <?php endforeach; ?>
71
 
72
+ </select>
73
 
74
+ </td>
75
 
76
+ </tr>
77
 
78
+ <?php if ( ! $start_time = $schedule->get_schedule_start_time( false ) ) {
79
+ $start_time = time();
80
+ } ?>
81
 
82
+ <tr id="start-day" class="recurring-setting">
83
 
84
+ <th scope="row">
85
+ <label for="hmbkp_schedule_start_day_of_week"><?php _e( 'Start Day', 'hmbkp' ); ?></label>
86
+ </th>
87
 
88
+ <td>
89
 
90
+ <select id="hmbkp_schedule_start_day_of_week" name="hmbkp_schedule_recurrence[hmbkp_schedule_start_day_of_week]">
91
 
92
+ <?php $weekdays = array(
93
+ 'monday' => __( 'Monday', 'hmbkp' ),
94
+ 'tuesday' => __( 'Tuesday', 'hmbkp' ),
95
+ 'wednesday' => __( 'Wednesday', 'hmbkp' ),
96
+ 'thursday' => __( 'Thursday', 'hmbkp' ),
97
+ 'friday' => __( 'Friday', 'hmbkp' ),
98
+ 'saturday' => __( 'Saturday', 'hmbkp' ),
99
+ 'sunday' => __( 'Sunday', 'hmbkp' )
100
+ );
101
 
102
+ foreach ( $weekdays as $key => $day ) : ?>
 
103
 
104
+ <option value="<?php echo esc_attr( $key ) ?>" <?php selected( strtolower( date_i18n( 'l', $start_time ) ), $key ); ?>><?php echo esc_html( $day ); ?></option>
 
105
 
106
+ <?php endforeach; ?>
107
 
108
+ </select>
109
 
110
+ </td>
111
 
112
+ </tr>
 
 
 
 
 
 
 
 
113
 
114
+ <tr id="start-date" class="recurring-setting">
115
 
116
+ <th scope="row">
117
+ <label for="hmbkp_schedule_start_day_of_month"><?php _e( 'Start Day of Month', 'hmbkp' ); ?></label>
118
+ </th>
119
 
120
+ <td>
121
+ <input type="number" min="0" max="31" step="1" id="hmbkp_schedule_start_day_of_month" name="hmbkp_schedule_recurrence[hmbkp_schedule_start_day_of_month]" value="<?php echo esc_attr( date_i18n( 'j', $start_time ) ); ?>">
122
+ </td>
123
 
124
+ </tr>
125
 
126
+ <tr id="schedule-start" class="recurring-setting">
127
 
128
+ <th scope="row">
129
+ <label for="hmbkp_schedule_start_hours"><?php _e( 'Start Time', 'hmbkp' ); ?></label>
130
+ </th>
131
 
132
+ <td>
133
 
134
+ <span class="field-group">
135
 
136
+ <label for="hmbkp_schedule_start_hours"><input type="number" min="0" max="23" step="1" name="hmbkp_schedule_recurrence[hmbkp_schedule_start_hours]" id="hmbkp_schedule_start_hours" value="<?php echo esc_attr( date_i18n( 'G', $start_time ) ); ?>">
137
 
138
+ <?php _e( 'Hours', 'hmbkp' ); ?></label>
139
 
140
+ <label for="hmbkp_schedule_start_minutes"><input type="number" min="0" max="59" step="1" name="hmbkp_schedule_recurrence[hmbkp_schedule_start_minutes]" id="hmbkp_schedule_start_minutes" value="<?php echo esc_attr( (float) date_i18n( 'i', $start_time ) ); ?>">
141
 
142
+ <?php _e( 'Minutes', 'hmbkp' ); ?></label>
143
 
144
+ </span>
145
 
146
+ <p class="twice-js description<?php if ( $schedule->get_reoccurrence() !== 'hmbkp_fortnightly' ) { ?> hidden<?php } ?>"><?php _e( 'The second backup will run 12 hours after the first', 'hmbkp' ); ?></p>
147
 
148
+ </td>
149
 
150
+ </tr>
151
 
152
+ <tr>
153
 
154
+ <th scope="row">
155
+ <label for="hmbkp_schedule_max_backups"><?php _e( 'Number of backups to store on this server', 'hmbkp' ); ?></label>
156
+ </th>
157
 
158
+ <td>
159
 
160
+ <input type="number" id="hmbkp_schedule_max_backups" name="hmbkp_schedule_max_backups" min="1" step="1" value="<?php echo esc_attr( $schedule->get_max_backups() ); ?>" />
161
 
162
+ <p class="description">
163
 
164
+ <?php printf( __( 'Past this limit older backups will be deleted automatically.', 'hmbkp' ) ); ?>
165
 
166
+ <?php if ( $schedule->is_site_size_cached() ) {
167
+ printf( __( 'This schedule will store a maximum of %s of backups.', 'hmbkp' ), '<code>' . size_format( $schedule->get_site_size() * $schedule->get_max_backups() ) . '</code>' );
168
+ } ?>
169
 
170
+ </p>
171
 
172
+ </td>
 
 
173
 
174
+ </tr>
175
 
176
+ <?php foreach ( HMBKP_Services::get_services( $schedule ) as $service ) {
177
+ $service->field();
178
+ } ?>
179
 
180
+ </tbody>
 
181
 
182
+ </table>
 
 
183
 
184
+ <p class="submit">
185
+ <button type="submit" class="button-primary"><?php _e( 'Done', 'hmbkp' ); ?></button>
186
+ </p>
187
 
 
188
 
189
+ </form>
admin/{schedule.php → schedule-sentence.php} RENAMED
@@ -1,7 +1,17 @@
1
  <?php
2
 
3
  // Calculated filesize
4
- $filesize = $schedule->is_filesize_cached() || isset( $recalculate_filesize ) ? '<code title="' . __( 'Backups will be compressed and should be smaller than this.', 'hmbkp' ) . '">' . esc_attr( $schedule->get_formatted_file_size() ) . '</code>' : '<code class="calculating" title="' . __( 'this shouldn\'t take long&hellip;', 'hmbkp' ) . '">' . __( 'calculating the size of your site&hellip;', 'hmbkp' ) . '</code>';
 
 
 
 
 
 
 
 
 
 
5
 
6
  // Backup Type
7
  $type = strtolower( hmbkp_human_get_type( $schedule->get_type() ) );
@@ -9,12 +19,13 @@ $type = strtolower( hmbkp_human_get_type( $schedule->get_type() ) );
9
  // Backup Time
10
  $day = date_i18n( 'l', $schedule->get_next_occurrence( false ) );
11
 
12
- $next_backup = 'title="' . esc_attr( sprintf( __( 'The next backup will be on %1$s at %2$s', 'hmbkp' ), date_i18n( get_option( 'date_format' ), $schedule->get_next_occurrence( false ) ), date_i18n( get_option( 'time_format' ), $schedule->get_next_occurrence( false ) ) ) ) . '"';
13
 
14
  // Backup Re-occurrence
15
  switch ( $schedule->get_reoccurrence() ) :
16
 
17
  case 'hmbkp_hourly' :
 
18
  $reoccurrence = date_i18n( 'i', $schedule->get_next_occurrence( false ) ) === '00' ? '<span ' . $next_backup . '>' . __( 'hourly on the hour', 'hmbkp' ) . '</span>' : sprintf( __( 'hourly at %s minutes past the hour', 'hmbkp' ), '<span ' . $next_backup . '>' . intval( date_i18n( 'i', $schedule->get_next_occurrence( false ) ) ) ) . '</span>';
19
 
20
  break;
@@ -25,7 +36,6 @@ switch ( $schedule->get_reoccurrence() ) :
25
 
26
  break;
27
 
28
-
29
  case 'hmbkp_twicedaily' :
30
 
31
  $times[] = date_i18n( get_option( 'time_format' ), $schedule->get_next_occurrence( false ) );
@@ -45,11 +55,10 @@ switch ( $schedule->get_reoccurrence() ) :
45
 
46
  case 'hmbkp_fortnightly' :
47
 
48
- $reoccurrence = sprintf( __( 'fortnightly on %1$s at %2$s', 'hmbkp' ), '<span ' . $next_backup . '>' . $day . '</span>', '<span>' . esc_html( date_i18n( get_option( 'time_format' ), $schedule->get_next_occurrence( false ) ) ) . '</span>' );
49
 
50
  break;
51
 
52
-
53
  case 'hmbkp_monthly' :
54
 
55
  $reoccurrence = sprintf( __( 'on the %1$s of each month at %2$s', 'hmbkp' ), '<span ' . $next_backup . '>' . esc_html( date_i18n( 'jS', $schedule->get_next_occurrence( false ) ) ) . '</span>', '<span>' . esc_html( date_i18n( get_option( 'time_format' ), $schedule->get_next_occurrence( false ) ) ) . '</span>' );
@@ -62,44 +71,48 @@ switch ( $schedule->get_reoccurrence() ) :
62
 
63
  break;
64
 
65
- default:
 
66
  $schedule->set_reoccurrence( 'manually' );
67
 
68
  endswitch;
69
 
70
  $server = '<span title="' . esc_attr( hmbkp_path() ) . '">' . __( 'this server', 'hmbkp' ) . '</span>';
 
71
 
72
  // Backup to keep
73
  switch ( $schedule->get_max_backups() ) :
74
 
75
  case 1 :
76
 
77
- $backup_to_keep = sprintf( __( 'store only the last backup on %s', 'hmbkp' ), $server );
78
 
79
  break;
80
 
81
  case 0 :
82
 
83
- $backup_to_keep = sprintf( __( 'don\'t store any backups on %s', 'hmbkp' ), $server );
84
 
85
  break;
86
 
87
  default :
88
 
89
- $backup_to_keep = sprintf( __( 'store only the last %1$s backups on %2$s', 'hmbkp' ), esc_html( $schedule->get_max_backups() ), $server );
90
 
91
  endswitch;
92
 
93
- $email_msg = '';
94
 
95
  foreach ( HMBKP_Services::get_services( $schedule ) as $file => $service ) {
96
 
97
- if ( 'Email' == $service->name )
98
  $email_msg = wp_kses_post( $service->display() );
99
 
100
- elseif ( $service->is_service_active() )
101
  $services[] = esc_html( $service->display() );
102
 
 
 
103
  }
104
 
105
  if ( ! empty( $services ) && count( $services ) > 1 ) {
@@ -112,13 +125,22 @@ if ( ! empty( $services ) && count( $services ) > 1 ) {
112
 
113
  <div class="hmbkp-schedule-sentence<?php if ( $schedule->get_status() ) { ?> hmbkp-running<?php } ?>">
114
 
115
- <?php
116
- if ( ! empty( $services ) )
117
- printf( __( 'Backup my %1$s %2$s %3$s, %4$s. %5$s Send a copy of each backup to %6$s.', 'hmbkp' ), $filesize, '<span>' . $type . '</span>', $reoccurrence, $backup_to_keep, $email_msg, implode( ', ', array_filter( $services ) ) );
118
- else
119
- printf( __( 'Backup my %1$s %2$s %3$s, %4$s. %5$s', 'hmbkp' ), $filesize, '<span>' . $type . '</span>', $reoccurrence, $backup_to_keep, $email_msg );
120
- ?>
 
 
 
 
 
 
 
 
 
121
 
122
- <?php hmbkp_schedule_actions( $schedule ); ?>
123
 
124
- </div>
1
  <?php
2
 
3
  // Calculated filesize
4
+ $cached = $schedule->is_site_size_cached();
5
+
6
+ if ( $schedule->get_type() === 'database' ) {
7
+ $cached = true;
8
+ }
9
+
10
+ $filesize = $cached ? '(<code title="' . __( 'Backups will be compressed and should be smaller than this.', 'hmbkp' ) . '">' . esc_attr( $schedule->get_formatted_site_size() ) . '</code>)' : '(<code class="calculating" title="' . __( 'this shouldn\'t take long&hellip;', 'hmbkp' ) . '">' . __( 'calculating the size of your backup&hellip;', 'hmbkp' ) . '</code>)';
11
+
12
+ if ( isset( $_GET['hmbkp_add_schedule'] ) ) {
13
+ $filesize = '';
14
+ }
15
 
16
  // Backup Type
17
  $type = strtolower( hmbkp_human_get_type( $schedule->get_type() ) );
19
  // Backup Time
20
  $day = date_i18n( 'l', $schedule->get_next_occurrence( false ) );
21
 
22
+ $next_backup = 'title="' . esc_attr( sprintf( __( 'The next backup will be on %1$s at %2$s %3$s', 'hmbkp' ), date_i18n( get_option( 'date_format' ), $schedule->get_next_occurrence( false ) ), date_i18n( get_option( 'time_format' ), $schedule->get_next_occurrence( false ) ), date_i18n( 'T', $schedule->get_next_occurrence( false ) ) ) ) . '"';
23
 
24
  // Backup Re-occurrence
25
  switch ( $schedule->get_reoccurrence() ) :
26
 
27
  case 'hmbkp_hourly' :
28
+
29
  $reoccurrence = date_i18n( 'i', $schedule->get_next_occurrence( false ) ) === '00' ? '<span ' . $next_backup . '>' . __( 'hourly on the hour', 'hmbkp' ) . '</span>' : sprintf( __( 'hourly at %s minutes past the hour', 'hmbkp' ), '<span ' . $next_backup . '>' . intval( date_i18n( 'i', $schedule->get_next_occurrence( false ) ) ) ) . '</span>';
30
 
31
  break;
36
 
37
  break;
38
 
 
39
  case 'hmbkp_twicedaily' :
40
 
41
  $times[] = date_i18n( get_option( 'time_format' ), $schedule->get_next_occurrence( false ) );
55
 
56
  case 'hmbkp_fortnightly' :
57
 
58
+ $reoccurrence = sprintf( __( 'biweekly on %1$s at %2$s', 'hmbkp' ), '<span ' . $next_backup . '>' . $day . '</span>', '<span>' . esc_html( date_i18n( get_option( 'time_format' ), $schedule->get_next_occurrence( false ) ) ) . '</span>' );
59
 
60
  break;
61
 
 
62
  case 'hmbkp_monthly' :
63
 
64
  $reoccurrence = sprintf( __( 'on the %1$s of each month at %2$s', 'hmbkp' ), '<span ' . $next_backup . '>' . esc_html( date_i18n( 'jS', $schedule->get_next_occurrence( false ) ) ) . '</span>', '<span>' . esc_html( date_i18n( get_option( 'time_format' ), $schedule->get_next_occurrence( false ) ) ) . '</span>' );
71
 
72
  break;
73
 
74
+ default :
75
+
76
  $schedule->set_reoccurrence( 'manually' );
77
 
78
  endswitch;
79
 
80
  $server = '<span title="' . esc_attr( hmbkp_path() ) . '">' . __( 'this server', 'hmbkp' ) . '</span>';
81
+ $server = '<code>' . esc_attr( str_replace( $schedule->get_home_path(), '', hmbkp_path() ) ) . '</code>';
82
 
83
  // Backup to keep
84
  switch ( $schedule->get_max_backups() ) :
85
 
86
  case 1 :
87
 
88
+ $backup_to_keep = sprintf( __( 'store the most recent backup in %s', 'hmbkp' ), $server );
89
 
90
  break;
91
 
92
  case 0 :
93
 
94
+ $backup_to_keep = sprintf( __( 'don\'t store any backups in on this server', 'hmbkp' ), $server );
95
 
96
  break;
97
 
98
  default :
99
 
100
+ $backup_to_keep = sprintf( __( 'store the last %1$s backups in %2$s', 'hmbkp' ), esc_html( $schedule->get_max_backups() ), $server );
101
 
102
  endswitch;
103
 
104
+ $email_msg = $services = '';
105
 
106
  foreach ( HMBKP_Services::get_services( $schedule ) as $file => $service ) {
107
 
108
+ if ( 'Email' === $service->name ) {
109
  $email_msg = wp_kses_post( $service->display() );
110
 
111
+ } elseif ( $service->is_service_active() ) {
112
  $services[] = esc_html( $service->display() );
113
 
114
+ }
115
+
116
  }
117
 
118
  if ( ! empty( $services ) && count( $services ) > 1 ) {
125
 
126
  <div class="hmbkp-schedule-sentence<?php if ( $schedule->get_status() ) { ?> hmbkp-running<?php } ?>">
127
 
128
+ <?php $sentence = sprintf( __( 'Backup my %1$s %2$s %3$s, %4$s. ', 'hmbkp' ), '<span>' . $type . '</span>', $filesize, $reoccurrence, $backup_to_keep );
129
+
130
+ if ( $email_msg ) {
131
+ $sentence .= sprintf( __( '%s. ', 'hmbkp' ), $email_msg );
132
+ }
133
+
134
+ if ( $services ) {
135
+ $sentence .= sprintf( __( 'Send a copy of each backup to %s.', 'hmbkp' ), implode( ', ', array_filter( $services ) ) );
136
+ }
137
+
138
+ echo $sentence; ?>
139
+
140
+ <?php if ( HMBKP_Schedules::get_instance()->get_schedule( $schedule->get_id() ) ) {
141
+ hmbkp_schedule_status( $schedule );
142
+ } ?>
143
 
144
+ <?php require( HMBKP_PLUGIN_PATH . 'admin/schedule-settings.php' ); ?>
145
 
146
+ </div>
admin/schedule-settings.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if ( HMBKP_Schedules::get_instance()->get_schedule( $schedule->get_id() ) ) { ?>
2
+
3
+ <div class="hmbkp-schedule-actions row-actions">
4
+
5
+ <a class="hmbkp-run" href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'action' => 'hmbkp_run_schedule', 'hmbkp_schedule_id' => $schedule->get_id() ), hmbkp_get_settings_url() ) ), 'hmbkp-run-schedule' ); ?>"><?php _e( 'Run now', 'hmbkp' ); ?></a> |
6
+
7
+ <a href="<?php echo esc_url( add_query_arg( array( 'action' => 'hmbkp_edit_schedule', 'hmbkp_panel' => 'hmbkp_edit_schedule_settings', 'hmbkp_schedule_id' => $schedule->get_id() ), hmbkp_get_settings_url() ), 'hmbkp-edit-schedule' ); ?>"><?php _e( 'Settings', 'hmbkp' ); ?></a> |
8
+
9
+ <?php // Only show excludes if we are backing up files
10
+ if ( $schedule->get_type() !== 'database' ) { ?>
11
+ <a href="<?php echo esc_url( add_query_arg( array( 'action' => 'hmbkp_edit_schedule', 'hmbkp_panel' => 'hmbkp_edit_schedule_excludes', 'hmbkp_schedule_id' => $schedule->get_id() ), hmbkp_get_settings_url() ) ); ?>"><?php _e( 'Excludes', 'hmbkp' ); ?></a> |
12
+ <?php } ?>
13
+
14
+ <?php foreach ( HMBKP_Services::get_services( $schedule ) as $service ) :
15
+
16
+ if ( ! $service->has_form() )
17
+ continue; ?>
18
+
19
+ <a href="<?php echo esc_url( add_query_arg( array( 'action' => 'hmbkp_edit_schedule', 'hmbkp_panel' => 'hmbkp_edit_schedule_settings_' . $service->get_slug() , 'hmbkp_schedule_id' => $schedule->get_id() ), hmbkp_get_settings_url() ) ); ?>"><?php echo esc_html( $service->name ); ?></a> |
20
+
21
+ <?php endforeach; ?>
22
+
23
+ <a class="delete-action" href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'action' => 'hmbkp_request_delete_schedule', 'hmbkp_schedule_id' => $schedule->get_id() ), admin_url( 'admin-post.php' ) ), 'hmbkp_delete_schedule', 'hmbkp_delete_schedule_nonce' ) ); ?>"><?php _e( 'Delete', 'hmbkp' ); ?></a>
24
+
25
+ </div>
26
+
27
+ <?php } ?>
28
+
29
+ <?php if ( ! isset( $_GET['action'] ) || $_GET['action'] !== 'hmbkp_edit_schedule' || ! isset( $_GET['hmbkp_panel'] ) ) {
30
+ return;
31
+ } ?>
32
+
33
+ <div class="hmbkp-schedule-settings">
34
+
35
+ <?php if ( $_GET['action'] === 'hmbkp_edit_schedule' && $_GET['hmbkp_panel'] === 'hmbkp_edit_schedule_settings' ) {
36
+ require( HMBKP_PLUGIN_PATH . 'admin/schedule-form.php' );
37
+ } ?>
38
+
39
+ <?php if ( $_GET['action'] === 'hmbkp_edit_schedule' && $_GET['hmbkp_panel'] === 'hmbkp_edit_schedule_excludes' ) {
40
+ require( HMBKP_PLUGIN_PATH . 'admin/schedule-form-excludes.php' );
41
+ } ?>
42
+
43
+ <?php // Show the service form if we are viewing one
44
+ foreach ( HMBKP_Services::get_services( $schedule ) as $service ) : ?>
45
+
46
+ <?php if ( $_GET['action'] === 'hmbkp_edit_schedule' && $_GET['hmbkp_panel'] === 'hmbkp_edit_schedule_settings_' . $service->get_slug() ) { ?>
47
+
48
+ <h3><?php echo esc_html( $service->name ); ?></h3>
49
+
50
+ <?php
51
+
52
+ $hmbkp_form_errors = hmbkp_get_settings_errors();
53
+
54
+ if ( ! empty( $hmbkp_form_errors ) ) :
55
+
56
+ ?>
57
+
58
+ <div id="hmbkp-warning" class="error settings-error">
59
+
60
+ <?php foreach ( $hmbkp_form_errors as $error ) { ?>
61
+ <p><strong><?php echo esc_html( $error ); ?></strong></p>
62
+ <?php } ?>
63
+
64
+ </div>
65
+
66
+ <?php endif; ?>
67
+
68
+ <form method="post" action="<?php echo admin_url( 'admin-post.php' ); ?>">
69
+
70
+ <input type="hidden" name="hmbkp_schedule_id" value="<?php echo esc_attr( $schedule->get_id() ); ?>" />
71
+ <input type="hidden" name="action" value="hmbkp_edit_schedule_services_submit" />
72
+
73
+ <?php wp_nonce_field( 'hmbkp-edit-schedule-services', 'hmbkp-edit-schedule-services-nonce' ); ?>
74
+
75
+ <?php $service->form(); ?>
76
+
77
+ <?php submit_button( __( 'Done', 'hmbkp' ) ); ?>
78
+
79
+ </form>
80
+
81
+ <?php break; ?>
82
+
83
+ <?php } ?>
84
+
85
+ <?php endforeach; ?>
86
+
87
+ </div>
admin/server-info.php CHANGED
@@ -41,5 +41,6 @@
41
 
42
  <?php endforeach;
43
 
44
- foreach ( HMBKP_Services::get_services() as $file => $service )
45
  echo wp_kses_post( call_user_func( array( $service, 'intercom_data_html' ) ) );
 
41
 
42
  <?php endforeach;
43
 
44
+ foreach ( HMBKP_Services::get_services() as $file => $service ) {
45
  echo wp_kses_post( call_user_func( array( $service, 'intercom_data_html' ) ) );
46
+ }
admin/upsell.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="hmbkp-upsell">
2
+
3
+ <span>Backup to</span>&nbsp;
4
+
5
+ <span class="hmbkp-upsell-sep">
6
+ <a target="_blank" href="http://bwp.hmn.md/downloads/backupwordpress-to-dropbox/">Dropbox</a> |
7
+ <a target="_blank" href="http://bwp.hmn.md/downloads/backupwordpress-to-google-drive/">Google Drive</a> |
8
+ <a target="_blank" href="http://bwp.hmn.md/downloads/backupwordpress-to-amazon-s3/">Amazon S3</a> |
9
+ <a target="_blank" href="http://bwp.hmn.md/downloads/backupwordpress-to-ftp/">FTP</a> |
10
+ <a target="_blank" href="http://bwp.hmn.md/downloads/backupwordpress-to-rackspace-cloud/" alt="Rackspace Cloud">Rackspace Cloud</a> |
11
+ <a target="_blank" href="http://bwp.hmn.md/downloads/backupwordpress-to-windows-azure/">Windows Azure</a> |
12
+ <a target="_blank" href="http://bwp.hmn.md/downloads/backupwordpress-to-dreamobjects/">DreamObjects</a>
13
+ </span>
14
+
15
+ &nbsp;<span>or buy the <a target="_blank" href="https://bwp.hmn.md/checkout?edd_action=add_to_cart&download_id=36">Developer Bundle</a> now for only &dollar;99 (all Destinations &amp; Unlimited Sites)</span>
16
+
17
+ </div>
assets/colorbox/README.md ADDED
@@ -0,0 +1,527 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## About Colorbox:
2
+ A customizable lightbox plugin for jQuery. See the [project page](http://jacklmoore.com/colorbox/) for documentation and a demonstration, and the [FAQ](http://jacklmoore.com/colorbox/faq/) for solutions and examples to common issues. Released under the [MIT license](http://www.opensource.org/licenses/mit-license.php).
3
+
4
+ ## Changelog:
5
+
6
+ ### Version 1.4.33 - 2013/10/31
7
+
8
+ * Fixed an issue where private events propagated to the document in versions of jQuery prior to 1.7. Fixes #525, Fixes #526
9
+
10
+ ### Version 1.4.32 - 2013/10/16
11
+
12
+ * Updated stylesheets to avoid issue with using `div {max-width:100%}` (Fixes #520)
13
+
14
+ ### Version 1.4.31 - 2013/9/25
15
+
16
+ * Used setAttribute to set londesc, so that the value is accessible via DOM Node longDesc property #508
17
+
18
+ ### Version 1.4.30 - 2013/9/24
19
+
20
+ * Added longdesc and aria-describedby attributes to photos. Fixes #508
21
+
22
+ ### Version 1.4.29 - 2013/9/10
23
+
24
+ * Fixed a slideshow regression from 1.4.27
25
+ * Fixed a potential issue with the starting size of #cboxLoadedContent
26
+
27
+ ### Version 1.4.28 - 2013/9/4
28
+
29
+ * Fixed a potential issue with using the open property with mixed slideshow and non-slideshow groups
30
+
31
+ ### Version 1.4.27 - 2013/7/16
32
+
33
+ * Fixed a width calculation issue relating to using margin:auto on #cboxLoadedContent.
34
+
35
+ ### Version 1.4.26 - 2013/6/30
36
+
37
+ * Fixed a regression in IE7 and IE8 that was causing an error.
38
+
39
+ ### Version 1.4.25 - 2013/6/28
40
+
41
+ * Use an animation speed of zero between same-sized content (fixed).
42
+ * Removed temporary fix for jQuery UI 1.8
43
+
44
+ ### Version 1.4.24 - 2013/6/24
45
+
46
+ * Added closeButton option. Set to false to remove the close button.
47
+
48
+ ### Version 1.4.23 - 2013/6/23
49
+
50
+ * Bugfix loading overlay/graphic append order
51
+
52
+ ### Version 1.4.22 - 2013/6/19
53
+
54
+ * Updated manifest files for the jQuery plugin repository and Bower (no changes to plugin)
55
+
56
+ ### Version 1.4.21 - 2013/6/6
57
+
58
+ * Replaced new Image() with document.createElement('img') to avoid a potential bug in Chrome 27.
59
+
60
+ ### Version 1.4.20 - 2013/6/5
61
+
62
+ * Fixing bug/typo from last update.
63
+
64
+ ### Version 1.4.19 - 2013/6/3
65
+
66
+ * Fixed bug where Colorbox was capturing ctrl+click on assigned links on windows browsers with jQuery 1.7+, rather than ignoring.
67
+
68
+ ### Version 1.4.18 - 2013/5/30
69
+
70
+ * Fixed a scroll position issue when using $.colorbox.resize()
71
+
72
+ ### Version 1.4.17 - 2013/5/23
73
+
74
+ * Possible fix for a Chrome 27 issue (https://github.com/jackmoore/colorbox/pull/438#issuecomment-18334804)
75
+
76
+ ### Version 1.4.16 - 2013/5/20
77
+
78
+ * Added trapFocus setting to allow disabling of focus trapping
79
+
80
+ ### Version 1.4.15 - 2013/4/22
81
+
82
+ * Added .webp to list of recognized image extensions
83
+
84
+ ### Version 1.4.14 - 2013/4/16
85
+
86
+ * Added fadeOut property to control the closing fadeOut speed.
87
+ * Removed longdesc attribute for now.
88
+
89
+ ### Version 1.4.13 - 2013/4/11
90
+
91
+ * Fixed an error involving IE7/IE8 and legacy versions of jQuery
92
+
93
+ ### Version 1.4.12 - 2013/4/9
94
+
95
+ * Fixed a potential conflict with Twitter Bootstrap default img styles.
96
+
97
+ ### Version 1.4.11 - 2013/4/9
98
+
99
+ * Added `type='button'` to buttons to prevent accidental form submission
100
+ * Added alt and longdesc attributes to photo content if they are present on the calling element.
101
+
102
+ ### Version 1.4.10 - 2013/4/2
103
+
104
+ * Better 'old IE' feature detection that fixes an error with jQuery 2.0.0pre.
105
+
106
+ ### Version 1.4.9 - 2013/4/2
107
+
108
+ * Fixes bug introduced in previous version.
109
+
110
+ ### Version 1.4.8 - 2013/4/2
111
+
112
+ * Dropped IE6 support.
113
+ * Fixed other issues with $.colorbox.remove.
114
+
115
+ ### Version 1.4.7 - 2013/4/1
116
+
117
+ * Prevented an error if $.colorbox.remove is called during the transition.
118
+
119
+ ### Version 1.4.6 - 2013/3/19
120
+
121
+ * Minor change to work around a jQuery 1.4.2 bug for legacy users.
122
+
123
+ ### Version 1.4.5 - 2013/3/10
124
+
125
+ * Minor change to apply the close and className properties sooner.
126
+
127
+ ### Version 1.4.4 - 2013/3/10
128
+
129
+ * Fixed an issue with percent-based heights in iOS
130
+ * Fixed an issue with ajax requests being applied at the wrong time.
131
+
132
+ ### Version 1.4.3 - 2013/2/18
133
+
134
+ * Made image preloading aware of retina settings.
135
+
136
+ ### Version 1.4.2 - 2013/2/18
137
+
138
+ * Removed $.contains for compatibility with jQuery 1.3.x
139
+
140
+ ### Version 1.4.1 - 2013/2/14
141
+
142
+ * Ignored left and right arrow keypresses if combined with the alt key.
143
+
144
+ ### Version 1.4.0 - 2013/2/12
145
+
146
+ * Better accessibility:
147
+ * Replaced div controls with buttons
148
+ * Tabbed navigation confined to modal window
149
+ * Added aria role
150
+
151
+ ### Version 1.3.34 - 2013/2/4
152
+
153
+ * Updated manifest for plugins.jquery.com
154
+
155
+ ### Version 1.3.33 - 2013/2/4
156
+
157
+ * Added retina display properties: retinaImage, retinaUrl, retinaSuffix
158
+ * Fixed iframe scrolling on iOS devices.
159
+
160
+ ### Version 1.3.32 - 2013/1/31
161
+
162
+ * Improved internal event subscribing & fixed event bug introduced in v1.3.21
163
+
164
+ ### Version 1.3.31 - 2013/1/28
165
+
166
+ * Fixed a size-calculation bug introduced in the previous commit.
167
+
168
+ ### Version 1.3.30 - 2013/1/25
169
+
170
+ * Delayed border-width calculations until after opening, to avoid a bug in FF when using Colorbox in a hidden iframe.
171
+
172
+ ### Version 1.3.29 - 2013/1/24
173
+
174
+ * Fixes bug with bubbling delegated events, introduced in the previous commit.
175
+
176
+ ### Version 1.3.28 - 2013/1/24
177
+
178
+ * Fixed compatibility issue with old versions of jQuery (1.3.2-1.4.2)
179
+
180
+ ### Version 1.3.27 - 2013/1/23
181
+
182
+ * Added className property.
183
+
184
+ ### Version 1.3.26 - 2013/1/23
185
+
186
+ * Minor bugfix: clear the onload event handler after photo has loaded.
187
+
188
+ ### Version 1.3.25 - 2013/1/23
189
+
190
+ * Removed grunt file & added Bower component.json.
191
+
192
+ ### Version 1.3.24 - 2013/1/22
193
+
194
+ * Added generated files (jquery.colorbox.js / jquery.colorbox-min.js) back to the repository.
195
+
196
+ ### Version 1.3.23 - 2013/1/18
197
+
198
+ * Minor bugfix for calling Colorbox on empty jQuery collections without a selector.
199
+
200
+ ### Version 1.3.22 - 2013/1/17
201
+
202
+ * Recommit for plugins.jquery.com
203
+
204
+ ### Version 1.3.21 - 2013/1/15
205
+ Files Changed: *.js
206
+
207
+ * Fixed compatibility issues with jQuery 1.9
208
+
209
+ ### Version 1.3.20 - August 15 2012
210
+ Files Changed:jquery.colorbox.js
211
+
212
+ * Added temporary workaround for jQuery-UI 1.8 bug (http://bugs.jquery.com/ticket/12273)
213
+ * Added *.jpe extension to the list of image types.
214
+
215
+ ### Version 1.3.19 - December 08 2011
216
+ Files Changed:jquery.colorbox.js, colorbox.css (all)
217
+
218
+ * Fixed bug related to using the 'fixed' property.
219
+ * Optimized the setup procedure to be more efficient.
220
+ * Removed $.colorbox.init() as it will no longer be needed (will self-init when called).
221
+ * Removed use of $.browser.
222
+
223
+ ### Version 1.3.18 - October 07 2011
224
+ Files Changed:jquery.colorbox.js/jquery.colorbox-min.js, colorbox.css (all) and example 1's controls.png
225
+
226
+ * Fixed a regression where Flash content displayed in Colorbox would be reloaded if the browser window was resized.
227
+ * Added safety check to make sure that Colorbox's markup is only added to the DOM a single time, even if $.colorbox.init() is called multiple times. This will allow site owners to manually initialize Colorbox if they need it before the DOM has finished loading.
228
+ * Updated the example index.html files to be HTML5 compliant.
229
+ * Changed the slideshow behavior so that it immediately moves to the next slide when the slideshow is started.
230
+ * Minor regex bugfix to allow automatic detection of image URLs that include fragments.
231
+
232
+ ### Version 1.3.17 - May 11 2011
233
+ Files Changed:jquery.colorbox.js/jquery.colorbox-min.js
234
+
235
+ * Added properties "top", "bottom", "left" and "right" to specify a position relative to the viewport, rather than using the default centering.
236
+ * Added property "data" to specify GET or POST data when using Ajax. Colorbox's ajax functionality is handled by jQuery's .load() method, so the data property works the same way as it does with .load().
237
+ * Added property "fixed" which can provide fixed positioning for Colorbox, rather than absolute positioning. This will allow Colorbox to remain in a fixed position within the visitors viewport, despite scrolling. IE6 support for this was not added, it will continue to use the default absolute positioning.
238
+ * Fixed ClearType problem with IE7.
239
+ * Minor fixes.
240
+
241
+ ### Version 1.3.16 - March 01 2011
242
+ Files Changed:jquery.colorbox.js/jquery.colorbox-min.js, colorbox.css (all) and example 4 background png files
243
+
244
+ * Better IE related transparency workarounds. IE7 and up now uses the same background image sprite as other browsers.
245
+ * Added error handling for broken image links. A message will be displayed telling the user that the image could not be loaded.
246
+ * Added new property: 'fastIframe' and set it to true by default. Setting to fastIframe:false will delay the loading graphic removal and onComplete event until iframe has completely loaded.
247
+ * Ability to redefine $.colorbox.close (or prev, or next) at any time.
248
+
249
+ ### Version 1.3.15 - October 27 2010
250
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
251
+
252
+ * Minor fixes for specific cases.
253
+
254
+ ### Version 1.3.14 - October 27 2010
255
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
256
+
257
+ * In IE6, closing an iframe when using HTTPS no longer generates a security warning.
258
+
259
+ ### Version 1.3.13 - October 22 2010
260
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
261
+
262
+ * Changed the index.html example files to use YouTube's new embedded link format.
263
+ * By default, Colorbox returns focus to the element it was launched from once it closes. This can now be disabled by setting the 'returnFocus' property to false. Focus was causing problems for some users who had their anchor elements inside animated containers.
264
+ * Minor bug fix involved in using a combination of slideshow and non-slideshow content.
265
+
266
+ ### Version 1.3.12 - October 20 2010
267
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
268
+
269
+ * Minor bug fix involved in preloading images when using a function as a value for the href property.
270
+
271
+ ### Version 1.3.11 - October 19 2010
272
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
273
+
274
+ * Fixed the slideshow functionality that broke with 1.3.10
275
+ * The slideshow now respects the loop property.
276
+
277
+ ### Version 1.3.10 - October 16 2010
278
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
279
+
280
+ * Fixed compatibility with jQuery 1.4.3
281
+ * The 'open' property now accepts a function as a value, like all of the other properties.
282
+ * Preloading now loads the correct href for images when using a dynamic (function) value for the href property.
283
+ * Fixed bug in Safari 3 for Win where Colorbox centered on the document, rather than the visitor's viewport.
284
+ * May have fixed an issue in Opera 10.6+ where Colorbox would rarely/randomly freeze up while switching between photos in a group.
285
+ * Some functionality better encapsulated & minor performance improvements.
286
+
287
+ ### Version 1.3.9 - July 7 2010
288
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js/ all colorbox.css (the core styles)
289
+
290
+ * Fixed a problem where iframed youtube videos would cause a security alert in IE.
291
+ * More code is event driven now, making the source easier to grasp.
292
+ * Removed some unnecessary style from the core CSS.
293
+
294
+ ### Version 1.3.8 - June 21 2010
295
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
296
+
297
+ * Fixed a bug in Chrome where it would sometimes render photos at 0 by 0 width and height (behavior introduced in recent update to Chrome).
298
+ * Fixed a bug where the onClosed callback would fire twice (only affected 1.3.7).
299
+ * Fixed a bug in IE7 that existed with some iframed websites that use JS to reposition the viewport caused Colorbox to move out of position.
300
+ * Abstracted the identifiers (HTML ids & classes, and JS plugin name, method, and events) so that the plugin can be easily rebranded.
301
+ * Small changes to improve either code readability or compression.
302
+
303
+ ### Version 1.3.7 - June 13 2010
304
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js/index.html
305
+
306
+ * $.colorbox can now be used for direct calls and accessing public methods. Example: $.colorbox.close();
307
+ * Resize now accepts 'width', 'innerWidth', 'height' and 'innerHeight'. Example: $.colorbox.resize({width:"100%"})
308
+ * Added option (loop:false) to disable looping in a group.
309
+ * Added options (escKey:false, arrowKey:false) to disable esc-key and arrow-key bindings.
310
+ * Added method for removing Colorbox from a document: $.colorbox.remove();
311
+ * Fixed a bug where iframed URLs would be truncated if they contained an unencoded apostrophe.
312
+ * Now uses the exact href specified on an anchor, rather than the version returned by 'this.href'. This was causing "#example" to be normalized to "http://domain/#example" which interfered with how some users were setting up links to inline content.
313
+ * Changed example documents over to HTML5.
314
+
315
+ ### Version 1.3.6 - Jan 13 2010
316
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
317
+
318
+ * Small change to make Colorbox compatible with jQuery 1.4
319
+
320
+ ### Version 1.3.5 - December 15 2009
321
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
322
+
323
+ * Fixed a bug introduced in 1.3.4 with IE7's display of example 2 and 3, and auto-width in Opera.
324
+ * Fixed a bug introduced in 1.3.4 where colorbox could not be launched by triggering an element's click event through JavaScript.
325
+ * Minor refinements.
326
+
327
+ ### Version 1.3.4 - December 5 2009
328
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
329
+
330
+ * Event delegation is now used for elements that Colorbox is assigned to, rather than individual click events.
331
+ * Additional callbacks have been added to represent other stages of Colorbox's lifecycle. Available callbacks, in order of their execution: onOpen, onLoad, onComplete, onCleanup, onClosed These take place at the same time as the event hooks, but will be better suited than the hooks for targeting specific instances of Colorbox.
332
+ * Ajax content is now immediately added to the DOM to be more compatible if that content contains script tags.
333
+ * Focus is now returned to the calling element on closing.
334
+ * Fixed a bug where maxHeight and maxWidth did not work for non-photo content.
335
+ * Direct calls no longer need 'open:true', it is assumed. Example: `$.colorbox({html:'<p>Hi</p>'});`
336
+
337
+ ### Version 1.3.3 - November 7 2009
338
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
339
+
340
+ * Changed $.colorbox.element() to return a jQuery object rather the DOM element.
341
+ * jQuery.colorbox-min.js is compressed with Google's Closure Compiler rather than YUI Compressor.
342
+
343
+ ### Version 1.3.2 - October 27 2009
344
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
345
+
346
+ * Added 'innerWidth' and 'innerHeight' options to allow people to easily set the size dimensions for Colorbox, without having to anticipate the size of the borders and buttons.
347
+ * Renamed 'scrollbars' option to 'scrolling' to be in keeping with the existing HTML attribute. The option now also applies to iframes.
348
+ * Bug fix: In Safari, positioning occassionally incorrect when using '100%' dimensions.
349
+ * Bug fix: In IE6, the background overlay is briefly not full size when first viewing.
350
+ * Bug fix: In Firefox, opening Colorbox causes a split second shift with a small minority of webpage layouts.
351
+ * Simplified code in a few areas.
352
+
353
+ ### Version 1.3.1 - September 16 2009
354
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js/colorbox.css/colorbox-ie.css(removed)
355
+
356
+ * Removed the IE-only stylesheets and conditional comments for example styles 1 & 4. All CSS is handled by a single CSS file for all examples.
357
+ * Removed user-agent sniffing from the js and replaced it with feature detection. This will allow correct rendering for visitors masking their agent type.
358
+
359
+ ### Version 1.3.0 - September 15 2009
360
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js/colorbox.css
361
+
362
+ * Added $.colorbox.resize() method to allow Colorbox to resize it's height if it's contents change.
363
+ * Added 'scrollbars' option to allow users to turn off scrollbars when using the resize() method.
364
+ * Renamed the 'resize' option to be less ambiguous. It's now 'scalePhotos'.
365
+ * Renamed the 'cbox_close' event to be less ambiguous. It's now 'cbox_cleanup'. It is the first thing to happen in the close method while the 'cbox_closed' event is the last to happen.
366
+ * Fixed a bug with the slideshow mouseover graphics that appeared after Colorbox is opened a 2nd time.
367
+ * Fixed a bug where ClearType may not work in IE6&7 if using the fade transition.
368
+ * Minor code optimizations to increase compression.
369
+
370
+ ### Version 1.2.9 - August 7 2009
371
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
372
+
373
+ * Minor change to enable use with $.getScript();
374
+ * Minor change to the timing of the 'cbox_load' event so that it is more useful.
375
+ * Added a direct link to a YouTube video to the examples.
376
+
377
+ ### Version 1.2.8 - August 5 2009
378
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
379
+
380
+ * Fixed a bug with the overlay in IE6
381
+ * Fixed a bug where left & right keypress events might be prematurely unbound.
382
+
383
+ ### Version 1.2.7 - July 31 2009
384
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js, example stylesheets and background images (core styles have not changed and the updates will not affect existing user themes / old example themes)
385
+
386
+ * Code cleanup and reduction, better organization and documentation in the full source.
387
+ * Added ability to use functions in place of static values for Colorbox's options (thanks Ken!).
388
+ * Added an option for straight HTML. Example: `$.colorbox({html:'<p>Howdy</p>', open:true})`
389
+ * Added an event for the beginning of the closing process. This is in addition to the event that already existed for when Colorbox had completely closed. 'cbox_close' and 'cbox_closed' respectively.
390
+ * Fixed a minor bug in IE6 that would cause a brief content shift in the parent document when opening Colorbox.
391
+ * Fixed a minor bug in IE6 that would reveal select elements that had a hidden visibility after closing Colorbox.
392
+ * The 'esc' key is unbound now when Colorbox is not open, to avoid any potential conflicts.
393
+ * Used background sprites for examples 1 & 4. Put IE-only (non-sprite) background images in a separate folder.
394
+ * Example themes 1, 3, & 4 received slight visual tweaks.
395
+ * Optimized pngs for smaller file size.
396
+ * Added slices, grid, and correct sizing to the Adobe Illustrator file, all theme files are now export ready!
397
+
398
+ ### Version 1.2.6 - July 15 2009
399
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
400
+
401
+ * Fixed a bug with fixed width/height images in Opera 9.64.
402
+ * Fixed a bug with trying to set a value for rel during a direct call to Colorbox. Example: `$.colorbox({rel:'foo', open:true});`
403
+ * Changed how href/rel/title settings are determined to avoid users having to manually update Colorbox settings if they use JavaScript to update any of those attributes, after Colorbox has been defined.
404
+ * Fixed a FF3 bug where the back button was disabled after closing an iframe.
405
+
406
+ ### Version 1.2.5 - June 23 2009
407
+ Files Changed: jquery.colorbox.js/jquery.colorbox-min.js
408
+
409
+ * Changed the point at which iframe srcs are set (to eliminate the need to refresh the iframe once it has been added to the DOM).
410
+ * Removed unnecessary return values for a very slight code reduction.
411
+
412
+ ### Version 1.2.4 - June 9 2009
413
+ Files Changed: jquery.colorbox.js, jquery.colorbox-min.js
414
+
415
+ * Fixed an issue where Colorbox may not close completely if it is closed during a transition animation.
416
+ * Minor code reduction.
417
+
418
+ ### Version 1.2.3 - June 4 2009
419
+ * Fixed a png transparency stacking issue in IE.
420
+ * More accurate Ajax auto-sizing if the user was depending on the #cboxLoadedContent ID for CSS styling.
421
+ * Added a public function for returning the current html element that Colorbox is associated with. Example use: var that = $.colorbox.element();
422
+ * Added bicubic scaling for resized images in the original IE7.
423
+ * Removed the IE6 stylesheet and png files from Example 3. It now uses the same png file for the controls that the rest of the browsers use (an alpha transparency PNG8). This example now only has 2 graphics files and 1 stylesheet.
424
+
425
+ ### Version 1.2.2 - May 28 2009
426
+ * Fixed an issue with the 'resize' option.
427
+
428
+ ### Version 1.2.1 - May 28 2009
429
+ * Note: If you are upgrading, update your jquery.colorbox.js and colorbox.css files.
430
+ * Added photo resizing.
431
+ * Added a maximum width and maximum height. Example: {height:800, maxHeight:'100%'}, would allow the box to be a maximum potential height of 800px, instead of a fixed height of 800px. With maxHeight of 100% the height of Colorbox cannot exceed the height of the browser window.
432
+ * Added 'rel' setting to add the ability to set an alternative rel for any Colorbox call. This allows the user to group any combination of elements together for a gallery, or to override an existing rel. attribute so those element are not grouped together, without having to alter their rel in the HTML.
433
+ * Added a 'photo' setting to force Colorbox to display a link as a photo. Use this when automatic photo detection fails (such as using a url like 'photo.php' instead of 'photo.jpg', 'photo.jpg#1', or 'photo.jpg?pic=1')
434
+ * Removed the need to ever create disposable elements to call colorbox on. Colorbox can now be called directly, without being associated with any existing element, by using the following format:
435
+ `$.colorbox({open:true, href:'yourLink.xxx'});`
436
+ * Colorbox settings are now persistent and unique for each element. This allows for extremely flexible options for individual elements. You could use this to create a gallery in which each page in the gallery has different settings. One could be a photo with a fade transition, next could be an inline element with an elastic transition with a set width and height, etc.
437
+ * For user callbacks, 'this' now refers to the element colorbox was opened from.
438
+ * Fixed a minor grouping issue with IE6, when transition type is set to 'none'.
439
+ * Added an Adobe Illustrator file that contains the borders and buttons used in the various examples.
440
+
441
+ ### Version 1.2 - May 13 2009
442
+ * Added a slideshow feature.
443
+ * Added re-positioning on browser resize. If the browser is resized, Colorbox will recenter itself onscreen.
444
+ * Added hooks for key events: cbox_open, cbox_load, cbox_complete, cbox_closed.
445
+ * Fixed an IE transparency-stacking problem, where transparent PNGs would show through to the background overlay.
446
+ * Fixed an IE iframe issue where the ifame might shift up and to the left under certain circumstances.
447
+ * Fixed an IE6 bug where the loading overlay was not at full height.
448
+ * Removed the delay in switching between same-sized gallery content when using transitions.
449
+ * Changed how iframes are loaded to make it more compatible with iframed pages that use DOM dependent JavaScript.
450
+ * Changed how the JS is structured to be better organized and increase compression. Increased documentation.
451
+ * Changed CSS :hover states to a .hover class. This sidesteps a minor IE8 bug with css hover states and allows easier access to hover state user styles from the JavaScript.
452
+ * Changed: elements added to the DOM have new ID's. The naming is more consistent and less likely to cause conflicts with existing website stylesheets. All stylesheets have been updated.
453
+ * Changed the behavior for prev/next links so that Colorbox does not get hung up on broken links. A visitor can now skip through broken or long-loading links by clicking prev/next buttons.
454
+ * Changed the naming of variables in the parameter map to be more concise and intuitive.
455
+ * Removed colorbox.css. Combined the colorbox.css styles with jquery.colorbox.js: the css file was not large enough to warrant being a separate file.
456
+
457
+ ### Version 1.1.6 - April 28 2009
458
+ * Prevented the default action of the next & previous anchors and the left and right keys for gallery mode.
459
+ * Fixed a bug where the title element was being added back to the DOM when closing Colorbox while using inline content.
460
+ * Fixed a bug where IE7 would crash for example 2.
461
+ * Smaller filesize: removed a small amount of unused code and rewrote the HTML injection with less syntax.
462
+ * Added a public method for closing Colorbox: $.colorbox.close(). This will allow iframe users to add an event to close Colorbox without having to create an additional function.
463
+
464
+ ### Version 1.1.5 - April 11 2009
465
+ * Fixed minor issues with exiting Colorbox.
466
+
467
+ ### Version 1.1.4 - April 08 2009
468
+ * Fixed a bug in the fade transition where Colorbox not close completely if instructed to close during the fade-in portion of the transition.
469
+
470
+ ### Version 1.1.3 - April 06 2009
471
+ * Fixed an IE6&7 issue with using Colorbox to display animated GIFs.
472
+
473
+ ### Version 1.1.2 - April 05 2009
474
+ * Added ability to change content when Colorbox is already open.
475
+ * Added vertical photo centering now works for all browsers (this feature previously excluded IE6&7).
476
+ * Added namespacing to the esc-key keydown event for people who want to disable it: "keydown.colorClose"
477
+ * Added 'title' setting to add the ability to set an alternative title for any Colorbox call.
478
+ * Fixed rollover navigation issue with IE8. (Added JS-based rollover state due to a browser-bug.)
479
+ * Fixed an overflow issue for when the fixed width/height is smaller than the size of a photo.
480
+ * Fixed a bug in the fade transition where the border would still come up if Colorbox was closed mid-transition.
481
+ * Switch from JSMin to Yui Compressor for minification. Minified code now under 7KB.
482
+
483
+ ### Version 1.1.1 - March 31 2009
484
+ * More robust image detection regex. Now detects image file types with url fragments and/or query strings.
485
+ * Added 'nofollow' exception to rel grouping.
486
+ * Changed how images are loaded into the DOM to prevent premature size calculation by Colorbox.
487
+ * Added timestamp to iframe name to prevent caching - this was a problem in some browsers if the user had multiple iframes and the visitor left the page and came back, or if they refreshed the page.
488
+
489
+ ### Version 1.1.0 - March 21 2009
490
+ * Animation is now much smoother and less resource intensive.
491
+ * Added support for % sizing.
492
+ * Callback option added.
493
+ * Inline content now preserves JavaScript events, and changes made while Colorbox is open are also preserved.
494
+ * Added 'href' setting to add the ability to set an alternative href for any anchor, or to assign the Colorbox event to non-anchors.
495
+ Example: $('button').colorbox({'href':'process.php'})
496
+ Example: $('a[href='http://msn.com']).colorbox({'href':'http://google.com', iframe:true});
497
+ * Photos are now horizontally centered if they are smaller than the lightbox size. Also vertically centered for browsers newer than IE7.
498
+ * Buttons in the examples are now included in the 'protected zone'. The lightbox will never expand it's borders or buttons beyond an accessible area of the screen.
499
+ * Keypress events don't queue up by holding down the arrow keys.
500
+ * Added option to close Colorbox by clicking on the background overlay.
501
+ * Added 'none' transition setting.
502
+ * Changed 'contentIframe' and 'contentInline' to 'inline' and 'iframe'. Removed 'contentAjax' because it is automatically assumed for non-image file types.
503
+ * Changed 'contentWidth' and 'contentHeight' to 'fixedWidth' and 'fixedHeight'. These sizes now reflect the total size of the lightbox, not just the inner content. This is so users can accurately anticipate % sizes without fear of creating scrollbars.
504
+ * Clicking on a photo will now switch to the next photo in a set.
505
+ * Loading.gif is more stable in it's position.
506
+ * Added a minified version.
507
+ * Code passes JSLint.
508
+
509
+ ### Version 1.0.5 - March 11 2009
510
+ * Redo: Fixed a bug where IE would cut off the bottom portion of a photo, if the photo was larger than the document dimensions.
511
+
512
+ ### Version 1.0.4 - March 10 2009
513
+ * Added an option to allow users to automatically open the lightbox. Example usage: $(".colorbox").colorbox({open:true});
514
+ * Fixed a bug where IE would cut off the bottom portion of a photo, if the photo was larger than the document dimensions.
515
+
516
+ ### Version 1.0.3 - March 09 2009
517
+ * Fixed vertical centering for Safari 3.0.x.
518
+
519
+ ### Version 1.0.2 - March 06 2009
520
+ * Corrected a typo.
521
+ * Changed the content-type check so that it does not assume all links to photos should actually display photos. This allows for Ajax/inline/and iframe calls on anchors linking to picture file types.
522
+
523
+ ### Version 1.0.1 - March 05 2009
524
+ * Fixed keydown events (esc, left arrow, right arrow) for Webkit browsers.
525
+
526
+ ### Version 1.0 - March 03 2009
527
+ * First release
assets/colorbox/bower.json ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "jquery-colorbox",
3
+ "description": "jQuery lightbox and modal window plugin",
4
+ "version": "1.4.33",
5
+ "dependencies": {
6
+ "jquery": ">=1.3.2"
7
+ },
8
+ "keywords": [
9
+ "modal",
10
+ "lightbox",
11
+ "window",
12
+ "popup",
13
+ "ui",
14
+ "jQuery"
15
+ ],
16
+ "authors": [
17
+ {
18
+ "name": "Jack Moore",
19
+ "url": "http://www.jacklmoore.com",
20
+ "email": "hello@jacklmoore.com"
21
+ }
22
+ ],
23
+ "licenses": [
24
+ {
25
+ "type": "MIT",
26
+ "url": "http://www.opensource.org/licenses/mit-license.php"
27
+ }
28
+ ],
29
+ "homepage": "http://www.jacklmoore.com/colorbox",
30
+ "main": "jquery.colorbox.js"
31
+ }
assets/colorbox/colorbox.ai ADDED
@@ -0,0 +1,1811 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0
  |Hc���笪@�������O`ҟC�Bu3Y��j�?`-���'%���I���M��F�%x^2�u��L5���ŔY�����\����P��*+$ھ�!qA�����Ө�
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
- ;���a|[fGЪ~l RH���0��Lq;O�������5v�ƽ� �F,����[�;p���Bc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  �U�s���”��a�'���J؏Ey��{~�Sk0V�T��o�� ���4,��j����@��~��:̈������Z�����o5�i����u�w�1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  ��}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
- �J������k�������Ԃxe I>�dwR*(]bI��]��U���.M� ��ɠ���n�`Ty]i��
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  �?����L�w��\ MKT֣�.�`�y�?O�c�� ,y���DIm�R�(ꑇ��M7�Xk&�6�H��H�ۑ���SrIi�n�}?�W��նs�9��6s��qw�d�b]ݮO����(u�|JFܺ�)�i�����x�d��nv�Xr͟��7�U8���w�uX�[����2=�~��/��>�J��E|f$�sߕ�e�*�����h��^�RSo��!z]y�j��b������a��9՝��8b0l��|*�Ӳs۠ c���ѹ��txz���<W�ʘ?�h{��� �Lj7�q��!�ԩ��/ZQ5AB����\�{�"��S�Ɍt�����e*xx���j�b�u����0�ȱ���k��q�0��5�������YnQ%i
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
- �'}])4�\��3u{b�NW��:��;�(�>��[/����׉�����~�&;d�#�C~��}����|��*��hD��qF3�%��f����1�vO;ʣ���O[�[?��
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ %PDF-1.4
2
+ 1 0 obj
3
+ <?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
4
+ <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.2.2-c063 53.351735, 2008/07/22-18:11:12 ">
5
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
6
+ <rdf:Description rdf:about=""
7
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
8
+ <dc:format>application/vnd.adobe.illustrator</dc:format>
9
+ <dc:title>
10
+ <rdf:Alt>
11
+ <rdf:li xml:lang="x-default">colorbox</rdf:li>
12
+ </rdf:Alt>
13
+ </dc:title>
14
+ </rdf:Description>
15
+ <rdf:Description rdf:about=""
16
+ xmlns:xmp="http://ns.adobe.com/xap/1.0/"
17
+ xmlns:xmpGImg="http://ns.adobe.com/xap/1.0/g/img/">
18
+ <xmp:CreatorTool>Adobe Illustrator CS4</xmp:CreatorTool>
19
+ <xmp:CreateDate>2009-05-27T04:22:39-04:00</xmp:CreateDate>
20
+ <xmp:ModifyDate>2009-07-30T21:43:35-05:00</xmp:ModifyDate>
21
+ <xmp:MetadataDate>2009-07-30T21:43:35-05:00</xmp:MetadataDate>
22
+ <xmp:Thumbnails>
23
+ <rdf:Alt>
24
+ <rdf:li rdf:parseType="Resource">
25
+ <xmpGImg:width>208</xmpGImg:width>
26
+ <xmpGImg:height>256</xmpGImg:height>
27
+ <xmpGImg:format>JPEG</xmpGImg:format>
28
+ <xmpGImg:image>/9j/4AAQSkZJRgABAgEBLAEsAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABABLAAAAAEA&#xA;AQEsAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK&#xA;DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f&#xA;Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAADQAwER&#xA;AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA&#xA;AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB&#xA;UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE&#xA;1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ&#xA;qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy&#xA;obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp&#xA;0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo&#xA;+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7&#xA;FXYq7FXYq7FXYq7FXnn5b+fNd85T6us6W9jHpkiRL6KOzOzl9zzagACdMVZt9U1D/lt/5Jr/AFxV&#xA;gf5ZfmZrHmfzJrei39vBGNIaSNbiEODIYpjFUqzNStK4q9JxV2KuxV2KuxV2KuxV2KuxV2KvG/Pf&#xA;5jfmBY/mDL5Z8twpdMyRNb2/pKzktEHf4jTYbmpxVQ/xJ/zkV/1Y1/4G3/6qYqh9G/ND8zYvPml+&#xA;WvMdtHZSXcsXqwtEgYwyEjkjKSCDQioPXFXueKvBB+aX5r6n5k1HSdAtI717OSX4EiT4Y0fiCzOV&#xA;H44qmH+JP+civ+rGv/A2/wD1UxVd5F/Nbzde6/qVh5lMVnHpcEj3aNGIzG0TANyPgBiqbeU/z18v&#xA;eZdcl0izkZZ2kZLEPEw9aONOTS1pRQTUKCa+OKqdh+fvlm882Dy+kzAycYoLkxsFN16jRtbsCOuy&#xA;lWFVNaVr1VRfnv8AN5/Jt9AmpWLvp1zbyPBexFWrcx7iEx1BFV/aO340VR+r/mFqWj+Sl8x6lYGG&#xA;aOOGS808MrPH6jKHVW2VivLbpX2xVMtC8622vaLFq+lzLPaTKxRuJHxLUMpBoQQRirDfIf5y6x5n&#xA;1DSrWaxhtl1HT7i/dkZmKmC7a2CCoHXjyriqH/5x3/vvNf8AzFQ/rmxV7Lirwb8hv/JkedP+M9z/&#xA;ANRhxV7zirsVdirsVdirsVdirsVdirsVeNSf+tKx/wDMKf8AqDOKvZcVeHfmF/60T5T/AOYO0/6i&#xA;7nFXuOKvDvyS/wDJleb/AJN/1EHFXuOKvCPKoB/O/wA3AioLSgg/OPFWbeXvLflPTby/m0e1gjnl&#xA;n5XRjCnhLxHJVP7O1KqPn1OKtQ+W/KaebH1VLaAa4LZVQhVBWIu9XVRtyZmYM3XtiqC8x+VvI2q6&#xA;79Y19I7m7WzkRbe5c+mkBPxyIhPFH/yx8W3XbFVeXQvK8/km20meQyeX1jgQPJI3xRqylQ7k1AOw&#xA;O+2Kp/bWdpb2iWtpEkNsiCOKKIBVVQOICgbAAbDFWE+SPKfkrTL7TZ9Eu7i4ltrCeCzEtaNbPdM8&#xA;jtVE3EzFR0+XfFVH/nHf++81/wDMVD+ubFXsuKvBvyG/8mR50/4z3P8A1GHFXvOKuxV2KuxV2Kux&#xA;V2KuxV2KuxV4tfgH/nISYHcfUl/6h1xV6LwT+Ufdil5J5sAH/OQPlWgp/o1r0/5ibjFD3/FXg/5T&#xA;gHzt5xqK/vk6/wDGWbFXqnBP5R92KXlnlqJJPzo80xNUI8AU8SVNDFCNitCD7jFDLfL3kW10fUZL&#xA;xLiWQh2MKsduDClHH7RB74qttvIVnD5iGrfWZSqfvEj5GplZmJJbrwoR8Pfvttiqt5q8pyeYJ4Vl&#xA;uBDawRuU4oDJ6zbAlj+xtuBT5+CqM1DRrrUPLf6LnlRJ5I40mljWiAggsVTbw2GKo3SNNg0uwgso&#xA;Gd4oBRWkYsx+k/qG2KpD5W8sajpU1k9y0TC3spraT02J+OS5MwIqo24/jiqS/wDOO/8Afea/+YqH&#xA;9c2KvZcVeDfkN/5Mjzp/xnuf+ow4q95xV2KuxV2KuxV2KuxV2KuxV2KvA/OPmPTvL356y6jqJZbM&#xA;W0cUsiKXKc4AAxUbkA9ab4qyL/ldX5a/9XZv+kW7/wCqWKsFm8z6R5m/PLy5qGkO81lALa19Z0aM&#xA;O6yySEqrgNQeqBuBvXtvir6UxV81eTfOmheWPPHmY6zI8EF5MwjnVHkUNFK54ssYZvi57bYqzv8A&#xA;5XV+Wv8A1dm/6Rbv/qlirFfy41m11v8ANXXtVtAwtbqImHmKMVT04wxHblwrir2LFLsVdirsVdir&#xA;sVeef847/wB95r/5iof1zYoey4q8G/Ib/wAmR50/4z3P/UYcVe84q7FXYq7FXYq7FXYq7FXYq7FU&#xA;p1Dyj5X1G6a7v9Ktbq6cAPNNEjuQooKkiuwGKob/AJV95G/6sNh/0jx/0xVVtfJPlC0uY7m10azg&#xA;uIWDxSxworKw6EEDY4qnWKpHN5F8mTSvLLollJLISzu0EZJYmpJNMVWf8q+8jf8AVhsP+keP+mKo&#xA;rT/KfljTpjNYaXa2sxHEyQxIjFT2qoGKph9Utv8AfS/dirvqlt/vpfuxV31S2/30v3Yq76pbf76X&#xA;7sVd9Utv99L92Ku+qW3++l+7FXj/APzjwQLjzUhNGNzCwU9aVl3pir2XFXg35DD/AJCN5zb9lprk&#xA;q3Yj62emKvecVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVSyfy1oU2&#xA;5soUbpySNUNPCoGKqH+D9B/5ZhiqN03RdK0xOFhaRWwIofSRUJHvxAxVG4q7FXYq7FXYq7FXYq7F&#xA;XYqg9H1jTdZ0u11XTLhLqwvI1mt54yCrI4qP7R2xVL/OHm6x8qaNca1qNrdTabaL6l3NaRiYxJWh&#xA;ZkDB+I7kKaDc7Yq84/6Gu/Kj0DcV1P0AokMv1GTgELcA3KtKc/hr47Yq9J8pea7PzTo1vrNha3UG&#xA;nXiCW0lu41iMsbfZdU5F+LdQSBUbjbFUdrOs6ZoulXWq6pcJa2FlG01zPIaKqIKn5nwHfFUZirsV&#xA;dirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdir8t7NtVW2nltHmS3gCvcNGzKq8mCK&#xA;TQjck0xV9Tf84pyar5v/AC088eUtS1CZ7GaM2dq8hMpgXULeaOXhyPTYNx6Vr44qxf8A6Fe/OhtP&#xA;Hllv0WNHEwYXv1iSgYOT6/GnPdTTjx+iu+Kss/5y2utV8sfl/wCTPLWnX80diA1vcshMbTixgiSI&#xA;vxPT4i3HpX5DFXyrdvqzW0El28z209XgaRmZGKEoSKkioNRir9SMVdirsVdirsVdirsVdirsVdir&#xA;sVdirsVdirsVdirsVdirsVdirsVfnX5S85aNpmjNFND6bwAGSJAC0xJA5DkRU+IJxV71/wA4TyrN&#xA;a+dJUHFZLq0dR4BhOR0xV9NYq+ZP+c25FjsvJsjCqpdXbMPYLCcVeC+YvOOiXnl4WyQCea4B9KNw&#xA;AYCCRzPGtG8ADv32xV+iuKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KvhDQ&#xA;P+cTvzc1nSbbU1gsrGO6jWWKC7uCk3BxyUskaScag9CajuMVfSX/ADjl+TmsflroGpx61cwz6nqs&#xA;8ckkVsWeKOOFWVBzZULMeZJ28MVeu4q8h/5yN/JzWfzK0HS49EuoYNS0qeR0iuSyRSRzqqv8aq5D&#xA;LwUjanXFXzb5h/5xQ/NzRdJudTaCzv4rSNpZobOcvNwQcmKo6R8qDsu57DFX3hirsVdirsVdirsV&#xA;dirsVdirsVdirsVdirsVdirsVdirsVdirsVdir4I0T/nKf8AOHSNKttMi1CC5htIxFFLc26SS8FF&#xA;FDPsWoNqnfxxV9Mf843fnBrf5j+XtSbXIYk1TSZ445Li3UokscysyEoSeLDgwNNumKvX8VePf85J&#xA;fnDrv5ceX9LbQoIX1LVp5I1uLhS6RRwKrOQgK1di60rt12xV80a7/wA5S/m/rGkXWlzahb28F5G0&#xA;M0ltbpHL6bijBX+LjUbVG/hir74xV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2K&#xA;uxV8lfkx+Uv5Sa1+Wlxd6peLeXGprGupX/NIZbF0kST6vGZAwiPNQGcirg7fCcVZD/zhpbW1sfPd&#xA;tauZLaC/t44HJDFo09dVNRQGoHbFX0pir5q/5zNt7e5/wLb3LcLea+uI5nqFojegGNTsNjiqTfnD&#xA;+T/5PaP+U8OoWF/Hp+oaajrpV7zWaTUHaR5DbycKeqxZyA4HwAb/AAjFX1dirsVdirsVdirsVdir&#xA;sVdirsVdirsVdirsVdirsVdirsVdirsVdir8vLF9eSxu7exFx9Sv1WO8jiDmOUROJEDgCh4uoI8M&#xA;VfRv/OPmm+ffKv5QeePN1gq6dLEgvbFb+BnjuYtPhlkn+Csb7g8UcNTlXFV7f85FfnGvkL/GBuNH&#xA;+r8liFl9RufW9RpjHUn1eAi4rX1a0LfB9rFW/wDnI7SPPnmL8qfJPmbUE/SVwVa61L6hAVhthfQx&#xA;yRfADJJxAXizs1OVOlaYq+br+XX3sbS2vvrP1HT1eOyilDiOISyGVwgIoOTsSfHFX6h4q7FXYq7F&#xA;XYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqhNI0nT9I0y10vToEtrGzjWG3gjAVVRBQA&#xA;AUGKq91bW91bS2tzGs1vOjRTROKq6OOLKw7gg0xV45H/AM4lflEmofWfT1BrblU6cbtvq5Tlz9I/&#xA;D6vDlvTnir2SCCG3gjggRYoYlCRRoAqqqiiqoHQAYqhtY0jTtZ0q70rUoFubC9iaC5gcAqyOKEb/&#xA;AIYqjMVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirs&#xA;VdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsV&#xA;dirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVd&#xA;irsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdi&#xA;rsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdir&#xA;sVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirs&#xA;VdirsVdirsVdirqitO/hirsVcSBudsVdirSujEhWBI60NaYq3irsVdirsVdirsVdirsVdirsVdir&#xA;sVdirsVdirsVdirsVdiq2WP1Inj5MnNSvNDRlqKVB33GKpL5U8sy6DbzwyahPf8ArSM49diQlXZv&#xA;hBrQtyq57nfFVlj5WmtvM9zrbalczJPHwWzd6otWZuO/7CcvgHY1xVT82eU5tdmtJI7sWwtg/JeD&#xA;MJQzI3pycXSsZ4bjFU21vTm1LSLuwWT0muomiEtK8eQpWm3TFVawtTaWUFqZpLgwoqGeU8pH4inJ&#xA;j3JxVJvKflmfQ2vDJOswuW5LxBFP3ssm9f8AjLirIMVdirsVdirsVdirsVdirsVdirsVdirsVdir&#xA;sVdirsVdirsVU7o3ItpTaqj3QRjAkrFIzJT4Q7KHIWvUhT8sVYV+VN9+a93pt8fzEsbOyu0uHFj9&#xA;UapaMyyVDgM6hUHERnqVoWq1TiqjomofnBJ+Z+p2urafYxeREgrYXUTn1i3qSek37RaRlH71DRVH&#xA;EjeoZVT/ADT1L807S90lPI9s1xayrINZcQwStDF6sIEsHrSwhp1Vn4Rn4WFSegxVlPnWbzFD5S1e&#xA;Xy2nq6+lrI2lx0VuVwF/dij/AA7t44qi9Bk1qTRbF9cihg1hoUOoRWrM8KzcfjEbMAeNf9s9cVYT&#xA;+UepfmTevrI86JOoikA0717eO3BT61dL8PppHy/crD1r2Pc4q9FxV2KuxV2KuxV2KuxV2KuxV2Ku&#xA;xV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Kux&#xA;V2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxVQmmkDiOIcpCK09vE4qome+hHO&#xA;ZF9MHcqa0riqMRgyhh3xVvFXYq7FXYq7FXYq7FVOW5ghkhjkfi9w5ihG/wAThGkI/wCAjY4q3PPF&#xA;bwSTzNwiiUvI57KoqTt7YqlekebvLusXLWum3q3M6IZGRVcUQEKT8SgdWGKppJNDEAZHVAenIgV+&#xA;/FWzJGE9QsAlK86ilPGuKujlikFY3VwNiVIIr9GKtLPA7lFkVnFaqCCduu2KpTqnnLyxpdwba/1G&#xA;KG4H2ovidl7/ABBA1PpxVB/8rJ8kf9XWP/gJf+aMVTzTtSsNStVurC4S5t2NBJGaio6g+B9sVS1f&#xA;OnlhtT/Ra36m/wDVNv6HF6+qG4la8adffFU7xV2KuxV2KuxVBqf9ytP+KW/4kuKrtV/4583yH6xi&#xA;qpZ/7zp8hiqtirsVdirsVdirsVdiqFvbH6zc2E3Ph9SnafjSvPlBLDxrUU/vq19sVUfMP/HA1P8A&#xA;5hJ/+TbYq8l/JT/lKrr/AJgZP+T0WKvSPM/6aEMg0uWK3vXdfSmncRp6QQ1XkUk35e21a+2Kooi4&#xA;FoZEAjFWMRk+JFkMYCu1APh9Tlv71xVC6IuuNYn9IzQ3V6FkEklqCE4FgY4+RJ5OFrvXb8SqttDr&#xA;bapcrNc2sun8h+joIUYTxkFd5KmihRy5Cn9MVeIaDpF75m8wpZ+uFuLx3kmuJKt0Bd2I7nFWXa/+&#xA;TtzpmkXWoQamt0bWNpXhaH0qogqxDc33A36Yqj/yMkflrMfI8ALdgvap9QVxVjdt/wCTYP8A22ZP&#xA;+ohsVe9Yq7FVK5mEMTOe2KqKQ3MirJ63HkAeIWvXfrXFVS3lYu8TmrxkAn5iuKqKf8dX/ni3/Elx&#xA;Vdqv/HPm+Q/WMVVbP/eZPkMVVsVdirsVdirsVdirsVQ9zexW81pC4YteSmCIrSgYRSTVapG3GI/T&#xA;iqH8w/8AHA1P/mEn/wCTbYq8l/JT/lKrr/mBk/5PRYq9G83+ZH0Wyku/q0t2ElWJbWBpFkasZcuP&#xA;TSRiB37AVPtlmLHxmrphOXCLR0uozLZSSAPP6aPIFg+KSULEsojj2WrNyoNq5ADemV7IHy55jn1P&#xA;ShffU7mxEglCw3gIb92VHqry+P0zy/a8NttzPJDhNXaISsWssfMc82vX2miwvofqFC19Op+rzfEg&#xA;4KT8PJ/UqnHw+jDLHUQbG6BOzVPGPJ2uxeX/ADJb6hcxNJFDzSaNaBwHUoaVpuK9MqZvQPM35t6B&#xA;eaDfWVjDcPcXcLwL6iKiKJFKsxIZjsDttiqF/Iz+91n/AFbf9cmKsdtv/JsH/tsyf9RDYq96xV2K&#xA;oe+hMtuyDqRiqHi1KKONIpI5A6gKaCo2264qq2il5pZypUSEEA9aAU/hiq1P+Or/AM8W/wCJLiq7&#xA;Vf8AjnzfIfrGKqtn/vMnyGKq2KuxV2KuxV2KuxV2Koe5soria0mcsGs5TPEFpQsYpIaNUHbjKfpx&#xA;VdeWsd3Zz2khIjuI3icrQMFdSppWu++Ksd8r/l5ovlvUJL6xmuZJZIjAyztGy8WZWqOKIa1Qd8VZ&#xA;HJbRSPzNVelOSMVJHgeJFcVd9Vg9IRcfgB5ChIIbx5V5V964q2ltChY0LFxRi5Lkjw+Inb2xVYll&#xA;AjKRyITdFZ2ZR8gSRirFta/Kvytqt9JeuJ7WaYl5hbOqqzHqxV1cAn2xVL/+VKeVf+Wq+/5GQ/8A&#xA;VLFWV+XvLOkeX7RrbTYiiueUsjHlI5HQs3t2HTFUmT8s9Bj8wnXhcXX1v6y15wLx+n6jOXIp6fLj&#xA;U/zYqyWXUbWI0dwDiqn+l7L/AH4MVd+l7L/fgxVb+k9PrXmMVXDVrEdHGKoe0vbe41grGwYiBj9H&#xA;NcVROsMF02dj0AH6xiqrYsGtYyOlBiqvirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdiqnc&#xA;kiFyOtDiqG0tFayR3UF3LFiRufiIxVF+lF/Iv3DFXelF/Iv3DFXelF/Iv3DFXelF/Iv3DFUPLA0c&#xA;3rwopfiVI6VBNeo+WKqMxuruMwPCscbbOeXKo8OgxVU0tStvw7KSo+QNMVRmKuxV2KuxV2KuxV2K&#xA;uxV2KuxV2KuxV2KuxV2KuxV2KtMoZSD0OKoJrGdaiCZo1JrxFCPxxVr6nf8A/LW/3D+mKu+p3/8A&#xA;y1v9w/pirvqd/wD8tb/cP6Yq76nf/wDLW/3D+mKu+p3/APy1v9w/piraWl6D8VyxHyAxVFwxLEgU&#xA;dsVf/9k=</xmpGImg:image>
29
+ </rdf:li>
30
+ </rdf:Alt>
31
+ </xmp:Thumbnails>
32
+ </rdf:Description>
33
+ <rdf:Description rdf:about=""
34
+ xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
35
+ xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
36
+ xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#">
37
+ <xmpMM:RenditionClass>default</xmpMM:RenditionClass>
38
+ <xmpMM:OriginalDocumentID>uuid:65E6390686CF11DBA6E2D887CEACB407</xmpMM:OriginalDocumentID>
39
+ <xmpMM:DocumentID>xmp.did:8BC7D877974ADE11BCECCFF09938C3CC</xmpMM:DocumentID>
40
+ <xmpMM:InstanceID>uuid:30267148-672c-4d34-8534-e8cce420f815</xmpMM:InstanceID>
41
+ <xmpMM:History>
42
+ <rdf:Seq>
43
+ <rdf:li rdf:parseType="Resource">
44
+ <stEvt:action>converted</stEvt:action>
45
+ <stEvt:params>from application/pdf to &lt;unknown&gt;</stEvt:params>
46
+ </rdf:li>
47
+ <rdf:li rdf:parseType="Resource">
48
+ <stEvt:action>saved</stEvt:action>
49
+ <stEvt:instanceID>xmp.iid:D47F11740720681191099C3B601C4548</stEvt:instanceID>
50
+ <stEvt:when>2008-04-17T14:19:21+05:30</stEvt:when>
51
+ <stEvt:softwareAgent>Adobe Illustrator CS4</stEvt:softwareAgent>
52
+ <stEvt:changed>
53
+ <rdf:Bag>
54
+ <rdf:li>/</rdf:li>
55
+ </rdf:Bag>
56
+ </stEvt:changed>
57
+ </rdf:li>
58
+ <rdf:li rdf:parseType="Resource">
59
+ <stEvt:action>converted</stEvt:action>
60
+ <stEvt:params>from application/pdf to &lt;unknown&gt;</stEvt:params>
61
+ </rdf:li>
62
+ <rdf:li rdf:parseType="Resource">
63
+ <stEvt:action>converted</stEvt:action>
64
+ <stEvt:params>from application/pdf to &lt;unknown&gt;</stEvt:params>
65
+ </rdf:li>
66
+ <rdf:li rdf:parseType="Resource">
67
+ <stEvt:action>saved</stEvt:action>
68
+ <stEvt:instanceID>xmp.iid:FD7F11740720681197C1BF14D1759E83</stEvt:instanceID>
69
+ <stEvt:when>2008-05-16T17:01:20-07:00</stEvt:when>
70
+ <stEvt:softwareAgent>Adobe Illustrator CS4</stEvt:softwareAgent>
71
+ <stEvt:changed>
72
+ <rdf:Bag>
73
+ <rdf:li>/</rdf:li>
74
+ </rdf:Bag>
75
+ </stEvt:changed>
76
+ </rdf:li>
77
+ <rdf:li rdf:parseType="Resource">
78
+ <stEvt:action>saved</stEvt:action>
79
+ <stEvt:instanceID>xmp.iid:F77F117407206811BC18AC99CBA78E83</stEvt:instanceID>
80
+ <stEvt:when>2008-05-19T18:10:15-07:00</stEvt:when>
81
+ <stEvt:softwareAgent>Adobe Illustrator CS4</stEvt:softwareAgent>
82
+ <stEvt:changed>
83
+ <rdf:Bag>
84
+ <rdf:li>/</rdf:li>
85
+ </rdf:Bag>
86
+ </stEvt:changed>
87
+ </rdf:li>
88
+ <rdf:li rdf:parseType="Resource">
89
+ <stEvt:action>converted</stEvt:action>
90
+ <stEvt:params>from application/vnd.adobe.illustrator to application/vnd.adobe.illustrator</stEvt:params>
91
+ </rdf:li>
92
+ <rdf:li rdf:parseType="Resource">
93
+ <stEvt:action>saved</stEvt:action>
94
+ <stEvt:instanceID>xmp.iid:FB7F117407206811B628E3BF27C8C41B</stEvt:instanceID>
95
+ <stEvt:when>2008-05-22T14:26:44-07:00</stEvt:when>
96
+ <stEvt:softwareAgent>Adobe Illustrator CS4</stEvt:softwareAgent>
97
+ <stEvt:changed>
98
+ <rdf:Bag>
99
+ <rdf:li>/</rdf:li>
100
+ </rdf:Bag>
101
+ </stEvt:changed>
102
+ </rdf:li>
103
+ <rdf:li rdf:parseType="Resource">
104
+ <stEvt:action>converted</stEvt:action>
105
+ <stEvt:params>from application/vnd.adobe.illustrator to application/vnd.adobe.illustrator</stEvt:params>
106
+ </rdf:li>
107
+ <rdf:li rdf:parseType="Resource">
108
+ <stEvt:action>saved</stEvt:action>
109
+ <stEvt:instanceID>xmp.iid:08C3BD25102DDD1181B594070CEB88D9</stEvt:instanceID>
110
+ <stEvt:when>2008-05-28T16:51:46-07:00</stEvt:when>
111
+ <stEvt:softwareAgent>Adobe Illustrator CS4</stEvt:softwareAgent>
112
+ <stEvt:changed>
113
+ <rdf:Bag>
114
+ <rdf:li>/</rdf:li>
115
+ </rdf:Bag>
116
+ </stEvt:changed>
117
+ </rdf:li>
118
+ <rdf:li rdf:parseType="Resource">
119
+ <stEvt:action>converted</stEvt:action>
120
+ <stEvt:params>from application/vnd.adobe.illustrator to application/vnd.adobe.illustrator</stEvt:params>
121
+ </rdf:li>
122
+ <rdf:li rdf:parseType="Resource">
123
+ <stEvt:action>saved</stEvt:action>
124
+ <stEvt:instanceID>xmp.iid:F77F11740720681192B0DFFC927805D7</stEvt:instanceID>
125
+ <stEvt:when>2008-05-30T21:26:38-07:00</stEvt:when>
126
+ <stEvt:softwareAgent>Adobe Illustrator CS4</stEvt:softwareAgent>
127
+ <stEvt:changed>
128
+ <rdf:Bag>
129
+ <rdf:li>/</rdf:li>
130
+ </rdf:Bag>
131
+ </stEvt:changed>
132
+ </rdf:li>
133
+ <rdf:li rdf:parseType="Resource">
134
+ <stEvt:action>converted</stEvt:action>
135
+ <stEvt:params>from application/vnd.adobe.illustrator to application/vnd.adobe.illustrator</stEvt:params>
136
+ </rdf:li>
137
+ <rdf:li rdf:parseType="Resource">
138
+ <stEvt:action>saved</stEvt:action>
139
+ <stEvt:instanceID>xmp.iid:F87F11740720681192B0DFFC927805D7</stEvt:instanceID>
140
+ <stEvt:when>2008-05-30T21:27-07:00</stEvt:when>
141
+ <stEvt:softwareAgent>Adobe Illustrator CS4</stEvt:softwareAgent>
142
+ <stEvt:changed>
143
+ <rdf:Bag>
144
+ <rdf:li>/</rdf:li>
145
+ </rdf:Bag>
146
+ </stEvt:changed>
147
+ </rdf:li>
148
+ <rdf:li rdf:parseType="Resource">
149
+ <stEvt:action>converted</stEvt:action>
150
+ <stEvt:params>from application/vnd.adobe.illustrator to application/vnd.adobe.illustrator</stEvt:params>
151
+ </rdf:li>
152
+ <rdf:li rdf:parseType="Resource">
153
+ <stEvt:action>saved</stEvt:action>
154
+ <stEvt:instanceID>xmp.iid:F97F1174072068119098B097FDA39BEF</stEvt:instanceID>
155
+ <stEvt:when>2008-06-02T13:26:10-07:00</stEvt:when>
156
+ <stEvt:softwareAgent>Adobe Illustrator CS4</stEvt:softwareAgent>
157
+ <stEvt:changed>
158
+ <rdf:Bag>
159
+ <rdf:li>/</rdf:li>
160
+ </rdf:Bag>
161
+ </stEvt:changed>
162
+ </rdf:li>
163
+ <rdf:li rdf:parseType="Resource">
164
+ <stEvt:action>saved</stEvt:action>
165
+ <stEvt:instanceID>xmp.iid:8BC7D877974ADE11BCECCFF09938C3CC</stEvt:instanceID>
166
+ <stEvt:when>2009-05-27T04:22:07-04:00</stEvt:when>
167
+ <stEvt:softwareAgent>Adobe Illustrator CS4</stEvt:softwareAgent>
168
+ <stEvt:changed>/</stEvt:changed>
169
+ </rdf:li>
170
+ </rdf:Seq>
171
+ </xmpMM:History>
172
+ <xmpMM:DerivedFrom rdf:parseType="Resource">
173
+ <stRef:instanceID>uuid:32300939-b1c4-8440-b812-b255b7b0d326</stRef:instanceID>
174
+ <stRef:documentID>xmp.did:F97F1174072068119098B097FDA39BEF</stRef:documentID>
175
+ <stRef:originalDocumentID>uuid:65E6390686CF11DBA6E2D887CEACB407</stRef:originalDocumentID>
176
+ <stRef:renditionClass>proof:pdf</stRef:renditionClass>
177
+ </xmpMM:DerivedFrom>
178
+ </rdf:Description>
179
+ <rdf:Description rdf:about=""
180
+ xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/">
181
+ <illustrator:StartupProfile>Web</illustrator:StartupProfile>
182
+ <illustrator:Type>Document</illustrator:Type>
183
+ </rdf:Description>
184
+ <rdf:Description rdf:about=""
185
+ xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/"
186
+ xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
187
+ xmlns:xmpG="http://ns.adobe.com/xap/1.0/g/">
188
+ <xmpTPg:NPages>1</xmpTPg:NPages>
189
+ <xmpTPg:HasVisibleTransparency>True</xmpTPg:HasVisibleTransparency>
190
+ <xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint>
191
+ <xmpTPg:MaxPageSize rdf:parseType="Resource">
192
+ <stDim:w>1024.000000</stDim:w>
193
+ <stDim:h>768.000000</stDim:h>
194
+ <stDim:unit>Pixels</stDim:unit>
195
+ </xmpTPg:MaxPageSize>
196
+ <xmpTPg:PlateNames>
197
+ <rdf:Seq>
198
+ <rdf:li>Cyan</rdf:li>
199
+ <rdf:li>Magenta</rdf:li>
200
+ <rdf:li>Yellow</rdf:li>
201
+ <rdf:li>Black</rdf:li>
202
+ </rdf:Seq>
203
+ </xmpTPg:PlateNames>
204
+ <xmpTPg:SwatchGroups>
205
+ <rdf:Seq>
206
+ <rdf:li rdf:parseType="Resource">
207
+ <xmpG:groupName>Default Swatch Group</xmpG:groupName>
208
+ <xmpG:groupType>0</xmpG:groupType>
209
+ <xmpG:Colorants>
210
+ <rdf:Seq>
211
+ <rdf:li rdf:parseType="Resource">
212
+ <xmpG:swatchName>White</xmpG:swatchName>
213
+ <xmpG:mode>RGB</xmpG:mode>
214
+ <xmpG:type>PROCESS</xmpG:type>
215
+ <xmpG:red>255</xmpG:red>
216
+ <xmpG:green>255</xmpG:green>
217
+ <xmpG:blue>255</xmpG:blue>
218
+ </rdf:li>
219
+ <rdf:li rdf:parseType="Resource">
220
+ <xmpG:swatchName>Black</xmpG:swatchName>
221
+ <xmpG:mode>RGB</xmpG:mode>
222
+ <xmpG:type>PROCESS</xmpG:type>
223
+ <xmpG:red>0</xmpG:red>
224
+ <xmpG:green>0</xmpG:green>
225
+ <xmpG:blue>0</xmpG:blue>
226
+ </rdf:li>
227
+ <rdf:li rdf:parseType="Resource">
228
+ <xmpG:swatchName>RGB Red</xmpG:swatchName>
229
+ <xmpG:mode>RGB</xmpG:mode>
230
+ <xmpG:type>PROCESS</xmpG:type>
231
+ <xmpG:red>255</xmpG:red>
232
+ <xmpG:green>0</xmpG:green>
233
+ <xmpG:blue>0</xmpG:blue>
234
+ </rdf:li>
235
+ <rdf:li rdf:parseType="Resource">
236
+ <xmpG:swatchName>RGB Yellow</xmpG:swatchName>
237
+ <xmpG:mode>RGB</xmpG:mode>
238
+ <xmpG:type>PROCESS</xmpG:type>
239
+ <xmpG:red>255</xmpG:red>
240
+ <xmpG:green>255</xmpG:green>
241
+ <xmpG:blue>0</xmpG:blue>
242
+ </rdf:li>
243
+ <rdf:li rdf:parseType="Resource">
244
+ <xmpG:swatchName>RGB Green</xmpG:swatchName>
245
+ <xmpG:mode>RGB</xmpG:mode>
246
+ <xmpG:type>PROCESS</xmpG:type>
247
+ <xmpG:red>0</xmpG:red>
248
+ <xmpG:green>255</xmpG:green>
249
+ <xmpG:blue>0</xmpG:blue>
250
+ </rdf:li>
251
+ <rdf:li rdf:parseType="Resource">
252
+ <xmpG:swatchName>RGB Cyan</xmpG:swatchName>
253
+ <xmpG:mode>RGB</xmpG:mode>
254
+ <xmpG:type>PROCESS</xmpG:type>
255
+ <xmpG:red>0</xmpG:red>
256
+ <xmpG:green>255</xmpG:green>
257
+ <xmpG:blue>255</xmpG:blue>
258
+ </rdf:li>
259
+ <rdf:li rdf:parseType="Resource">
260
+ <xmpG:swatchName>RGB Blue</xmpG:swatchName>
261
+ <xmpG:mode>RGB</xmpG:mode>
262
+ <xmpG:type>PROCESS</xmpG:type>
263
+ <xmpG:red>0</xmpG:red>
264
+ <xmpG:green>0</xmpG:green>
265
+ <xmpG:blue>255</xmpG:blue>
266
+ </rdf:li>
267
+ <rdf:li rdf:parseType="Resource">
268
+ <xmpG:swatchName>RGB Magenta</xmpG:swatchName>
269
+ <xmpG:mode>RGB</xmpG:mode>
270
+ <xmpG:type>PROCESS</xmpG:type>
271
+ <xmpG:red>255</xmpG:red>
272
+ <xmpG:green>0</xmpG:green>
273
+ <xmpG:blue>255</xmpG:blue>
274
+ </rdf:li>
275
+ <rdf:li rdf:parseType="Resource">
276
+ <xmpG:swatchName>R=193 G=39 B=45</xmpG:swatchName>
277
+ <xmpG:mode>RGB</xmpG:mode>
278
+ <xmpG:type>PROCESS</xmpG:type>
279
+ <xmpG:red>193</xmpG:red>
280
+ <xmpG:green>39</xmpG:green>
281
+ <xmpG:blue>45</xmpG:blue>
282
+ </rdf:li>
283
+ <rdf:li rdf:parseType="Resource">
284
+ <xmpG:swatchName>R=237 G=28 B=36</xmpG:swatchName>
285
+ <xmpG:mode>RGB</xmpG:mode>
286
+ <xmpG:type>PROCESS</xmpG:type>
287
+ <xmpG:red>237</xmpG:red>
288
+ <xmpG:green>28</xmpG:green>
289
+ <xmpG:blue>36</xmpG:blue>
290
+ </rdf:li>
291
+ <rdf:li rdf:parseType="Resource">
292
+ <xmpG:swatchName>R=241 G=90 B=36</xmpG:swatchName>
293
+ <xmpG:mode>RGB</xmpG:mode>
294
+ <xmpG:type>PROCESS</xmpG:type>
295
+ <xmpG:red>241</xmpG:red>
296
+ <xmpG:green>90</xmpG:green>
297
+ <xmpG:blue>36</xmpG:blue>
298
+ </rdf:li>
299
+ <rdf:li rdf:parseType="Resource">
300
+ <xmpG:swatchName>R=247 G=147 B=30</xmpG:swatchName>
301
+ <xmpG:mode>RGB</xmpG:mode>
302
+ <xmpG:type>PROCESS</xmpG:type>
303
+ <xmpG:red>247</xmpG:red>
304
+ <xmpG:green>147</xmpG:green>
305
+ <xmpG:blue>30</xmpG:blue>
306
+ </rdf:li>
307
+ <rdf:li rdf:parseType="Resource">
308
+ <xmpG:swatchName>R=251 G=176 B=59</xmpG:swatchName>
309
+ <xmpG:mode>RGB</xmpG:mode>
310
+ <xmpG:type>PROCESS</xmpG:type>
311
+ <xmpG:red>251</xmpG:red>
312
+ <xmpG:green>176</xmpG:green>
313
+ <xmpG:blue>59</xmpG:blue>
314
+ </rdf:li>
315
+ <rdf:li rdf:parseType="Resource">
316
+ <xmpG:swatchName>R=252 G=238 B=33</xmpG:swatchName>
317
+ <xmpG:mode>RGB</xmpG:mode>
318
+ <xmpG:type>PROCESS</xmpG:type>
319
+ <xmpG:red>252</xmpG:red>
320
+ <xmpG:green>238</xmpG:green>
321
+ <xmpG:blue>33</xmpG:blue>
322
+ </rdf:li>
323
+ <rdf:li rdf:parseType="Resource">
324
+ <xmpG:swatchName>R=217 G=224 B=33</xmpG:swatchName>
325
+ <xmpG:mode>RGB</xmpG:mode>
326
+ <xmpG:type>PROCESS</xmpG:type>
327
+ <xmpG:red>217</xmpG:red>
328
+ <xmpG:green>224</xmpG:green>
329
+ <xmpG:blue>33</xmpG:blue>
330
+ </rdf:li>
331
+ <rdf:li rdf:parseType="Resource">
332
+ <xmpG:swatchName>R=140 G=198 B=63</xmpG:swatchName>
333
+ <xmpG:mode>RGB</xmpG:mode>
334
+ <xmpG:type>PROCESS</xmpG:type>
335
+ <xmpG:red>140</xmpG:red>
336
+ <xmpG:green>198</xmpG:green>
337
+ <xmpG:blue>63</xmpG:blue>
338
+ </rdf:li>
339
+ <rdf:li rdf:parseType="Resource">
340
+ <xmpG:swatchName>R=57 G=181 B=74</xmpG:swatchName>
341
+ <xmpG:mode>RGB</xmpG:mode>
342
+ <xmpG:type>PROCESS</xmpG:type>
343
+ <xmpG:red>57</xmpG:red>
344
+ <xmpG:green>181</xmpG:green>
345
+ <xmpG:blue>74</xmpG:blue>
346
+ </rdf:li>
347
+ <rdf:li rdf:parseType="Resource">
348
+ <xmpG:swatchName>R=0 G=146 B=69</xmpG:swatchName>
349
+ <xmpG:mode>RGB</xmpG:mode>
350
+ <xmpG:type>PROCESS</xmpG:type>
351
+ <xmpG:red>0</xmpG:red>
352
+ <xmpG:green>146</xmpG:green>
353
+ <xmpG:blue>69</xmpG:blue>
354
+ </rdf:li>
355
+ <rdf:li rdf:parseType="Resource">
356
+ <xmpG:swatchName>R=0 G=104 B=55</xmpG:swatchName>
357
+ <xmpG:mode>RGB</xmpG:mode>
358
+ <xmpG:type>PROCESS</xmpG:type>
359
+ <xmpG:red>0</xmpG:red>
360
+ <xmpG:green>104</xmpG:green>
361
+ <xmpG:blue>55</xmpG:blue>
362
+ </rdf:li>
363
+ <rdf:li rdf:parseType="Resource">
364
+ <xmpG:swatchName>R=34 G=181 B=115</xmpG:swatchName>
365
+ <xmpG:mode>RGB</xmpG:mode>
366
+ <xmpG:type>PROCESS</xmpG:type>
367
+ <xmpG:red>34</xmpG:red>
368
+ <xmpG:green>181</xmpG:green>
369
+ <xmpG:blue>115</xmpG:blue>
370
+ </rdf:li>
371
+ <rdf:li rdf:parseType="Resource">
372
+ <xmpG:swatchName>R=0 G=169 B=157</xmpG:swatchName>
373
+ <xmpG:mode>RGB</xmpG:mode>
374
+ <xmpG:type>PROCESS</xmpG:type>
375
+ <xmpG:red>0</xmpG:red>
376
+ <xmpG:green>169</xmpG:green>
377
+ <xmpG:blue>157</xmpG:blue>
378
+ </rdf:li>
379
+ <rdf:li rdf:parseType="Resource">
380
+ <xmpG:swatchName>R=41 G=171 B=226</xmpG:swatchName>
381
+ <xmpG:mode>RGB</xmpG:mode>
382
+ <xmpG:type>PROCESS</xmpG:type>
383
+ <xmpG:red>41</xmpG:red>
384
+ <xmpG:green>171</xmpG:green>
385
+ <xmpG:blue>226</xmpG:blue>
386
+ </rdf:li>
387
+ <rdf:li rdf:parseType="Resource">
388
+ <xmpG:swatchName>R=0 G=113 B=188</xmpG:swatchName>
389
+ <xmpG:mode>RGB</xmpG:mode>
390
+ <xmpG:type>PROCESS</xmpG:type>
391
+ <xmpG:red>0</xmpG:red>
392
+ <xmpG:green>113</xmpG:green>
393
+ <xmpG:blue>188</xmpG:blue>
394
+ </rdf:li>
395
+ <rdf:li rdf:parseType="Resource">
396
+ <xmpG:swatchName>R=46 G=49 B=146</xmpG:swatchName>
397
+ <xmpG:mode>RGB</xmpG:mode>
398
+ <xmpG:type>PROCESS</xmpG:type>
399
+ <xmpG:red>46</xmpG:red>
400
+ <xmpG:green>49</xmpG:green>
401
+ <xmpG:blue>146</xmpG:blue>
402
+ </rdf:li>
403
+ <rdf:li rdf:parseType="Resource">
404
+ <xmpG:swatchName>R=27 G=20 B=100</xmpG:swatchName>
405
+ <xmpG:mode>RGB</xmpG:mode>
406
+ <xmpG:type>PROCESS</xmpG:type>
407
+ <xmpG:red>27</xmpG:red>
408
+ <xmpG:green>20</xmpG:green>
409
+ <xmpG:blue>100</xmpG:blue>
410
+ </rdf:li>
411
+ <rdf:li rdf:parseType="Resource">
412
+ <xmpG:swatchName>R=102 G=45 B=145</xmpG:swatchName>
413
+ <xmpG:mode>RGB</xmpG:mode>
414
+ <xmpG:type>PROCESS</xmpG:type>
415
+ <xmpG:red>102</xmpG:red>
416
+ <xmpG:green>45</xmpG:green>
417
+ <xmpG:blue>145</xmpG:blue>
418
+ </rdf:li>
419
+ <rdf:li rdf:parseType="Resource">
420
+ <xmpG:swatchName>R=147 G=39 B=143</xmpG:swatchName>
421
+ <xmpG:mode>RGB</xmpG:mode>
422
+ <xmpG:type>PROCESS</xmpG:type>
423
+ <xmpG:red>147</xmpG:red>
424
+ <xmpG:green>39</xmpG:green>
425
+ <xmpG:blue>143</xmpG:blue>
426
+ </rdf:li>
427
+ <rdf:li rdf:parseType="Resource">
428
+ <xmpG:swatchName>R=158 G=0 B=93</xmpG:swatchName>
429
+ <xmpG:mode>RGB</xmpG:mode>
430
+ <xmpG:type>PROCESS</xmpG:type>
431
+ <xmpG:red>158</xmpG:red>
432
+ <xmpG:green>0</xmpG:green>
433
+ <xmpG:blue>93</xmpG:blue>
434
+ </rdf:li>
435
+ <rdf:li rdf:parseType="Resource">
436
+ <xmpG:swatchName>R=212 G=20 B=90</xmpG:swatchName>
437
+ <xmpG:mode>RGB</xmpG:mode>
438
+ <xmpG:type>PROCESS</xmpG:type>
439
+ <xmpG:red>212</xmpG:red>
440
+ <xmpG:green>20</xmpG:green>
441
+ <xmpG:blue>90</xmpG:blue>
442
+ </rdf:li>
443
+ <rdf:li rdf:parseType="Resource">
444
+ <xmpG:swatchName>R=237 G=30 B=121</xmpG:swatchName>
445
+ <xmpG:mode>RGB</xmpG:mode>
446
+ <xmpG:type>PROCESS</xmpG:type>
447
+ <xmpG:red>237</xmpG:red>
448
+ <xmpG:green>30</xmpG:green>
449
+ <xmpG:blue>121</xmpG:blue>
450
+ </rdf:li>
451
+ <rdf:li rdf:parseType="Resource">
452
+ <xmpG:swatchName>R=199 G=178 B=153</xmpG:swatchName>
453
+ <xmpG:mode>RGB</xmpG:mode>
454
+ <xmpG:type>PROCESS</xmpG:type>
455
+ <xmpG:red>199</xmpG:red>
456
+ <xmpG:green>178</xmpG:green>
457
+ <xmpG:blue>153</xmpG:blue>
458
+ </rdf:li>
459
+ <rdf:li rdf:parseType="Resource">
460
+ <xmpG:swatchName>R=153 G=134 B=117</xmpG:swatchName>
461
+ <xmpG:mode>RGB</xmpG:mode>
462
+ <xmpG:type>PROCESS</xmpG:type>
463
+ <xmpG:red>153</xmpG:red>
464
+ <xmpG:green>134</xmpG:green>
465
+ <xmpG:blue>117</xmpG:blue>
466
+ </rdf:li>
467
+ <rdf:li rdf:parseType="Resource">
468
+ <xmpG:swatchName>R=115 G=99 B=87</xmpG:swatchName>
469
+ <xmpG:mode>RGB</xmpG:mode>
470
+ <xmpG:type>PROCESS</xmpG:type>
471
+ <xmpG:red>115</xmpG:red>
472
+ <xmpG:green>99</xmpG:green>
473
+ <xmpG:blue>87</xmpG:blue>
474
+ </rdf:li>
475
+ <rdf:li rdf:parseType="Resource">
476
+ <xmpG:swatchName>R=83 G=71 B=65</xmpG:swatchName>
477
+ <xmpG:mode>RGB</xmpG:mode>
478
+ <xmpG:type>PROCESS</xmpG:type>
479
+ <xmpG:red>83</xmpG:red>
480
+ <xmpG:green>71</xmpG:green>
481
+ <xmpG:blue>65</xmpG:blue>
482
+ </rdf:li>
483
+ <rdf:li rdf:parseType="Resource">
484
+ <xmpG:swatchName>R=198 G=156 B=109</xmpG:swatchName>
485
+ <xmpG:mode>RGB</xmpG:mode>
486
+ <xmpG:type>PROCESS</xmpG:type>
487
+ <xmpG:red>198</xmpG:red>
488
+ <xmpG:green>156</xmpG:green>
489
+ <xmpG:blue>109</xmpG:blue>
490
+ </rdf:li>
491
+ <rdf:li rdf:parseType="Resource">
492
+ <xmpG:swatchName>R=166 G=124 B=82</xmpG:swatchName>
493
+ <xmpG:mode>RGB</xmpG:mode>
494
+ <xmpG:type>PROCESS</xmpG:type>
495
+ <xmpG:red>166</xmpG:red>
496
+ <xmpG:green>124</xmpG:green>
497
+ <xmpG:blue>82</xmpG:blue>
498
+ </rdf:li>
499
+ <rdf:li rdf:parseType="Resource">
500
+ <xmpG:swatchName>R=140 G=98 B=57</xmpG:swatchName>
501
+ <xmpG:mode>RGB</xmpG:mode>
502
+ <xmpG:type>PROCESS</xmpG:type>
503
+ <xmpG:red>140</xmpG:red>
504
+ <xmpG:green>98</xmpG:green>
505
+ <xmpG:blue>57</xmpG:blue>
506
+ </rdf:li>
507
+ <rdf:li rdf:parseType="Resource">
508
+ <xmpG:swatchName>R=117 G=76 B=36</xmpG:swatchName>
509
+ <xmpG:mode>RGB</xmpG:mode>
510
+ <xmpG:type>PROCESS</xmpG:type>
511
+ <xmpG:red>117</xmpG:red>
512
+ <xmpG:green>76</xmpG:green>
513
+ <xmpG:blue>36</xmpG:blue>
514
+ </rdf:li>
515
+ <rdf:li rdf:parseType="Resource">
516
+ <xmpG:swatchName>R=96 G=56 B=19</xmpG:swatchName>
517
+ <xmpG:mode>RGB</xmpG:mode>
518
+ <xmpG:type>PROCESS</xmpG:type>
519
+ <xmpG:red>96</xmpG:red>
520
+ <xmpG:green>56</xmpG:green>
521
+ <xmpG:blue>19</xmpG:blue>
522
+ </rdf:li>
523
+ <rdf:li rdf:parseType="Resource">
524
+ <xmpG:swatchName>R=66 G=33 B=11</xmpG:swatchName>
525
+ <xmpG:mode>RGB</xmpG:mode>
526
+ <xmpG:type>PROCESS</xmpG:type>
527
+ <xmpG:red>66</xmpG:red>
528
+ <xmpG:green>33</xmpG:green>
529
+ <xmpG:blue>11</xmpG:blue>
530
+ </rdf:li>
531
+ <rdf:li rdf:parseType="Resource">
532
+ <xmpG:swatchName>R=0 G=0 B=0</xmpG:swatchName>
533
+ <xmpG:mode>RGB</xmpG:mode>
534
+ <xmpG:type>PROCESS</xmpG:type>
535
+ <xmpG:red>0</xmpG:red>
536
+ <xmpG:green>0</xmpG:green>
537
+ <xmpG:blue>0</xmpG:blue>
538
+ </rdf:li>
539
+ <rdf:li rdf:parseType="Resource">
540
+ <xmpG:swatchName>R=26 G=26 B=26</xmpG:swatchName>
541
+ <xmpG:mode>RGB</xmpG:mode>
542
+ <xmpG:type>PROCESS</xmpG:type>
543
+ <xmpG:red>26</xmpG:red>
544
+ <xmpG:green>26</xmpG:green>
545
+ <xmpG:blue>26</xmpG:blue>
546
+ </rdf:li>
547
+ <rdf:li rdf:parseType="Resource">
548
+ <xmpG:swatchName>R=51 G=51 B=51</xmpG:swatchName>
549
+ <xmpG:mode>RGB</xmpG:mode>
550
+ <xmpG:type>PROCESS</xmpG:type>
551
+ <xmpG:red>51</xmpG:red>
552
+ <xmpG:green>51</xmpG:green>
553
+ <xmpG:blue>51</xmpG:blue>
554
+ </rdf:li>
555
+ <rdf:li rdf:parseType="Resource">
556
+ <xmpG:swatchName>R=77 G=77 B=77</xmpG:swatchName>
557
+ <xmpG:mode>RGB</xmpG:mode>
558
+ <xmpG:type>PROCESS</xmpG:type>
559
+ <xmpG:red>77</xmpG:red>
560
+ <xmpG:green>77</xmpG:green>
561
+ <xmpG:blue>77</xmpG:blue>
562
+ </rdf:li>
563
+ <rdf:li rdf:parseType="Resource">
564
+ <xmpG:swatchName>R=102 G=102 B=102</xmpG:swatchName>
565
+ <xmpG:mode>RGB</xmpG:mode>
566
+ <xmpG:type>PROCESS</xmpG:type>
567
+ <xmpG:red>102</xmpG:red>
568
+ <xmpG:green>102</xmpG:green>
569
+ <xmpG:blue>102</xmpG:blue>
570
+ </rdf:li>
571
+ <rdf:li rdf:parseType="Resource">
572
+ <xmpG:swatchName>R=128 G=128 B=128</xmpG:swatchName>
573
+ <xmpG:mode>RGB</xmpG:mode>
574
+ <xmpG:type>PROCESS</xmpG:type>
575
+ <xmpG:red>128</xmpG:red>
576
+ <xmpG:green>128</xmpG:green>
577
+ <xmpG:blue>128</xmpG:blue>
578
+ </rdf:li>
579
+ <rdf:li rdf:parseType="Resource">
580
+ <xmpG:swatchName>R=153 G=153 B=153</xmpG:swatchName>
581
+ <xmpG:mode>RGB</xmpG:mode>
582
+ <xmpG:type>PROCESS</xmpG:type>
583
+ <xmpG:red>153</xmpG:red>
584
+ <xmpG:green>153</xmpG:green>
585
+ <xmpG:blue>153</xmpG:blue>
586
+ </rdf:li>
587
+ <rdf:li rdf:parseType="Resource">
588
+ <xmpG:swatchName>R=179 G=179 B=179</xmpG:swatchName>
589
+ <xmpG:mode>RGB</xmpG:mode>
590
+ <xmpG:type>PROCESS</xmpG:type>
591
+ <xmpG:red>179</xmpG:red>
592
+ <xmpG:green>179</xmpG:green>
593
+ <xmpG:blue>179</xmpG:blue>
594
+ </rdf:li>
595
+ <rdf:li rdf:parseType="Resource">
596
+ <xmpG:swatchName>R=204 G=204 B=204</xmpG:swatchName>
597
+ <xmpG:mode>RGB</xmpG:mode>
598
+ <xmpG:type>PROCESS</xmpG:type>
599
+ <xmpG:red>204</xmpG:red>
600
+ <xmpG:green>204</xmpG:green>
601
+ <xmpG:blue>204</xmpG:blue>
602
+ </rdf:li>
603
+ <rdf:li rdf:parseType="Resource">
604
+ <xmpG:swatchName>R=230 G=230 B=230</xmpG:swatchName>
605
+ <xmpG:mode>RGB</xmpG:mode>
606
+ <xmpG:type>PROCESS</xmpG:type>
607
+ <xmpG:red>230</xmpG:red>
608
+ <xmpG:green>230</xmpG:green>
609
+ <xmpG:blue>230</xmpG:blue>
610
+ </rdf:li>
611
+ <rdf:li rdf:parseType="Resource">
612
+ <xmpG:swatchName>R=242 G=242 B=242</xmpG:swatchName>
613
+ <xmpG:mode>RGB</xmpG:mode>
614
+ <xmpG:type>PROCESS</xmpG:type>
615
+ <xmpG:red>242</xmpG:red>
616
+ <xmpG:green>242</xmpG:green>
617
+ <xmpG:blue>242</xmpG:blue>
618
+ </rdf:li>
619
+ <rdf:li rdf:parseType="Resource">
620
+ <xmpG:swatchName>R=63 G=169 B=245</xmpG:swatchName>
621
+ <xmpG:mode>RGB</xmpG:mode>
622
+ <xmpG:type>PROCESS</xmpG:type>
623
+ <xmpG:red>63</xmpG:red>
624
+ <xmpG:green>169</xmpG:green>
625
+ <xmpG:blue>245</xmpG:blue>
626
+ </rdf:li>
627
+ <rdf:li rdf:parseType="Resource">
628
+ <xmpG:swatchName>R=122 G=201 B=67</xmpG:swatchName>
629
+ <xmpG:mode>RGB</xmpG:mode>
630
+ <xmpG:type>PROCESS</xmpG:type>
631
+ <xmpG:red>122</xmpG:red>
632
+ <xmpG:green>201</xmpG:green>
633
+ <xmpG:blue>67</xmpG:blue>
634
+ </rdf:li>
635
+ <rdf:li rdf:parseType="Resource">
636
+ <xmpG:swatchName>R=255 G=147 B=30</xmpG:swatchName>
637
+ <xmpG:mode>RGB</xmpG:mode>
638
+ <xmpG:type>PROCESS</xmpG:type>
639
+ <xmpG:red>255</xmpG:red>
640
+ <xmpG:green>147</xmpG:green>
641
+ <xmpG:blue>30</xmpG:blue>
642
+ </rdf:li>
643
+ <rdf:li rdf:parseType="Resource">
644
+ <xmpG:swatchName>R=255 G=29 B=37</xmpG:swatchName>
645
+ <xmpG:mode>RGB</xmpG:mode>
646
+ <xmpG:type>PROCESS</xmpG:type>
647
+ <xmpG:red>255</xmpG:red>
648
+ <xmpG:green>29</xmpG:green>
649
+ <xmpG:blue>37</xmpG:blue>
650
+ </rdf:li>
651
+ <rdf:li rdf:parseType="Resource">
652
+ <xmpG:swatchName>R=255 G=123 B=172</xmpG:swatchName>
653
+ <xmpG:mode>RGB</xmpG:mode>
654
+ <xmpG:type>PROCESS</xmpG:type>
655
+ <xmpG:red>255</xmpG:red>
656
+ <xmpG:green>123</xmpG:green>
657
+ <xmpG:blue>172</xmpG:blue>
658
+ </rdf:li>
659
+ <rdf:li rdf:parseType="Resource">
660
+ <xmpG:swatchName>R=189 G=204 B=212</xmpG:swatchName>
661
+ <xmpG:mode>RGB</xmpG:mode>
662
+ <xmpG:type>PROCESS</xmpG:type>
663
+ <xmpG:red>189</xmpG:red>
664
+ <xmpG:green>204</xmpG:green>
665
+ <xmpG:blue>212</xmpG:blue>
666
+ </rdf:li>
667
+ <rdf:li rdf:parseType="Resource">
668
+ <xmpG:swatchName>R=138 G=138 B=138 1</xmpG:swatchName>
669
+ <xmpG:mode>RGB</xmpG:mode>
670
+ <xmpG:type>PROCESS</xmpG:type>
671
+ <xmpG:red>138</xmpG:red>
672
+ <xmpG:green>138</xmpG:green>
673
+ <xmpG:blue>138</xmpG:blue>
674
+ </rdf:li>
675
+ </rdf:Seq>
676
+ </xmpG:Colorants>
677
+ </rdf:li>
678
+ </rdf:Seq>
679
+ </xmpTPg:SwatchGroups>
680
+ </rdf:Description>
681
+ <rdf:Description rdf:about=""
682
+ xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
683
+ <pdf:Producer>Adobe PDF library 9.00</pdf:Producer>
684
+ </rdf:Description>
685
+ </rdf:RDF>
686
+ </x:xmpmeta>
687
+
688
+
689
+
690
+
691
+
692
+
693
+
694
+
695
+
696
+
697
+
698
+
699
+
700
+
701
+
702
+
703
+
704
+
705
+
706
+
707
+
708
+ <?xpacket end="w"?>
709
+ endstream
710
+ H���-�0�a�S����' �Ƌv��������,$���<�=��FC�b����8A��-��F�{�(V(�\E���3>�����IGIykF���S><H�朗7)d��5�?�L��3������` 5�S�
711
+ endstream
712
+ 8;Z\ui<k5l%"j!.(Yn<rGVB89DS9W38A;imV+n")c,d,Cr$jiKcnTe_@#q%%4(.C8
713
+ HN;BSQ0K3*YFS=EP`>nRqnec:hag&4%a](-!f93L:A4D\h\gZ/n@lX;HcTPGfEHCj
714
+ Q%6lr1C^ia9#<W0(GV,aU!d`IC%Y0XNP6><b7'6om5]6K!.0N/D61*)F/P7m\Pl,G
715
+ gpGL0adN#/Z594=1XIk%(grE!EB@RojEgmQOd52KE0$6o\NS1_@3+<#Mt:Yj;B;Fb
716
+ IK^@:(iq@&!<@UeLT(~>
717
+ endstream
718
+ 8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0
719
+ b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup`
720
+ E1r!/,*0[*9.aFIR2&b-C#s<Xl5FH@[<=!#6V)uDBXnIr.F>oRZ7Dl%MLY\.?d>Mn
721
+ 6%Q2oYfNRF$$+ON<+]RUJmC0I<jlL.oXisZ;SYU[/7#<&37rclQKqeJe#,UF7Rgb1
722
+ VNWFKf>nDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j<etJICj7e7nPMb=O6S7UOH<
723
+ PO7r\I.Hu&e0d&E<.')fERr/l+*W,)q^D*ai5<uuLX.7g/>$XKrcYp0n+Xl_nU*O(
724
+ l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~>
725
+ endstream
726
+ BT
727
+ /CS0 cs 0 0 0 scn
728
+ /GS0 gs
729
+ /T1_0 1 Tf
730
+ 0 Tc 0 Tw 0 Ts 100 Tz 0 Tr 12 0 0 -12 -103.0967 -61.2773 Tm
731
+ [(T)7(his is an A)12(dobe\256 I)-10(llustr)5(a)4(t)6(or\256 F)26(ile tha)4(t w)4(as)]TJ
732
+ 0 -1.2 TD
733
+ [(sa)8(v)10(ed without PDF C)11(on)4(t)6(en)4(t)3(.)]TJ
734
+ 0 -1.2 TD
735
+ [(T)71(o P)5(lac)6(e or open this \037le in other)]TJ
736
+ 0 -1.2 TD
737
+ [(applica)4(tions)11(, it should be r)10(e)-28(-sa)8(v)10(ed fr)10(om)]TJ
738
+ 0 -1.2 TD
739
+ [(A)12(dobe I)-10(llustr)5(a)4(t)6(or with the ")3(C)3(r)10(ea)4(t)6(e PDF)]TJ
740
+ 0 -1.2 TD
741
+ [(C)11(ompa)4(tible F)26(ile" option tur)-4(ned on. )41(T)7(his)]TJ
742
+ T*
743
+ [(option is in the I)-10(llustr)5(a)4(t)6(or Na)4(tiv)10(e F)31(or)-4(ma)4(t)]TJ
744
+ 0 -1.2 TD
745
+ [(Options dialog bo)14(x, which appears when)]TJ
746
+ 0 -1.2 TD
747
+ [(sa)8(ving an A)12(dobe I)-10(llustr)5(a)4(t)6(or \037le using the)]TJ
748
+ 0 -1.2 TD
749
+ [(S)-3(a)8(v)10(e A)6(s c)6(ommand)10(.)]TJ
750
+ ET
751
+
752
+ endstream
753
+ H�|TyPw�ffz �$��D���#hD�[-�o!b(/�a��@e0��E
754
+ D%"�g�C �Ed=��
755
+ 1�M�}�?�l[[��������{�}�����q|�����W��<�U�
756
+ ou�������@�1�r���l!��
757
+ ٣����{������g�|6c����O��߫Z�c�he�˗;��Ӵt��9,]�tZ:��(���2�C�2B#�)�RGG��J��lMx�lB#S+5Ju�����U���,���·��ّ|�:'g'[�ev��v/SidJ�6D��� �*����N�T(#�a�(c�o���ӎL)�d~�*���Y`�b �5]E�U���%||E+e�d
758
+ �~�g�0��4��0����/1l� �c��!�R?�a6F=1o,��ʰ���
759
+ � 5X���qWA�e�1��>��0Ι�<ȤR�n�v������ݻ��D
760
+ x��m��o�Kh��#��v܃:y�<������1�E[l�!/UXFV#���m � >dY�
761
+ �Y�E~��>�h�
762
+ L��U�~O�F�]^>g/(Irq,��>��gi�^C���k ����Bc!�fvYT p�l�졉�5�-Z����ZΜ��/oȿN���sWH���+c�Vd&]ߴ������,�L��&!R���j�.
763
+ ��i{~)�$!x63���'(&}�����hg�1̅��H ����_�r�
764
+ endstream
765
+ H���yTSw�oɞ����c
766
+ 2y�.-;!���K�Z� ���^�i�"L��0���-��
767
+ �V��)g�B�0�i�W��8#�8wթ��8_�٥ʨQ����Q�j@�&�A)/��g�>'K�� �t�;\��
768
+ �x������- �����[��� 0����}��y)7ta�����>j���T�7���@���tܛ�`q�2��ʀ��&���6�Z�L�Ą?�_��yxg)˔z���çL�U���*�u�Sk�Se�O4?׸�c����.� � �� R�
769
+ �ꇆ��n���Q�t�}MA�0�al������S�x ��k�&�^���>�0|>_�'��,�G!"F$H:R��!z��F�Qd?r9�\A&�G���rQ��h������E��]�a�4z�Bg�����E#H �*B=��0H�I��p�p�0MxJ$�D1��D, V���ĭ����KĻ�Y�dE�"E��I2���E�B�G��t�4MzN�����r!YK� ���?%_&�#���(��0J:EAi��Q�(�()ӔWT6U@���P+���!�~��m���D�e�Դ�!��h�Ӧh/��']B/����ҏӿ�?a0n�hF!��X���8����܌k�c&5S�����6�l��Ia�2c�K�M�A�!�E�#��ƒ�d�V��(�k��e���l
770
+ N'��)�].�u�J�r�
771
+ ��w�G� xR^���[�oƜch�g�`>b���$���*~� �:����E���b��~���,m,�-��ݖ,�Y��¬�*�6X�[ݱF�=�3�뭷Y��~dó ���t���i�z�f�6�~`{�v���.�Ng����#{�}�}��������j������c1X6���fm���;'_9 �r�:�8�q�:��˜�O:ϸ8������u��Jq���nv=���M����m����R 4 �
772
+ n�3ܣ�k�Gݯz=��[=��=�<�=G</z�^�^j��^�� ޡ�Z�Q�B�0FX'�+������t���<�u�-���{���_�_�ߘ�-G�,�}���/���Hh8�m�W�2p[����AiA��N�#8$X�?�A�KHI�{!7�<q��W�y(!46�-���a�a���a�W�� ��@�@�`l���YĎ��H,�$����(�(Y�h�7��ъ���b<b*b��<�����~�L&Y&9��%�u�M�s�s��NpJP%�M�IJlN<�DHJIڐtCj'�KwKg�C��%�N��d��|�ꙪO=��%�mL���u�v�x:H��oL��!Ȩ��C&13#s$�/Y����������=�Osbs�rn��sO�1��v�=ˏ��ϟ\�h٢���#��¼����oZ<]T�Ut}�`IÒsK��V-���Y,+>TB(�/�S�,]6*�-���W:#��7�*���e��^YDY�}U�j��AyT�`�#�D=���"�b{ų���+�ʯ:�!kJ4G�m��t�}uC�%���K7YV��fF���Y�.�=b��?S��ƕƩ�Ⱥ����y���
773
+ �����z���p���g���_���X���Q���K���F���Aǿ�=ȼ�:ɹ�8ʷ�6˶�5̵�5͵�6ζ�7ϸ�9к�<Ѿ�?���D���I���N���U���\���d���l���v��ۀ�܊�ݖ�ޢ�)߯�6��D���S���c���s����
774
+ endstream
775
+