XCloner – Backup and Restore - Version 4.0.1

Version Description

  • Code rewritten from ground up to make use of latest code standards
  • Added support for Dropbox, Amazon S3, Azure Blob and SFTP storage
  • Added a new restore script
  • Added an improved backup and system logger
  • New Setting Panel
  • New Manage Backups Panel with the options to Delete, Transfer to Remote Storage, Download and List Backup archive contents
  • Added mail notifications for scheduled backups
  • Added a new Cron Scheduler to make use of Wordpress System Cron option
  • Improved user input sanitization
  • Improved recursive file scanning and archiving
  • Improved Mysql Backup dump
  • Added Multiple Cleanup options both for local storage and remote
  • Added Improved Backup Compressing option
Download this release

Release Info

Developer xcloner
Plugin Icon 128x128 XCloner – Backup and Restore
Version 4.0.1
Comparing to
See all releases

Code changes from version 3.1.5 to 4.0.1

Files changed (87) hide show
  1. license.txt → LICENSE.txt +8 -9
  2. README.md +58 -0
  3. README.txt +168 -0
  4. admin.cloner.html.php +0 -2701
  5. admin.cloner.php +0 -215
  6. admin/assets/database-icon.png +0 -0
  7. admin/assets/file-icon-d.png +0 -0
  8. admin/assets/file-icon-f.png +0 -0
  9. admin/assets/file-icon-l.png +0 -0
  10. admin/assets/file-icon-root.png +0 -0
  11. admin/assets/table-icon.png +0 -0
  12. admin/class-xcloner-admin.php +265 -0
  13. admin/css/jquery.dataTables.min.css +1 -0
  14. admin/css/materialize.clockpicker.css +25 -0
  15. admin/css/materialize.min.css +16 -0
  16. admin/css/responsive.dataTables.css +178 -0
  17. admin/css/xcloner-admin.css +370 -0
  18. admin/fonts/roboto/Roboto-Bold.eot +0 -0
  19. admin/fonts/roboto/Roboto-Bold.ttf +0 -0
  20. admin/fonts/roboto/Roboto-Bold.woff +0 -0
  21. admin/fonts/roboto/Roboto-Bold.woff2 +0 -0
  22. admin/fonts/roboto/Roboto-Light.eot +0 -0
  23. admin/fonts/roboto/Roboto-Light.ttf +0 -0
  24. admin/fonts/roboto/Roboto-Light.woff +0 -0
  25. admin/fonts/roboto/Roboto-Light.woff2 +0 -0
  26. admin/fonts/roboto/Roboto-Medium.eot +0 -0
  27. admin/fonts/roboto/Roboto-Medium.ttf +0 -0
  28. admin/fonts/roboto/Roboto-Medium.woff +0 -0
  29. admin/fonts/roboto/Roboto-Medium.woff2 +0 -0
  30. admin/fonts/roboto/Roboto-Regular.eot +0 -0
  31. admin/fonts/roboto/Roboto-Regular.ttf +0 -0
  32. admin/fonts/roboto/Roboto-Regular.woff +0 -0
  33. admin/fonts/roboto/Roboto-Regular.woff2 +0 -0
  34. admin/fonts/roboto/Roboto-Thin.eot +0 -0
  35. admin/fonts/roboto/Roboto-Thin.ttf +0 -0
  36. admin/fonts/roboto/Roboto-Thin.woff +0 -0
  37. admin/fonts/roboto/Roboto-Thin.woff2 +0 -0
  38. admin/images/Sorting icons.psd +0 -0
  39. admin/images/favicon.ico +0 -0
  40. admin/images/sort_asc.png +0 -0
  41. admin/images/sort_asc_disabled.png +0 -0
  42. admin/images/sort_both.png +0 -0
  43. admin/images/sort_desc.png +0 -0
  44. admin/images/sort_desc_disabled.png +0 -0
  45. admin/index.php +1 -0
  46. admin/js/dataTables.responsive.js +1232 -0
  47. admin/js/jquery.dataTables.min.js +167 -0
  48. admin/js/materialize.clockpicker.js +1 -0
  49. admin/js/materialize.min.js +10 -0
  50. admin/js/xcloner-admin.js +132 -0
  51. admin/js/xcloner-backup-class.js +422 -0
  52. admin/js/xcloner-manage-backups-class.js +257 -0
  53. admin/js/xcloner-remote-storage-class.js +31 -0
  54. admin/js/xcloner-restore-class.js +827 -0
  55. admin/js/xcloner-scheduler-class.js +237 -0
  56. admin/partials/xcloner_console_page.php +51 -0
  57. admin/partials/xcloner_generate_backups_page.php +502 -0
  58. admin/partials/xcloner_init_page.php +237 -0
  59. admin/partials/xcloner_manage_backups_page.php +135 -0
  60. admin/partials/xcloner_remote_storage_page.php +593 -0
  61. admin/partials/xcloner_restore_page.php +331 -0
  62. admin/partials/xcloner_scheduled_backups_page.php +173 -0
  63. administrator/.htaccess +0 -2
  64. administrator/backups/.htaccess +0 -2
  65. administrator/backups/index.html +0 -0
  66. administrator/index.html +0 -0
  67. browser/file.gif +0 -0
  68. browser/filebrowser.css +0 -34
  69. browser/files_inpage.php +0 -23
  70. browser/files_xml.php +0 -266
  71. browser/folder.gif +0 -0
  72. browser/timer.gif +0 -0
  73. browser/xmlhttp.js +0 -156
  74. classes/.htaccess +0 -2
  75. classes/DropboxClient.php +0 -672
  76. classes/OAuthSimple.php +0 -532
  77. classes/S3.php +0 -1368
  78. classes/error.class.php +0 -0
  79. classes/fileRecursion.php +0 -477
  80. classes/index.html +0 -0
  81. classes/main.class.php +0 -116
  82. classes/mysqlBackup.class.php +0 -480
  83. classes/phpseclib/Crypt/AES.php +0 -594
  84. classes/phpseclib/Crypt/DES.php +0 -1245
  85. classes/phpseclib/Crypt/RC4.php +0 -505
  86. classes/phpseclib/Crypt/Random.php +0 -133
  87. classes/phpseclib/Crypt/Rijndael.php +0 -270
license.txt → LICENSE.txt RENAMED
@@ -1,12 +1,12 @@
1
- GNU GENERAL PUBLIC LICENSE
2
- Version 2, June 1991
3
 
4
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
  Everyone is permitted to copy and distribute verbatim copies
7
  of this license document, but changing it is not allowed.
8
 
9
- Preamble
10
 
11
  The licenses for most software are designed to take away your
12
  freedom to share and change it. By contrast, the GNU General Public
@@ -56,7 +56,7 @@ patent must be licensed for everyone's free use or not licensed at all.
56
  The precise terms and conditions for copying, distribution and
57
  modification follow.
58
 
59
- GNU GENERAL PUBLIC LICENSE
60
  TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
 
62
  0. This License applies to any program or other work which contains
@@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
255
  of preserving the free status of all derivatives of our free software and
256
  of promoting the sharing and reuse of software generally.
257
 
258
- NO WARRANTY
259
 
260
  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
  FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
  PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
  POSSIBILITY OF SUCH DAMAGES.
279
 
280
- END OF TERMS AND CONDITIONS
281
 
282
- How to Apply These Terms to Your New Programs
283
 
284
  If you develop a new program, and you want it to be of the greatest
285
  possible use to the public, the best way to achieve this is to make it
@@ -336,5 +336,4 @@ This General Public License does not permit incorporating your program into
336
  proprietary programs. If your program is a subroutine library, you may
337
  consider it more useful to permit linking proprietary applications with the
338
  library. If this is what you want to do, use the GNU Lesser General
339
- Public License instead of this License.
340
-
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 2, June 1991
3
 
4
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
  Everyone is permitted to copy and distribute verbatim copies
7
  of this license document, but changing it is not allowed.
8
 
9
+ Preamble
10
 
11
  The licenses for most software are designed to take away your
12
  freedom to share and change it. By contrast, the GNU General Public
56
  The precise terms and conditions for copying, distribution and
57
  modification follow.
58
 
59
+ GNU GENERAL PUBLIC LICENSE
60
  TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
 
62
  0. This License applies to any program or other work which contains
255
  of preserving the free status of all derivatives of our free software and
256
  of promoting the sharing and reuse of software generally.
257
 
258
+ NO WARRANTY
259
 
260
  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
  FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
277
  PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
  POSSIBILITY OF SUCH DAMAGES.
279
 
280
+ END OF TERMS AND CONDITIONS
281
 
282
+ How to Apply These Terms to Your New Programs
283
 
284
  If you develop a new program, and you want it to be of the greatest
285
  possible use to the public, the best way to achieve this is to make it
336
  proprietary programs. If your program is a subroutine library, you may
337
  consider it more useful to permit linking proprietary applications with the
338
  library. If this is what you want to do, use the GNU Lesser General
339
+ Public License instead of this License.
 
README.md ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # XCloner Wordpress Plugin - Backup and Restore
2
+
3
+ Backup your Wordpress site, restore to any web location, send your backups to Dropbox, Amazon S3, Azure, FTP, SFTP and many others with XCloner backup plugin.
4
+
5
+ XCloner is a Backup and Restore plugin that is perfectly integrated with Wordpress.
6
+
7
+ XCloner design was specifically created to Generate custom backups of any LAMP website through custom admin inputs, and to be able to Restore the clone on any other location with the help of the automatic Restore script we provide!
8
+
9
+ XCloner Backup tool uses Open Source standards like TAR, Mysql and CSV formats so you can rest assured your backups can be restored in a variety of ways, giving you more flexibility and full control.
10
+
11
+ ## Features
12
+
13
+ * Backup and Restore your Wordpress site easily
14
+ * Create compressed and uncompressed backups using TAR open source format
15
+ * Create automated backups from your Scheduled Backups Section
16
+ * Received email notifications of created backups
17
+ * Generate automatic backups based on cronjobs, it can run daily, weekly, monthly or even hourly
18
+ * Restore your backups on any other location, XCloner will attempt to extract the backup archive files for you, as well as import the mysql dump and update the Wordpress config details
19
+ * Upload your backups to Remote Storage locations supporting FTP, SFTP, Dropbox, AWS, Azure Blog and many more to come
20
+ * Watch every step of XCloner through it's built in debugger
21
+ * Althrough we have optimized XCloner to run properly on most hosts, we give Developers options to customize it's running speed and avoid backup timeouts, all from the XCloner Config-> System Options
22
+ * Ability to split backups into multiple smaller parts if a certain size limit is reached
23
+
24
+ ## Installation
25
+
26
+ 1. Upload the plugin directory to wp-content/plugins directory
27
+ 2. Activate the plugin
28
+ 3. Access the plugin Dashboard from the Admin Sidebar -> Site Backup Menu
29
+
30
+ ## UPGRADE
31
+
32
+ You can do it easily from the Wordpress backend.
33
+
34
+ ## Frequently Asked Questions
35
+
36
+ <b>Where does XCloner keep it's database backups?</b>
37
+
38
+ XCloner stores them in separate mysql dump files, inside a folder called xcloner-XXXXX inside the backup archive root path, where XXXXX is a hash number that is identical with the last 5 characters of the backup name,
39
+ so if the backup name is backup_localhost-2017-02-16_15-36-sql-1c6c6.tgz , the mysql backup file will be stored in xcloner-1c6c6/ folder.
40
+
41
+ <b>How do I restore my backup?</b>
42
+
43
+ XCloner provide an easy to use restore script available in the Site Backup -> Restore Backups menu, the process is being described there as well.
44
+
45
+ If the XCloner Restore option fails, you can manually restore your backup as follows:
46
+
47
+ 1. extract the backup archive files to your new location
48
+ 2. locate the xcloner-XXXXX folder inside your backup root folder, and look for the mysql backup in database-sql and import it through phpmyadmin
49
+ 3. update your wp-config.php file to reflect the new mysql details
50
+
51
+ <b>How do I know which files were include in the backup?</b>
52
+
53
+ The XCloner Manager Backups Panel provides an easy utility to view each backup content files list. It also stores a copy of the archived backup files inside the xcloner-XXXXX/backup_files.csv file in an easy to read CSV format.
54
+
55
+ <b>Do you have a log for the created backup?</b>
56
+
57
+ Yes, if XCloner Logger option is enabled, it will store a log file inside the xcloner-XXXXX folder inside the backup archive, file is named xcloner-xxxxx.log
58
+
README.txt ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === XCloner - Backup and Restore===
2
+ Contributors: xcloner
3
+ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=AAPE8PLAE554S
4
+ Tags: backup plugin, restore plugin, database backup, full site backup, xcloner, website cloner, wordpress backup, database restore, blog transfer
5
+ Requires at least: 3.0.1
6
+ Tested up to: 4.7
7
+ Stable tag: 4.0.1
8
+
9
+ Backup your site, restore to any web location, send your backups to Dropbox, Amazon S3, Azure, FTP, SFTP and many others with XCloner backup plugin.
10
+
11
+ == Description ==
12
+
13
+ XCloner is a Backup and Restore plugin that is perfectly integrated with Wordpress.
14
+
15
+ [youtube http://www.youtube.com/watch?v=V9iWpPyG1EE]
16
+
17
+ XCloner design was specifically created to Generate custom backups of any Wordpress website through custom admin inputs, and to be able to Restore the backup on any other location with the help of the automatic Restore script we provide!
18
+
19
+ XCloner Backup tool uses Open Source standards like TAR, Mysql and CSV formats so you can rest assured your backups can be restored in a variety of ways, giving you more flexibility and full control.
20
+
21
+ Project is actively maintained through github https://github.com/ovidiul/XCloner-Wordpress/ , all issues can be reported here https://github.com/ovidiul/XCloner-Wordpress/issues .
22
+
23
+ <strong>Requirements:</strong>
24
+
25
+ PHP 5.4+ with mod CURL installed
26
+
27
+ <strong>Features:</strong>
28
+
29
+ * Backup and Restore your Wordpress site easily
30
+ * Create compressed and uncompressed backups using TAR open source format
31
+ * Create automated backups from your Scheduled Backups Section
32
+ * Received email notifications of created backups
33
+ * Generate automatic backups based on cronjobs, it can run daily, weekly, monthly or even hourly
34
+ * Restore your backups on any other location, XCloner will attempt to extract the backup archive files for you, as well as import the mysql dump and update the Wordpress config details
35
+ * Upload your backups to Remote Storage locations supporting FTP, SFTP, Dropbox, AWS, Azure Blog, BackBlaze and many more to come
36
+ * Watch every step of XCloner through it's built in debugger
37
+ * Althrough we have optimized XCloner to run properly on most hosts, we give Developers options to customize it's running speed and avoid backup timeouts, all from the XCloner Config-> System Options
38
+ * Ability to split backups into multiple smaller parts if a certain size limit is reached
39
+
40
+ == Installation ==
41
+
42
+ 1. Upload the plugin directory to wp-content/plugins directory
43
+ 2. Activate the plugin
44
+ 3. Access the plugin Dashboard from the Admin Sidebar -> Site Backup Menu
45
+
46
+ UPGRADE:
47
+
48
+ You can do it easily from the Wordpress backend.
49
+
50
+ == Frequently Asked Questions ==
51
+
52
+ = Where does XCloner keep it's database backups? =
53
+
54
+ XCloner stores them in separate mysql dump files, inside a folder called xcloner-XXXXX inside the backup archive root path, where XXXXX is a hash number that is identical with the last 5 characters of the backup name,
55
+ so if the backup name is backup_localhost-2017-02-16_15-36-sql-1c6c6.tgz , the mysql backup file will be stored in xcloner-1c6c6/ folder.
56
+
57
+ = How do I restore my backup? =
58
+
59
+ XCloner provide an easy to use restore script available in the Site Backup -> Restore Backups menu, the process is being described there as well.
60
+
61
+ If the XCloner Restore option fails, you can manually restore your backup as follows:
62
+
63
+ 1. extract the backup archive files to your new location
64
+ 2. locate the xcloner-XXXXX folder inside your backup root folder, and look for the mysql backup in database-sql and import it through phpmyadmin
65
+ 3. update your wp-config.php file to reflect the new mysql details
66
+
67
+ = How do I know which files were include in the backup? =
68
+
69
+ The XCloner Manager Backups Panel provides an easy utility to view each backup content files list. It also stores a copy of the archived backup files inside the xcloner-XXXXX/backup_files.csv file in an easy to read CSV format.
70
+
71
+ = Do you have a log for the created backup? =
72
+
73
+ Yes, if XCloner Logger option is enabled, it will store a log file inside the xcloner-XXXXX folder inside the backup archive, file is named xcloner-xxxxx.log
74
+
75
+ == Screenshots ==
76
+
77
+ 1. XCloner Dashboard
78
+ 2. General Backup Settings
79
+ 3. List Backup Content
80
+ 4. Cleanup Options for Local Storage
81
+ 5. Remote Storage Panel supporting ftp, sftp, dropbox, amazon s3, azure blob and many more to come
82
+ 6. Manage Scheduled Backups Panel
83
+ 7. Edit Scheduled Backup
84
+ 8. Generate Backup ->Files Options tab
85
+ 9. Restore Backup Panel
86
+ 10. Generate Backup Process
87
+ 11. Generate Backup Screen
88
+
89
+ == Changelog ==
90
+
91
+ = 4.0.1 =
92
+ * Code rewritten from ground up to make use of latest code standards
93
+ * Added support for Dropbox, Amazon S3, Azure Blob and SFTP storage
94
+ * Added a new restore script
95
+ * Added an improved backup and system logger
96
+ * New Setting Panel
97
+ * New Manage Backups Panel with the options to Delete, Transfer to Remote Storage, Download and List Backup archive contents
98
+ * Added mail notifications for scheduled backups
99
+ * Added a new Cron Scheduler to make use of Wordpress System Cron option
100
+ * Improved user input sanitization
101
+ * Improved recursive file scanning and archiving
102
+ * Improved Mysql Backup dump
103
+ * Added Multiple Cleanup options both for local storage and remote
104
+ * Added Improved Backup Compressing option
105
+
106
+ = 3.1.5 =
107
+ * Config variables save sanitization addon
108
+
109
+ = 3.1.4 =
110
+ * DropPHP DropBox library update, upload fixes for files larger than 150MB
111
+
112
+ = 3.1.3 =
113
+ * XSS fix
114
+
115
+ = 3.1.2 =
116
+ * vulnerability fix
117
+
118
+ = 3.1.1 =
119
+ * added CSRF protection
120
+
121
+ = 3.1.0 =
122
+ * added Wordpress login-less integration
123
+ * plugin settings are now saved to database
124
+ * security audit and hardening
125
+
126
+ = 3.0.8 =
127
+ * added russian language support
128
+
129
+ = 3.0.7 =
130
+ * added sftp support for backup transfer, thanks Todd Bluhm - dynamicts.com
131
+
132
+ = 3.0.6 =
133
+ * added php 5.4 compatibility
134
+
135
+ = 3.0.4 =
136
+ * LFI vulnerability fix
137
+
138
+ = 3.0.3 =
139
+ * added amazon ssl option box
140
+ * moved the compress option to the System tab, don't use it unless you know what you are doing!
141
+
142
+ = 3.0.1 =
143
+ * several important security and bug fixes
144
+
145
+ = 3.0 =
146
+ * incremental database backup
147
+ * incremental file system scan
148
+ * backup size limit and option to split it into additional archives, default 2GB
149
+ * exclude files larger than a certain size option
150
+ * incremental files restore
151
+ * JQuery Start interface
152
+
153
+ = 2.2.1 =
154
+ * Added JSON AJAX interface to the Generate Backup process
155
+ * Added incremental filesystem scan
156
+ * several bug fixes
157
+ * php >=5.2.0 version check
158
+
159
+ = 2.1.2 =
160
+ * Added Amazon S3 cron storage support
161
+
162
+ = 2.1 =
163
+ * Initial release
164
+
165
+ == Upgrade Notice ==
166
+
167
+ = 3.0.3 =
168
+ Please check changelog!
admin.cloner.html.php DELETED
@@ -1,2701 +0,0 @@
1
- <?php
2
- /*
3
- * admin.cloner.html.php
4
- *
5
- * Copyright 2011 Ovidiu Liuta <info@thinkovi.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program; if not, write to the Free Software
19
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
- * MA 02110-1301, USA.
21
- */
22
-
23
-
24
- /** ensure this file is being included by a parent file */
25
- defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
26
-
27
- class mosTabs{
28
-
29
- function mosTabs($int){
30
-
31
- echo "<div id=\"tabs\">";
32
-
33
- }
34
-
35
- function startTab($name, $class){
36
-
37
- echo "<div id=\"tabs-$class\"><p>";
38
-
39
-
40
- }
41
-
42
- function endTab(){
43
-
44
- echo "</pp></div>";
45
-
46
- }
47
-
48
- function endPane(){
49
-
50
- echo "</div>";
51
- }
52
-
53
- }
54
-
55
- /**
56
- * @package Joomla
57
- * @subpackage JoomlaCloner
58
- */
59
- class HTML_cloner {
60
-
61
- function header(){
62
-
63
- global $mosConfig_live_site, $task;
64
- $excl_tasks = array("view", "config","");
65
-
66
- ?>
67
-
68
- <script type="text/javascript">
69
-
70
- /* Optional: Temporarily hide the "tabber" class so it does not "flash"
71
- on the page as plain HTML. After tabber runs, the class is changed
72
- to "tabberlive" and it will appear. */
73
-
74
- document.write('<style type="text/css">.tabber{display:none;}<\/style>');
75
- </script>
76
-
77
- <table width='100%' style="padding-left: 3px; padding-right: 4px;align:center;" bgcolor='#ffffff'>
78
- <tr><td align='right'>
79
-
80
- </td></tr>
81
-
82
- <tr><td align='center'>
83
-
84
- <div class="status" >
85
- <table width='100%' bgcolor='white' class="header">
86
- <tr>
87
- <td width='auto'>
88
- <table><tr><td>
89
- <img src="<?php echo plugins_url('images/backup.png', __FILE__) ?>" align="middle">&nbsp;
90
- </td><td>
91
- <a href="plugins.php?page=xcloner_show"><h2><?php echo LM_COM_TITLE.$_SERVER['HTTP_HOST']; ?></h2>
92
- <h1>Backup and Restore</h1>
93
- </a>
94
- </td></tr>
95
- </table>
96
- </td>
97
- <td align="right">
98
- <div id="toolbar" style="display:none">
99
- <?php
100
- # Generating the buttons...
101
- require_once( "toolbar.cloner.php" );
102
- ?>
103
- </div>
104
- </td>
105
- </tr>
106
- </table>
107
- </div>
108
-
109
- <br />
110
- <table width="100%" cellspacing='3' cellpadding="4" >
111
- <tr><td valign='top' width="160" >
112
- <table width='100%' cellpadding='5' height='100%' class='menu_table'><tr><td>
113
-
114
-
115
- <div class="dtree">
116
-
117
- <a href="javascript: d.openAll();"><?php echo LM_MENU_OPEN_ALL?></a> | <a href="javascript: d.closeAll();"><?php echo LM_MENU_CLOSE_ALL?>l</a><br />
118
- <br />
119
- <script type="text/javascript">
120
- <!--
121
-
122
- d = new dTree('d');
123
-
124
- d.add(0,-1,'&nbsp;<?php echo LM_MENU_CLONER;?>','plugins.php?page=xcloner_show&option=com_cloner','','','<?php echo plugins_url('images/logo.gif', __FILE__) ?>');
125
-
126
- d.add(800,0,'&nbsp;<?php echo LM_MENU_ADMINISTRATION;?>','','','','<?php echo plugins_url('images/actions.gif', __FILE__) ?>','<?php echo plugins_url('images/actions.gif', __FILE__) ?>');
127
-
128
- d.add(801,800,'&nbsp;<?php echo LM_MENU_CONFIGURATION;?>','plugins.php?page=xcloner_show&option=com_cloner&task=config','','','<?php echo plugins_url('images/gen_settings.png', __FILE__) ?>');
129
- d.add(802,800,'&nbsp;<?php echo LM_MENU_CRON;?>','plugins.php?page=xcloner_show&option=com_cloner&task=cron','','','<?php echo plugins_url('images/templatessm.png', __FILE__) ?>');
130
- d.add(803,800,'&nbsp;<?php echo LM_MENU_LANG;?>','plugins.php?page=xcloner_show&option=com_cloner&task=lang','','','<?php echo plugins_url('images/lang.png', __FILE__) ?>');
131
-
132
-
133
- d.add(840,0,'&nbsp;<?php echo LM_MENU_ACTIONS;?>','','','','<?php echo plugins_url('images/actions.gif', __FILE__) ?>','<?php echo plugins_url('images/actions.gif', __FILE__) ?>');
134
- d.add(841,840,'&nbsp;<?php echo LM_MENU_View_backups;?>','plugins.php?page=xcloner_show&option=com_cloner&task=view','','','<?php echo plugins_url('images/editionssm.png', __FILE__) ?>');
135
- d.add(842,840,'&nbsp;<?php echo LM_MENU_Generate_backup;?>','plugins.php?page=xcloner_show&option=com_cloner&task=confirm','','','<?php echo plugins_url('images/wizardsm.png', __FILE__) ?>');
136
- d.add(843,840,'&nbsp;<?php echo LM_MENU_Restore_backup;?>','plugins.php?page=xcloner_show&option=com_cloner&task=restore','','','<?php echo plugins_url('images/wizardsm_restore.png', __FILE__) ?>');
137
-
138
- d.add(830,0,'&nbsp;<?php echo LM_MENU_SUPPORT;?>','','','','<?php echo plugins_url('images/support.png', __FILE__) ?>','<?php echo plugins_url('images/support.png', __FILE__) ?>');
139
- d.add(831,830,'&nbsp;<?php echo LM_MENU_FORUM;?>','http://www.xcloner.com/support/forums/','','_blank','<?php echo plugins_url('images/forum.png', __FILE__) ?>','<?php echo plugins_url('images/forum.png', __FILE__) ?>');
140
- d.add(832,830,'&nbsp;<?php echo LM_MENU_WEBSITE;?>','http://www.xcloner.com','','_blank','<?php echo plugins_url('images/website.png', __FILE__) ?>','<?php echo plugins_url('images/website.png', __FILE__) ?>');
141
-
142
-
143
-
144
- d.add(820,0,'&nbsp;<?php echo LM_MENU_Documentation;?>','','','','<?php echo plugins_url('images/help.png', __FILE__) ?>','<?php echo plugins_url('images/gen_settings.png', __FILE__) ?>');
145
- d.add(821,820,'&nbsp;<?php echo LM_MENU_ABOUT;?>','plugins.php?page=xcloner_show&option=com_cloner&task=about','','','<?php echo plugins_url('images/about.png', __FILE__) ?>','<?php echo plugins_url('images/about.png', __FILE__) ?>');
146
-
147
- document.write(d);
148
-
149
- //-->
150
- </script></div> </td></tr></table>
151
- <br />
152
- <table width='100%' cellpadding='5' height='100%' class='menu_table'><tr><td>
153
- <a href="http://www.thinkovi.com/services/website-migration/" target="_blank">
154
- <img src="<?php echo plugins_url('images/thinkovi.png', __FILE__) ?>" border="0" />
155
- </a>
156
- </td></tr></table>
157
-
158
- </td><td valign='top' align='left' style="padding-left: 20px;">
159
-
160
-
161
- <?php
162
- if($_REQUEST['mosmsg']!="")
163
-
164
- echo "<center><h2>".strip_tags($_REQUEST['mosmsg'])."</h2></center>";
165
-
166
- }
167
-
168
- function footer(){
169
-
170
- ?>
171
- </td></tr></table>
172
- <hr><br /><br />
173
- <center>
174
- <p>Powered by <a href='http://www.xcloner.com' target='_blank'>XCloner</a>. Backup and Restore Made Easy!</p></center>
175
-
176
- </td></tr></table>
177
- <script>
178
-
179
- jQuery( "#toolbar" ).show();
180
-
181
- </script>
182
-
183
-
184
- <?php
185
-
186
- }
187
-
188
- function goRefreshHtml($filename, $perm_lines, $excl_manual){
189
-
190
- global $_CONFIG;
191
-
192
- $f = pathinfo($filename);
193
- $backupFile = $f['basename'];
194
-
195
- if (file_exists($filename)) {
196
- echo "<h2>Initializing backup...</h2>";
197
- echo "<h3 >Backup <b>$filename</b> created, we may continue!</h3><br />";
198
-
199
- $urlReturn = "plugins.php?page=xcloner_show&option=com_cloner&lines=" . $perm_lines . "&task=refresh&backup=$backupFile&excl_manual=$excl_manual";
200
-
201
- if(!$_CONFIG['refresh_mode']){
202
-
203
- echo "<a href=\"".$urlReturn."\" id='cLink'>Please click here to continue!</a>";
204
- echo " <strong id='countdown'>5</strong>";
205
- echo "<script type='text/javascript'>cLink_load();</script>";
206
-
207
- }else{
208
-
209
- echo "<script>var dbbackup = ".intval($_REQUEST['dbbackup']).";</script>";
210
-
211
- ?>
212
- <!--Start ProgressBar-->
213
- <script type="text/javascript">
214
-
215
- jQuery(document).ready(function() {
216
-
217
- var globalUrl;
218
- var step = "r1";
219
- var count = 0;
220
- var counter = 0;
221
- var counter_old = 0;
222
- var completeSize = 0;
223
- var oldBackupName = "";
224
- var parts = 0;
225
- var oldSize = 0;
226
-
227
- jQuery("#progressbar").progressbar({ value: 0 });
228
-
229
- jQuery.ajaxSetup({
230
- "error":function(request, status, error) {
231
- //reset state here;
232
- jQuery("#error").show();
233
- jQuery("#errorText").append(status+" -- "+error);
234
- jQuery("#errorText").append("<br /><br /><strong>JSON url:</strong> "+globalUrl);
235
- jQuery("#errorText").append("<br /><br /><strong>Response body:</strong> "+request.responseText);
236
- }});
237
-
238
- function getSize(bytes, conv){
239
-
240
- return (parseInt(bytes)/parseInt(conv)).toFixed(2);
241
-
242
- }
243
- function appendIcon(icon){
244
-
245
- return '<span class="ui-icon ui-icon-'+icon+'" style="float:left;"></span>';
246
-
247
- }
248
-
249
- function xclonerRecurseMYSQL(url){
250
- // create database backup
251
- globalUrl = url;
252
- step = "r1";
253
-
254
- jQuery.getJSON(url, function(json) {
255
-
256
- if(!json){
257
- jQuery("#error").show();
258
- jQuery("#errorText").text(url);
259
- }
260
-
261
- if(json.dumpsize && !json.endDump){
262
- jQuery("#mysqlProcess").append(" ("+getSize(json.dumpsize, 1024*1024)+" MB) <br />");
263
- }
264
-
265
- if(json.newDump){
266
- count++;
267
- //jQuery("#mysqlProcess").append(appendIcon("arrowthick-1-e"));
268
- if(json.databaseName!="")
269
- jQuery("#mysqlProcess").append("<b>["+json.databaseName+"]</b> <span id='db"+count+"'></span> tables ");
270
- counter = parseInt(json.startAtLine);
271
-
272
- }else{
273
- jQuery("#db"+count).text(json.startAtLine - counter);
274
- }
275
-
276
- if(!parseInt(json.finished)){
277
- //get next records
278
-
279
- jQuery("#db"+count).text(json.startAtLine - counter);
280
-
281
- recurseUrl = "admin-ajax.php?action=json_return&task=recurse_database&nohtml=1&dbbackup_comp="+json.dbbackup_comp+"&dbbackup_drop="+json.dbbackup_drop+"&startAtLine="+json.startAtLine+"&startAtRecord="+json.startAtRecord+"&dumpfile="+json.dumpfile;
282
- xclonerRecurseMYSQL(recurseUrl);
283
-
284
- }
285
- else{
286
-
287
- jQuery("#fileSystem").show();
288
- var recurseUrl="admin-ajax.php?action=json_return&task=recurse_files&mode=start&nohtml=1";
289
- xclonerRecurseJSON(recurseUrl);
290
-
291
- }
292
-
293
-
294
- });
295
- }
296
-
297
- function xclonerRecurseJSON(url){
298
- //scan file system
299
- jQuery("#result").hide();
300
-
301
- globalUrl = url;
302
- step = "r2";
303
-
304
- jQuery.getJSON(url, function(json) {
305
-
306
- if(!json){
307
- jQuery("#error").show();
308
- jQuery("#errorText").text(url);
309
- }
310
-
311
- if(!parseInt(json.finished)){
312
-
313
- jQuery("#recurseStatus").text(json.tfiles);
314
-
315
- var recurseUrl = "admin-ajax.php?action=json_return&task=recurse_files&mode="+json.mode+"&nohtml=1&files="+json.tfiles;
316
- xclonerRecurseJSON(recurseUrl);
317
-
318
- }
319
- else{
320
- var size = parseFloat(json.size)/(1024*1024);
321
- jQuery("#recurseStatus").text(" done! (Estimated size:"+size.toFixed(2)+"MB) in "+json.tfiles+" files");
322
- jQuery("#result").show();
323
-
324
- if(json.overlimit.length > 0){
325
- jQuery("#overlimit").show();
326
- for(var i=0; i < json.overlimit.length; i++){
327
-
328
- jQuery("#overlimit").append("<span class='oversizedFile'></span>"+json.overlimit[i]+"<br />");
329
-
330
- }
331
- }
332
-
333
- //xclonerGetJSON("<?php echo $urlReturn;?>");
334
- returnUrl = "admin-ajax.php?action=json_return&option=com_cloner&lines="+json.tfiles+"&task=refresh&backup=<?php echo $backupFile; ?>&excl_manual=";
335
- xclonerGetJSON(returnUrl);
336
-
337
- }
338
-
339
-
340
- });
341
- }
342
-
343
- function xclonerGetJSON(url){
344
- //create backup archive
345
- globalUrl = url;
346
- step = "r3";
347
-
348
- jQuery.getJSON(url, function(json) {
349
-
350
- if(!json){
351
- jQuery("#error").show();
352
- jQuery("#errorText").append(url);
353
- }
354
-
355
- var percent = parseInt(json.percent);
356
- jQuery("#progressbar").progressbar({ value: percent });
357
- jQuery("#backupSize").text(getSize(json.backupSize, 1024*1024));
358
- jQuery("#nFiles").text(json.startf);
359
- jQuery("#percent").text(json.percent);
360
- jQuery("#backupName").text(json.backup);
361
- if(!json.finished){
362
-
363
- if(oldBackupName != json.backup){
364
- oldBackupName = json.backup;
365
- completeSize = completeSize + oldSize;
366
- parts++;
367
- }else{
368
- oldSize = parseInt(json.backupSize);
369
- }
370
-
371
- var url = "admin-ajax.php?action=json_return&option="+json.option+"&task="+json.task+"&json="+json.json+"&startf="+json.startf+"&lines="+json.lines+"&backup="+json.backup+"&excl_manual="+json.excl_manual;
372
- xclonerGetJSON(url);
373
- }else{
374
-
375
- //all done
376
- url = "admin-ajax.php?action=json_return&task=cleanup&nohtml=1";
377
- jQuery.getJSON(url, function(json) {
378
- });
379
-
380
- jQuery("#complete").show();
381
- jQuery("#nFiles").text(json.lines);
382
- if(parts > 0){
383
- jQuery("#backupParts").show();
384
- jQuery("#backupPartsNr").text(parts);
385
- }
386
- jQuery("#backupFiles").text(json.lines);
387
- jQuery("#backupSizeComplete").append(getSize(completeSize+parseInt(json.backupSize), 1024*1024));
388
- jQuery("#backupNameC").text(json.backup);
389
- jQuery( "#dialog:ui-dialog" ).dialog( "destroy" );
390
- jQuery( "#dialog-message" ).dialog({
391
- modal: true,
392
- width: 600,
393
- buttons: {
394
- Close: function() {
395
- jQuery( this ).dialog( "close" );
396
- }
397
- }
398
- });
399
-
400
- }
401
-
402
- });
403
-
404
- }
405
-
406
- //Main program here
407
-
408
- jQuery("#retry").click(function(){
409
- jQuery("#error").hide();
410
- jQuery("#errorText").empty();
411
- if(step == "r1"){
412
- xclonerRecurseMYSQL(globalUrl);
413
- }
414
- else
415
- if(step == "r2"){
416
- xclonerRecurseJSON(globalUrl);
417
- }
418
- else if(step == "r3"){
419
- xclonerGetJSON(globalUrl);
420
- }
421
- });
422
-
423
- jQuery("#result").hide();
424
- jQuery("#fileSystem").hide();
425
-
426
- if(dbbackup){
427
- recurseUrl = "admin-ajax.php?action=json_return&task=recurse_database&nohtml=1&dbbackup_comp=<?php echo $_REQUEST['dbbackup_comp']?>&dbbackup_drop=<?php echo $_REQUEST['dbbackup_drop']?>";
428
- xclonerRecurseMYSQL(recurseUrl);
429
- }else{
430
- jQuery("#fileSystem").show();
431
- var recurseUrl="admin-ajax.php?action=json_return&task=recurse_files&mode=start&nohtml=1";
432
- xclonerRecurseJSON(recurseUrl);
433
-
434
- }
435
-
436
- });
437
- </script>
438
-
439
- <?php
440
-
441
- if($_REQUEST['dbbackup']){
442
- //lets start the incremental procedure
443
- ?>
444
-
445
- <div id="mysqlBackup">
446
- <h2>Database backup...</h2><br />
447
- <div id="mysqlProcess"></div><div id="counter"></div>
448
- </div>
449
-
450
- <?php
451
- }
452
- ?>
453
-
454
- <div id="fileSystem">
455
- <h2>Filesystem backup...</h2>
456
-
457
- <div id="recurseFiles">
458
- <br /><strong>Scanning files system...</strong> <span id="recurseStatus"></span>
459
- <br /><div id="overlimit" style="display:none"><b>Excluded oversized files:</b><br /> </div>
460
- </div>
461
-
462
- <div id="result">
463
- <br /> <strong>Processing Files:</strong> <span id="percent">0</span>% (<span id="nFiles"></span> files)
464
- <br /><br /> <strong>Backup Name: </strong><span id="backupName"></span>
465
- <br /><br /> <strong>Backup Size: </strong><span id="backupSize"></span>MB
466
- <br /><br /> <div id="progressbar"></div>
467
- </div>
468
-
469
- <div id="complete">
470
- <br /><h2>Backup completed!</h2>
471
-
472
- <form action="" name="adminForm" method="post">
473
- <input type=hidden name=files[1] value='<?php echo $backupFile?>'>
474
- <input type=hidden name=cid[1] value='<?php echo $backupFile?>'>
475
- <input type="hidden" name="option" value="<?php echo $option; ?>"/>
476
- <input type="hidden" name="task" value=""/>
477
- </form>
478
-
479
- <div id="dialog-message" title="Backup completed">
480
- <p>
481
- <span class="ui-icon ui-icon-arrowthick-1-e" style="float:left;"></span>
482
- <strong>Backup name:</strong> <span id="backupNameC"></span>
483
- </p>
484
- <p>
485
- <span class="ui-icon ui-icon-arrowthick-1-e" style="float:left;"></span><strong>Backup size:</strong> <span id="backupSizeComplete"></span>MB
486
- </p>
487
- <p>
488
- <span class="ui-icon ui-icon-arrowthick-1-e" style="float:left;"></span><strong>Number of files:</strong> <span id="backupFiles"></span>
489
- </p>
490
- <p class="backupParts">
491
- <span class="ui-icon ui-icon-arrowthick-1-e" style="float:left;"></span><strong>Backup Parts:</strong> <span id="backupPartsNr"></span>
492
- </p>
493
- </div>
494
-
495
- </div>
496
- </div>
497
-
498
- <div id="error" style="display:none;">
499
- <br /><h2 style="color:Red"><?php echo LM_REFRESH_ERROR;?></h2>
500
- <br /><b>Details:</b> <span id="errorText"></span>
501
- <br /><br />
502
- <a href="#" id="retry"><h3>Click to Retry >></h3></a>
503
-
504
- </div>
505
-
506
- <!-- End ProgressBar -->
507
-
508
- <?php
509
-
510
- }
511
- return;
512
- } else {
513
- E_print("Backup failed, please check your tar server utility support!");
514
- return;
515
- }
516
-
517
- }
518
-
519
- function path_check($path){
520
-
521
- if(!is_dir($path)){
522
- $stat['code'] = 1;
523
- $stat['message'] = "Invalid directory";
524
- return $stat;
525
- }
526
-
527
- if(!is_readable($path)){
528
- $stat['code'] = 2;
529
- $stat['message'] = "Directory is not readable";
530
- return $stat;
531
- }
532
-
533
- if(!is_writeable($path)){
534
- $stat['code'] = 3;
535
- $stat['message'] = "Directory not writeable";
536
- return $stat;
537
- }
538
-
539
- return 0;
540
-
541
- }
542
-
543
- function _FDefault(){
544
- global $_CONFIG, $html;
545
- ?>
546
-
547
- <form action="" method="post" name="adminForm">
548
-
549
- <table class="adminform">
550
- <tr><th valign='top' >
551
- <?php echo LM_JOOMLAPLUG_CP?>
552
- </th>
553
- </table>
554
-
555
- <table class="adminform" >
556
- <tr><td >
557
- <div id="cpanel">
558
-
559
- <div style="float:left;">
560
- <div class="icon">
561
-
562
- <a href="plugins.php?page=xcloner_show&option=com_cloner&amp;task=config">
563
- <img src="<?php echo plugins_url('images/settings.png', __FILE__) ?>"
564
- alt="Settings" align="middle" name="" border="0" />
565
- <span><?php echo LM_MAIN_Settings?></span>
566
- </a>
567
- </div>
568
- </div>
569
-
570
- <div style="float:left;">
571
- <div class="icon">
572
-
573
- <a href="plugins.php?page=xcloner_show&option=com_cloner&amp;task=view">
574
- <img src="<?php echo plugins_url('images/editions.png', __FILE__) ?>"
575
- alt="View Backups" align="middle" name="" border="0" />
576
- <span><?php echo LM_MAIN_View_Backups?></span>
577
- </a>
578
- </div>
579
- </div>
580
-
581
- <div style="float:left;">
582
- <div class="icon">
583
-
584
- <a href="plugins.php?page=xcloner_show&option=com_cloner&amp;task=confirm">
585
- <img src="<?php echo plugins_url('images/wizard.png', __FILE__) ?>"
586
- alt="MagaGenerate Backup" align="middle" name="" border="0" />
587
- <span><?php echo LM_MAIN_Generate_Backup?></span>
588
- </a>
589
- </div>
590
- </div>
591
-
592
- <div style="float:left;">
593
- <div class="icon">
594
-
595
- <a href="plugins.php?page=xcloner_show&option=com_cloner&amp;task=about">
596
- <img src="<?php echo plugins_url('images/lhelp.png', __FILE__) ?>"
597
- alt="MagaGenerate Backup" align="middle" name="" border="0" />
598
- <span><?php echo LM_MAIN_Help?></span>
599
- </a>
600
- </div>
601
- </div>
602
-
603
-
604
-
605
-
606
- </div>
607
- </td></tr>
608
- <tr><td>
609
-
610
- <?php
611
- $error = 0;
612
- ?>
613
-
614
- <div class="statusCheck">
615
-
616
- <div class="status">
617
- <span class="mtext">Backup Start Path Check: </span>
618
- <?php
619
- $html = new HTML_cloner();
620
- $stat = $html->path_check($_CONFIG[backup_start_path]);
621
-
622
- if( $stat['code'] > 0 and $stat['code'] < 3){
623
- echo "<span class='error'>".$stat['message']; $error = 1;
624
- }
625
- else{
626
- echo "<span class='success'>OK";
627
- if(!is_dir($_CONFIG[backup_start_path]."/administrator/backups")){
628
- @mkdir($_CONFIG[backup_start_path]."/administrator");
629
- if(@mkdir($_CONFIG[backup_start_path]."/administrator/backups"))
630
- echo "<script>window.location='plugins.php?page=xcloner_show'</script";
631
- }
632
- }
633
- echo " ($_CONFIG[backup_start_path])";
634
- ?>
635
- </span></div>
636
-
637
- <div class="status">
638
- <span class="mtext">Backup Store Path Check: </span>
639
- <?php
640
-
641
- $stat = $html->path_check($_CONFIG[backup_store_path]);
642
-
643
- if( $stat['code'] > 0){
644
- echo "<span class='error'>".$stat['message']; $error = 1;
645
- }
646
- else{
647
- echo "<span class='success'>OK";
648
- }
649
- echo " ($_CONFIG[backup_store_path])";
650
- ?>
651
- </span>
652
- </div>
653
-
654
- <div class="status">
655
- <span class="mtext">Temporary Path Check: </span>
656
- <?php
657
-
658
- $stat = $html->path_check($_CONFIG[temp_dir]);
659
-
660
- if( $stat['code'] > 0){
661
- echo "<span class='error'>".$stat['message']; $error = 1;
662
- }
663
- else{
664
- echo "<span class='success'>OK";
665
- }
666
- echo " ($_CONFIG[temp_dir])";
667
- ?>
668
- </span></div>
669
-
670
- <!--<div class="status">
671
- <span class="mtext">Authentication: </span>
672
- <?php
673
-
674
- if($_CONFIG['jcpass'] == md5('admin')){
675
- #echo "<span class='error'>Change default password 'admin'"; $error = 1;
676
- }
677
- else{
678
- #echo "<span class='success'>OK";
679
- }
680
-
681
- ?>
682
- </span></div>-->
683
-
684
- <div class="status">
685
- <span class="mtext">Backup Ready: </span>
686
- <?php
687
-
688
- if($error ){
689
- echo "<span class='error'>NO"; $error = 1;
690
- }
691
- else{
692
- echo "<span class='success'>YES";
693
- }
694
-
695
- ?>
696
- </span></div>
697
-
698
- </div>
699
- </td></tr>
700
- </table>
701
- <input type="hidden" name="option" value="com_cloner" />
702
- <input type="hidden" name="task" value="lang" />
703
- </form>
704
-
705
- <?php
706
- }
707
-
708
- /*The basic Authentication form*/
709
- function Login(){
710
-
711
- ?>
712
- <center><br />
713
-
714
- <script>
715
- jQuery(function() {
716
- jQuery( "#login" ).button({
717
- icons: {
718
- primary: "ui-icon-locked"
719
- }
720
- })
721
- jQuery("#login").click(function() {
722
- jQuery("#adminForm")[0].submit();
723
- return false;
724
- })
725
-
726
- jQuery( "#reset" ).button({
727
- icons: {
728
- primary: "ui-icon-trash"
729
- }
730
- })
731
- jQuery( "#reset" ).click(function() {
732
- jQuery("#username").val('');jQuery("#password").val('');
733
- return false;
734
- });
735
-
736
- });
737
- </script>
738
-
739
-
740
- <div class="loginform">
741
- <form action="" method="post" name="adminForm" id="adminForm">
742
- <table class="loginForm">
743
- <tr><td align='center'>
744
- <table align='center' cellpadding='10' cellspacing='20'>
745
- <tr ><td colspan='2' align='center'><b>Authentication Area:</b></td></tr>
746
- <tr><td>Username:</td><td><input type='text' size='30' name='username' id='username'></td></tr>
747
- <tr><td>Password:</td><td><input type='password' size='30' name='password' id='password'></td></tr>
748
- <tr><td>&nbsp;</td><td>
749
- <div class="loginform">
750
- <button id="login">Login</button>
751
- <button id="reset">Reset</button>
752
-
753
-
754
- </div>
755
- </td></tr>
756
- <tr><td colspan='2'><?php echo LM_LOGIN_TEXT;?></td></tr>
757
- </table>
758
- </td></tr>
759
- </table>
760
-
761
- <input type="hidden" name="option" value="com_cloner" />
762
- <input type="hidden" name="task" value="dologin" />
763
- <input type="hidden" name="boxchecked" value="0" />
764
- <input type="hidden" name="hidemainmenu" value="0" />
765
-
766
- </form>
767
- </center>
768
- <?php
769
-
770
- }
771
-
772
- function Cron(){
773
- global $_CONFIG;
774
- ?>
775
-
776
- <script>
777
- jQuery(function() {
778
- jQuery( "#tabs" ).tabs();
779
- });
780
- </script>
781
-
782
- <div id="tabs">
783
- <ul>
784
- <li><a href="#tabs-1"><?php echo LM_CRON_TOP?></a></li>
785
- </ul>
786
-
787
- <div id="tabs-1"><p>
788
-
789
- <div class="mainText">
790
- <?php echo LM_CRON_SUB?>
791
- <br /><br />
792
-
793
- <ul>
794
- <li><input type="text" value="/usr/bin/php <?php echo dirname(__FILE__);?>/cloner.cron.php custom_cron_config.php" size="150" /></li>
795
- </ul>
796
- <br /><br />
797
-
798
- For <b>Running Multiple Crons</b>, you need to first create a custom configuration file in the XCloner Configuration -> Cron tab
799
- and then replace "cloner.cron.php" with "cloner.cron.php myconfig.php"
800
- <br /><br />
801
-
802
- <?php echo LM_CRON_HELP?>
803
- </div>
804
-
805
- </p></div>
806
- </div>
807
-
808
- <?php
809
- }
810
-
811
-
812
- function Translator_Edit_DEFAULT($option, $content, $file, $lang){
813
- global $_CONFIG;
814
- ?>
815
- <form action="" method="post" name="adminForm">
816
- <table class="adminlist">
817
- <tr>
818
- <th align="left"><?php echo LM_LANG_EDIT_FILE?> <?php echo $file?></th>
819
- </tr>
820
-
821
- <tr>
822
-
823
- <td><textarea name='def_content' cols='100' rows='30'><?php echo $content;?></textarea></td>
824
-
825
- </tr>
826
-
827
- <input type="hidden" name="option" value="com_cloner" />
828
- <input type="hidden" name="language" value="<?php echo $lang?>" />
829
- <input type="hidden" name="task" value="lang" />
830
- <input type="hidden" name="boxchecked" value="0" />
831
- <input type="hidden" name="hidemainmenu" value="0" />
832
- </form>
833
-
834
- <?php
835
-
836
- }
837
-
838
- function Translator_Add($option){
839
- global $_CONFIG;
840
- ?>
841
- <form action="" method="post" name="adminForm">
842
- <table class="adminlist">
843
- <tr>
844
- <th align="left"><?php echo LM_LANG_NEW?></th>
845
- </tr>
846
-
847
- <tr>
848
-
849
- <td><input size='40' type=text name='lname' value=''></td>
850
-
851
- </tr>
852
-
853
- <input type="hidden" name="option" value="com_cloner" />
854
- <input type="hidden" name="language" value="<?php echo $lang?>" />
855
- <input type="hidden" name="task" value="add_lang_new" />
856
- <input type="hidden" name="boxchecked" value="0" />
857
- <input type="hidden" name="hidemainmenu" value="0" />
858
- <?php wp_nonce_field('add_lang','csrf'); ?>
859
-
860
- </form>
861
- <?php
862
- }
863
-
864
- function Translator_Edit($option, $data, $def_data, $file, $lang){
865
- global $_CONFIG;
866
- ?>
867
-
868
- <form action="" method="post" name="adminForm">
869
- <table class="adminlist">
870
- <tr>
871
- <th align="left"><?php echo LM_LANG_EDIT_FILE?> <input type=text name='lfile' size=100 value='<?php echo $file?>'><br />
872
- <font color='red'><?php echo LM_LANG_EDIT_FILE_SUB?></font>
873
-
874
- <script language="javascript" type="text/javascript">
875
- function submitbutton(pressbutton) {
876
- var form = document.adminForm;
877
-
878
- if (pressbutton == 'save_lang_apply') {
879
- if(confirm('Before you continue please make sure you are still logged in, else press Cancel and then try again!')){
880
- submitform( pressbutton );
881
- }
882
- return;
883
- }
884
- else
885
- if (pressbutton == 'save_lang') {
886
- if(confirm('Before you continue please make sure you are still logged in, else press Cancel and then try again!')){
887
- submitform( pressbutton );
888
- }
889
- return;
890
- }
891
- else{
892
- submitform( pressbutton );
893
- }
894
- }
895
- </script>
896
-
897
- </th>
898
- </tr>
899
- </table>
900
- <?php
901
- foreach($data as $key=>$value)
902
- if($def_data[$key]!="") {
903
- if($i++ %2 == 0)
904
- $bgcolor = '#eeeeee';
905
- else
906
- $bgcolor = '#dddddd';
907
- ?>
908
- <table class="adminlist">
909
- <tr>
910
- <th width='50%' align="left">Default Variable <?php echo $key?></th>
911
- <th width='50%' align="left">Translation <?php echo $key?></th>
912
- </tr>
913
- <tr bgcolor="<?php echo $bgcolor?>">
914
- <td><textarea cols=65 rows=3 ><?php echo stripslashes($def_data[$key])?></textarea></td>
915
-
916
- <td bgcolor='<?php if( trim(str_replace(array("\n","\r"," "),array("","",""),$def_data[$key])) !=
917
- trim(str_replace(array("\n","\r"," "),array("","",""),$value)))
918
- echo 'green';
919
- else
920
- echo 'red';?>'>
921
- <textarea cols=65 rows=3 name=lang[<?php echo $key?>]><?php echo stripslashes($value)?></textarea></td>
922
- </tr>
923
-
924
- <?php
925
- }
926
- ?>
927
-
928
- <input type="hidden" name="option" value="com_cloner" />
929
- <input type="hidden" name="language" value="<?php echo $lang?>" />
930
- <input type="hidden" name="task" value="lang" />
931
- <input type="hidden" name="boxchecked" value="0" />
932
- <input type="hidden" name="hidemainmenu" value="0" />
933
- <?php wp_nonce_field('save_lang','csrf'); ?>
934
- </form>
935
-
936
- <?php
937
- }
938
-
939
- function Translator($option, $lang_arr){
940
- global $_CONFIG;
941
-
942
- ?>
943
- <script>
944
- jQuery(function() {
945
- jQuery( "#toggle" ).button();
946
- jQuery( "#toggle" ).click(function() { checkJAll(<?php echo count( $lang_arr ); ?>, "toggle", "cb"); });
947
- jQuery( "#checklist" ).buttonset();
948
- });
949
- </script>
950
-
951
- <form action="" method="post" name="adminForm">
952
- <div id="checklist">
953
- <table class="adminlist">
954
- <tr>
955
- <th align="center">
956
- <input id="toggle" type="checkbox" name="toggle" value="" /><label for="toggle">Check All</label>
957
- </th>
958
- <th align="left">
959
- <?php echo LM_LANG_NAME ?>
960
- </th>
961
- </tr>
962
-
963
- <?php
964
- for($i=0; $i<sizeof($lang_arr); $i++){
965
-
966
- ?>
967
-
968
- <tr>
969
- <!--<td width="5" align="left"><?php echo ($i+1);?></td>-->
970
- <td align="center" width="100">
971
- <label for="cb<?php echo $i ?>"><?php echo $i ?></label>
972
- <input type="checkbox" id="cb<?php echo $i ?>" name="cid[<?php echo $i?>]" value="<?php echo $i ?>" />
973
- <input type="hidden" name="files[<?php echo $i?>]" value="<?php echo $lang_arr[$i] ?>" />
974
- </td>
975
- <td align="left" >
976
- <a href="plugins.php?page=xcloner_show&option=<?php echo $option;?>&task=edit_lang&langx=<?php echo $lang_arr[$i];?>"><?php echo ucfirst($lang_arr[$i])?>
977
- </td>
978
- </tr>
979
- <?php
980
-
981
- }
982
- ?>
983
- </table></div>
984
- <input type="hidden" name="option" value="com_cloner" />
985
- <input type="hidden" name="task" value="lang" />
986
- <input type="hidden" name="boxchecked" value="0" />
987
- <input type="hidden" name="hidemainmenu" value="0" />
988
-
989
- </form>
990
- <?php
991
- }
992
-
993
- function showBackups( &$files, &$sizes, $path, $option ) {
994
- // ----------------------------------------------------------
995
- // Presentation of the backup set list screen
996
- // ----------------------------------------------------------
997
- global $baDownloadPath, $_CONFIG;
998
-
999
- ?>
1000
-
1001
- <script type="text/javascript">
1002
-
1003
- jQuery(function() {
1004
- jQuery( "#toggle" ).button();
1005
- jQuery( "#toggle" ).click(function() { checkJAll(<?php echo (count( $files )); ?>, "toggle", "cb"); });
1006
- jQuery( "#checklist" ).buttonset();
1007
-
1008
- jQuery( "#Clone, #Rename, #Delete, #Move" ).unbind("click");
1009
- jQuery( "#Clone, #Rename, #Delete, #Move" ).click(function(){
1010
- if(!jQuery("input:checked").length){
1011
-
1012
- jQuery( "#error-message" ).dialog({
1013
- width: 500,
1014
- height: 200,
1015
- modal: true,
1016
- buttons: {
1017
- Ok: function() {
1018
- jQuery( this ).dialog( "close" );
1019
- }
1020
- }
1021
- });
1022
-
1023
- return false;
1024
- }else{
1025
- var action = jQuery(this).attr('id').toLowerCase();
1026
- document.adminForm.task.value=action;
1027
- document.adminForm.submit();
1028
- }
1029
- })
1030
-
1031
-
1032
- })
1033
- </script>
1034
-
1035
- <div id="error-message" title="Error" style="display:none;">
1036
- <p>
1037
- <span class="ui-icon ui-icon-circle-check" style="float:left; margin:0 7px 50px 0;"></span>
1038
- Please select at least one backup archive.
1039
- </p>
1040
-
1041
- </div>
1042
- <div id="checklist">
1043
- <form action="" method="post" name="adminForm">
1044
- <table class="adminlist">
1045
- <tr>
1046
- <th width="100">
1047
- <input type="checkbox" id="toggle" name="toggle" value="" /><label for="toggle">Check All</label>
1048
- </th>
1049
- <th align="left" width="100px;">
1050
- <?php echo LM_COL_DOWNLOAD ?>
1051
- </th>
1052
- <th width="50%" class="title">
1053
- <?php echo LM_COL_FILENAME ?>
1054
- </th>
1055
- <th align="left" width="10%">
1056
- <?php echo LM_COL_SIZE ?>
1057
- </th>
1058
- <th align="left" width="">
1059
- <?php echo LM_COL_DATE ?>
1060
- </th>
1061
- </tr>
1062
- <?php
1063
- $k = 0;
1064
- for ($i=0; $i <= (count( $files )-1); $i++) {
1065
- $date = date ("D jS M Y H:i:s (\G\M\T O)", filemtime($path.'/'.$files[$i]));
1066
- $url = "admin-ajax.php?action=json_return&page=xcloner_show&option=com_cloner&task=download&file=".'/'.urlencode($files[$i]);
1067
- ?>
1068
- <tr class="<?php echo "row$k"; ?>">
1069
-
1070
- <td align="center">
1071
- <label for="cb<?php echo $i ?>"><?php echo $i ?></label>
1072
- <input type="checkbox" id="cb<?php echo $i ?>" name="cid[<?php echo $i?>]" value="<?php echo $i ?>" />
1073
- <input type="hidden" name="files[<?php echo $i?>]" value="<?php echo $files[$i] ?>" />
1074
- </td>
1075
- <td align="left">
1076
- <a target='_blank' href="<?php echo $url ?>"><img src="<?php echo plugins_url('images/filesave.png', __FILE__) ?>" border="0" title="<?php echo LM_DOWNLOAD_TITLE." - ".$files[$i] ?>" /></a>
1077
- </td>
1078
- <td>
1079
- <span class="backup_name"><?php echo $files[$i]; ?></span>
1080
- <input type="hidden" id="f<?php echo $i ?>" name="f<?php echo $i ?>" value="<?php echo $files[$i]; ?>" >
1081
- </td>
1082
-
1083
- <td align="left">
1084
- <?php echo $sizes[$i]; ?>
1085
- </td >
1086
- <td align="left">
1087
- <?php echo $date; ?>
1088
- </td>
1089
- </tr>
1090
- <?php
1091
- $k = 1 - $k;
1092
- }
1093
- ?>
1094
- </table>
1095
- </div>
1096
- <input type="hidden" name="option" value="com_cloner" />
1097
- <input type="hidden" name="task" value="" />
1098
- <input type="hidden" name="boxchecked" value="0" />
1099
- <input type="hidden" name="hidemainmenu" value="0" />
1100
- </form>
1101
- <br/>&nbsp;
1102
- <?php
1103
- }
1104
-
1105
- function Config($option){
1106
- global $config_file,$_CONFIG, $lang_array, $database, $mosConfig_db;
1107
- ?>
1108
- <form name='adminForm' action='' method='POST'>
1109
-
1110
- <script>
1111
- jQuery(function() {
1112
- jQuery( "#tabs" ).tabs();
1113
- });
1114
-
1115
- jQuery(function() {
1116
- jQuery( "#radiog1" ).buttonset();
1117
- jQuery( "#radiog2" ).buttonset();
1118
- jQuery( "#radiog3" ).buttonset();
1119
- jQuery( "#radiog4" ).buttonset();
1120
- jQuery( "#radio" ).buttonset();
1121
- jQuery( "#radiom" ).buttonset();
1122
- jQuery( "#radiob" ).buttonset();
1123
- jQuery( "#radioftp" ).buttonset();
1124
- jQuery( "#radioftps" ).buttonset();
1125
- jQuery( "#radiodebug" ).buttonset();
1126
- jQuery( "#radiorefresh" ).buttonset();
1127
- jQuery( "#checktar" ).button();
1128
- jQuery( "#cron_file_delete_act" ).button();
1129
- jQuery( "#cron_sql_drop" ).button();
1130
- jQuery( "#cron_amazon_active" ).button();
1131
- jQuery( "#cron_dropbox_active" ).button();
1132
- jQuery( "#cron_dropbox_authorize" ).button();
1133
- jQuery( "#cron_amazon_ssl" ).button();
1134
- jQuery( "#cron_ftp_delb" ).button();
1135
- jQuery( "#checkmysqldump" ).button();
1136
- });
1137
- </script>
1138
-
1139
- <?php $tabs = new mosTabs(1);?>
1140
- <ul>
1141
-
1142
- <li><a href="#tabs-1"><?php echo LM_TAB_GENERAL;?></a></li>
1143
- <li><a href="#tabs-2"><?php echo LM_TAB_MYSQL;?></a></li>
1144
- <!--<li><a href="#tabs-3"><?php echo LM_TAB_AUTH;?></a></li>-->
1145
- <li><a href="#tabs-4"><?php echo LM_TAB_SYSTEM;?></a></li>
1146
- <li><a href="#tabs-5"><?php echo LM_TAB_CRON;?></a></li>
1147
- <li><a href="#tabs-6"><?php echo LM_TAB_INFO;?></a></li>
1148
- </ul>
1149
-
1150
- <table class='adminform'>
1151
- <!--<tr><th colspan='2'>
1152
- <?php #echo LM_CONFIG_EDIT?> <?php #echo $config_file?>
1153
- </th></tr>-->
1154
- </table>
1155
- <?php
1156
- $tabs->startTab(LM_TAB_GENERAL,"1");
1157
- ?>
1158
-
1159
- <div id="configtabinside">
1160
-
1161
- <div>
1162
- <h3><a href="#"> <?php echo LM_CONFIG_BSETTINGS?></a></h3>
1163
- <div><p>
1164
- <table class='adminform'>
1165
-
1166
- <tr>
1167
- <td>
1168
- <?php echo LM_CONFIG_UBPATH?>
1169
- </td>
1170
- <td>
1171
- <input type=text size=100 name='backup_path' value='<?php echo $_CONFIG[backup_path]?>'>
1172
- <br /><?php echo LM_CONFIG_UBPATH_SUB?>
1173
- </td>
1174
- </tr>
1175
-
1176
- <tr>
1177
- <td width='250'>
1178
- <?php echo LM_CONFIG_BPATH?>
1179
- </td>
1180
- <td>
1181
- <input type=text size=100 name='clonerPath' value='<?php echo $_CONFIG[clonerPath]?>'>
1182
- <br /><?php echo LM_CONFIG_BPATH_SUB?>
1183
- </td>
1184
- </tr>
1185
-
1186
- </table>
1187
- </p></div>
1188
- </div>
1189
-
1190
- <div>
1191
- <h3><a href="#"> <?php echo LM_CONFIG_BSETTINGS_OPTIONS?></a></h3>
1192
- <div><p>
1193
- <table class='adminform'>
1194
-
1195
- <tr>
1196
- <td width='250'>
1197
- <?php echo LM_CONFIG_MANUAL_BACKUP;?>
1198
- </td>
1199
- <td>
1200
- <div id="radiog1">
1201
- <label for="radiog11"><?php echo LM_YES?></label> <input id="radiog11" type=radio size=50 value=1 name='backup_refresh' <?php if($_CONFIG[backup_refresh]==1) echo 'checked';?>>
1202
- <label for="radiog12"><?php echo LM_NO?></label> <input id="radiog12" type=radio size=50 value=0 name='backup_refresh' <?php if($_CONFIG[backup_refresh]==0) echo 'checked';?>>
1203
- <br><small><?php echo LM_CONFIG_MANUAL_BACKUP_SUB?></small>
1204
- </div>
1205
- </td>
1206
- </tr>
1207
-
1208
-
1209
-
1210
- <tr>
1211
- <td>
1212
- <?php echo LM_CRON_DB_BACKUP?>
1213
- </td>
1214
- <td>
1215
- <div id="radiog3">
1216
- <label for="radiog31">Yes</label> <input id="radiog31" type=radio size=50 value=1 name='enable_db_backup' <?php if($_CONFIG[enable_db_backup]==1 or $_CONFIG['disable_mysql']) echo 'checked';?>>
1217
- <label for="radiog32">No</label> <input id="radiog32" type=radio size=50 value=0 name='enable_db_backup' <?php if($_CONFIG[enable_db_backup]==0 and !$_CONFIG['disable_mysql']) echo 'checked';?>>
1218
- <br /><?php echo LM_CRON_DB_BACKUP_SUB?>
1219
- </div>
1220
-
1221
- </td>
1222
- </tr>
1223
-
1224
- <tr>
1225
- <td>
1226
- <?php echo LM_CONFIG_SYSTEM_MBACKUP?>
1227
- </td>
1228
- <td>
1229
- <div id="radiog4">
1230
- <label for="radiog41">Yes</label> <input id="radiog41" type=radio size=50 value=1 name='add_backups_dir' <?php if($_CONFIG[add_backups_dir]==1) echo 'checked';?>>
1231
- <label for="radiog42">No</label> <input id="radiog42" type=radio size=50 value=0 name='add_backups_dir' <?php if($_CONFIG[add_backups_dir]==0) echo 'checked';?>>
1232
- <br /><?php echo LM_CONFIG_SYSTEM_MBACKUP_SUB?>
1233
- </td>
1234
- </div>
1235
- </tr>
1236
-
1237
- </table>
1238
- </p></div>
1239
- </div>
1240
-
1241
- <div>
1242
- <h3><a href="#"> <?php echo LM_CONFIG_BSETTINGS_SERVER?></a></h3>
1243
- <div><p>
1244
- <table class='adminform'>
1245
-
1246
- <tr><td width='250'>
1247
- <?php echo LM_CONFIG_MEM?>
1248
- </td>
1249
- <td align='left'>
1250
- <table style="width:auto; margin-bottom: 10px;" cellpadding='0' cellspacing='2' border='0'>
1251
- <tr bgcolor='#efefef'><td style="width:70px;">
1252
- <label for="checktar"><?php echo LM_ACTIVE;?></label> <input type=checkbox id="checktar" value=1 name='mem' <?php if($_CONFIG[mem]==1) echo 'checked';?>>
1253
- </td><td align='left'>
1254
-
1255
- <table width='100%' cellpadding='0' cellspacing='0'>
1256
- <tr><td>
1257
- <?php echo LM_TAR_PATH;?> <br /><input size='50' type=text name=tarpath value='<?php echo $_CONFIG[tarpath]?>'><br />
1258
- <?php echo LM_TAR_PATH_SUB;?>
1259
- </td></tr>
1260
-
1261
- </table>
1262
-
1263
-
1264
- </td></tr>
1265
-
1266
- <tr bgcolor='#dedede'><td>
1267
- <label for="checkmysqldump"><?php echo LM_ACTIVE?></label> <input id="checkmysqldump" type=checkbox value=1 name='sql_mem' <?php if($_CONFIG[sql_mem]==1) echo 'checked';?>>
1268
- </td><td align='left'>
1269
- <?php echo LM_MYSQLDUMP_PATH;?> <br /><input type=text size='50' name='sqldump' value='<?php echo $_CONFIG[sqldump]?>'>
1270
-
1271
- </td></tr>
1272
- </table>
1273
-
1274
- <?php echo LM_CONFIG_MEM_SUB?>
1275
-
1276
- </td>
1277
- </tr>
1278
- </table>
1279
- </p></div>
1280
- </div>
1281
-
1282
- <!--<div>
1283
- <h3><a href="#">Public Key Management</a></h3>
1284
- <div><p>
1285
- <table class='adminForm'>
1286
-
1287
- <tr><td width="250">
1288
- Public Key
1289
- </td>
1290
- <td>
1291
- <input type-text size=50 name='license_code' value="<?php echo $_CONFIG[license_code]?>"/>
1292
- <br />Use this code in the MultiSite XCloner Manager <a target='_blank' href='http://www.xcloner.com/'>XCloner.com Members area</a>
1293
- <br />Leave it empty to disable it
1294
-
1295
- </td>
1296
- </tr>
1297
-
1298
- </table>
1299
- </p></div>
1300
- </div>-->
1301
-
1302
- </div>
1303
-
1304
- <?php
1305
- $tabs->endTab();
1306
- $tabs->startTab(LM_TAB_MYSQL,"2");
1307
- ?>
1308
- <div id="configtabinside">
1309
- <div>
1310
- <h3><a href="#"><?php echo LM_CONFIG_MYSQL?></a></h3>
1311
- <div><p>
1312
-
1313
- <table class='adminform'>
1314
-
1315
- <tr>
1316
- <td width='250'>
1317
- <?php echo LM_CONFIG_MYSQLH?>
1318
- </td>
1319
- <td>
1320
- <input type=text size=50 name='mysql_host' value='<?php echo $_CONFIG[mysql_host]?>'>
1321
- <br /><?php echo LM_CONFIG_MYSQLH_SUB?>
1322
- </td>
1323
- </tr>
1324
-
1325
- <tr>
1326
- <td>
1327
- <?php echo LM_CONFIG_MYSQLU?>
1328
- </td>
1329
- <td>
1330
- <input type=text size=50 name='mysql_user' value='<?php echo $_CONFIG[mysql_user]?>'>
1331
- <br /><?php echo LM_CONFIG_MYSQLU_SUB?>
1332
- </td>
1333
- </tr>
1334
-
1335
- <tr>
1336
- <td>
1337
- <?php echo LM_CONFIG_MYSQLP?>
1338
- </td>
1339
- <td>
1340
- <input type=password size=50 name='mysql_pass' value='<?php echo $_CONFIG[mysql_pass]?>'>
1341
- <br /><?php echo LM_CONFIG_MYSQLP_SUB?>
1342
- </td>
1343
- </tr>
1344
-
1345
- <tr>
1346
- <td>
1347
- <?php echo LM_CONFIG_MYSQLD?>
1348
- </td>
1349
- <td>
1350
- <input type=text size=50 name='mysql_database' value='<?php echo $_CONFIG[mysql_database]?>'>
1351
- <br /><?php echo LM_CONFIG_MYSQLD_SUB?>
1352
- </td>
1353
- </tr>
1354
-
1355
- <tr>
1356
- <td width='200'>
1357
- <?php echo LM_CONFIG_SYSTEM_MDATABASES?>
1358
- </td>
1359
- <td>
1360
- <div id="radiom">
1361
- <label for="radiom1"><?php echo LM_YES?></label> <input id="radiom1" type=radio name='system_mdatabases' value='0' <?php if(abs($_CONFIG[system_mdatabases])==0) echo "checked";?>>
1362
- <label for="radiom2"><?php echo LM_NO?></label> <input id="radiom2" type=radio name='system_mdatabases' value='1' <?php if(abs($_CONFIG[system_mdatabases])==1) echo "checked";?>>
1363
- <br /> <?php echo LM_CONFIG_SYSTEM_MDATABASES_SUB?>
1364
- </div>
1365
- </td>
1366
- </tr>
1367
-
1368
- </table>
1369
- </p></div>
1370
- </div>
1371
- </div>
1372
- <?php
1373
- $tabs->endTab();
1374
- /*$tabs->startTab(LM_TAB_AUTH,"3");
1375
- ?>
1376
- <div id="configtabinside">
1377
- <div>
1378
- <h3><a href="#"><?php echo LM_CONFIG_AUTH?></a></h3>
1379
- <div><p>
1380
- <table class='adminform'>
1381
- <tr>
1382
- <td width='250'>
1383
- <?php echo LM_CONFIG_AUTH_USER?>
1384
- </td>
1385
- <td>
1386
- <input type=text size=30 name='jcuser' value='<?php echo $_CONFIG[jcuser]?>'>
1387
- <br /><?php echo LM_CONFIG_AUTH_USER_SUB?>
1388
- </td>
1389
- </tr>
1390
-
1391
- <tr>
1392
- <td>
1393
- <?php echo LM_CONFIG_AUTH_PASS?>
1394
- </td>
1395
- <td>
1396
- <input type=text size=30 name='jcpass' value=''> <?php if($_CONFIG['jcpass'] == md5('admin')) echo "<font color=red>please change the default password 'admin'</font>"?>
1397
- <br /><?php echo LM_CONFIG_AUTH_PASS_SUB?>
1398
- </td>
1399
- </tr>
1400
- </table>
1401
- </p></div>
1402
- </div>
1403
- </div>
1404
- <?php
1405
- $tabs->endTab();*/
1406
- $tabs->startTab(LM_TAB_SYSTEM,"4");
1407
- ?>
1408
-
1409
- <div id="configtabinside">
1410
- <div>
1411
- <h3><a href="#"><?php echo LM_CONFIG_DISPLAY?></a></h3>
1412
- <div><p>
1413
- <table class='adminform'>
1414
- <tr>
1415
- <td width='250'>
1416
- <?php echo LM_CONFIG_SYSTEM_LANG?>
1417
- </td><td>
1418
- <select name='select_lang'>
1419
- <option value=''><?php echo LM_CONFIG_SYSTEM_LANG_DEFAULT;?></option>
1420
- <?php
1421
- foreach($lang_array as $value)
1422
- if($_CONFIG['select_lang'] == $value)
1423
- echo "<option value='$value' selected>$value</option>\n";
1424
- else
1425
- echo "<option value='$value'>$value</option>\n";
1426
- ?>
1427
- </select>
1428
- <br>
1429
- <br /><?php echo LM_CONFIG_SYSTEM_LANG_SUB?>
1430
- </td></tr>
1431
- </table>
1432
- </p></div>
1433
- </div>
1434
- <div>
1435
- <h3><a href="#"> <?php echo LM_CONFIG_SYSTEM?></a></h3>
1436
- <div><p>
1437
-
1438
- <table class='adminform'>
1439
-
1440
- <tr>
1441
- <td width='250'>
1442
- <?php echo LM_CONFIG_SYSTEM_FTP?>
1443
- </td>
1444
- <td>
1445
- <div id="radioftp">
1446
- <label for="radioftp1">Direct</label><input id="radioftp1" type=radio name='system_ftptransfer' value='0' <?php if(abs($_CONFIG[system_ftptransfer])==0) echo "checked";?>>
1447
- <label for="radioftp2">Passive</label><input id="radioftp2" type=radio name='system_ftptransfer' value='1' <?php if(abs($_CONFIG[system_ftptransfer])==1) echo "checked";?>> <br>
1448
- <br /><?php echo LM_CONFIG_SYSTEM_FTP_SUB?>
1449
- </div>
1450
-
1451
- </td></tr>
1452
- <tr><td>
1453
- <?php echo LM_FTP_TRANSFER_MORE?>
1454
- </td><td>
1455
- <div id="radioftps">
1456
- <label for="radioftps1">Normal</label><input id="radioftps1" type=radio size=50 value=0 name='secure_ftp' <?php if($_CONFIG[secure_ftp]==0) echo 'checked';?>>
1457
- <label for="radioftps2">Secure(SFTP)</label><input id="radioftps2" type=radio size=50 value=1 name='secure_ftp' <?php if($_CONFIG[secure_ftp]==1) echo 'checked';?>>
1458
- </td>
1459
- </tr>
1460
-
1461
- </table>
1462
- </p></div>
1463
- </div>
1464
- <div>
1465
- <h3><a href="#"> <?php echo LM_CONFIG_MANUAL?></a></h3>
1466
- <div><p>
1467
-
1468
- <script>
1469
- jQuery(function() {
1470
- jQuery( "#slider" ).slider({
1471
- value:parseInt(<?php echo $_CONFIG[backup_refresh_number];?>),
1472
- min: 10,
1473
- max: 1000,
1474
- step: 10,
1475
- slide: function( event, ui ) {
1476
- jQuery( "#backup_refresh_number" ).val( ui.value );
1477
- }
1478
- });
1479
- jQuery( "#backup_refresh_number" ).val( jQuery( "#slider" ).slider( "value" ) );
1480
- });
1481
- jQuery(function() {
1482
- jQuery( "#sliderRPS" ).slider({
1483
- value:parseInt(<?php echo $_CONFIG[recordsPerSession];?>),
1484
- min: 100,
1485
- max: 100000,
1486
- step: 100,
1487
- slide: function( event, ui ) {
1488
- jQuery( "#recordsPerSession" ).val( ui.value );
1489
- }
1490
- });
1491
- jQuery( "#recordsPerSession" ).val( jQuery( "#sliderRPS" ).slider( "value" ) );
1492
- });
1493
- jQuery(function() {
1494
- jQuery( "#sliderEFZ" ).slider({
1495
- value:parseInt(<?php echo $_CONFIG[excludeFilesSize];?>),
1496
- min: -1,
1497
- max: 10240,
1498
- step: 1,
1499
- slide: function( event, ui ) {
1500
- jQuery( "#excludeFilesSize" ).val( ui.value );
1501
- }
1502
- });
1503
- jQuery( "#excludeFilesSize" ).val( jQuery( "#sliderEFZ" ).slider( "value" ) );
1504
- });
1505
-
1506
- jQuery(function() {
1507
- jQuery( "#sliderSBS" ).slider({
1508
- value:parseInt(<?php echo $_CONFIG[splitBackupSize];?>),
1509
- min: -1,
1510
- max: 10000,
1511
- step: 1,
1512
- slide: function( event, ui ) {
1513
- jQuery( "#splitBackupSize" ).val( ui.value );
1514
- }
1515
- });
1516
- jQuery( "#splitBackupSize" ).val( jQuery( "#sliderSBS" ).slider( "value" ) );
1517
- });
1518
- </script>
1519
-
1520
- <table class='adminform'>
1521
-
1522
- <tr><td width="250">
1523
- <?php echo LM_CONFIG_MANUAL_FILES;?>
1524
- </td><td>
1525
- <div class="sliderContainer">
1526
- <div id="slider" style="width:500px;padding:5px 0 0 0;float:left"></div>
1527
- <label for="backup_refresh_number"></label>
1528
- <input id="backup_refresh_number" type=text size=10 name='backup_refresh_number' value=<?php echo $_CONFIG[backup_refresh_number];?>>
1529
- </div>
1530
- </td></tr>
1531
-
1532
- <tr><td width="250">
1533
- <?php echo LM_CONFIG_DB_RECORDS;?>
1534
- </td><td>
1535
- <div class="sliderContainer">
1536
- <div id="sliderRPS" style="width:500px;padding:5px 0 0 0;float:left;"></div>
1537
- <label for="recordsPerSession"></label>
1538
- <input id="recordsPerSession" type=text size=10 name='recordsPerSession' value=<?php echo $_CONFIG[recordsPerSession];?>>
1539
- </div>
1540
- </td></tr>
1541
-
1542
- <tr><td width="250">
1543
- <?php echo LM_CONFIG_EXCLUDE_FILES_SIZE;?>
1544
- </td><td>
1545
- <div class="sliderContainer">
1546
- <div id="sliderEFZ" style="width:500px;padding:5px 0 0 0;float:left"></div>
1547
- <label for="excludeFilesSize"></label>
1548
- <input id="excludeFilesSize" type=text size=10 name='excludeFilesSize' value=<?php echo $_CONFIG[excludeFilesSize];?>> MB
1549
- </div>
1550
- </td></tr>
1551
-
1552
- <tr><td width="250">
1553
- <?php echo LM_CONFIG_SPLIT_BACKUP_SIZE;?>
1554
- </td><td>
1555
- <div class="sliderContainer">
1556
- <div id="sliderSBS" style="width:500px;padding:5px 0 0 0;float:left;"></div>
1557
- <label for="splitBackupSize"></label>
1558
- <input id="splitBackupSize" type=text size=10 name='splitBackupSize' value=<?php echo $_CONFIG[splitBackupSize];?>> MB
1559
- </div>
1560
-
1561
- </td></tr>
1562
-
1563
- <tr><td>
1564
- <?php echo LM_CONFIG_MANUAL_REFRESH;?>
1565
- </td><td>
1566
- <input type=text size=20 name='refresh_time' value=<?php echo $_CONFIG[refresh_time];?>> miliseconds
1567
-
1568
- </td></tr>
1569
-
1570
- <tr>
1571
- <td>
1572
- <?php echo LM_CRON_COMPRESS?>
1573
- </td>
1574
- <td>
1575
- <div id="radiog2">
1576
- <label for="radiog21"><?php echo LM_YES?></label> <input id="radiog21" type=radio size=50 value=1 name='backup_compress' <?php if($_CONFIG[backup_compress]==1) echo 'checked';?>>
1577
- <label for="radiog22"><?php echo LM_NO?></label> <input id="radiog22" type=radio size=50 value=0 name='backup_compress' <?php if($_CONFIG[backup_compress]==0) echo 'checked';?>>
1578
- <br /> <small>Note: this option might break your backup process if the Manual backup option is also enabled</small>
1579
- </div>
1580
- </td>
1581
- </tr>
1582
-
1583
- <tr><td>
1584
- <?php echo LM_REFRESH_MODE?>
1585
- </td><td>
1586
- <div id="radiorefresh">
1587
- <label for="radiorefresh1">Normal</label> <input id="radiorefresh1" type=radio size=50 value=0 name='refresh_mode' <?php if($_CONFIG[refresh_mode]==0) echo 'checked';?>>
1588
- <label for="radiorefresh2">AJAX</label> <input id="radiorefresh2" type=radio size=50 value=1 name='refresh_mode' <?php if($_CONFIG[refresh_mode]==1) echo 'checked';?>>
1589
- </div>
1590
- </td></tr>
1591
-
1592
- <tr><td>
1593
- <?php echo LM_DEBUG_MODE?>
1594
- </td><td>
1595
- <div id="radiodebug">
1596
- <label for="radiodebug1">No</label> <input id="radiodebug1" type=radio size=50 value=0 name='debug' <?php if($_CONFIG[debug]==0) echo 'checked';?>>
1597
- <label for="radiodebug2">Yes</label> <input id="radiodebug2" type=radio size=50 value=1 name='debug' <?php if($_CONFIG[debug]==1) echo 'checked';?>>
1598
- </td></tr>
1599
- </table>
1600
-
1601
- </p></div>
1602
- </div>
1603
-
1604
- </div>
1605
- <?php
1606
- $tabs->endTab();
1607
- $tabs->startTab(LM_TAB_CRON,"5");
1608
- ?>
1609
- <div id="configtabinside">
1610
-
1611
- <div>
1612
- <h3><a href="#"> <?php echo LM_CRON_SETTINGS_M?> - all configs are saved in directory configs/ </a></h3>
1613
- <div><p>
1614
- <table class='adminform'>
1615
-
1616
- <tr>
1617
- <td width='250'>
1618
- <?php echo LM_CRON_MCRON?>
1619
- </td>
1620
- <td>
1621
- <input type=text size=30 value="<?php echo $_CONFIG[cron_save_as]?>" name='cron_save_as' >.php <br />
1622
- <?php echo LM_CRON_MCRON_SUB?>
1623
- </td>
1624
- </tr>
1625
-
1626
- <tr>
1627
- <td>
1628
- <?php echo LM_CRON_MCRON_AVAIL?>
1629
- </td>
1630
- <td>
1631
- <?php
1632
-
1633
- if ($handle = opendir($_CONFIG['multiple_config_dir'])) {
1634
-
1635
- while (false !== ($file = readdir($handle))) {
1636
- if( ($file!=".") && ($file!="..") &&($file!="") && (strstr($file, '.php'))){
1637
- $fcron = plugins_url('cloner.cron.php', __FILE__)."?config=$file";
1638
-
1639
- echo "<b>$fcron</b>";
1640
-
1641
- echo " - <a href='$fcron' target='_blank'>execute cron</a>";
1642
-
1643
- echo " | <a href='plugins.php?page=xcloner_show&option=com_cloner&task=cron_delete&fconfig=$file'>delete config</a>";
1644
-
1645
- echo "\n<br />";
1646
- }
1647
- }
1648
-
1649
- closedir($handle);
1650
- }
1651
- ?>
1652
- </td>
1653
- </tr>
1654
- </table>
1655
- </p></div>
1656
- </div>
1657
-
1658
- <div>
1659
- <h3><a href="#"> <?php echo LM_CRON_SETTINGS?></a></h3>
1660
- <div><p>
1661
- <table class='adminform'>
1662
-
1663
- <tr>
1664
- <td width='250'>
1665
- <?php echo LM_CRON_SEMAIL?>
1666
- </td>
1667
- <td>
1668
- <input type=text size=30 value="<?php echo $_CONFIG[cron_logemail]?>" name='cron_logemail' > <br />
1669
- <?php echo LM_CRON_SEMAIL_SUB?>
1670
- </td>
1671
- </tr>
1672
-
1673
- <tr>
1674
- <td>
1675
- <?php echo LM_CRON_MODE?>
1676
- </td>
1677
- <td>
1678
-
1679
- <div id="radio">
1680
- <input id="radio1" type=radio size=50 value=0 name='cron_send' <?php if($_CONFIG[cron_send]==0) echo 'checked';?>>
1681
- <label for="radio1"><?php echo LM_CONFIG_CRON_LOCAL?></label>
1682
- <input id="radio2" type=radio size=50 value=1 name='cron_send' <?php if($_CONFIG[cron_send]==1) echo 'checked';?>>
1683
- <label for="radio2"><?php echo LM_CONFIG_CRON_REMOTE?></label>
1684
- <input id="radio3" type=radio size=50 value=2 name='cron_send' <?php if($_CONFIG[cron_send]==2) echo 'checked';?>>
1685
- <label for="radio3"><?php echo LM_CONFIG_CRON_EMAIL?></label>
1686
- </div>
1687
- <?php echo LM_CRON_MODE_INFO?>
1688
- </td>
1689
- </tr>
1690
-
1691
-
1692
- <tr>
1693
- <td>
1694
- <?php echo LM_CRON_TYPE?>
1695
- </td>
1696
- <td>
1697
- <div id="radiob">
1698
- <input id="radiob1" type=radio size=50 value=0 name='cron_btype' <?php if($_CONFIG[cron_btype]==0) echo 'checked';?>>
1699
- <label for="radiob1"><?php echo LM_CONFIG_CRON_FULL?></label>
1700
- <input id="radiob2" type=radio size=50 value=1 name='cron_btype' <?php if($_CONFIG[cron_btype]==1) echo 'checked';?>>
1701
- <label for="radiob2"><?php echo LM_CONFIG_CRON_FILES?></label>
1702
- <input id="radiob3" type=radio size=50 value=2 name='cron_btype' <?php if($_CONFIG[cron_btype]==2) echo 'checked';?>>
1703
- <label for="radiob3"><?php echo LM_CONFIG_CRON_DATABASE?></label>
1704
- <?php echo LM_CRON_TYPE_INFO?>
1705
- </div>
1706
- </td>
1707
- </tr>
1708
-
1709
- <tr>
1710
- <td>
1711
- <?php echo LM_CRON_BNAME?>
1712
- </td>
1713
- <td>
1714
- <input type=text size=50 value="<?php echo $_CONFIG[cron_bname]?>" name='cron_bname' > <br />
1715
- <?php echo LM_CRON_BNAME_SUB?>
1716
- </td>
1717
- </tr>
1718
-
1719
-
1720
- <!-- <tr>
1721
- <td>
1722
- <?php echo LM_CRON_IP?>
1723
- </td>
1724
- <td>
1725
- <textarea type=text size=50 name='cron_ip' cols='30' rows='5'><?php echo $_CONFIG[cron_ip]?></textarea> <br />
1726
- <?php echo LM_CRON_IP_SUB?>
1727
- </td>
1728
- </tr>-->
1729
- </table>
1730
- </p></div>
1731
- </div>
1732
-
1733
- <div>
1734
- <h3><a href="#"> <?php echo LM_CRON_FTP_DETAILS?></a></h3>
1735
- <div><p>
1736
- <table class='adminform'>
1737
-
1738
- <tr>
1739
- <td width='250'>
1740
- <?php echo LM_CRON_FTP_SERVER?>
1741
- </td>
1742
- <td>
1743
- <input type=text size=50 name='cron_ftp_server' value='<?php echo $_CONFIG[cron_ftp_server]?>'>
1744
- </td>
1745
- </tr>
1746
- <tr>
1747
- <td>
1748
- <?php echo LM_CRON_FTP_USER?>
1749
- </td>
1750
- <td>
1751
- <input type=text size=50 name='cron_ftp_user' value='<?php echo $_CONFIG[cron_ftp_user]?>'>
1752
- </td>
1753
- </tr>
1754
- <tr>
1755
- <td>
1756
- <?php echo LM_CRON_FTP_PASS?>
1757
- </td>
1758
- <td>
1759
- <input type=password size=50 name='cron_ftp_pass' value='<?php echo $_CONFIG[cron_ftp_pass]?>'>
1760
- </td>
1761
- </tr>
1762
- <tr>
1763
- <td>
1764
- <?php echo LM_CRON_FTP_PATH?>
1765
- </td>
1766
- <td>
1767
- <input type=text size=50 name='cron_ftp_path' value='<?php echo $_CONFIG[cron_ftp_path]?>'>
1768
- </td>
1769
- </tr>
1770
- <tr>
1771
- <td>
1772
- <!--<?php echo LM_CRON_FTP_DELB?>-->
1773
- </td>
1774
- <td>
1775
- <input id="cron_ftp_delb" type=checkbox name='cron_ftp_delb' <?php if($_CONFIG[cron_ftp_delb]==1) echo "checked";?> value='1'>
1776
- <label for="cron_ftp_delb"><?php echo LM_CRON_FTP_DELB?></label>
1777
- </td>
1778
- </tr>
1779
- </table>
1780
- </p></div>
1781
- </div>
1782
-
1783
- <div>
1784
- <h3><a href="#"> <?php echo LM_AMAZON_S3?></a></h3>
1785
- <div><p>
1786
- <table class='adminform'>
1787
-
1788
- <tr>
1789
- <td width='250'>
1790
- <?php #echo LM_AMAZON_S3_ACTIVATE?>
1791
- </td>
1792
- <td>
1793
- <label for="cron_amazon_active"><?php echo LM_AMAZON_S3_ACTIVATE?></label>
1794
- <input id="cron_amazon_active" type=checkbox name='cron_amazon_active' <?php if($_CONFIG[cron_amazon_active]==1) echo "checked";?> value='1'>
1795
-
1796
- <label for="cron_amazon_ssl"><?php echo LM_AMAZON_S3_SSL?></label>
1797
- <input id="cron_amazon_ssl" type=checkbox name='cron_amazon_ssl' <?php if($_CONFIG[cron_amazon_ssl]==1) echo "checked";?> value='1'>
1798
- </td>
1799
- </tr>
1800
-
1801
- <tr>
1802
- <td>
1803
- <?php echo LM_AMAZON_S3_AWSACCESSKEY;?>
1804
- </td>
1805
- <td>
1806
- <input type=text size=50 name='cron_amazon_awsAccessKey' value="<?php echo $_CONFIG['cron_amazon_awsAccessKey'];?>">
1807
- </td>
1808
- </tr>
1809
-
1810
- <tr>
1811
- <td>
1812
- <?php echo LM_AMAZON_S3_AWSSECRETKEY;?>
1813
- </td>
1814
- <td>
1815
- <input type=text size=50 name='cron_amazon_awsSecretKey' value="<?php echo $_CONFIG['cron_amazon_awsSecretKey'];?>">
1816
- </td>
1817
- </tr>
1818
-
1819
- <tr>
1820
- <td width='200'>
1821
- <?php echo LM_AMAZON_S3_BUCKET;?>
1822
- </td>
1823
- <td>
1824
- <input type=text size=50 name='cron_amazon_bucket' value="<?php echo $_CONFIG['cron_amazon_bucket'];?>">
1825
- </td>
1826
- </tr>
1827
-
1828
- <tr>
1829
- <td>
1830
- <?php echo LM_AMAZON_S3_DIRNAME;?>
1831
- </td>
1832
- <td>
1833
- <input type=text size=50 name='cron_amazon_dirname' value="<?php echo $_CONFIG['cron_amazon_dirname'];?>">
1834
- </td>
1835
- </tr>
1836
- </tr>
1837
- </table>
1838
- </p></div>
1839
- </div>
1840
-
1841
- <div>
1842
- <h3><a href="#"> <?php echo LM_DROPBOX?></a></h3>
1843
- <div><p>
1844
- <table class='adminform'>
1845
-
1846
- <tr>
1847
- <td width='250'>
1848
- <?php #echo LM_AMAZON_S3_ACTIVATE?>
1849
- </td>
1850
- <td>
1851
- <label for="cron_dropbox_active"><?php echo LM_DROPBOX_ACTIVATE?></label>
1852
- <input id="cron_dropbox_active" type=checkbox name='cron_dropbox_active' <?php if($_CONFIG['cron_dropbox_active']==1) echo "checked";?> value='1'>
1853
- <?php
1854
- $access_token = load_token("access");
1855
- if(empty($access_token) and $_CONFIG["cron_dropbox_active"]){
1856
- ?>
1857
- <a target="_blank" href="?page=xcloner_show&task=dropbox_authorize"><?php echo LM_DROPBOX_AUTHORIZE?></a>
1858
- <?php
1859
- }
1860
- ?>
1861
- </td>
1862
- </tr>
1863
-
1864
- <tr>
1865
- <td>
1866
- <?php echo LM_DROPBOX_AWSACCESSKEY;?>
1867
- </td>
1868
- <td>
1869
- <input type=text size=50 name='cron_dropbox_Key' value="<?php echo $_CONFIG['cron_dropbox_Key'];?>">
1870
- </td>
1871
- </tr>
1872
-
1873
- <tr>
1874
- <td>
1875
- <?php echo LM_DROPBOX_AWSSECRETKEY;?>
1876
- </td>
1877
- <td>
1878
- <input type=text size=50 name='cron_dropbox_Secret' value="<?php echo $_CONFIG['cron_dropbox_Secret'];?>">
1879
- </td>
1880
- </tr>
1881
-
1882
- <tr>
1883
- <td>
1884
- <?php echo LM_DROPBOX_DIRNAME;?>
1885
- </td>
1886
- <td>
1887
- <input type=text size=50 name='cron_dropbox_dirname' value="<?php echo $_CONFIG['cron_dropbox_dirname'];?>">
1888
- </td>
1889
- </tr>
1890
- </tr>
1891
-
1892
- </tr>
1893
- </table>
1894
- </p></div>
1895
- </div>
1896
-
1897
- <div>
1898
- <h3><a href="#"> <?php echo LM_CRON_EMAIL_DETAILS?></a></h3>
1899
- <div><p>
1900
- <table class='adminform'>
1901
-
1902
- <tr>
1903
- <td width="250">
1904
- <?php echo LM_CRON_EMAIL_ACCOUNT?>
1905
- </td>
1906
- <td>
1907
- <input type=text size=50 name='cron_email_address' value='<?php echo $_CONFIG[cron_email_address]?>'>
1908
- </td>
1909
- </tr>
1910
- </table>
1911
- </p></div>
1912
- </div>
1913
-
1914
- <div>
1915
- <h3><a href="#"> <?php echo LM_CRON_MYSQL_DETAILS?></a></h3>
1916
- <div><p>
1917
- <table class='adminform'>
1918
-
1919
- <tr bgcolor='#ffffff'>
1920
- <td width='250'>
1921
- <?php #echo LM_CRON_MYSQL_DROP?>
1922
- </td>
1923
- <td>
1924
- <label for="cron_sql_drop"><?php echo LM_CRON_MYSQL_DROP?></label>
1925
- <input id="cron_sql_drop" type=checkbox name='cron_sql_drop' value='1' <?php if($_CONFIG[cron_sql_drop]) echo "checked";?> >
1926
- </td>
1927
- </tr>
1928
-
1929
- <?php
1930
- if((abs($_CONFIG['system_mdatabases'])==0) && ($_CONFIG['enable_db_backup']==1) ){
1931
- ?>
1932
- <tr><td valign='top'>
1933
- <?php echo LM_DATABASE_INCLUDE_DATABASES?>
1934
- </td><td>
1935
- <select name='databases_incl[]' MULTIPLE SIZE=5>
1936
- <?php
1937
-
1938
- $curent_dbs = explode(",", $_CONFIG['databases_incl_list']);
1939
-
1940
- $query = @$_CONFIG['mysqli']->query("SHOW databases");
1941
-
1942
- if($query)
1943
- while($row = @$query->fetch_array()){
1944
-
1945
- $table = $row[0];
1946
-
1947
- if($table != $_CONFIG['mysql_database'])
1948
-
1949
- if(in_array($table, $curent_dbs)){
1950
-
1951
- echo "<option value='".$table."' selected>$table</option>";
1952
-
1953
- }else{
1954
-
1955
- echo "<option value='".$table."'>$table</option>";
1956
-
1957
- }
1958
- }
1959
- ?>
1960
- </select><br />
1961
- <?php echo LM_DATABASE_INCLUDE_DATABASES_SUB?>
1962
- </td></tr>
1963
- <?php
1964
- }
1965
- ?>
1966
- </table>
1967
- </p></div>
1968
- </div>
1969
-
1970
- <div>
1971
- <h3><a href="#"> <?php echo LM_CRON_DELETE_FILES?></a></h3>
1972
- <div><p>
1973
-
1974
- <script>
1975
- jQuery(function() {
1976
- jQuery( "#slider2" ).slider({
1977
- value:parseInt(<?php echo (int)$_CONFIG[cron_file_delete];?>),
1978
- min: 0,
1979
- max: 100,
1980
- step: 1,
1981
- slide: function( event, ui ) {
1982
- jQuery( "#cron_file_delete" ).val( ui.value );
1983
- }
1984
- });
1985
- jQuery( "#cron_file_delete" ).val( jQuery( "#slider2" ).slider( "value" ) );
1986
- });
1987
- </script>
1988
-
1989
- <table class='adminform'>
1990
-
1991
- <tr>
1992
- <td width='250'>
1993
- <?php #echo LM_CRON_DELETE_FILES_SUB_ACTIVE?>
1994
- </td>
1995
- <td>
1996
- <label for="cron_file_delete_act"><?php echo LM_CRON_DELETE_FILES_SUB_ACTIVE?></label>
1997
- <input id="cron_file_delete_act" type=checkbox name='cron_file_delete_act' <?php if ($_CONFIG['cron_file_delete_act'] == 1) echo 'checked';?> value='1'>
1998
- </td>
1999
- </tr>
2000
- <tr>
2001
- <td>
2002
- <?php echo LM_CRON_DELETE_FILES_SUB?>
2003
- </td>
2004
- <td>
2005
- <div id="slider2" style="width:300px;padding-top:5px;"></div>
2006
- <br /><label for="cron_file_delete"></label>
2007
- <input id="cron_file_delete" size=5 name='cron_file_delete' value='<?php echo $_CONFIG[cron_file_delete]?>'> days:
2008
- </td>
2009
- </tr>
2010
- </table>
2011
-
2012
- <table class='adminform'>
2013
- <tr>
2014
- <th colspan='2'>
2015
- <?php echo LM_CRON_EXCLUDE?>
2016
- </th>
2017
- </tr>
2018
- </tr>
2019
- <tr>
2020
- <td width='250'>
2021
- <?php echo LM_CRON_EXCLUDE_DIR?>
2022
- </td>
2023
- <td>
2024
- <textarea cols=50 rows=5 name='cron_exclude'><?php echo $_CONFIG[cron_exclude]?></textarea>
2025
- </td>
2026
- </tr>
2027
-
2028
- </table>
2029
- </p></div>
2030
- </div>
2031
-
2032
- </div>
2033
- <?php
2034
- $tabs->endTab();
2035
- $tabs->startTab(LM_TAB_INFO,"6");
2036
- ?>
2037
-
2038
- <div id="configtabinside">
2039
- <div>
2040
- <h3><a href="#"><?php echo LM_CONFIG_INFO_PHP?></a></h3>
2041
- <div><p>
2042
-
2043
- <table class='adminform'>
2044
-
2045
- <tr>
2046
- <td width='250'>
2047
- <?php echo LM_CONFIG_INFO_T_VERSION?>
2048
- </td>
2049
- <td>
2050
- <b><?php
2051
- $version = phpversion();
2052
- $ver = str_replace(".", "", $version);
2053
- $val = (version_compare(PHP_VERSION, '5.2.3') < 0)? $version: "Off";
2054
- echo HTML_cloner::get_color($version, $val);
2055
- ?></b>
2056
- <br />
2057
- <?php echo LM_CONFIG_INFO_VERSION?>
2058
- </td>
2059
- </tr>
2060
-
2061
- <tr>
2062
- <td>
2063
- <?php echo LM_CONFIG_INFO_T_SAFEMODE?>
2064
- </td>
2065
- <td>
2066
- <b><?php $val = (ini_get('safe_mode') != "")? ini_get('safe_mode'):"Off";
2067
- echo HTML_cloner::get_color($val, 'On');
2068
- ?></b>
2069
- <br />
2070
- <?php echo LM_CONFIG_INFO_SAFEMODE?>
2071
- </td>
2072
- </tr>
2073
-
2074
- <tr>
2075
- <td>
2076
- <?php echo LM_CONFIG_INFO_T_MTIME?>
2077
- </td>
2078
- <td>
2079
- <b><?php echo (ini_get('max_execution_time') != "")? ini_get('max_execution_time'):"no value";
2080
-
2081
- ?></b>
2082
- <br />
2083
- <?php echo LM_CONFIG_INFO_TIME?>
2084
- </td>
2085
- </tr>
2086
-
2087
- <tr>
2088
- <td>
2089
- <?php echo LM_CONFIG_INFO_T_MEML?>
2090
- </td>
2091
- <td>
2092
- <b><?php echo (ini_get('memory_limit') != "")? ini_get('memory_limit'):"no value";?> </b>
2093
- <br />
2094
- <?php echo LM_CONFIG_INFO_MEMORY?>
2095
- </td>
2096
- </tr>
2097
-
2098
- <tr>
2099
- <td>
2100
- <?php echo LM_CONFIG_INFO_T_BDIR?>
2101
- </td>
2102
- <td>
2103
- <b><?php $val = (ini_get('open_basedir') != "")? ini_get('open_basedir'):"no value";
2104
- echo HTML_cloner::get_color($val, '/');
2105
- ?> </b>
2106
- <br />
2107
- <?php echo LM_CONFIG_INFO_BASEDIR?>
2108
- </td>
2109
- </tr>
2110
-
2111
- <tr>
2112
- <td>
2113
- <?php echo LM_CONFIG_INFO_T_EXEC?>
2114
- </td>
2115
- <td>
2116
- <b><?php
2117
-
2118
- $out = "";
2119
- if(function_exists("exec")){
2120
-
2121
- $out = @exec("ls -al");
2122
- }
2123
-
2124
- $val = ($out != "")? "ENABLED":"<font color='red'>DISABLED</font>";
2125
- echo HTML_cloner::get_color($val, 'DISABLED');
2126
- ?> </b>
2127
- <br />
2128
- <?php echo LM_CONFIG_INFO_EXEC?>
2129
- </td>
2130
- </tr>
2131
- </table>
2132
- </p></div>
2133
- </div>
2134
- <div>
2135
- <h3><a href="#"><?php echo LM_CONFIG_INFO_PATHS?></a></h3>
2136
- <div><p>
2137
- <table class='adminform'>
2138
-
2139
- <tr>
2140
- <td width='250'>
2141
- <?php echo LM_CONFIG_INFO_ROOT_BPATH_TMP?>
2142
- </td>
2143
- <td>
2144
- <b><?php $tmp_dir = realpath($_CONFIG['backup_path']."/administrator/backups");
2145
- echo (@is_writeable( $tmp_dir ))? $tmp_dir . " is <font color=green>writeable</font>":$tmp_dir. " <font color=red>incorrect or unreadable</font>";?></b>
2146
- <br />
2147
- <?php echo LM_CONFIG_INFO_ROOT_PATH_TMP_SUB?>
2148
- </td>
2149
- </tr>
2150
-
2151
- <tr>
2152
- <td>
2153
- <?php echo LM_CONFIG_INFO_ROOT_BPATH?>
2154
- </td>
2155
- <td>
2156
- <b><?php echo (@is_readable($_CONFIG['backup_path']) )? $_CONFIG['backup_path'] . " is <font color=green>readable</font>":$_CONFIG['backup_path']. " <font color=red>incorrect or unreadable</font>";?></b>
2157
- <br />
2158
- <?php echo LM_CONFIG_INFO_ROOT_PATH_SUB?>
2159
- </td>
2160
- </tr>
2161
-
2162
-
2163
- <tr>
2164
- <td>
2165
- <?php echo LM_CONFIG_INFO_T_BPATH?>
2166
- </td>
2167
- <td>
2168
- <b><?php echo (@is_writeable($_CONFIG['clonerPath']) )? $_CONFIG['clonerPath'] . " is <font color=green>writeable</font>":$_CONFIG['clonerPath']. " <font color=red>unwriteable</font>";?></b>
2169
- <br />
2170
- <?php echo LM_CONFIG_INFO_BPATH?>
2171
- </td>
2172
- </tr>
2173
-
2174
-
2175
- <tr>
2176
- <td>
2177
- <?php echo LM_CONFIG_INFO_T_TAR?>
2178
- </td>
2179
- <td>
2180
- <b><?php
2181
- if(function_exists('exec')){
2182
- $info_tar_path = explode(" ", @exec("whereis tar"));
2183
- }
2184
- echo ($info_tar_path['1'] != "")? $info_tar_path['1']:"unable to determine";
2185
- ?> </b>
2186
- <br />
2187
- <?php echo LM_CONFIG_INFO_TAR?>
2188
- </td>
2189
- </tr>
2190
-
2191
-
2192
- <tr>
2193
- <td>
2194
- <?php echo LM_CONFIG_INFO_T_MSQL?>
2195
- </td>
2196
- <td>
2197
- <b><?php
2198
- if(function_exists('exec')){
2199
- $info_msql_path = explode(" ", @exec("whereis mysqldump"));
2200
- }
2201
- echo ($info_msql_path['1'] != "")? $info_msql_path['1']:"unable to determine";
2202
- ?> </b>
2203
- <br />
2204
- <?php echo LM_CONFIG_INFO_MSQL?>
2205
- </td>
2206
- </tr>
2207
-
2208
- </table>
2209
- </p></div>
2210
-
2211
- </div></div>
2212
-
2213
- <?php
2214
- $tabs->endTab();
2215
- $tabs->endPane();
2216
- ?>
2217
- <input type="hidden" name="option" value="com_cloner" />
2218
- <input type="hidden" name="task" value="config" />
2219
- <input type="hidden" name='action' value='save'>
2220
- <?php wp_nonce_field('save','csrf'); ?>
2221
- </form>
2222
-
2223
- <?php
2224
- }
2225
-
2226
- function get_color($val, $comp){
2227
-
2228
- if(!stristr($val, $comp))
2229
- echo "<span style='color:green'>$val</span>";
2230
- else
2231
- echo "<span style='color:red'>$val</span>";
2232
-
2233
- }
2234
-
2235
- function TransferForm($option, $files){
2236
- global $baDownloadPath, $mosConfig_absolute_path, $clonerPath, $task;
2237
-
2238
- ?>
2239
- <form action="" method="POST" name="adminForm">
2240
- <script language="javascript" type="text/javascript">
2241
-
2242
-
2243
- function submitbutton(pressbutton) {
2244
- var form = document.adminForm;
2245
- if (pressbutton == 'cancel') {
2246
- submitform( pressbutton );
2247
- return;
2248
- }
2249
-
2250
- submitform( pressbutton );
2251
-
2252
- }
2253
-
2254
- function gotocontact( id ) {
2255
- var form = document.adminForm;
2256
- form.contact_id.value = id;
2257
- submitform( 'contact' );
2258
- }
2259
- </script>
2260
- <table class='adminform'>
2261
- <tr><td colspan='2'>
2262
- <b>Transfer <?php echo $file;?> details:</b>
2263
- <br /><b>Attempting to
2264
- <?php echo (($_REQUEST[task]=='move')||($_REQUEST[task2]=='move'))?'Move':'Clone';?> backup(s):</b><br /><?php echo implode("<br />",$files)?>
2265
-
2266
- </td></tr>
2267
- <tr><td colspan='2'><?php echo LM_CLONE_FORM_TOP?></td></tr>
2268
- <?php
2269
- if(($_REQUEST[task]=='move')||($_REQUEST[task2]=='move')){
2270
- }
2271
- else{
2272
-
2273
- ?>
2274
- <tr>
2275
- <td width='110'><b><?php echo LM_TRANSFER_URL?></b> </td>
2276
- <td><input type='text' size='30' name='ftp_url' value='<?php echo $_REQUEST[ftp_url]?>'></td>
2277
- </tr>
2278
- <tr>
2279
- <td colspan='2'><?php echo LM_TRANSFER_URL_SUB?></td>
2280
- </tr>
2281
- <?php } ?>
2282
- <tr>
2283
- <td width='110'><b><?php echo LM_TRANSFER_FTP_HOST?></b> </td>
2284
- <td><input type='text' size='30' name='ftp_server' value='<?php echo $_REQUEST[ftp_server]?>'></td>
2285
- </tr>
2286
- <tr>
2287
- <td colspan='2'><small><?php echo LM_TRANSFER_FTP_HOST_SUB?></small></td></tr>
2288
- <tr>
2289
- <td width='110'><b><?php echo LM_TRANSFER_FTP_USER?></b> </td>
2290
- <td><input type='text' size='30' name='ftp_user' value='<?php echo $_REQUEST[ftp_user]?>'></td>
2291
- </tr>
2292
- <tr>
2293
- <td colspan='2'><small><?php echo LM_TRANSFER_FTP_USER_SUB?></small></td></tr>
2294
- <tr>
2295
- <td width='110'><b><?php echo LM_TRANSFER_FTP_PASS?></b> </td>
2296
- <td><input type='text' size='30' name='ftp_pass' value='<?php echo $_REQUEST[ftp_pass]?>'></td>
2297
- </tr>
2298
- <tr>
2299
- <td colspan='2'><small><?php echo LM_TRANSFER_FTP_PASS_SUB?></small></td></tr>
2300
- <tr>
2301
- <td width='110'><b><?php echo LM_TRANSFER_FTP_DIR?></b> </td>
2302
- <td><input type='text' size='30' name='ftp_dir' value='<?php echo $_REQUEST[ftp_dir]?>'></td>
2303
- </tr>
2304
- <tr>
2305
- <td colspan='2'><small><?php echo LM_TRANSFER_FTP_DIR_SUB?></small></td></tr>
2306
-
2307
- <tr>
2308
- <td width='140'><b><?php echo LM_TRANSFER_FTP_INCT?></b> </td>
2309
- <td><input type='checkbox' name='ftp_inct' value='1' <?php if($_REQUEST[ftp_inct] ==1 ) echo "checked";?>></td>
2310
- </tr>
2311
- <tr>
2312
- <td colspan='2'><small><?php echo LM_TRANSFER_FTP_INCT_SUB?></small></td></tr>
2313
-
2314
- </table>
2315
- <input type="hidden" name="option" value="com_cloner" />
2316
- <input type="hidden" name="task" value="" />
2317
- <input type="hidden" name="task2" value="<?php if($_REQUEST[task2]!="") echo $_REQUEST[task2]; else echo $task;?>" />
2318
- <?php
2319
- foreach($files as $key=>$value)
2320
- {
2321
- ?>
2322
- <input type="hidden" name="files[<?php echo $key;?>]" value="<?php echo $value?>" />
2323
- <input type="hidden" name="cid[<?php echo $key;?>]" value="<?php echo $value?>" />
2324
- <?php
2325
- }
2326
- ?>
2327
- <input type="hidden" name="action" value="connect" />
2328
- <input type="hidden" name="hidemainmenu" value="0" />
2329
- <?php wp_nonce_field('transfer','csrf'); ?>
2330
- </form>
2331
- <?php
2332
- }
2333
- function confirmBackups( &$folders, &$sizes, $path, $option ) {
2334
- // ----------------------------------------------------------
2335
- // Presentation of the confirmation screen
2336
- // ----------------------------------------------------------
2337
- global $baDownloadPath, $mosConfig_absolute_path, $clonerPath, $_CONFIG, $database, $mosConfig_db;
2338
-
2339
- ?>
2340
- <form action="" method="post" name="adminForm">
2341
- <?php
2342
- $tabs = new mosTabs(1);
2343
- ?>
2344
-
2345
- <script>
2346
- jQuery(function() {
2347
- jQuery( "#tabs" ).tabs().find( ".ui-tabs-nav" ).sortable({ axis: "x" });
2348
- jQuery( "#radio_dbbackup" ).buttonset();
2349
- jQuery( "#radio_dbbackup1" ).button( { icons: {primary:'ui-icon-bullet'} } );
2350
- jQuery( "#radio_dbbackup2" ).button( { icons: {primary:'ui-icon-bullet'} } );
2351
- });
2352
- </script>
2353
-
2354
-
2355
- <ul>
2356
- <?php
2357
- if($_CONFIG['enable_db_backup']){
2358
- ?>
2359
- <li><a href="#tabs-users-databse-options-tab"><?php echo LM_TAB_G_DATABASE;?></a></li>
2360
- <?php }?>
2361
- <li><a href="#tabs-users-files-options-tab"><?php echo LM_TAB_G_FILES;?></a></li>
2362
- <li><a href="#tabs-users-comments-options-tab"><?php echo LM_TAB_G_COMMENTS;?></a></li>
2363
- </ul>
2364
-
2365
- <?php
2366
- #$tabs->startPane("BGeneratePane");
2367
- if($_CONFIG['enable_db_backup']){
2368
- $tabs->startTab(LM_TAB_G_DATABASE,"users-databse-options-tab");
2369
- ?>
2370
-
2371
- <div id="radio_dbbackup">
2372
- <table class="adminform">
2373
- <tr>
2374
- <td>
2375
- <label for="radio_dbbackup1"><?php echo LM_CONFIRM_DATABASE; ?></label>
2376
- <input id="radio_dbbackup1" type="checkbox" id="dbbackup" name="dbbackup" checked value="1" />
2377
- &nbsp;<label for="radio_dbbackup2">Add DROP SYNTAX</label>
2378
- <input id="radio_dbbackup2" type="checkbox" id="dbbackup_drop" name="dbbackup_drop" value="1" />
2379
- </td>
2380
- </tr>
2381
- <tr>
2382
- <td><?php echo "Mysql Compatibility"; ?> &nbsp;
2383
- <select name='dbbackup_comp'>
2384
- <option value=''>Default</option>
2385
- <option value='MYSQL40'>MYSQL40</option>
2386
- <option balue='MYSQL323'>MYSQL323</option>
2387
- </select>
2388
- </td>
2389
- </tr>
2390
- <tr><th colspan=2>
2391
- <?php echo LM_DATABASE_EXCLUDE_TABLES?>
2392
- </th></tr>
2393
- <tr><td>
2394
- <?php echo LM_DATABASE_CURRENT?> <b><?php echo $_CONFIG['mysql_database'];?></b><br />
2395
- <select name='excltables[]' MULTIPLE SIZE=15>
2396
- <?php
2397
-
2398
- $query = $_CONFIG['mysqli']->query("SHOW tables");
2399
- while($row = $query->fetch_array()){
2400
-
2401
- echo "<option value='".$row[0]."'>$row[0]</option>";
2402
-
2403
- }
2404
- ?>
2405
- </select>
2406
- </td></tr>
2407
-
2408
- <?php
2409
- if(abs($_CONFIG[system_mdatabases])==0){
2410
- ?>
2411
-
2412
- <tr><th colspan=2>
2413
- <?php echo LM_DATABASE_INCLUDE_DATABASES?>
2414
- </th></tr>
2415
- <tr><td>
2416
- <select name='databases_incl[]' MULTIPLE SIZE=5>
2417
- <?php
2418
-
2419
- $query = $_CONFIG['mysqli']->query("SHOW databases");
2420
-
2421
- if($query)
2422
- while($row = $query->fetch_array()){
2423
-
2424
- if($_CONFIG['mysql_database'] != $row[0])
2425
- echo "<option value='".$row[0]."'>$row[0]</option>";
2426
-
2427
- }
2428
-
2429
- ?>
2430
- </select><br />
2431
- <?php echo LM_DATABASE_INCLUDE_DATABASES_SUB?>
2432
- </td></tr>
2433
-
2434
- <?php
2435
- }
2436
- ?>
2437
-
2438
- </table>
2439
- </div>
2440
- <?php
2441
- $tabs->endTab();
2442
- }
2443
- $tabs->startTab(LM_TAB_G_FILES,"users-files-options-tab");
2444
- ?>
2445
- <table class="adminform">
2446
- <tr>
2447
- <th>
2448
- <b><?php echo LM_BACKUP_NAME; ?></b>
2449
- </th>
2450
- </tr>
2451
- <tr>
2452
- <td>
2453
- <input type=text name='bname' value='' size=100><br/>
2454
- <?php echo LM_BACKUP_NAME_SUB?>
2455
- </td>
2456
- </tr>
2457
-
2458
- <tr>
2459
- <td width="50%"><?php echo LM_CONFIRM_INSTRUCTIONS ?></td>
2460
- </tr>
2461
- </table>
2462
- <table class="adminlist" >
2463
- <tr>
2464
- <th width="200" valign='top' colspan='2' align='left'>
2465
-
2466
- <?php echo LM_COL_FOLDER ?>
2467
- <?php
2468
- {
2469
- ?>
2470
- <tr><td>
2471
- <link href="<?php echo plugins_url('browser/filebrowser.css', __FILE__) ?>" rel="stylesheet" type="text/css">
2472
-
2473
- <script type="text/javascript" src="<?php echo plugins_url('browser/xmlhttp.js', __FILE__) ?>"></script>
2474
-
2475
-
2476
- <div id="browser">
2477
- <?php require_once("browser/files_inpage.php"); ?>
2478
- </div>
2479
- <script>do_browser()</script>
2480
-
2481
- </td></tr>
2482
- <?php
2483
- }
2484
- ?>
2485
-
2486
- </table>
2487
- <?php
2488
- $tabs->endTab();
2489
- $tabs->startTab(LM_TAB_G_COMMENTS,"users-comments-options-tab");
2490
- ?>
2491
- <div class="mainText">
2492
- <h2><?php echo LM_TAB_G_COMMENTS_H2?></h2>
2493
- <textarea name="backupComments" rows=20 cols=80></textarea>
2494
- <br /><small> <?php echo LM_TAB_G_COMMENTS_NOTE?></small>
2495
- </div>
2496
- <?php
2497
- $tabs->endTab();
2498
- $tabs->endPane();
2499
- ?>
2500
- <input type="hidden" name="option" value="com_cloner" />
2501
- <input type="hidden" name="task" value="" />
2502
- <input type="hidden" name="boxchecked" value="0" />
2503
- <input type="hidden" name="hidemainmenu" value="0" />
2504
- <?php wp_nonce_field('generate','csrf'); ?>
2505
- </form>
2506
- <br/>&nbsp;
2507
- <?php
2508
- }
2509
-
2510
-
2511
- function generateBackup( $archiveName, $archiveSize, $originalSize, $d, $f, $databaseResult, $option ) {
2512
- // ----------------------------------------------------------
2513
- // Presentation of the final report screen
2514
- // ----------------------------------------------------------
2515
-
2516
-
2517
- ?>
2518
- <table cellpadding="4" cellspacing="0" border="0" width="100%">
2519
-
2520
- <table border="0" align="center" cellspacing="0" cellpadding="2" width="100%" class="adminform">
2521
- </tr>
2522
- <tr>
2523
- <td width="20%"><strong>&nbsp;</strong></td><td>&nbsp;</td>
2524
- </tr>
2525
- <tr>
2526
- <td><strong>&nbsp;<?php echo LM_ARCHIVE_NAME; ?></strong></td><td><?php echo $archiveName; ?></td>
2527
- </tr>
2528
- <tr>
2529
- <td><strong>&nbsp;<?php echo LM_NUMBER_FILES; ?></strong></td><td><?php echo $f; ?></td>
2530
- </tr>
2531
- <tr>
2532
- <td><strong>&nbsp;<?php echo LM_SIZE_ORIGINAL; ?></strong></td><td><?php echo $originalSize; ?></td>
2533
- </tr>
2534
- <tr>
2535
- <td><strong>&nbsp;<?php echo LM_SIZE_ARCHIVE; ?></strong></td><td><?php echo $archiveSize; ?></td>
2536
- </tr>
2537
- <tr>
2538
- <td><strong>&nbsp;<?php echo LM_DATABASE_ARCHIVE; ?></strong></td><td><?php echo $databaseResult; ?></td>
2539
- </tr>
2540
-
2541
-
2542
- <tr>
2543
- <td><strong>&nbsp;</strong></td><td>&nbsp;</td>
2544
- </tr>
2545
- </table>
2546
- <form action="" name="adminForm" method="post">
2547
- <input type=hidden name=files[1] value='<?php echo $archiveName?>'>
2548
- <input type=hidden name=cid[1] value='<?php echo $archiveName?>'>
2549
- <input type="hidden" name="option" value="<?php echo $option; ?>"/>
2550
- <input type="hidden" name="task" value=""/>
2551
- </form>
2552
- <?php
2553
- }
2554
-
2555
- function generateBackup_text( $archiveName, $archiveSize, $originalSize, $d, $f, $databaseResult, $option ) {
2556
- // ----------------------------------------------------------
2557
- // Presentation of the final report screen in text mode
2558
- // ----------------------------------------------------------
2559
-
2560
- ob_start();
2561
- ?>
2562
- <?php echo LM_ARCHIVE_NAME; ?>: <?php echo $archiveName."\r\n"; ?><br />
2563
- <?php echo LM_NUMBER_FILES; ?>: <?php echo $f."\r\n"; ?><br />
2564
- <?php echo LM_SIZE_ORIGINAL; ?>: <?php echo $originalSize."\r\n"; ?><br />
2565
- <?php echo LM_SIZE_ARCHIVE; ?>: <?php echo $archiveSize."\r\n"; ?><br />
2566
- <?php echo LM_DATABASE_ARCHIVE; ?>: <?php echo $databaseResult."\r\n"; ?><br />
2567
- ### END REPORT
2568
- <?php
2569
- $content = ob_get_contents();
2570
- ob_end_clean();
2571
-
2572
- return $content;
2573
- }
2574
-
2575
- function showHelp( $option ) {
2576
- ?>
2577
- <script>
2578
- jQuery(function() {
2579
- jQuery( "#tabs" ).tabs();
2580
- });
2581
- </script>
2582
-
2583
- <div id="tabs" >
2584
- <ul>
2585
- <li><a href="#tabs-1"><?php echo LM_CREDIT_TOP?></a></li>
2586
- </ul>
2587
- <div id="tabs-1" >
2588
- <div class="mainText">
2589
-
2590
- <?php echo LM_CLONER_ABOUT?>
2591
- </div>
2592
- </div>
2593
- </div>
2594
- <form action="" name="adminForm" method="post">
2595
- <input type="hidden" name="option" value="<?php echo $option; ?>"/>
2596
- <input type="hidden" name="task" value=""/>
2597
- </form>
2598
- <?php
2599
- }
2600
-
2601
- function Restore( $option ) {
2602
- // ----------------------------------------------------------
2603
- // Presentation of the Help Screem
2604
- // ----------------------------------------------------------
2605
-
2606
- ?>
2607
-
2608
- <script>
2609
- jQuery(function() {
2610
- jQuery( "#tabs" ).tabs();
2611
- });
2612
- </script>
2613
-
2614
- <div id="tabs">
2615
- <ul>
2616
- <li><a href="#tabs-1"><?php echo LM_RESTORE_TOP?></a></li>
2617
- </ul>
2618
- <div id="tabs-1"><p class="mainText">
2619
- <table border="0" align="center" cellspacing="0" cellpadding="2" width="100%" class="adminform">
2620
- <tr>
2621
- <td>
2622
- <?php echo LM_CLONER_RESTORE?>
2623
- </td>
2624
- </tr>
2625
- </table>
2626
- </p></div>
2627
- </div>
2628
- <form action="" name="adminForm" method="post">
2629
- <input type="hidden" name="option" value="<?php echo $option; ?>"/>
2630
- <input type="hidden" name="task" value=""/>
2631
- </form>
2632
- <?php
2633
- }
2634
- function showCredits( $option ) {
2635
- // ----------------------------------------------------------
2636
- // Presentation of the Help Screem
2637
- // ----------------------------------------------------------
2638
-
2639
- ?>
2640
- <script>
2641
- jQuery(function() {
2642
- jQuery( "#tabs" ).tabs();
2643
- });
2644
- </script>
2645
-
2646
- <div id="tabs">
2647
- <ul>
2648
- <li><a href="#tabs-1"><?php echo LM_CREDIT_TOP?></a></li>
2649
- </ul>
2650
- <div id="tabs-1"><p class="mainText">
2651
- <table border="0" align="center" cellspacing="0" cellpadding="2" width="100%" class="adminform">
2652
- <tr>
2653
- <td>
2654
- <?echo LM_CLONER_CREDITS?>
2655
- </td>
2656
- </tr>
2657
- </table>
2658
- </p></div>
2659
- </div>
2660
- <form action="" name="adminForm" method="post">
2661
- <input type="hidden" name="option" value="<?php echo $option; ?>"/>
2662
- <input type="hidden" name="task" value=""/>
2663
- </form>
2664
- <?php
2665
- }
2666
-
2667
-
2668
- function Rename($files, $option){
2669
- global $_CONFIG;
2670
-
2671
- ?>
2672
- <form action="" method="post" name="adminForm">
2673
- <table border="0" align="center" cellspacing="0" cellpadding="2" width="100%" class="adminform">
2674
- <tr><th colspan='2'>
2675
- <?php echo LM_RENAME_TOP?>
2676
- </th></tr>
2677
- <?php
2678
-
2679
- foreach($files as $key=>$file){
2680
- echo "<tr>
2681
- <td >
2682
- ".LM_RENAME." <input type=hidden name='cfile[]' value='$file' ><b>$file</b>
2683
- </td>
2684
- <td align='left'>
2685
- ".LM_RENAME_TO." <input type=text name='dfile[]' value='$file' size=100>
2686
- </td>
2687
- </tr>";
2688
- }
2689
-
2690
- ?>
2691
- </table>
2692
- <form action="" name="adminForm" method="post">
2693
- <input type="hidden" name="option" value="<?php echo $option; ?>"/>
2694
- <input type="hidden" name="task" value="rename_save"/>
2695
- </form>
2696
-
2697
- <?php
2698
- }
2699
-
2700
- }
2701
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin.cloner.php DELETED
@@ -1,215 +0,0 @@
1
- <?php
2
- /*
3
- * admin.cloner.php
4
- *
5
- * Copyright 2011 Ovidiu Liuta <info@thinkovi.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program; if not, write to the Free Software
19
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
- * MA 02110-1301, USA.
21
- */
22
-
23
-
24
- defined( '_VALID_MOS' ) or die( 'Restricted access' );
25
-
26
- @set_time_limit("3600");
27
- @error_reporting(E_ALL ^ E_NOTICE);
28
-
29
- //load configuration
30
- $config_file = __XCLONERDIR__."/cloner.config.php";
31
-
32
- require_once($config_file);
33
-
34
- require_once("restore/TAR.php");
35
- require_once("cloner.functions.php");
36
- require_once("admin.cloner.html.php");
37
- require_once("common.php");
38
-
39
- $option = "xcloner";
40
-
41
- //###########GLOBALS in effect
42
- $GLOBALS['lang_dir'] = $lang_dir;
43
- //###########
44
- $lang_array = get_avalaible_langs();
45
-
46
-
47
- // retrieve row selection from forms
48
- $cid = $_REQUEST['cid'];
49
- if (!is_array($cid))
50
- {
51
- $cid = array(0);
52
- }
53
-
54
- if(!$_REQUEST['nohtml'])
55
- {
56
- if (($task != 'download') and (($_REQUEST['task']!="refresh") or (!$_CONFIG['refresh_mode']))){
57
- //HTML_cloner::header();
58
- $html = new HTML_cloner();
59
- $html->header();
60
- }
61
- }
62
-
63
- //########## SETTING THE GLOBALS VARIABLES #########################
64
-
65
- $GLOBALS['joomla_compatible'] = $joomla_compatible;
66
-
67
- $GLOBALS['_CONFIG'] = $_CONFIG;
68
-
69
- $GLOBALS['clonerPath'] = $clonerPath;
70
-
71
- $GLOBALS['baDownloadPath'] = $baDownloadPath;
72
-
73
- $GLOBALS['config_file'] = $config_file;
74
-
75
- $GLOBALS['lang_array'] = $lang_array;
76
-
77
- openXLog();
78
-
79
- // process the workflow selection
80
- switch ($task) {
81
- case 'rename_save':
82
- case 'rename':
83
- clone_rename($option);
84
- break;
85
- case 'action':
86
- xclonerAction($option);
87
- break;
88
-
89
-
90
- case 'dropbox_authorize':
91
- authorize_dropbox();
92
- break;
93
-
94
- case 'cancel_lang':
95
- mosRedirect('plugins.php?page=xcloner_show&option=' . $option . "&task=lang");
96
- break;
97
- case 'add_lang':
98
- case 'add_lang_new':
99
- translator_add($option, $task);
100
- break;
101
- case 'save_lang_apply':
102
- case 'save_lang':
103
- case 'edit_lang':
104
- translator_edit($option, $task);
105
- break;
106
-
107
-
108
- case 'del_lang':
109
- case 'lang':
110
- translator($option);
111
- break;
112
-
113
- case 'recurse_database';
114
- goRecurseDatabases();
115
- break;
116
-
117
- case 'recurse_files':
118
- goRecurseFiles();
119
- break;
120
-
121
- case 'cleanup':
122
- include_once("classes/main.class.php");
123
- $main = new Main();
124
- $main->init($_CONFIG);
125
- $main->cleanUp();
126
- break;
127
-
128
- case 'refresh':
129
- generateBackuprefresh($cid, $option, $_REQUEST['backup'], $_CONFIG['refresh_mode']);
130
- break;
131
-
132
- case 'generate':
133
- if ( empty($_POST) || !wp_verify_nonce($_POST['csrf'],'generate') ){
134
- print 'Sorry, your nonce did not verify.';
135
- exit;
136
- }
137
-
138
- if($_CONFIG['refresh_mode']){
139
- $_REQUEST['mode'] = "start";
140
- if($_CONFIG['enable_db_backup'])
141
- goRecurseDatabases();
142
- //initBackup($_REQUEST['bname']);
143
- //break;
144
- }
145
- generateBackup($cid, $option);
146
- break;
147
-
148
- case 'confirm':
149
- deleteXLog();
150
- confirmBackup($option);
151
- break;
152
- case 'download':
153
- $file = pathinfo($_REQUEST['file']);
154
- downloadBackup($file['basename']);
155
- break;
156
- case 'cron':
157
- $html->Cron();
158
- break;
159
- case 'about':
160
- case 'credits':
161
- showHelp($option);
162
- break;
163
- case 'restore':
164
- $html->Restore($option);
165
- break;
166
-
167
- case 'cron_delete':
168
- $fconfig = basename($_REQUEST['fconfig']);
169
- if (unlink($_CONFIG['multiple_config_dir'] . "/" . $fconfig))
170
- $msg = " was deleted";
171
- else
172
- $msg = " was not deleted, please delete it manually!";
173
-
174
- mosRedirect('plugins.php?page=xcloner_show&option=' . $option . "&task=config", $_REQUEST['fconfig'] . $msg);
175
- break;
176
-
177
- case 'delete':
178
- case 'remove':
179
- deleteBackups($cid, $option);
180
- break;
181
- case 'continue':
182
- case 'move':
183
- case 'clone':
184
- moveBackup($option);
185
- break;
186
-
187
- case 'cancel':
188
- mosRedirect('plugins.php?page=xcloner_show&option=' . $option);
189
- break;
190
- case 'config':
191
- config($option);
192
- break;
193
- case 'rename_cancel':
194
- mosRedirect('plugins.php?page=xcloner_show&option=' . $option . "&task=view");
195
- break;
196
- case 'show':
197
- case 'view':
198
- showBackups($option);
199
- break;
200
- case 'logout':
201
- doLogout();
202
- break;
203
- default:
204
- fdefault();
205
- break;
206
- }
207
-
208
- closeXLog();
209
-
210
- if(!$_REQUEST['nohtml'])
211
- {
212
- $html->footer();
213
- }
214
-
215
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/assets/database-icon.png ADDED
Binary file
admin/assets/file-icon-d.png ADDED
Binary file
admin/assets/file-icon-f.png ADDED
Binary file
admin/assets/file-icon-l.png ADDED
Binary file
admin/assets/file-icon-root.png ADDED
Binary file
admin/assets/table-icon.png ADDED
Binary file
admin/class-xcloner-admin.php ADDED
@@ -0,0 +1,265 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The admin-specific functionality of the plugin.
5
+ *
6
+ * @link http://www.thinkovi.com
7
+ * @since 1.0.0
8
+ *
9
+ * @package Xcloner
10
+ * @subpackage Xcloner/admin
11
+ */
12
+
13
+ /**
14
+ * The admin-specific functionality of the plugin.
15
+ *
16
+ * Defines the plugin name, version, and two examples hooks for how to
17
+ * enqueue the admin-specific stylesheet and JavaScript.
18
+ *
19
+ * @package Xcloner
20
+ * @subpackage Xcloner/admin
21
+ * @author Liuta Ovidiu <info@thinkovi.com>
22
+ */
23
+ class Xcloner_Admin {
24
+
25
+ /**
26
+ * The ID of this plugin.
27
+ *
28
+ * @since 1.0.0
29
+ * @access private
30
+ * @var string $plugin_name The ID of this plugin.
31
+ */
32
+ private $plugin_name;
33
+
34
+ /**
35
+ * The version of this plugin.
36
+ *
37
+ * @since 1.0.0
38
+ * @access private
39
+ * @var string $version The current version of this plugin.
40
+ */
41
+ private $version;
42
+
43
+ /**
44
+ * Initialize the class and set its properties.
45
+ *
46
+ * @since 1.0.0
47
+ * @param string $plugin_name The name of this plugin.
48
+ * @param string $version The version of this plugin.
49
+ */
50
+ public function __construct( $plugin_name, $version ) {
51
+
52
+ $this->plugin_name = $plugin_name;
53
+ $this->version = $version;
54
+
55
+ }
56
+
57
+ /**
58
+ * Register the stylesheets for the admin area.
59
+ *
60
+ * @since 1.0.0
61
+ */
62
+ public function enqueue_styles($hook) {
63
+
64
+ if(!stristr($hook, "page_".$this->plugin_name) || (isset($_GET['option']) and $_GET['option']=="com_cloner"))
65
+ return;
66
+
67
+ /**
68
+ * This function is provided for demonstration purposes only.
69
+ *
70
+ * An instance of this class should be passed to the run() function
71
+ * defined in Xcloner_Loader as all of the hooks are defined
72
+ * in that particular class.
73
+ *
74
+ * The Xcloner_Loader will then create the relationship
75
+ * between the defined hooks and the functions defined in this
76
+ * class.
77
+ */
78
+
79
+ wp_enqueue_style( $this->plugin_name."_materialize", plugin_dir_url( __FILE__ ) . 'css/materialize.min.css', array(), $this->version, 'all' );
80
+ wp_enqueue_style( $this->plugin_name."_materialize.clockpicker", plugin_dir_url( __FILE__ ) . 'css/materialize.clockpicker.css', array(), $this->version, 'all' );
81
+ wp_enqueue_style( $this->plugin_name."_materialize.icons", '//fonts.googleapis.com/icon?family=Material+Icons', array(), $this->version, 'all' );
82
+ wp_enqueue_style( $this->plugin_name."_jquery.datatables", plugin_dir_url( __FILE__ ) . 'css/jquery.dataTables.min.css', array(), $this->version, 'all' );
83
+ wp_enqueue_style( $this->plugin_name."_jquery.datatables.responsive", plugin_dir_url( __FILE__ ) . 'css/responsive.dataTables.css', array(), $this->version, 'all' );
84
+ wp_enqueue_style( $this->plugin_name."_jstree", dirname(plugin_dir_url( __FILE__ )) . '/vendor/vakata/jstree/dist/themes/default/style.min.css', array(), '3.3', 'all' );
85
+ wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/xcloner-admin.css', array(), $this->version, 'all' );
86
+
87
+ }
88
+
89
+ /**
90
+ * Register the JavaScript for the admin area.
91
+ *
92
+ * @since 1.0.0
93
+ */
94
+ public function enqueue_scripts($hook) {
95
+
96
+ if(!stristr($hook, "page_".$this->plugin_name))
97
+ return;
98
+
99
+ /**
100
+ * This function is provided for demonstration purposes only.
101
+ *
102
+ * An instance of this class should be passed to the run() function
103
+ * defined in Xcloner_Loader as all of the hooks are defined
104
+ * in that particular class.
105
+ *
106
+ * The Xcloner_Loader will then create the relationship
107
+ * between the defined hooks and the functions defined in this
108
+ * class.
109
+ */
110
+
111
+ wp_enqueue_script( $this->plugin_name."_materialize", plugin_dir_url( __FILE__ ) . 'js/materialize.min.js', array( 'jquery' ), $this->version, false );
112
+ wp_enqueue_script( $this->plugin_name."_materialize.clockpicker", plugin_dir_url( __FILE__ ) . 'js/materialize.clockpicker.js', array( 'jquery' ), $this->version, false );
113
+ wp_enqueue_script( $this->plugin_name."_jquery.datatables", plugin_dir_url( __FILE__ ) . 'js/jquery.dataTables.min.js', array( 'jquery' ), $this->version, false );
114
+ wp_enqueue_script( $this->plugin_name."_jquery.datatables.respnsive", plugin_dir_url( __FILE__ ) . 'js/dataTables.responsive.js', array( 'jquery' ), $this->version, false );
115
+ wp_enqueue_script( $this->plugin_name."_vakata", dirname(plugin_dir_url( __FILE__ )) . '/vendor/vakata/jstree/dist/jstree.min.js', array( 'jquery' ), '3.3', false );
116
+ wp_enqueue_script( $this->plugin_name."_xcloner-backup-class", plugin_dir_url( __FILE__ ) . 'js/xcloner-backup-class.js', array( 'jquery' ), $this->version, false );
117
+ wp_enqueue_script( $this->plugin_name."_xcloner-scheduler-class", plugin_dir_url( __FILE__ ) . 'js/xcloner-scheduler-class.js', array( 'jquery' ), $this->version, false );
118
+ wp_enqueue_script( $this->plugin_name."_xcloner-restore-class", plugin_dir_url( __FILE__ ) . 'js/xcloner-restore-class.js', array( 'jquery' ), $this->version, false );
119
+ wp_enqueue_script( $this->plugin_name."_xcloner-manage-backups-class", plugin_dir_url( __FILE__ ) . 'js/xcloner-manage-backups-class.js', array( 'jquery' ), $this->version, false );
120
+ wp_enqueue_script( $this->plugin_name."_xcloner-remote-storage-class", plugin_dir_url( __FILE__ ) . 'js/xcloner-remote-storage-class.js', array( 'jquery' ), $this->version, false );
121
+ wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/xcloner-admin.js', array( 'jquery' ), $this->version, false );
122
+
123
+
124
+ }
125
+
126
+ public function xcloner_init_page()
127
+ {
128
+ require_once("partials/xcloner_init_page.php");
129
+
130
+ }
131
+
132
+ public function xcloner_remote_storage_page()
133
+ {
134
+ if(isset($_POST['action']))
135
+ {
136
+ $remote_storage = new Xcloner_Remote_Storage();
137
+ $remote_storage->save($_POST['action']);
138
+ }
139
+ require_once("partials/xcloner_remote_storage_page.php");
140
+
141
+ }
142
+
143
+ public function xcloner_scheduled_backups_page()
144
+ {
145
+ $requirements = new XCloner_Requirements();
146
+ if(!$requirements->check_backup_ready_status())
147
+ {
148
+ require_once("partials/xcloner_init_page.php");
149
+ return false;
150
+ }
151
+
152
+ require_once("partials/xcloner_scheduled_backups_page.php");
153
+
154
+ }
155
+
156
+ public function xcloner_manage_backups_page()
157
+ {
158
+ require_once("partials/xcloner_manage_backups_page.php");
159
+
160
+ }
161
+
162
+ public function xcloner_debugger_page()
163
+ {
164
+ require_once("partials/xcloner_console_page.php");
165
+
166
+ }
167
+
168
+ public function xcloner_restore_page()
169
+ {
170
+ require_once("partials/xcloner_restore_page.php");
171
+
172
+ }
173
+
174
+ public function xcloner_generate_backups_page()
175
+ {
176
+ $requirements = new XCloner_Requirements();
177
+ if(!$requirements->check_backup_ready_status())
178
+ {
179
+ require_once("partials/xcloner_init_page.php");
180
+ return false;
181
+ }
182
+
183
+ require_once("partials/xcloner_generate_backups_page.php");
184
+ return;
185
+ }
186
+
187
+ public function xcloner_settings_page()
188
+ {
189
+ // check user capabilities
190
+ if (!current_user_can('manage_options')) {
191
+ return;
192
+ }
193
+
194
+ // add error/update messages
195
+
196
+ // check if the user have submitted the settings
197
+ // wordpress will add the "settings-updated" $_GET parameter to the url
198
+ if (isset($_GET['settings-updated'])) {
199
+ // add settings saved message with the class of "updated"
200
+ add_settings_error('wporg_messages', 'wporg_message', __('Settings Saved', 'wporg'), 'updated');
201
+ }
202
+
203
+ // show error/update messages
204
+ settings_errors('wporg_messages');
205
+ ?>
206
+
207
+ <?php
208
+ if( isset( $_GET[ 'tab' ] ) ) {
209
+ $active_tab = $_GET[ 'tab' ];
210
+ } // end if
211
+ else{
212
+ $active_tab = "general_options";
213
+ }
214
+
215
+ ?>
216
+ <h1><?= esc_html(get_admin_page_title()); ?></h1>
217
+
218
+ <ul class="nav-tab-wrapper row">
219
+ <li><a href="?page=xcloner_settings_page&tab=general_options" class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'general_options' ? 'nav-tab-active' : ''; ?>"><?php echo __('General Options', 'xcloner-backup-and-restore')?></a></li>
220
+ <li><a href="?page=xcloner_settings_page&tab=mysql_options" class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'mysql_options' ? 'nav-tab-active' : ''; ?>"><?php echo __('Mysql Options', 'xcloner-backup-and-restore')?></a></li>
221
+ <li><a href="?page=xcloner_settings_page&tab=system_options" class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'system_options' ? 'nav-tab-active' : ''; ?>"><?php echo __('System Options', 'xcloner-backup-and-restore')?></a></li>
222
+ <li><a href="?page=xcloner_settings_page&tab=cleanup_options" class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'cleanup_options' ? 'nav-tab-active' : ''; ?>"><?php echo __('Cleanup Options', 'xcloner-backup-and-restore')?></a></li>
223
+ <!--<li><a href="?page=xcloner_settings_page&tab=cron_options" class="nav-tab col s12 m3 l2 <?php echo $active_tab == 'cron_options' ? 'nav-tab-active' : ''; ?>"><?php echo __('Cron Options', 'xcloner-backup-and-restore')?></a></li>
224
+ -->
225
+ </ul>
226
+
227
+ <div class="wrap">
228
+
229
+ <form action="options.php" method="post">
230
+ <?php
231
+
232
+ if( $active_tab == 'general_options' ) {
233
+
234
+ settings_fields('xcloner_general_settings_group');
235
+ do_settings_sections('xcloner_settings_page');
236
+
237
+ }elseif( $active_tab == 'mysql_options' ) {
238
+
239
+ settings_fields('xcloner_mysql_settings_group');
240
+ do_settings_sections('xcloner_mysql_settings_page');
241
+ }elseif( $active_tab == 'system_options' ) {
242
+
243
+ settings_fields('xcloner_system_settings_group');
244
+ do_settings_sections('xcloner_system_settings_page');
245
+ }elseif( $active_tab == 'cleanup_options' ) {
246
+
247
+ settings_fields('xcloner_cleanup_settings_group');
248
+ do_settings_sections('xcloner_cleanup_settings_page');
249
+ }/*else{
250
+
251
+ settings_fields('xcloner_cron_settings_group');
252
+ do_settings_sections('xcloner_cron_settings_page');
253
+ }*/
254
+
255
+ // output save settings button
256
+ submit_button('Save Settings');
257
+ ?>
258
+ </form>
259
+
260
+ </div>
261
+ <?php
262
+
263
+ }
264
+
265
+ }
admin/css/jquery.dataTables.min.css ADDED
@@ -0,0 +1 @@
 
1
+ table.dataTable{width:100%;margin:0 auto;clear:both;border-collapse:separate;border-spacing:0}table.dataTable thead th,table.dataTable tfoot th{font-weight:bold}table.dataTable thead th,table.dataTable thead td{padding:10px 18px;border-bottom:1px solid #111}table.dataTable thead th:active,table.dataTable thead td:active{outline:none}table.dataTable tfoot th,table.dataTable tfoot td{padding:10px 18px 6px 18px;border-top:1px solid #111}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc{cursor:pointer;*cursor:hand}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{background-repeat:no-repeat;background-position:center right}table.dataTable thead .sorting{background-image:url("../images/sort_both.png")}table.dataTable thead .sorting_asc{background-image:url("../images/sort_asc.png")}table.dataTable thead .sorting_desc{background-image:url("../images/sort_desc.png")}table.dataTable thead .sorting_asc_disabled{background-image:url("../images/sort_asc_disabled.png")}table.dataTable thead .sorting_desc_disabled{background-image:url("../images/sort_desc_disabled.png")}table.dataTable tbody tr{background-color:#ffffff}table.dataTable tbody tr.selected{background-color:#B0BED9}table.dataTable tbody th,table.dataTable tbody td{padding:8px 10px}table.dataTable.row-border tbody th,table.dataTable.row-border tbody td,table.dataTable.display tbody th,table.dataTable.display tbody td{border-top:1px solid #ddd}table.dataTable.row-border tbody tr:first-child th,table.dataTable.row-border tbody tr:first-child td,table.dataTable.display tbody tr:first-child th,table.dataTable.display tbody tr:first-child td{border-top:none}table.dataTable.cell-border tbody th,table.dataTable.cell-border tbody td{border-top:1px solid #ddd;border-right:1px solid #ddd}table.dataTable.cell-border tbody tr th:first-child,table.dataTable.cell-border tbody tr td:first-child{border-left:1px solid #ddd}table.dataTable.cell-border tbody tr:first-child th,table.dataTable.cell-border tbody tr:first-child td{border-top:none}table.dataTable.stripe tbody tr.odd,table.dataTable.display tbody tr.odd{background-color:#f9f9f9}table.dataTable.stripe tbody tr.odd.selected,table.dataTable.display tbody tr.odd.selected{background-color:#acbad4}table.dataTable.hover tbody tr:hover,table.dataTable.display tbody tr:hover{background-color:#f6f6f6}table.dataTable.hover tbody tr:hover.selected,table.dataTable.display tbody tr:hover.selected{background-color:#aab7d1}table.dataTable.order-column tbody tr>.sorting_1,table.dataTable.order-column tbody tr>.sorting_2,table.dataTable.order-column tbody tr>.sorting_3,table.dataTable.display tbody tr>.sorting_1,table.dataTable.display tbody tr>.sorting_2,table.dataTable.display tbody tr>.sorting_3{background-color:#fafafa}table.dataTable.order-column tbody tr.selected>.sorting_1,table.dataTable.order-column tbody tr.selected>.sorting_2,table.dataTable.order-column tbody tr.selected>.sorting_3,table.dataTable.display tbody tr.selected>.sorting_1,table.dataTable.display tbody tr.selected>.sorting_2,table.dataTable.display tbody tr.selected>.sorting_3{background-color:#acbad5}table.dataTable.display tbody tr.odd>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd>.sorting_1{background-color:#f1f1f1}table.dataTable.display tbody tr.odd>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd>.sorting_2{background-color:#f3f3f3}table.dataTable.display tbody tr.odd>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd>.sorting_3{background-color:whitesmoke}table.dataTable.display tbody tr.odd.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_1{background-color:#a6b4cd}table.dataTable.display tbody tr.odd.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_2{background-color:#a8b5cf}table.dataTable.display tbody tr.odd.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_3{background-color:#a9b7d1}table.dataTable.display tbody tr.even>.sorting_1,table.dataTable.order-column.stripe tbody tr.even>.sorting_1{background-color:#fafafa}table.dataTable.display tbody tr.even>.sorting_2,table.dataTable.order-column.stripe tbody tr.even>.sorting_2{background-color:#fcfcfc}table.dataTable.display tbody tr.even>.sorting_3,table.dataTable.order-column.stripe tbody tr.even>.sorting_3{background-color:#fefefe}table.dataTable.display tbody tr.even.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_1{background-color:#acbad5}table.dataTable.display tbody tr.even.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_2{background-color:#aebcd6}table.dataTable.display tbody tr.even.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_3{background-color:#afbdd8}table.dataTable.display tbody tr:hover>.sorting_1,table.dataTable.order-column.hover tbody tr:hover>.sorting_1{background-color:#eaeaea}table.dataTable.display tbody tr:hover>.sorting_2,table.dataTable.order-column.hover tbody tr:hover>.sorting_2{background-color:#ececec}table.dataTable.display tbody tr:hover>.sorting_3,table.dataTable.order-column.hover tbody tr:hover>.sorting_3{background-color:#efefef}table.dataTable.display tbody tr:hover.selected>.sorting_1,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1{background-color:#a2aec7}table.dataTable.display tbody tr:hover.selected>.sorting_2,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2{background-color:#a3b0c9}table.dataTable.display tbody tr:hover.selected>.sorting_3,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3{background-color:#a5b2cb}table.dataTable.no-footer{border-bottom:1px solid #111}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable.compact thead th,table.dataTable.compact thead td{padding:4px 17px 4px 4px}table.dataTable.compact tfoot th,table.dataTable.compact tfoot td{padding:4px}table.dataTable.compact tbody th,table.dataTable.compact tbody td{padding:4px}table.dataTable th.dt-left,table.dataTable td.dt-left{text-align:left}table.dataTable th.dt-center,table.dataTable td.dt-center,table.dataTable td.dataTables_empty{text-align:center}table.dataTable th.dt-right,table.dataTable td.dt-right{text-align:right}table.dataTable th.dt-justify,table.dataTable td.dt-justify{text-align:justify}table.dataTable th.dt-nowrap,table.dataTable td.dt-nowrap{white-space:nowrap}table.dataTable thead th.dt-head-left,table.dataTable thead td.dt-head-left,table.dataTable tfoot th.dt-head-left,table.dataTable tfoot td.dt-head-left{text-align:left}table.dataTable thead th.dt-head-center,table.dataTable thead td.dt-head-center,table.dataTable tfoot th.dt-head-center,table.dataTable tfoot td.dt-head-center{text-align:center}table.dataTable thead th.dt-head-right,table.dataTable thead td.dt-head-right,table.dataTable tfoot th.dt-head-right,table.dataTable tfoot td.dt-head-right{text-align:right}table.dataTable thead th.dt-head-justify,table.dataTable thead td.dt-head-justify,table.dataTable tfoot th.dt-head-justify,table.dataTable tfoot td.dt-head-justify{text-align:justify}table.dataTable thead th.dt-head-nowrap,table.dataTable thead td.dt-head-nowrap,table.dataTable tfoot th.dt-head-nowrap,table.dataTable tfoot td.dt-head-nowrap{white-space:nowrap}table.dataTable tbody th.dt-body-left,table.dataTable tbody td.dt-body-left{text-align:left}table.dataTable tbody th.dt-body-center,table.dataTable tbody td.dt-body-center{text-align:center}table.dataTable tbody th.dt-body-right,table.dataTable tbody td.dt-body-right{text-align:right}table.dataTable tbody th.dt-body-justify,table.dataTable tbody td.dt-body-justify{text-align:justify}table.dataTable tbody th.dt-body-nowrap,table.dataTable tbody td.dt-body-nowrap{white-space:nowrap}table.dataTable,table.dataTable th,table.dataTable td{-webkit-box-sizing:content-box;box-sizing:content-box}.dataTables_wrapper{position:relative;clear:both;*zoom:1;zoom:1}.dataTables_wrapper .dataTables_length{float:left}.dataTables_wrapper .dataTables_filter{float:right;text-align:right}.dataTables_wrapper .dataTables_filter input{margin-left:0.5em}.dataTables_wrapper .dataTables_info{clear:both;float:left;padding-top:0.755em}.dataTables_wrapper .dataTables_paginate{float:right;text-align:right;padding-top:0.25em}.dataTables_wrapper .dataTables_paginate .paginate_button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:0.5em 1em;margin-left:2px;text-align:center;text-decoration:none !important;cursor:pointer;*cursor:hand;color:#333 !important;border:1px solid transparent;border-radius:2px}.dataTables_wrapper .dataTables_paginate .paginate_button.current,.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{color:#333 !important;border:1px solid #979797;background-color:white;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), color-stop(100%, #dcdcdc));background:-webkit-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-moz-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-ms-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-o-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:linear-gradient(to bottom, #fff 0%, #dcdcdc 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active{cursor:default;color:#666 !important;border:1px solid transparent;background:transparent;box-shadow:none}.dataTables_wrapper .dataTables_paginate .paginate_button:hover{color:white !important;border:1px solid #111;background-color:#585858;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));background:-webkit-linear-gradient(top, #585858 0%, #111 100%);background:-moz-linear-gradient(top, #585858 0%, #111 100%);background:-ms-linear-gradient(top, #585858 0%, #111 100%);background:-o-linear-gradient(top, #585858 0%, #111 100%);background:linear-gradient(to bottom, #585858 0%, #111 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button:active{outline:none;background-color:#2b2b2b;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));background:-webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);box-shadow:inset 0 0 3px #111}.dataTables_wrapper .dataTables_paginate .ellipsis{padding:0 1em}.dataTables_wrapper .dataTables_processing{position:absolute;top:50%;left:50%;width:100%;height:40px;margin-left:-50%;margin-top:-25px;padding-top:20px;text-align:center;font-size:1.2em;background-color:white;background:-webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(255,255,255,0.9)), color-stop(75%, rgba(255,255,255,0.9)), color-stop(100%, rgba(255,255,255,0)));background:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-ms-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-o-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%)}.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_processing,.dataTables_wrapper .dataTables_paginate{color:#333}.dataTables_wrapper .dataTables_scroll{clear:both}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody{*margin-top:-1px;-webkit-overflow-scrolling:touch}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td{vertical-align:middle}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td>div.dataTables_sizing{height:0;overflow:hidden;margin:0 !important;padding:0 !important}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:1px solid #111}.dataTables_wrapper.no-footer div.dataTables_scrollHead table,.dataTables_wrapper.no-footer div.dataTables_scrollBody table{border-bottom:none}.dataTables_wrapper:after{visibility:hidden;display:block;content:"";clear:both;height:0}@media screen and (max-width: 767px){.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_paginate{float:none;text-align:center}.dataTables_wrapper .dataTables_paginate{margin-top:0.5em}}@media screen and (max-width: 640px){.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter{float:none;text-align:center}.dataTables_wrapper .dataTables_filter{margin-top:0.5em}}
admin/css/materialize.clockpicker.css ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .materialize-red{background-color:#e51c23 !important}.materialize-red-text{color:#e51c23 !important}.materialize-red.lighten-5{background-color:#fdeaeb !important}.materialize-red-text.text-lighten-5{color:#fdeaeb !important}.materialize-red.lighten-4{background-color:#f8c1c3 !important}.materialize-red-text.text-lighten-4{color:#f8c1c3 !important}.materialize-red.lighten-3{background-color:#f3989b !important}.materialize-red-text.text-lighten-3{color:#f3989b !important}.materialize-red.lighten-2{background-color:#ee6e73 !important}.materialize-red-text.text-lighten-2{color:#ee6e73 !important}.materialize-red.lighten-1{background-color:#ea454b !important}.materialize-red-text.text-lighten-1{color:#ea454b !important}.materialize-red.darken-1{background-color:#d0181e !important}.materialize-red-text.text-darken-1{color:#d0181e !important}.materialize-red.darken-2{background-color:#b9151b !important}.materialize-red-text.text-darken-2{color:#b9151b !important}.materialize-red.darken-3{background-color:#a21318 !important}.materialize-red-text.text-darken-3{color:#a21318 !important}.materialize-red.darken-4{background-color:#8b1014 !important}.materialize-red-text.text-darken-4{color:#8b1014 !important}.red{background-color:#F44336 !important}.red-text{color:#F44336 !important}.red.lighten-5{background-color:#FFEBEE !important}.red-text.text-lighten-5{color:#FFEBEE !important}.red.lighten-4{background-color:#FFCDD2 !important}.red-text.text-lighten-4{color:#FFCDD2 !important}.red.lighten-3{background-color:#EF9A9A !important}.red-text.text-lighten-3{color:#EF9A9A !important}.red.lighten-2{background-color:#E57373 !important}.red-text.text-lighten-2{color:#E57373 !important}.red.lighten-1{background-color:#EF5350 !important}.red-text.text-lighten-1{color:#EF5350 !important}.red.darken-1{background-color:#E53935 !important}.red-text.text-darken-1{color:#E53935 !important}.red.darken-2{background-color:#D32F2F !important}.red-text.text-darken-2{color:#D32F2F !important}.red.darken-3{background-color:#C62828 !important}.red-text.text-darken-3{color:#C62828 !important}.red.darken-4{background-color:#B71C1C !important}.red-text.text-darken-4{color:#B71C1C !important}.red.accent-1{background-color:#FF8A80 !important}.red-text.text-accent-1{color:#FF8A80 !important}.red.accent-2{background-color:#FF5252 !important}.red-text.text-accent-2{color:#FF5252 !important}.red.accent-3{background-color:#FF1744 !important}.red-text.text-accent-3{color:#FF1744 !important}.red.accent-4{background-color:#D50000 !important}.red-text.text-accent-4{color:#D50000 !important}.pink{background-color:#e91e63 !important}.pink-text{color:#e91e63 !important}.pink.lighten-5{background-color:#fce4ec !important}.pink-text.text-lighten-5{color:#fce4ec !important}.pink.lighten-4{background-color:#f8bbd0 !important}.pink-text.text-lighten-4{color:#f8bbd0 !important}.pink.lighten-3{background-color:#f48fb1 !important}.pink-text.text-lighten-3{color:#f48fb1 !important}.pink.lighten-2{background-color:#f06292 !important}.pink-text.text-lighten-2{color:#f06292 !important}.pink.lighten-1{background-color:#ec407a !important}.pink-text.text-lighten-1{color:#ec407a !important}.pink.darken-1{background-color:#d81b60 !important}.pink-text.text-darken-1{color:#d81b60 !important}.pink.darken-2{background-color:#c2185b !important}.pink-text.text-darken-2{color:#c2185b !important}.pink.darken-3{background-color:#ad1457 !important}.pink-text.text-darken-3{color:#ad1457 !important}.pink.darken-4{background-color:#880e4f !important}.pink-text.text-darken-4{color:#880e4f !important}.pink.accent-1{background-color:#ff80ab !important}.pink-text.text-accent-1{color:#ff80ab !important}.pink.accent-2{background-color:#ff4081 !important}.pink-text.text-accent-2{color:#ff4081 !important}.pink.accent-3{background-color:#f50057 !important}.pink-text.text-accent-3{color:#f50057 !important}.pink.accent-4{background-color:#c51162 !important}.pink-text.text-accent-4{color:#c51162 !important}.purple{background-color:#9c27b0 !important}.purple-text{color:#9c27b0 !important}.purple.lighten-5{background-color:#f3e5f5 !important}.purple-text.text-lighten-5{color:#f3e5f5 !important}.purple.lighten-4{background-color:#e1bee7 !important}.purple-text.text-lighten-4{color:#e1bee7 !important}.purple.lighten-3{background-color:#ce93d8 !important}.purple-text.text-lighten-3{color:#ce93d8 !important}.purple.lighten-2{background-color:#ba68c8 !important}.purple-text.text-lighten-2{color:#ba68c8 !important}.purple.lighten-1{background-color:#ab47bc !important}.purple-text.text-lighten-1{color:#ab47bc !important}.purple.darken-1{background-color:#8e24aa !important}.purple-text.text-darken-1{color:#8e24aa !important}.purple.darken-2{background-color:#7b1fa2 !important}.purple-text.text-darken-2{color:#7b1fa2 !important}.purple.darken-3{background-color:#6a1b9a !important}.purple-text.text-darken-3{color:#6a1b9a !important}.purple.darken-4{background-color:#4a148c !important}.purple-text.text-darken-4{color:#4a148c !important}.purple.accent-1{background-color:#ea80fc !important}.purple-text.text-accent-1{color:#ea80fc !important}.purple.accent-2{background-color:#e040fb !important}.purple-text.text-accent-2{color:#e040fb !important}.purple.accent-3{background-color:#d500f9 !important}.purple-text.text-accent-3{color:#d500f9 !important}.purple.accent-4{background-color:#a0f !important}.purple-text.text-accent-4{color:#a0f !important}.deep-purple{background-color:#673ab7 !important}.deep-purple-text{color:#673ab7 !important}.deep-purple.lighten-5{background-color:#ede7f6 !important}.deep-purple-text.text-lighten-5{color:#ede7f6 !important}.deep-purple.lighten-4{background-color:#d1c4e9 !important}.deep-purple-text.text-lighten-4{color:#d1c4e9 !important}.deep-purple.lighten-3{background-color:#b39ddb !important}.deep-purple-text.text-lighten-3{color:#b39ddb !important}.deep-purple.lighten-2{background-color:#9575cd !important}.deep-purple-text.text-lighten-2{color:#9575cd !important}.deep-purple.lighten-1{background-color:#7e57c2 !important}.deep-purple-text.text-lighten-1{color:#7e57c2 !important}.deep-purple.darken-1{background-color:#5e35b1 !important}.deep-purple-text.text-darken-1{color:#5e35b1 !important}.deep-purple.darken-2{background-color:#512da8 !important}.deep-purple-text.text-darken-2{color:#512da8 !important}.deep-purple.darken-3{background-color:#4527a0 !important}.deep-purple-text.text-darken-3{color:#4527a0 !important}.deep-purple.darken-4{background-color:#311b92 !important}.deep-purple-text.text-darken-4{color:#311b92 !important}.deep-purple.accent-1{background-color:#b388ff !important}.deep-purple-text.text-accent-1{color:#b388ff !important}.deep-purple.accent-2{background-color:#7c4dff !important}.deep-purple-text.text-accent-2{color:#7c4dff !important}.deep-purple.accent-3{background-color:#651fff !important}.deep-purple-text.text-accent-3{color:#651fff !important}.deep-purple.accent-4{background-color:#6200ea !important}.deep-purple-text.text-accent-4{color:#6200ea !important}.indigo{background-color:#3f51b5 !important}.indigo-text{color:#3f51b5 !important}.indigo.lighten-5{background-color:#e8eaf6 !important}.indigo-text.text-lighten-5{color:#e8eaf6 !important}.indigo.lighten-4{background-color:#c5cae9 !important}.indigo-text.text-lighten-4{color:#c5cae9 !important}.indigo.lighten-3{background-color:#9fa8da !important}.indigo-text.text-lighten-3{color:#9fa8da !important}.indigo.lighten-2{background-color:#7986cb !important}.indigo-text.text-lighten-2{color:#7986cb !important}.indigo.lighten-1{background-color:#5c6bc0 !important}.indigo-text.text-lighten-1{color:#5c6bc0 !important}.indigo.darken-1{background-color:#3949ab !important}.indigo-text.text-darken-1{color:#3949ab !important}.indigo.darken-2{background-color:#303f9f !important}.indigo-text.text-darken-2{color:#303f9f !important}.indigo.darken-3{background-color:#283593 !important}.indigo-text.text-darken-3{color:#283593 !important}.indigo.darken-4{background-color:#1a237e !important}.indigo-text.text-darken-4{color:#1a237e !important}.indigo.accent-1{background-color:#8c9eff !important}.indigo-text.text-accent-1{color:#8c9eff !important}.indigo.accent-2{background-color:#536dfe !important}.indigo-text.text-accent-2{color:#536dfe !important}.indigo.accent-3{background-color:#3d5afe !important}.indigo-text.text-accent-3{color:#3d5afe !important}.indigo.accent-4{background-color:#304ffe !important}.indigo-text.text-accent-4{color:#304ffe !important}.blue{background-color:#2196F3 !important}.blue-text{color:#2196F3 !important}.blue.lighten-5{background-color:#E3F2FD !important}.blue-text.text-lighten-5{color:#E3F2FD !important}.blue.lighten-4{background-color:#BBDEFB !important}.blue-text.text-lighten-4{color:#BBDEFB !important}.blue.lighten-3{background-color:#90CAF9 !important}.blue-text.text-lighten-3{color:#90CAF9 !important}.blue.lighten-2{background-color:#64B5F6 !important}.blue-text.text-lighten-2{color:#64B5F6 !important}.blue.lighten-1{background-color:#42A5F5 !important}.blue-text.text-lighten-1{color:#42A5F5 !important}.blue.darken-1{background-color:#1E88E5 !important}.blue-text.text-darken-1{color:#1E88E5 !important}.blue.darken-2{background-color:#1976D2 !important}.blue-text.text-darken-2{color:#1976D2 !important}.blue.darken-3{background-color:#1565C0 !important}.blue-text.text-darken-3{color:#1565C0 !important}.blue.darken-4{background-color:#0D47A1 !important}.blue-text.text-darken-4{color:#0D47A1 !important}.blue.accent-1{background-color:#82B1FF !important}.blue-text.text-accent-1{color:#82B1FF !important}.blue.accent-2{background-color:#448AFF !important}.blue-text.text-accent-2{color:#448AFF !important}.blue.accent-3{background-color:#2979FF !important}.blue-text.text-accent-3{color:#2979FF !important}.blue.accent-4{background-color:#2962FF !important}.blue-text.text-accent-4{color:#2962FF !important}.light-blue{background-color:#03a9f4 !important}.light-blue-text{color:#03a9f4 !important}.light-blue.lighten-5{background-color:#e1f5fe !important}.light-blue-text.text-lighten-5{color:#e1f5fe !important}.light-blue.lighten-4{background-color:#b3e5fc !important}.light-blue-text.text-lighten-4{color:#b3e5fc !important}.light-blue.lighten-3{background-color:#81d4fa !important}.light-blue-text.text-lighten-3{color:#81d4fa !important}.light-blue.lighten-2{background-color:#4fc3f7 !important}.light-blue-text.text-lighten-2{color:#4fc3f7 !important}.light-blue.lighten-1{background-color:#29b6f6 !important}.light-blue-text.text-lighten-1{color:#29b6f6 !important}.light-blue.darken-1{background-color:#039be5 !important}.light-blue-text.text-darken-1{color:#039be5 !important}.light-blue.darken-2{background-color:#0288d1 !important}.light-blue-text.text-darken-2{color:#0288d1 !important}.light-blue.darken-3{background-color:#0277bd !important}.light-blue-text.text-darken-3{color:#0277bd !important}.light-blue.darken-4{background-color:#01579b !important}.light-blue-text.text-darken-4{color:#01579b !important}.light-blue.accent-1{background-color:#80d8ff !important}.light-blue-text.text-accent-1{color:#80d8ff !important}.light-blue.accent-2{background-color:#40c4ff !important}.light-blue-text.text-accent-2{color:#40c4ff !important}.light-blue.accent-3{background-color:#00b0ff !important}.light-blue-text.text-accent-3{color:#00b0ff !important}.light-blue.accent-4{background-color:#0091ea !important}.light-blue-text.text-accent-4{color:#0091ea !important}.cyan{background-color:#00bcd4 !important}.cyan-text{color:#00bcd4 !important}.cyan.lighten-5{background-color:#e0f7fa !important}.cyan-text.text-lighten-5{color:#e0f7fa !important}.cyan.lighten-4{background-color:#b2ebf2 !important}.cyan-text.text-lighten-4{color:#b2ebf2 !important}.cyan.lighten-3{background-color:#80deea !important}.cyan-text.text-lighten-3{color:#80deea !important}.cyan.lighten-2{background-color:#4dd0e1 !important}.cyan-text.text-lighten-2{color:#4dd0e1 !important}.cyan.lighten-1{background-color:#26c6da !important}.cyan-text.text-lighten-1{color:#26c6da !important}.cyan.darken-1{background-color:#00acc1 !important}.cyan-text.text-darken-1{color:#00acc1 !important}.cyan.darken-2{background-color:#0097a7 !important}.cyan-text.text-darken-2{color:#0097a7 !important}.cyan.darken-3{background-color:#00838f !important}.cyan-text.text-darken-3{color:#00838f !important}.cyan.darken-4{background-color:#006064 !important}.cyan-text.text-darken-4{color:#006064 !important}.cyan.accent-1{background-color:#84ffff !important}.cyan-text.text-accent-1{color:#84ffff !important}.cyan.accent-2{background-color:#18ffff !important}.cyan-text.text-accent-2{color:#18ffff !important}.cyan.accent-3{background-color:#00e5ff !important}.cyan-text.text-accent-3{color:#00e5ff !important}.cyan.accent-4{background-color:#00b8d4 !important}.cyan-text.text-accent-4{color:#00b8d4 !important}.teal{background-color:#009688 !important}.teal-text{color:#009688 !important}.teal.lighten-5{background-color:#e0f2f1 !important}.teal-text.text-lighten-5{color:#e0f2f1 !important}.teal.lighten-4{background-color:#b2dfdb !important}.teal-text.text-lighten-4{color:#b2dfdb !important}.teal.lighten-3{background-color:#80cbc4 !important}.teal-text.text-lighten-3{color:#80cbc4 !important}.teal.lighten-2{background-color:#4db6ac !important}.teal-text.text-lighten-2{color:#4db6ac !important}.teal.lighten-1{background-color:#26a69a !important}.teal-text.text-lighten-1{color:#26a69a !important}.teal.darken-1{background-color:#00897b !important}.teal-text.text-darken-1{color:#00897b !important}.teal.darken-2{background-color:#00796b !important}.teal-text.text-darken-2{color:#00796b !important}.teal.darken-3{background-color:#00695c !important}.teal-text.text-darken-3{color:#00695c !important}.teal.darken-4{background-color:#004d40 !important}.teal-text.text-darken-4{color:#004d40 !important}.teal.accent-1{background-color:#a7ffeb !important}.teal-text.text-accent-1{color:#a7ffeb !important}.teal.accent-2{background-color:#64ffda !important}.teal-text.text-accent-2{color:#64ffda !important}.teal.accent-3{background-color:#1de9b6 !important}.teal-text.text-accent-3{color:#1de9b6 !important}.teal.accent-4{background-color:#00bfa5 !important}.teal-text.text-accent-4{color:#00bfa5 !important}.green{background-color:#4CAF50 !important}.green-text{color:#4CAF50 !important}.green.lighten-5{background-color:#E8F5E9 !important}.green-text.text-lighten-5{color:#E8F5E9 !important}.green.lighten-4{background-color:#C8E6C9 !important}.green-text.text-lighten-4{color:#C8E6C9 !important}.green.lighten-3{background-color:#A5D6A7 !important}.green-text.text-lighten-3{color:#A5D6A7 !important}.green.lighten-2{background-color:#81C784 !important}.green-text.text-lighten-2{color:#81C784 !important}.green.lighten-1{background-color:#66BB6A !important}.green-text.text-lighten-1{color:#66BB6A !important}.green.darken-1{background-color:#43A047 !important}.green-text.text-darken-1{color:#43A047 !important}.green.darken-2{background-color:#388E3C !important}.green-text.text-darken-2{color:#388E3C !important}.green.darken-3{background-color:#2E7D32 !important}.green-text.text-darken-3{color:#2E7D32 !important}.green.darken-4{background-color:#1B5E20 !important}.green-text.text-darken-4{color:#1B5E20 !important}.green.accent-1{background-color:#B9F6CA !important}.green-text.text-accent-1{color:#B9F6CA !important}.green.accent-2{background-color:#69F0AE !important}.green-text.text-accent-2{color:#69F0AE !important}.green.accent-3{background-color:#00E676 !important}.green-text.text-accent-3{color:#00E676 !important}.green.accent-4{background-color:#00C853 !important}.green-text.text-accent-4{color:#00C853 !important}.light-green{background-color:#8bc34a !important}.light-green-text{color:#8bc34a !important}.light-green.lighten-5{background-color:#f1f8e9 !important}.light-green-text.text-lighten-5{color:#f1f8e9 !important}.light-green.lighten-4{background-color:#dcedc8 !important}.light-green-text.text-lighten-4{color:#dcedc8 !important}.light-green.lighten-3{background-color:#c5e1a5 !important}.light-green-text.text-lighten-3{color:#c5e1a5 !important}.light-green.lighten-2{background-color:#aed581 !important}.light-green-text.text-lighten-2{color:#aed581 !important}.light-green.lighten-1{background-color:#9ccc65 !important}.light-green-text.text-lighten-1{color:#9ccc65 !important}.light-green.darken-1{background-color:#7cb342 !important}.light-green-text.text-darken-1{color:#7cb342 !important}.light-green.darken-2{background-color:#689f38 !important}.light-green-text.text-darken-2{color:#689f38 !important}.light-green.darken-3{background-color:#558b2f !important}.light-green-text.text-darken-3{color:#558b2f !important}.light-green.darken-4{background-color:#33691e !important}.light-green-text.text-darken-4{color:#33691e !important}.light-green.accent-1{background-color:#ccff90 !important}.light-green-text.text-accent-1{color:#ccff90 !important}.light-green.accent-2{background-color:#b2ff59 !important}.light-green-text.text-accent-2{color:#b2ff59 !important}.light-green.accent-3{background-color:#76ff03 !important}.light-green-text.text-accent-3{color:#76ff03 !important}.light-green.accent-4{background-color:#64dd17 !important}.light-green-text.text-accent-4{color:#64dd17 !important}.lime{background-color:#cddc39 !important}.lime-text{color:#cddc39 !important}.lime.lighten-5{background-color:#f9fbe7 !important}.lime-text.text-lighten-5{color:#f9fbe7 !important}.lime.lighten-4{background-color:#f0f4c3 !important}.lime-text.text-lighten-4{color:#f0f4c3 !important}.lime.lighten-3{background-color:#e6ee9c !important}.lime-text.text-lighten-3{color:#e6ee9c !important}.lime.lighten-2{background-color:#dce775 !important}.lime-text.text-lighten-2{color:#dce775 !important}.lime.lighten-1{background-color:#d4e157 !important}.lime-text.text-lighten-1{color:#d4e157 !important}.lime.darken-1{background-color:#c0ca33 !important}.lime-text.text-darken-1{color:#c0ca33 !important}.lime.darken-2{background-color:#afb42b !important}.lime-text.text-darken-2{color:#afb42b !important}.lime.darken-3{background-color:#9e9d24 !important}.lime-text.text-darken-3{color:#9e9d24 !important}.lime.darken-4{background-color:#827717 !important}.lime-text.text-darken-4{color:#827717 !important}.lime.accent-1{background-color:#f4ff81 !important}.lime-text.text-accent-1{color:#f4ff81 !important}.lime.accent-2{background-color:#eeff41 !important}.lime-text.text-accent-2{color:#eeff41 !important}.lime.accent-3{background-color:#c6ff00 !important}.lime-text.text-accent-3{color:#c6ff00 !important}.lime.accent-4{background-color:#aeea00 !important}.lime-text.text-accent-4{color:#aeea00 !important}.yellow{background-color:#ffeb3b !important}.yellow-text{color:#ffeb3b !important}.yellow.lighten-5{background-color:#fffde7 !important}.yellow-text.text-lighten-5{color:#fffde7 !important}.yellow.lighten-4{background-color:#fff9c4 !important}.yellow-text.text-lighten-4{color:#fff9c4 !important}.yellow.lighten-3{background-color:#fff59d !important}.yellow-text.text-lighten-3{color:#fff59d !important}.yellow.lighten-2{background-color:#fff176 !important}.yellow-text.text-lighten-2{color:#fff176 !important}.yellow.lighten-1{background-color:#ffee58 !important}.yellow-text.text-lighten-1{color:#ffee58 !important}.yellow.darken-1{background-color:#fdd835 !important}.yellow-text.text-darken-1{color:#fdd835 !important}.yellow.darken-2{background-color:#fbc02d !important}.yellow-text.text-darken-2{color:#fbc02d !important}.yellow.darken-3{background-color:#f9a825 !important}.yellow-text.text-darken-3{color:#f9a825 !important}.yellow.darken-4{background-color:#f57f17 !important}.yellow-text.text-darken-4{color:#f57f17 !important}.yellow.accent-1{background-color:#ffff8d !important}.yellow-text.text-accent-1{color:#ffff8d !important}.yellow.accent-2{background-color:#ff0 !important}.yellow-text.text-accent-2{color:#ff0 !important}.yellow.accent-3{background-color:#ffea00 !important}.yellow-text.text-accent-3{color:#ffea00 !important}.yellow.accent-4{background-color:#ffd600 !important}.yellow-text.text-accent-4{color:#ffd600 !important}.amber{background-color:#ffc107 !important}.amber-text{color:#ffc107 !important}.amber.lighten-5{background-color:#fff8e1 !important}.amber-text.text-lighten-5{color:#fff8e1 !important}.amber.lighten-4{background-color:#ffecb3 !important}.amber-text.text-lighten-4{color:#ffecb3 !important}.amber.lighten-3{background-color:#ffe082 !important}.amber-text.text-lighten-3{color:#ffe082 !important}.amber.lighten-2{background-color:#ffd54f !important}.amber-text.text-lighten-2{color:#ffd54f !important}.amber.lighten-1{background-color:#ffca28 !important}.amber-text.text-lighten-1{color:#ffca28 !important}.amber.darken-1{background-color:#ffb300 !important}.amber-text.text-darken-1{color:#ffb300 !important}.amber.darken-2{background-color:#ffa000 !important}.amber-text.text-darken-2{color:#ffa000 !important}.amber.darken-3{background-color:#ff8f00 !important}.amber-text.text-darken-3{color:#ff8f00 !important}.amber.darken-4{background-color:#ff6f00 !important}.amber-text.text-darken-4{color:#ff6f00 !important}.amber.accent-1{background-color:#ffe57f !important}.amber-text.text-accent-1{color:#ffe57f !important}.amber.accent-2{background-color:#ffd740 !important}.amber-text.text-accent-2{color:#ffd740 !important}.amber.accent-3{background-color:#ffc400 !important}.amber-text.text-accent-3{color:#ffc400 !important}.amber.accent-4{background-color:#ffab00 !important}.amber-text.text-accent-4{color:#ffab00 !important}.orange{background-color:#ff9800 !important}.orange-text{color:#ff9800 !important}.orange.lighten-5{background-color:#fff3e0 !important}.orange-text.text-lighten-5{color:#fff3e0 !important}.orange.lighten-4{background-color:#ffe0b2 !important}.orange-text.text-lighten-4{color:#ffe0b2 !important}.orange.lighten-3{background-color:#ffcc80 !important}.orange-text.text-lighten-3{color:#ffcc80 !important}.orange.lighten-2{background-color:#ffb74d !important}.orange-text.text-lighten-2{color:#ffb74d !important}.orange.lighten-1{background-color:#ffa726 !important}.orange-text.text-lighten-1{color:#ffa726 !important}.orange.darken-1{background-color:#fb8c00 !important}.orange-text.text-darken-1{color:#fb8c00 !important}.orange.darken-2{background-color:#f57c00 !important}.orange-text.text-darken-2{color:#f57c00 !important}.orange.darken-3{background-color:#ef6c00 !important}.orange-text.text-darken-3{color:#ef6c00 !important}.orange.darken-4{background-color:#e65100 !important}.orange-text.text-darken-4{color:#e65100 !important}.orange.accent-1{background-color:#ffd180 !important}.orange-text.text-accent-1{color:#ffd180 !important}.orange.accent-2{background-color:#ffab40 !important}.orange-text.text-accent-2{color:#ffab40 !important}.orange.accent-3{background-color:#ff9100 !important}.orange-text.text-accent-3{color:#ff9100 !important}.orange.accent-4{background-color:#ff6d00 !important}.orange-text.text-accent-4{color:#ff6d00 !important}.deep-orange{background-color:#ff5722 !important}.deep-orange-text{color:#ff5722 !important}.deep-orange.lighten-5{background-color:#fbe9e7 !important}.deep-orange-text.text-lighten-5{color:#fbe9e7 !important}.deep-orange.lighten-4{background-color:#ffccbc !important}.deep-orange-text.text-lighten-4{color:#ffccbc !important}.deep-orange.lighten-3{background-color:#ffab91 !important}.deep-orange-text.text-lighten-3{color:#ffab91 !important}.deep-orange.lighten-2{background-color:#ff8a65 !important}.deep-orange-text.text-lighten-2{color:#ff8a65 !important}.deep-orange.lighten-1{background-color:#ff7043 !important}.deep-orange-text.text-lighten-1{color:#ff7043 !important}.deep-orange.darken-1{background-color:#f4511e !important}.deep-orange-text.text-darken-1{color:#f4511e !important}.deep-orange.darken-2{background-color:#e64a19 !important}.deep-orange-text.text-darken-2{color:#e64a19 !important}.deep-orange.darken-3{background-color:#d84315 !important}.deep-orange-text.text-darken-3{color:#d84315 !important}.deep-orange.darken-4{background-color:#bf360c !important}.deep-orange-text.text-darken-4{color:#bf360c !important}.deep-orange.accent-1{background-color:#ff9e80 !important}.deep-orange-text.text-accent-1{color:#ff9e80 !important}.deep-orange.accent-2{background-color:#ff6e40 !important}.deep-orange-text.text-accent-2{color:#ff6e40 !important}.deep-orange.accent-3{background-color:#ff3d00 !important}.deep-orange-text.text-accent-3{color:#ff3d00 !important}.deep-orange.accent-4{background-color:#dd2c00 !important}.deep-orange-text.text-accent-4{color:#dd2c00 !important}.brown{background-color:#795548 !important}.brown-text{color:#795548 !important}.brown.lighten-5{background-color:#efebe9 !important}.brown-text.text-lighten-5{color:#efebe9 !important}.brown.lighten-4{background-color:#d7ccc8 !important}.brown-text.text-lighten-4{color:#d7ccc8 !important}.brown.lighten-3{background-color:#bcaaa4 !important}.brown-text.text-lighten-3{color:#bcaaa4 !important}.brown.lighten-2{background-color:#a1887f !important}.brown-text.text-lighten-2{color:#a1887f !important}.brown.lighten-1{background-color:#8d6e63 !important}.brown-text.text-lighten-1{color:#8d6e63 !important}.brown.darken-1{background-color:#6d4c41 !important}.brown-text.text-darken-1{color:#6d4c41 !important}.brown.darken-2{background-color:#5d4037 !important}.brown-text.text-darken-2{color:#5d4037 !important}.brown.darken-3{background-color:#4e342e !important}.brown-text.text-darken-3{color:#4e342e !important}.brown.darken-4{background-color:#3e2723 !important}.brown-text.text-darken-4{color:#3e2723 !important}.blue-grey{background-color:#607d8b !important}.blue-grey-text{color:#607d8b !important}.blue-grey.lighten-5{background-color:#eceff1 !important}.blue-grey-text.text-lighten-5{color:#eceff1 !important}.blue-grey.lighten-4{background-color:#cfd8dc !important}.blue-grey-text.text-lighten-4{color:#cfd8dc !important}.blue-grey.lighten-3{background-color:#b0bec5 !important}.blue-grey-text.text-lighten-3{color:#b0bec5 !important}.blue-grey.lighten-2{background-color:#90a4ae !important}.blue-grey-text.text-lighten-2{color:#90a4ae !important}.blue-grey.lighten-1{background-color:#78909c !important}.blue-grey-text.text-lighten-1{color:#78909c !important}.blue-grey.darken-1{background-color:#546e7a !important}.blue-grey-text.text-darken-1{color:#546e7a !important}.blue-grey.darken-2{background-color:#455a64 !important}.blue-grey-text.text-darken-2{color:#455a64 !important}.blue-grey.darken-3{background-color:#37474f !important}.blue-grey-text.text-darken-3{color:#37474f !important}.blue-grey.darken-4{background-color:#263238 !important}.blue-grey-text.text-darken-4{color:#263238 !important}.grey{background-color:#9e9e9e !important}.grey-text{color:#9e9e9e !important}.grey.lighten-5{background-color:#fafafa !important}.grey-text.text-lighten-5{color:#fafafa !important}.grey.lighten-4{background-color:#f5f5f5 !important}.grey-text.text-lighten-4{color:#f5f5f5 !important}.grey.lighten-3{background-color:#eee !important}.grey-text.text-lighten-3{color:#eee !important}.grey.lighten-2{background-color:#e0e0e0 !important}.grey-text.text-lighten-2{color:#e0e0e0 !important}.grey.lighten-1{background-color:#bdbdbd !important}.grey-text.text-lighten-1{color:#bdbdbd !important}.grey.darken-1{background-color:#757575 !important}.grey-text.text-darken-1{color:#757575 !important}.grey.darken-2{background-color:#616161 !important}.grey-text.text-darken-2{color:#616161 !important}.grey.darken-3{background-color:#424242 !important}.grey-text.text-darken-3{color:#424242 !important}.grey.darken-4{background-color:#212121 !important}.grey-text.text-darken-4{color:#212121 !important}.shades.black{background-color:#000 !important}.shades-text.text-black{color:#000 !important}.shades.white{background-color:#fff !important}.shades-text.text-white{color:#fff !important}.shades.transparent{background-color:transparent !important}.shades-text.text-transparent{color:transparent !important}.black{background-color:#000 !important}.black-text{color:#000 !important}.white{background-color:#fff !important}.white-text{color:#fff !important}.transparent{background-color:transparent !important}.transparent-text{color:transparent !important}/*!
2
+ * ClockPicker v0.0.7 for jQuery (http://weareoutman.github.io/clockpicker/)
3
+ * Copyright 2014 Wang Shenwei.
4
+ * Licensed under MIT (https://github.com/weareoutman/clockpicker/blob/gh-pages/LICENSE)
5
+ *
6
+ * Further modified
7
+ * Copyright 2015 Ching Yaw Hao.
8
+ *
9
+ * Bootstrap v3.1.1 (http://getbootstrap.com)
10
+ * Copyright 2011-2014 Twitter, Inc.
11
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
12
+ */.picker__box{background:#fff}.picker__date-display{background-color:#26a69a}.clockpicker-display{vertical-align:middle;display:inline-block;margin:auto;height:85px;font-size:70px;padding:10px;padding-bottom:0px;color:#b2dfdb}.clockpicker-display-column{float:left}.clockpicker-display-am-pm{padding-left:5px;vertical-align:bottom;height:85px}.clockpicker-span-am-pm{display:inline-block;font-size:23px;line-height:25px;color:#b2dfdb}.clockpicker-span-hours,.clockpicker-span-minutes{-webkit-animation-duration:500ms;animation-duration:500ms;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-transition:color 500ms;-moz-transition:color 500ms;-ms-transition:color 500ms;-o-transition:color 500ms;transition:color 500ms;cursor:pointer}@-webkit-keyframes pulse{from{-webkit-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}50%{-webkit-transform:scale3d(1.1, 1.1, 1.1);transform:scale3d(1.1, 1.1, 1.1)}to{-webkit-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}}@-moz-keyframes pulse{from{-moz-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}50%{-moz-transform:scale3d(1.1, 1.1, 1.1);transform:scale3d(1.1, 1.1, 1.1)}to{-moz-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}}@-ms-keyframes pulse{from{-ms-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}50%{-ms-transform:scale3d(1.1, 1.1, 1.1);transform:scale3d(1.1, 1.1, 1.1)}to{-ms-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}}@-o-keyframes pulse{from{-o-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}50%{-o-transform:scale3d(1.1, 1.1, 1.1);transform:scale3d(1.1, 1.1, 1.1)}to{-o-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}}@keyframes pulse{from{transform:scale3d(1, 1, 1)}50%{transform:scale3d(1.1, 1.1, 1.1)}to{transform:scale3d(1, 1, 1)}}#click-am,#click-pm{cursor:pointer}.clockpicker-span-hours.text-primary,.clockpicker-span-minutes.text-primary,#click-am.text-primary,#click-pm.text-primary{-webkit-animation-name:pulse;animation-name:pulse;color:white}.clockpicker-moving{cursor:move}.clockpicker-plate{background-color:#eeeeee;border-radius:50%;width:270px;height:270px;overflow:visible;position:relative;margin:auto;margin-top:20px;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.clockpicker-canvas,.clockpicker-dial{width:270px;height:270px;position:absolute;left:-1px;top:-1px}.clockpicker-minutes{visibility:hidden}.clockpicker-tick{border-radius:50%;color:#666;line-height:40px;text-align:center;width:40px;height:40px;position:absolute;cursor:pointer;-webkit-transition:background-color 300ms;-moz-transition:background-color 300ms;-ms-transition:background-color 300ms;-o-transition:background-color 300ms;transition:background-color 300ms;background-color:rgba(0,150,136,0)}.clockpicker-tick.active,.clockpicker-tick:hover{background-color:rgba(0,150,136,0.25)}.clockpicker-dial{-webkit-transition:-webkit-transform 350ms, opacity 350ms;-moz-transition:-moz-transform 350ms, opacity 350ms;-ms-transition:-ms-transform 350ms, opacity 350ms;-o-transition:-o-transform 350ms, opacity 350ms;transition:transform 350ms, opacity 350ms}.clockpicker-dial-out{opacity:0}.clockpicker-hours.clockpicker-dial-out{-webkit-transform:scale(1.2, 1.2);-moz-transform:scale(1.2, 1.2);-ms-transform:scale(1.2, 1.2);-o-transform:scale(1.2, 1.2);transform:scale(1.2, 1.2)}.clockpicker-minutes.clockpicker-dial-out{-webkit-transform:scale(0.8, 0.8);-moz-transform:scale(0.8, 0.8);-ms-transform:scale(0.8, 0.8);-o-transform:scale(0.8, 0.8);transform:scale(0.8, 0.8)}.clockpicker-canvas{-webkit-transition:opacity 300ms;-moz-transition:opacity 300ms;-ms-transition:opacity 300ms;-o-transition:opacity 300ms;transition:opacity 300ms}.clockpicker-canvas-out{opacity:0.25}.clockpicker-canvas-bearing{stroke:none;fill:rgba(0,77,64,0.75)}.clockpicker-canvas-fg{stroke:none;fill:rgba(0,77,64,0)}.clockpicker-canvas-fg.active{fill:rgba(0,77,64,0.5)}.clockpicker-canvas-bg{stroke:none;fill:rgba(0,150,136,0.25)}.clockpicker-canvas-bg-trans{fill:rgba(0,150,136,0.25)}.clockpicker-canvas line{stroke:rgba(0,150,136,0.25);stroke-width:1;stroke-linecap:round}.clockpicker-am-pm-block{margin-top:-10px;width:100%;height:50px}.clockpicker-button.am-button{height:45px;width:45px;float:left}.clockpicker-button.pm-button{height:45px;width:45px;float:right}button{color:#343434}.btn-floating.btn-flat:focus,.btn-floating.btn-flat:visited{background-color:transparent}.btn-floating.btn-flat:hover{box-shadow:none;background-color:transparent}.btn-floating.btn-flat.active{background-color:rgba(0,150,136,0.25)}.btn-floating.btn-flat:active{background-color:rgba(0,150,136,0.5)}.picker__footer .clockpicker-button{margin:auto;margin-top:15px}.picker__footer .clockpicker-button:focus{background-color:transparent}.picker__footer .clockpicker-button:active{background-color:rgba(0,150,136,0.25)}/*!
13
+ * ClockPicker v0.0.7 for jQuery (http://weareoutman.github.io/clockpicker/)
14
+ * Copyright 2014 Wang Shenwei.
15
+ * Licensed under MIT (https://github.com/weareoutman/clockpicker/blob/gh-pages/LICENSE)
16
+ *
17
+ * Further modified
18
+ * Copyright 2015 Ching Yaw Hao.
19
+ *
20
+ * Bootstrap v3.1.1 (http://getbootstrap.com)
21
+ * Copyright 2011-2014 Twitter, Inc.
22
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
23
+ */.darktheme .picker__box{background-color:#212121}.darktheme .picker__date-display{background-color:transparent}.darktheme .clockpicker-display{color:white}.darktheme .clockpicker-span-am-pm{color:white}.darktheme .clockpicker-span-hours.text-primary,.darktheme .clockpicker-span-minutes.text-primary,.darktheme #click-am.text-primary,.darktheme #click-pm.text-primary{color:#ff4081}.darktheme .clockpicker-plate{background-color:transparent}.darktheme .clockpicker-tick{color:white;background-color:rgba(255,64,129,0)}.darktheme .clockpicker-tick.active,.darktheme .clockpicker-tick:hover{background-color:rgba(255,64,129,0.25)}.darktheme .clockpicker-canvas-bearing{fill:white}.darktheme .clockpicker-canvas-fg{fill:rgba(255,64,129,0)}.darktheme .clockpicker-canvas-fg.active{fill:rgba(255,64,129,0.5)}.darktheme .clockpicker-canvas-bg{fill:rgba(255,64,129,0.25)}.darktheme .clockpicker-canvas-bg-trans{fill:rgba(255,64,129,0.25)}.darktheme .clockpicker-canvas line{stroke:rgba(255,64,129,0.25)}.darktheme button{color:white}.darktheme .btn-floating.btn-flat.active{background-color:rgba(255,64,129,0.25)}.darktheme .btn-floating.btn-flat:active{background-color:rgba(255,64,129,0.5)}.darktheme .picker__footer .clockpicker-button:active{background-color:rgba(255,64,129,0.25)}
24
+
25
+ /*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL2Jvd2VyX2NvbXBvbmVudHMvTWF0ZXJpYWxpemUvc2Fzcy9jb21wb25lbnRzL19jb2xvci5zY3NzIiwiY29tcG9uZW50cy9fcHJpbWFyeS5zY3NzIiwiY29tcG9uZW50cy9fdmFyaWFibGVzLnNjc3MiLCIuLi8uLi9ib3dlcl9jb21wb25lbnRzL01hdGVyaWFsaXplL3Nhc3MvY29tcG9uZW50cy9fdmFyaWFibGVzLnNjc3MiLCJjb21wb25lbnRzL19kYXJrLnNjc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBaVhNLGdCQUFBLEFBQWdCLENBQ2QsZ0JBQWdCLENBeFdSLE9BQU8sQ0F3V2dCLFVBQVUsQ0FDMUMsQUFDRCxxQkFBQSxBQUFxQixDQUNuQixLQUFLLENBM1dHLE9BQU8sQ0EyV0ssVUFBVSxDQUMvQixBQUdELGdCQUFnQixVQUFoQixBQUEwQixDQUN4QixnQkFBZ0IsQ0EvV1IsT0FBTyxDQStXZ0IsVUFBVSxDQUMxQyxBQUNELHFCQUFxQixlQUFyQixBQUFvQyxDQUNsQyxLQUFLLENBbFhHLE9BQU8sQ0FrWEssVUFBVSxDQUpoQyxBQUtDLGdCQUxlLFVBQWhCLEFBQTBCLENBQ3hCLGdCQUFnQixDQTlXUixPQUFPLENBOFdnQixVQUFVLENBQzFDLEFBQ0QscUJBQXFCLGVBQXJCLEFBQW9DLENBQ2xDLEtBQUssQ0FqWEcsT0FBTyxDQWlYSyxVQUFVLENBSmhDLEFBS0MsZ0JBTGUsVUFBaEIsQUFBMEIsQ0FDeEIsZ0JBQWdCLENBN1dSLE9BQU8sQ0E2V2dCLFVBQVUsQ0FDMUMsQUFDRCxxQkFBcUIsZUFBckIsQUFBb0MsQ0FDbEMsS0FBSyxDQWhYRyxPQUFPLENBZ1hLLFVBQVUsQ0FKaEMsQUFLQyxnQkFMZSxVQUFoQixBQUEwQixDQUN4QixnQkFBZ0IsQ0E1V1IsT0FBTyxDQTRXZ0IsVUFBVSxDQUMxQyxBQUNELHFCQUFxQixlQUFyQixBQUFvQyxDQUNsQyxLQUFLLENBL1dHLE9BQU8sQ0ErV0ssVUFBVSxDQUpoQyxBQUtDLGdCQUxl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QUMsSUFBSSxBQUFDLENBQ3JCLE1BQU0sQ0FBRSxxQkFBSSxDQTdEcEIsQUE4REssVUE5REssQ0FnRU4sTUFBTSxBQUFDLENBQ0gsS0FBSyxDQUFFLEtBQU0sQ0FqRXJCLEFBa0VLLFVBbEVLLENBb0VOLGFBQWEsU0FBUyxPQUFPLEFBQUMsQ0FDMUIsZ0JBQWdCLENBQUUscUJBQUksQ0FyRTlCLEFBc0VLLFVBdEVLLENBd0VOLGFBQWEsU0FBUyxPQUFPLEFBQUMsQ0FDMUIsZ0JBQWdCLENBQUUsb0JBQUksQ0F6RTlCLEFBMEVLLFVBMUVLLENBNEVOLGVBQWUsQ0FBQyxtQkFBbUIsT0FBTyxBQUFDLENBQ3ZDLGdCQUFnQixDQUFFLHFCQUFJLENBQ3pCIiwiZmlsZSI6Im1hdGVyaWFsaXplLmNsb2NrcGlja2VyLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIFV0aWxpdHkgQ29sb3IgQ2xhc3Nlc1xuXG4vLy5zdWNjZXNzIHtcbi8vXG4vL31cblxuLy8gR29vZ2xlIENvbG9yIFBhbGV0dGUgZGVmaW5lZDogaHR0cDovL3d3dy5nb29nbGUuY29tL2Rlc2lnbi9zcGVjL3N0eWxlL2NvbG9yLmh0bWxcblxuXG4kbWF0ZXJpYWxpemUtcmVkOiAoXG4gIFwiYmFzZVwiOiAgICAgICAjZTUxYzIzLFxuICBcImxpZ2h0ZW4tNVwiOiAgI2ZkZWFlYixcbiAgXCJsaWdodGVuLTRcIjogICNmOGMxYzMsXG4gIFwibGlnaHRlbi0zXCI6ICAjZjM5ODliLFxuICBcImxpZ2h0ZW4tMlwiOiAgI2VlNmU3MyxcbiAgXCJsaWdodGVuLTFcIjogICNlYTQ1NGIsXG4gIFwiZGFya2VuLTFcIjogICAjZDAxODFlLFxuICBcImRhcmtlbi0yXCI6ICAgI2I5MTUxYixcbiAgXCJkYXJrZW4tM1wiOiAgICNhMjEzMTgsXG4gIFwiZGFya2VuLTRcIjogICAjOGIxMDE0LFxuKTtcblxuJHJlZDogKFxuICBcImJhc2VcIjogICAgICAgI0Y0NDMzNixcbiAgXCJsaWdodGVuLTVcIjogICNGRkVCRUUsXG4gIFwibGlnaHRlbi00XCI6ICAjRkZDREQyLFxuICBcImxpZ2h0ZW4tM1wiOiAgI0VGOUE5QSxcbiAgXCJsaWdodGVuLTJcIjogICNFNTczNzMsXG4gIFwibGlnaHRlbi0xXCI6ICAjRUY1MzUwLFxuICBcImRhcmtlbi0xXCI6ICAgI0U1MzkzNSxcbiAgXCJkYXJrZW4tMlwiOiAgICNEMzJGMkYsXG4gIFwiZGFya2VuLTNcIjogICAjQzYyODI4LFxuICBcImRhcmtlbi00XCI6ICAgI0I3MUMxQyxcbiAgXCJhY2NlbnQtMVwiOiAgICAjRkY4QTgwLFxuICBcImFjY2VudC0yXCI6ICAgICNGRjUyNTIsXG4gIFwiYWNjZW50LTNcIjogICAgI0ZGMTc0NCxcbiAgXCJhY2NlbnQtNFwiOiAgICAjRDUwMDAwXG4pO1xuXG4kcGluazogKFxuICBcImJhc2VcIjogICAgICAgI2U5MWU2MyxcbiAgXCJsaWdodGVuLTVcIjogICNmY2U0ZWMsXG4gIFwibGlnaHRlbi00XCI6ICAjZjhiYmQwLFxuICBcImxpZ2h0ZW4tM1wiOiAgI2Y0OGZiMSxcbiAgXCJsaWdodGVuLTJcIjogICNmMDYyOTIsXG4gIFwibGlnaHRlbi0xXCI6ICAjZWM0MDdhLFxuICBcImRhcmtlbi0xXCI6ICAgI2Q4MWI2MCxcbiAgXCJkYXJrZW4tMlwiOiAgICNjMjE4NWIsXG4gIFwiZGFya2VuLTNcIjogICAjYWQxNDU3LFxuICBcImRhcmtlbi00XCI6ICAgIzg4MGU0ZixcbiAgXCJhY2NlbnQtMVwiOiAgICAjZmY4MGFiLFxuICBcImFjY2VudC0yXCI6ICAgICNmZjQwODEsXG4gIFwiYWNjZW50LTNcIjogICAgI2Y1MDA1NyxcbiAgXCJhY2NlbnQtNFwiOiAgICAjYzUxMTYyXG4pO1xuXG4kcHVycGxlOiAoXG4gIFwiYmFzZVwiOiAgICAgICAjOWMyN2IwLFxuICBcImxpZ2h0ZW4tNVwiOiAgI2YzZTVmNSxcbiAgXCJsaWdodGVuLTRcIjogICNlMWJlZTcsXG4gIFwibGlnaHRlbi0zXCI6ICAjY2U5M2Q4LFxuICBcImxpZ2h0ZW4tMlwiOiAgI2JhNjhjOCxcbiAgXCJsaWdodGVuLTFcIjogICNhYjQ3YmMsXG4gIFwiZGFya2VuLTFcIjogICAjOGUyNGFhLFxuICBcImRhcmtlbi0yXCI6ICAgIzdiMWZhMixcbiAgXCJkYXJrZW4tM1wiOiAgICM2YTFiOWEsXG4gIFwiZGFya2VuLTRcIjogICAjNGExNDhjLFxuICBcImFjY2VudC0xXCI6ICAgICNlYTgwZmMsXG4gIFwiYWNjZW50LTJcIjogICAgI2UwNDBmYixcbiAgXCJhY2NlbnQtM1wiOiAgICAjZDUwMGY5LFxuICBcImFjY2VudC00XCI6ICAgICNhYTAwZmZcbik7XG5cbiRkZWVwLXB1cnBsZTogKFxuICBcImJhc2VcIjogICAgICAgIzY3M2FiNyxcbiAgXCJsaWdodGVuLTVcIjogICNlZGU3ZjYsXG4gIFwibGlnaHRlbi00XCI6ICAjZDFjNGU5LFxuICBcImxpZ2h0ZW4tM1wiOiAgI2IzOWRkYixcbiAgXCJsaWdodGVuLTJcIjogICM5NTc1Y2QsXG4gIFwibGlnaHRlbi0xXCI6ICAjN2U1N2MyLFxuICBcImRhcmtlbi0xXCI6ICAgIzVlMzViMSxcbiAgXCJkYXJrZW4tMlwiOiAgICM1MTJkYTgsXG4gIFwiZGFya2VuLTNcIjogICAjNDUyN2EwLFxuICBcImRhcmtlbi00XCI6ICAgIzMxMWI5MixcbiAgXCJhY2NlbnQtMVwiOiAgICAjYjM4OGZmLFxuICBcImFjY2VudC0yXCI6ICAgICM3YzRkZmYsXG4gIFwiYWNjZW50LTNcIjogICAgIzY1MWZmZixcbiAgXCJhY2NlbnQtNFwiOiAgICAjNjIwMGVhXG4pO1xuXG4kaW5kaWdvOiAoXG4gIFwiYmFzZVwiOiAgICAgICAjM2Y1MWI1LFxuICBcImxpZ2h0ZW4tNVwiOiAgI2U4ZWFmNixcbiAgXCJsaWdodGVuLTRcIjogICNjNWNhZTksXG4gIFwibGlnaHRlbi0zXCI6ICAjOWZhOGRhLFxuICBcImxpZ2h0ZW4tMlwiOiAgIzc5ODZjYixcbiAgXCJsaWdodGVuLTFcIjogICM1YzZiYzAsXG4gIFwiZGFya2VuLTFcIjogICAjMzk0OWFiLFxuICBcImRhcmtlbi0yXCI6ICAgIzMwM2Y5ZixcbiAgXCJkYXJrZW4tM1wiOiAgICMyODM1OTMsXG4gIFwiZGFya2VuLTRcIjogICAjMWEyMzdlLFxuICBcImFjY2VudC0xXCI6ICAgICM4YzllZmYsXG4gIFwiYWNjZW50LTJcIjogICAgIzUzNmRmZSxcbiAgXCJhY2NlbnQtM1wiOiAgICAjM2Q1YWZlLFxuICBcImFjY2VudC00XCI6ICAgICMzMDRmZmVcbik7XG5cbiRibHVlOiAoXG4gIFwiYmFzZVwiOiAgICAgICAjMjE5NkYzLFxuICBcImxpZ2h0ZW4tNVwiOiAgI0UzRjJGRCxcbiAgXCJsaWdodGVuLTRcIjogICNCQkRFRkIsXG4gIFwibGlnaHRlbi0zXCI6ICAjOTBDQUY5LFxuICBcImxpZ2h0ZW4tMlwiOiAgIzY0QjVGNixcbiAgXCJsaWdodGVuLTFcIjogICM0MkE1RjUsXG4gIFwiZGFya2VuLTFcIjogICAjMUU4OEU1LFxuICBcImRhcmtlbi0yXCI6ICAgIzE5NzZEMixcbiAgXCJkYXJrZW4tM1wiOiAgICMxNTY1QzAsXG4gIFwiZGFya2VuLTRcIjogICAjMEQ0N0ExLFxuICBcImFjY2VudC0xXCI6ICAgICM4MkIxRkYsXG4gIFwiYWNjZW50LTJcIjogICAgIzQ0OEFGRixcbiAgXCJhY2NlbnQtM1wiOiAgICAjMjk3OUZGLFxuICBcImFjY2VudC00XCI6ICAgICMyOTYyRkZcbik7XG5cbiRsaWdodC1ibHVlOiAoXG4gIFwiYmFzZVwiOiAgICAgICAjMDNhOWY0LFxuICBcImxpZ2h0ZW4tNVwiOiAgI2UxZjVmZSxcbiAgXCJsaWdodGVuLTRcIjogICNiM2U1ZmMsXG4gIFwibGlnaHRlbi0zXCI6ICAjODFkNGZhLFxuICBcImxpZ2h0ZW4tMlwiOiAgIzRmYzNmNyxcbiAgXCJsaWdodGVuLTFcIjogICMyOWI2ZjYsXG4gIFwiZGFya2VuLTFcIjogICAjMDM5YmU1LFxuICBcImRhcmtlbi0yXCI6ICAgIzAyODhkMSxcbiAgXCJkYXJrZW4tM1wiOiAgICMwMjc3YmQsXG4gIFwiZGFya2VuLTRcIjogICAjMDE1NzliLFxuICBcImFjY2VudC0xXCI6ICAgICM4MGQ4ZmYsXG4gIFwiYWNjZW50LTJcIjogICAgIzQwYzRmZixcbiAgXCJhY2NlbnQtM1wiOiAgICAjMDBiMGZmLFxuICBcImFjY2VudC00XCI6ICAgICMwMDkxZWFcbik7XG5cbiRjeWFuOiAoXG4gIFwiYmFzZVwiOiAgICAgICAjMDBiY2Q0LFxuICBcImxpZ2h0ZW4tNVwiOiAgI2UwZjdmYSxcbiAgXCJsaWdodGVuLTRcIjogICNiMmViZjIsXG4gIFwibGlnaHRlbi0zXCI6ICAjODBkZWVhLFxuICBcImxpZ2h0ZW4tMlwiOiAgIzRkZDBlMSxcbiAgXCJsaWdodGVuLTFcIjogICMyNmM2ZGEsXG4gIFwiZGFya2VuLTFcIjogICAjMDBhY2MxLFxuICBcImRhcmtlbi0yXCI6ICAgIzAwOTdhNyxcbiAgXCJkYXJrZW4tM1wiOiAgICMwMDgzOGYsXG4gIFwiZGFya2VuLTRcIjogICAjMDA2MDY0LFxuICBcImFjY2VudC0xXCI6ICAgICM4NGZmZmYsXG4gIFwiYWNjZW50LTJcIjogICAgIzE4ZmZmZixcbiAgXCJhY2NlbnQtM1wiOiAgICAjMDBlNWZmLFxuICBcImFjY2VudC00XCI6ICAgICMwMGI4ZDRcbik7XG5cbiR0ZWFsOiAoXG4gIFwiYmFzZVwiOiAgICAgICAjMDA5Njg4LFxuICBcImxpZ2h0ZW4tNVwiOiAgI2UwZjJmMSxcbiAgXCJsaWdodGVuLTRcIjogICNiMmRmZGIsXG4gIFwibGlnaHRlbi0zXCI6ICAjODBjYmM0LFxuICBcImxpZ2h0ZW4tMlwiOiAgIzRkYjZhYyxcbiAgXCJsaWdodGVuLTFcIjogICMyNmE2OWEsXG4gIFwiZGFya2VuLTFcIjogICAjMDA4OTdiLFxuICBcImRhcmtlbi0yXCI6ICAgIzAwNzk2YixcbiAgXCJkYXJrZW4tM1wiOiAgICMwMDY5NWMsXG4gIFwiZGFya2VuLTRcIjogICAjMDA0ZDQwLFxuICBcImFjY2VudC0xXCI6ICAgICNhN2ZmZWIsXG4gIFwiYWNjZW50LTJcIjogICAgIzY0ZmZkYSxcbiAgXCJhY2NlbnQtM1wiOiAgICAjMWRlOWI2LFxuICBcImFjY2VudC00XCI6ICAgICMwMGJmYTVcbik7XG5cbiRncmVlbjogKFxuICBcImJhc2VcIjogICAgICAgIzRDQUY1MCxcbiAgXCJsaWdodGVuLTVcIjogICNFOEY1RTksXG4gIFwibGlnaHRlbi00XCI6ICAjQzhFNkM5LFxuICBcImxpZ2h0ZW4tM1wiOiAgI0E1RDZBNyxcbiAgXCJsaWdodGVuLTJcIjogICM4MUM3ODQsXG4gIFwibGlnaHRlbi0xXCI6ICAjNjZCQjZBLFxuICBcImRhcmtlbi0xXCI6ICAgIzQzQTA0NyxcbiAgXCJkYXJrZW4tMlwiOiAgICMzODhFM0MsXG4gIFwiZGFya2VuLTNcIjogICAjMkU3RDMyLFxuICBcImRhcmtlbi00XCI6ICAgIzFCNUUyMCxcbiAgXCJhY2NlbnQtMVwiOiAgICAjQjlGNkNBLFxuICBcImFjY2VudC0yXCI6ICAgICM2OUYwQUUsXG4gIFwiYWNjZW50LTNcIjogICAgIzAwRTY3NixcbiAgXCJhY2NlbnQtNFwiOiAgICAjMDBDODUzXG4pO1xuXG4kbGlnaHQtZ3JlZW46IChcbiAgXCJiYXNlXCI6ICAgICAgICM4YmMzNGEsXG4gIFwibGlnaHRlbi01XCI6ICAjZjFmOGU5LFxuICBcImxpZ2h0ZW4tNFwiOiAgI2RjZWRjOCxcbiAgXCJsaWdodGVuLTNcIjogICNjNWUxYTUsXG4gIFwibGlnaHRlbi0yXCI6ICAjYWVkNTgxLFxuICBcImxpZ2h0ZW4tMVwiOiAgIzljY2M2NSxcbiAgXCJkYXJrZW4tMVwiOiAgICM3Y2IzNDIsXG4gIFwiZGFya2VuLTJcIjogICAjNjg5ZjM4LFxuICBcImRhcmtlbi0zXCI6ICAgIzU1OGIyZixcbiAgXCJkYXJrZW4tNFwiOiAgICMzMzY5MWUsXG4gIFwiYWNjZW50LTFcIjogICAgI2NjZmY5MCxcbiAgXCJhY2NlbnQtMlwiOiAgICAjYjJmZjU5LFxuICBcImFjY2VudC0zXCI6ICAgICM3NmZmMDMsXG4gIFwiYWNjZW50LTRcIjogICAgIzY0ZGQxN1xuKTtcblxuJGxpbWU6IChcbiAgXCJiYXNlXCI6ICAgICAgICNjZGRjMzksXG4gIFwibGlnaHRlbi01XCI6ICAjZjlmYmU3LFxuICBcImxpZ2h0ZW4tNFwiOiAgI2YwZjRjMyxcbiAgXCJsaWdodGVuLTNcIjogICNlNmVlOWMsXG4gIFwibGlnaHRlbi0yXCI6ICAjZGNlNzc1LFxuICBcImxpZ2h0ZW4tMVwiOiAgI2Q0ZTE1NyxcbiAgXCJkYXJrZW4tMVwiOiAgICNjMGNhMzMsXG4gIFwiZGFya2VuLTJcIjogICAjYWZiNDJiLFxuICBcImRhcmtlbi0zXCI6ICAgIzllOWQyNCxcbiAgXCJkYXJrZW4tNFwiOiAgICM4Mjc3MTcsXG4gIFwiYWNjZW50LTFcIjogICAgI2Y0ZmY4MSxcbiAgXCJhY2NlbnQtMlwiOiAgICAjZWVmZjQxLFxuICBcImFjY2VudC0zXCI6ICAgICNjNmZmMDAsXG4gIFwiYWNjZW50LTRcIjogICAgI2FlZWEwMFxuKTtcblxuJHllbGxvdzogKFxuICBcImJhc2VcIjogICAgICAgI2ZmZWIzYixcbiAgXCJsaWdodGVuLTVcIjogICNmZmZkZTcsXG4gIFwibGlnaHRlbi00XCI6ICAjZmZmOWM0LFxuICBcImxpZ2h0ZW4tM1wiOiAgI2ZmZjU5ZCxcbiAgXCJsaWdodGVuLTJcIjogICNmZmYxNzYsXG4gIFwibGlnaHRlbi0xXCI6ICAjZmZlZTU4LFxuICBcImRhcmtlbi0xXCI6ICAgI2ZkZDgzNSxcbiAgXCJkYXJrZW4tMlwiOiAgICNmYmMwMmQsXG4gIFwiZGFya2VuLTNcIjogICAjZjlhODI1LFxuICBcImRhcmtlbi00XCI6ICAgI2Y1N2YxNyxcbiAgXCJhY2NlbnQtMVwiOiAgICAjZmZmZjhkLFxuICBcImFjY2VudC0yXCI6ICAgICNmZmZmMDAsXG4gIFwiYWNjZW50LTNcIjogICAgI2ZmZWEwMCxcbiAgXCJhY2NlbnQtNFwiOiAgICAjZmZkNjAwXG4pO1xuXG4kYW1iZXI6IChcbiAgXCJiYXNlXCI6ICAgICAgICNmZmMxMDcsXG4gIFwibGlnaHRlbi01XCI6ICAjZmZmOGUxLFxuICBcImxpZ2h0ZW4tNFwiOiAgI2ZmZWNiMyxcbiAgXCJsaWdodGVuLTNcIjogICNmZmUwODIsXG4gIFwibGlnaHRlbi0yXCI6ICAjZmZkNTRmLFxuICBcImxpZ2h0ZW4tMVwiOiAgI2ZmY2EyOCxcbiAgXCJkYXJrZW4tMVwiOiAgICNmZmIzMDAsXG4gIFwiZGFya2VuLTJcIjogICAjZmZhMDAwLFxuICBcImRhcmtlbi0zXCI6ICAgI2ZmOGYwMCxcbiAgXCJkYXJrZW4tNFwiOiAgICNmZjZmMDAsXG4gIFwiYWNjZW50LTFcIjogICAgI2ZmZTU3ZixcbiAgXCJhY2NlbnQtMlwiOiAgICAjZmZkNzQwLFxuICBcImFjY2VudC0zXCI6ICAgICNmZmM0MDAsXG4gIFwiYWNjZW50LTRcIjogICAgI2ZmYWIwMFxuKTtcblxuJG9yYW5nZTogKFxuICBcImJhc2VcIjogICAgICAgI2ZmOTgwMCxcbiAgXCJsaWdodGVuLTVcIjogICNmZmYzZTAsXG4gIFwibGlnaHRlbi00XCI6ICAjZmZlMGIyLFxuICBcImxpZ2h0ZW4tM1wiOiAgI2ZmY2M4MCxcbiAgXCJsaWdodGVuLTJcIjogICNmZmI3NGQsXG4gIFwibGlnaHRlbi0xXCI6ICAjZmZhNzI2LFxuICBcImRhcmtlbi0xXCI6ICAgI2ZiOGMwMCxcbiAgXCJkYXJrZW4tMlwiOiAgICNmNTdjMDAsXG4gIFwiZGFya2VuLTNcIjogICAjZWY2YzAwLFxuICBcImRhcmtlbi00XCI6ICAgI2U2NTEwMCxcbiAgXCJhY2NlbnQtMVwiOiAgICAjZmZkMTgwLFxuICBcImFjY2VudC0yXCI6ICAgICNmZmFiNDAsXG4gIFwiYWNjZW50LTNcIjogICAgI2ZmOTEwMCxcbiAgXCJhY2NlbnQtNFwiOiAgICAjZmY2ZDAwXG4pO1xuXG4kZGVlcC1vcmFuZ2U6IChcbiAgXCJiYXNlXCI6ICAgICAgICNmZjU3MjIsXG4gIFwibGlnaHRlbi01XCI6ICAjZmJlOWU3LFxuICBcImxpZ2h0ZW4tNFwiOiAgI2ZmY2NiYyxcbiAgXCJsaWdodGVuLTNcIjogICNmZmFiOTEsXG4gIFwibGlnaHRlbi0yXCI6ICAjZmY4YTY1LFxuICBcImxpZ2h0ZW4tMVwiOiAgI2ZmNzA0MyxcbiAgXCJkYXJrZW4tMVwiOiAgICNmNDUxMWUsXG4gIFwiZGFya2VuLTJcIjogICAjZTY0YTE5LFxuICBcImRhcmtlbi0zXCI6ICAgI2Q4NDMxNSxcbiAgXCJkYXJrZW4tNFwiOiAgICNiZjM2MGMsXG4gIFwiYWNjZW50LTFcIjogICAgI2ZmOWU4MCxcbiAgXCJhY2NlbnQtMlwiOiAgICAjZmY2ZTQwLFxuICBcImFjY2VudC0zXCI6ICAgICNmZjNkMDAsXG4gIFwiYWNjZW50LTRcIjogICAgI2RkMmMwMFxuKTtcblxuJGJyb3duOiAoXG4gIFwiYmFzZVwiOiAgICAgICAjNzk1NTQ4LFxuICBcImxpZ2h0ZW4tNVwiOiAgI2VmZWJlOSxcbiAgXCJsaWdodGVuLTRcIjogICNkN2NjYzgsXG4gIFwibGlnaHRlbi0zXCI6ICAjYmNhYWE0LFxuICBcImxpZ2h0ZW4tMlwiOiAgI2ExODg3ZixcbiAgXCJsaWdodGVuLTFcIjogICM4ZDZlNjMsXG4gIFwiZGFya2VuLTFcIjogICAjNmQ0YzQxLFxuICBcImRhcmtlbi0yXCI6ICAgIzVkNDAzNyxcbiAgXCJkYXJrZW4tM1wiOiAgICM0ZTM0MmUsXG4gIFwiZGFya2VuLTRcIjogICAjM2UyNzIzXG4pO1xuXG4kYmx1ZS1ncmV5OiAoXG4gIFwiYmFzZVwiOiAgICAgICAjNjA3ZDhiLFxuICBcImxpZ2h0ZW4tNVwiOiAgI2VjZWZmMSxcbiAgXCJsaWdodGVuLTRcIjogICNjZmQ4ZGMsXG4gIFwibGlnaHRlbi0zXCI6ICAjYjBiZWM1LFxuICBcImxpZ2h0ZW4tMlwiOiAgIzkwYTRhZSxcbiAgXCJsaWdodGVuLTFcIjogICM3ODkwOWMsXG4gIFwiZGFya2VuLTFcIjogICAjNTQ2ZTdhLFxuICBcImRhcmtlbi0yXCI6ICAgIzQ1NWE2NCxcbiAgXCJkYXJrZW4tM1wiOiAgICMzNzQ3NGYsXG4gIFwiZGFya2VuLTRcIjogICAjMjYzMjM4XG4pO1xuXG4kZ3JleTogKFxuICBcImJhc2VcIjogICAgICAgIzllOWU5ZSxcbiAgXCJsaWdodGVuLTVcIjogICNmYWZhZmEsXG4gIFwibGlnaHRlbi00XCI6ICAjZjVmNWY1LFxuICBcImxpZ2h0ZW4tM1wiOiAgI2VlZWVlZSxcbiAgXCJsaWdodGVuLTJcIjogICNlMGUwZTAsXG4gIFwibGlnaHRlbi0xXCI6ICAjYmRiZGJkLFxuICBcImRhcmtlbi0xXCI6ICAgIzc1NzU3NSxcbiAgXCJkYXJrZW4tMlwiOiAgICM2MTYxNjEsXG4gIFwiZGFya2VuLTNcIjogICAjNDI0MjQyLFxuICBcImRhcmtlbi00XCI6ICAgIzIxMjEyMVxuKTtcblxuJHNoYWRlczogKFxuICBcImJsYWNrXCI6ICAgICAgICAjMDAwMDAwLFxuICBcIndoaXRlXCI6ICAgICAgICAjRkZGRkZGLFxuICBcInRyYW5zcGFyZW50XCI6ICB0cmFuc3BhcmVudFxuKTtcblxuJGNvbG9yczogKFxuICBcIm1hdGVyaWFsaXplLXJlZFwiOiAkbWF0ZXJpYWxpemUtcmVkLFxuICBcInJlZFwiOiAkcmVkLFxuICBcInBpbmtcIjogJHBpbmssXG4gIFwicHVycGxlXCI6ICRwdXJwbGUsXG4gIFwiZGVlcC1wdXJwbGVcIjogJGRlZXAtcHVycGxlLFxuICBcImluZGlnb1wiOiAkaW5kaWdvLFxuICBcImJsdWVcIjogJGJsdWUsXG4gIFwibGlnaHQtYmx1ZVwiOiAkbGlnaHQtYmx1ZSxcbiAgXCJjeWFuXCI6ICRjeWFuLFxuICBcInRlYWxcIjogJHRlYWwsXG4gIFwiZ3JlZW5cIjogJGdyZWVuLFxuICBcImxpZ2h0LWdyZWVuXCI6ICRsaWdodC1ncmVlbixcbiAgXCJsaW1lXCI6ICRsaW1lLFxuICBcInllbGxvd1wiOiAkeWVsbG93LFxuICBcImFtYmVyXCI6ICRhbWJlcixcbiAgXCJvcmFuZ2VcIjogJG9yYW5nZSxcbiAgXCJkZWVwLW9yYW5nZVwiOiAkZGVlcC1vcmFuZ2UsXG4gIFwiYnJvd25cIjogJGJyb3duLFxuICBcImJsdWUtZ3JleVwiOiAkYmx1ZS1ncmV5LFxuICBcImdyZXlcIjogJGdyZXksXG4gIFwic2hhZGVzXCI6ICRzaGFkZXNcbik7XG5cblxuLy8gQ29sb3IgQ2xhc3Nlc1xuXG5AZWFjaCAkY29sb3JfbmFtZSwgJGNvbG9yIGluICRjb2xvcnMge1xuICBAZWFjaCAkY29sb3JfdHlwZSwgJGNvbG9yX3ZhbHVlIGluICRjb2xvciB7XG4gICAgQGlmICRjb2xvcl90eXBlID09IFwiYmFzZVwiIHtcbiAgICAgIC4jeyRjb2xvcl9uYW1lfSB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl92YWx1ZSAhaW1wb3J0YW50O1xuICAgICAgfVxuICAgICAgLiN7JGNvbG9yX25hbWV9LXRleHQge1xuICAgICAgICBjb2xvcjogJGNvbG9yX3ZhbHVlICFpbXBvcnRhbnQ7XG4gICAgICB9XG4gICAgfVxuICAgIEBlbHNlIHtcbiAgICAgIC4jeyRjb2xvcl9uYW1lfS4jeyRjb2xvcl90eXBlfSB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl92YWx1ZSAhaW1wb3J0YW50O1xuICAgICAgfVxuICAgICAgLiN7JGNvbG9yX25hbWV9LXRleHQudGV4dC0jeyRjb2xvcl90eXBlfSB7XG4gICAgICAgIGNvbG9yOiAkY29sb3JfdmFsdWUgIWltcG9ydGFudDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLy8gU2hhZGUgY2xhc3Nlc1xuQGVhY2ggJGNvbG9yLCAkY29sb3JfdmFsdWUgaW4gJHNoYWRlcyB7XG4gIC4jeyRjb2xvcn0ge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcl92YWx1ZSAhaW1wb3J0YW50O1xuICB9XG4gIC4jeyRjb2xvcn0tdGV4dCB7XG4gICAgY29sb3I6ICRjb2xvcl92YWx1ZSAhaW1wb3J0YW50O1xuICB9XG59XG5cblxuLy8gdXNhZ2U6IGNvbG9yKFwibmFtZV9vZl9jb2xvclwiLCBcInR5cGVfb2ZfY29sb3JcIilcbi8vIHRvIGF2b2lkIHRvIHJlcGVhdGluZyBtYXAtZ2V0KCRjb2xvcnMsIC4uLilcblxuQGZ1bmN0aW9uIGNvbG9yKCRjb2xvciwgJHR5cGUpIHtcbiAgQGlmIG1hcC1oYXMta2V5KCRjb2xvcnMsICRjb2xvcikge1xuICAgICRjdXJyX2NvbG9yOiBtYXAtZ2V0KCRjb2xvcnMsICRjb2xvcik7XG4gICAgQGlmIG1hcC1oYXMta2V5KCRjdXJyX2NvbG9yLCAkdHlwZSkge1xuICAgICAgQHJldHVybiBtYXAtZ2V0KCRjdXJyX2NvbG9yLCAkdHlwZSk7XG4gICAgfVxuICB9XG4gIEB3YXJuIFwiVW5rbm93biBgI3tuYW1lfWAgaW4gJGNvbG9ycy5cIjtcbiAgQHJldHVybiBudWxsO1xufVxuXG4iLCIvKiFcbiAqIENsb2NrUGlja2VyIHYwLjAuNyBmb3IgalF1ZXJ5IChodHRwOi8vd2VhcmVvdXRtYW4uZ2l0aHViLmlvL2Nsb2NrcGlja2VyLylcbiAqIENvcHlyaWdodCAyMDE0IFdhbmcgU2hlbndlaS5cbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3dlYXJlb3V0bWFuL2Nsb2NrcGlja2VyL2Jsb2IvZ2gtcGFnZXMvTElDRU5TRSlcbiAqXG4gKiBGdXJ0aGVyIG1vZGlmaWVkXG4gKiBDb3B5cmlnaHQgMjAxNSBDaGluZyBZYXcgSGFvLlxuICpcbiAqIEJvb3RzdHJhcCB2My4xLjEgKGh0dHA6Ly9nZXRib290c3RyYXAuY29tKVxuICogQ29weXJpZ2h0IDIwMTEtMjAxNCBUd2l0dGVyLCBJbmMuXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21hc3Rlci9MSUNFTlNFKVxuICovXG5cbi5waWNrZXJfX2JveCB7XG4gICAgYmFja2dyb3VuZDogJGNsb2NrcGlja2VyLXBpY2tlci1ib3gtYmFja2dyb3VuZDtcbn1cblxuLnBpY2tlcl9fZGF0ZS1kaXNwbGF5IHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY2xvY2twaWNrZXItcGlja2VyLWJveC1kYXRlLWRpc3BsYXktYmFja2dyb3VuZC1jb2xvcjtcbn1cblxuLmNsb2NrcGlja2VyLWRpc3BsYXkge1xuICAgIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIG1hcmdpbjogYXV0bztcbiAgICBoZWlnaHQ6IDg1cHg7XG4gICAgZm9udC1zaXplOiA3MHB4O1xuICAgIHBhZGRpbmc6IDEwcHg7XG4gICAgcGFkZGluZy1ib3R0b206IDBweDtcbiAgICBjb2xvcjogJGNsb2NrcGlja2VyLXByaW1hcnktY29sb3I7XG59XG5cbi5jbG9ja3BpY2tlci1kaXNwbGF5LWNvbHVtbiB7XG4gICAgZmxvYXQ6IGxlZnQ7XG59XG5cbi5jbG9ja3BpY2tlci1kaXNwbGF5LWFtLXBtIHtcbiAgICBwYWRkaW5nLWxlZnQ6IDVweDtcbiAgICB2ZXJ0aWNhbC1hbGlnbjogYm90dG9tO1xuICAgIGhlaWdodDogODVweDtcbn1cblxuLmNsb2NrcGlja2VyLXNwYW4tYW0tcG0ge1xuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICBmb250LXNpemU6IDIzcHg7XG4gICAgbGluZS1oZWlnaHQ6IDI1cHg7XG4gICAgY29sb3I6ICRjbG9ja3BpY2tlci1wcmltYXJ5LWNvbG9yO1xufVxuXG4uY2xvY2twaWNrZXItc3Bhbi1ob3Vycyxcbi5jbG9ja3BpY2tlci1zcGFuLW1pbnV0ZXMge1xuICAgIC13ZWJraXQtYW5pbWF0aW9uLWR1cmF0aW9uOiA1MDBtcztcbiAgICBhbmltYXRpb24tZHVyYXRpb246IDUwMG1zO1xuICAgIC13ZWJraXQtYW5pbWF0aW9uLWZpbGwtbW9kZTogYm90aDtcbiAgICBhbmltYXRpb24tZmlsbC1tb2RlOiBib3RoO1xuICAgIC13ZWJraXQtdHJhbnNpdGlvbjogY29sb3IgNTAwbXM7XG4gICAgLW1vei10cmFuc2l0aW9uOiBjb2xvciA1MDBtcztcbiAgICAtbXMtdHJhbnNpdGlvbjogY29sb3IgNTAwbXM7XG4gICAgLW8tdHJhbnNpdGlvbjogY29sb3IgNTAwbXM7XG4gICAgdHJhbnNpdGlvbjogY29sb3IgNTAwbXM7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xufVxuXG5ALXdlYmtpdC1rZXlmcmFtZXMgcHVsc2Uge1xuICAgIGZyb20ge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogc2NhbGUzZCgxLCAxLCAxKTtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZTNkKDEsIDEsIDEpO1xuICAgIH1cbiAgICA1MCUge1xuICAgICAgICAtd2Via2l0LXRyYW5zZm9ybTogc2NhbGUzZCgxLjEsIDEuMSwgMS4xKTtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZTNkKDEuMSwgMS4xLCAxLjEpO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIC13ZWJraXQtdHJhbnNmb3JtOiBzY2FsZTNkKDEsIDEsIDEpO1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlM2QoMSwgMSwgMSk7XG4gICAgfVxufVxuXG5ALW1vei1rZXlmcmFtZXMgcHVsc2Uge1xuICAgIGZyb20ge1xuICAgICAgICAtbW96LXRyYW5zZm9ybTogc2NhbGUzZCgxLCAxLCAxKTtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZTNkKDEsIDEsIDEpO1xuICAgIH1cbiAgICA1MCUge1xuICAgICAgICAtbW96LXRyYW5zZm9ybTogc2NhbGUzZCgxLjEsIDEuMSwgMS4xKTtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZTNkKDEuMSwgMS4xLCAxLjEpO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIC1tb3otdHJhbnNmb3JtOiBzY2FsZTNkKDEsIDEsIDEpO1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlM2QoMSwgMSwgMSk7XG4gICAgfVxufVxuXG5ALW1zLWtleWZyYW1lcyBwdWxzZSB7XG4gICAgZnJvbSB7XG4gICAgICAgIC1tcy10cmFuc2Zvcm06IHNjYWxlM2QoMSwgMSwgMSk7XG4gICAgICAgIHRyYW5zZm9ybTogc2NhbGUzZCgxLCAxLCAxKTtcbiAgICB9XG4gICAgNTAlIHtcbiAgICAgICAgLW1zLXRyYW5zZm9ybTogc2NhbGUzZCgxLjEsIDEuMSwgMS4xKTtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZTNkKDEuMSwgMS4xLCAxLjEpO1xuICAgIH1cbiAgICB0byB7XG4gICAgICAgIC1tcy10cmFuc2Zvcm06IHNjYWxlM2QoMSwgMSwgMSk7XG4gICAgICAgIHRyYW5zZm9ybTogc2NhbGUzZCgxLCAxLCAxKTtcbiAgICB9XG59XG5cbkAtby1rZXlmcmFtZXMgcHVsc2Uge1xuICAgIGZyb20ge1xuICAgICAgICAtby10cmFuc2Zvcm06IHNjYWxlM2QoMSwgMSwgMSk7XG4gICAgICAgIHRyYW5zZm9ybTogc2NhbGUzZCgxLCAxLCAxKTtcbiAgICB9XG4gICAgNTAlIHtcbiAgICAgICAgLW8tdHJhbnNmb3JtOiBzY2FsZTNkKDEuMSwgMS4xLCAxLjEpO1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlM2QoMS4xLCAxLjEsIDEuMSk7XG4gICAgfVxuICAgIHRvIHtcbiAgICAgICAgLW8tdHJhbnNmb3JtOiBzY2FsZTNkKDEsIDEsIDEpO1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlM2QoMSwgMSwgMSk7XG4gICAgfVxufVxuXG5Aa2V5ZnJhbWVzIHB1bHNlIHtcbiAgICBmcm9tIHtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZTNkKDEsIDEsIDEpO1xuICAgIH1cbiAgICA1MCUge1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlM2QoMS4xLCAxLjEsIDEuMSk7XG4gICAgfVxuICAgIHRvIHtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZTNkKDEsIDEsIDEpO1xuICAgIH1cbn1cblxuI2NsaWNrLWFtLFxuI2NsaWNrLXBtIHtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG59XG5cbi5jbG9ja3BpY2tlci1zcGFuLWhvdXJzLFxuLmNsb2NrcGlja2VyLXNwYW4tbWludXRlcyxcbiNjbGljay1hbSxcbiNjbGljay1wbSB7XG4gICAgJi50ZXh0LXByaW1hcnkge1xuICAgICAgICAtd2Via2l0LWFuaW1hdGlvbi1uYW1lOiBwdWxzZTtcbiAgICAgICAgYW5pbWF0aW9uLW5hbWU6IHB1bHNlO1xuICAgICAgICBjb2xvcjogd2hpdGU7XG4gICAgfVxufVxuXG4uY2xvY2twaWNrZXItbW92aW5nIHtcbiAgICBjdXJzb3I6IG1vdmU7XG59XG5cbi5jbG9ja3BpY2tlci1wbGF0ZSB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2VlZWVlZTtcbiAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgd2lkdGg6IDI3MHB4O1xuICAgIGhlaWdodDogMjcwcHg7XG4gICAgb3ZlcmZsb3c6IHZpc2libGU7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIG1hcmdpbjogYXV0bztcbiAgICBtYXJnaW4tdG9wOiAyMHB4O1xuICAgIC8qIERpc2FibGUgdGV4dCBzZWxlY3Rpb24gaGlnaGxpZ2h0aW5nLiBUaGFua3MgdG8gSGVybWFueWEgKi9cbiAgICAtd2Via2l0LXRvdWNoLWNhbGxvdXQ6IG5vbmU7XG4gICAgLXdlYmtpdC11c2VyLXNlbGVjdDogbm9uZTtcbiAgICAta2h0bWwtdXNlci1zZWxlY3Q6IG5vbmU7XG4gICAgLW1vei11c2VyLXNlbGVjdDogbm9uZTtcbiAgICAtbXMtdXNlci1zZWxlY3Q6IG5vbmU7XG4gICAgdXNlci1zZWxlY3Q6IG5vbmU7XG59XG5cbi5jbG9ja3BpY2tlci1jYW52YXMsXG4uY2xvY2twaWNrZXItZGlhbCB7XG4gICAgd2lkdGg6IDI3MHB4O1xuICAgIGhlaWdodDogMjcwcHg7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIGxlZnQ6IC0xcHg7XG4gICAgdG9wOiAtMXB4O1xufVxuXG4uY2xvY2twaWNrZXItbWludXRlcyB7XG4gICAgdmlzaWJpbGl0eTogaGlkZGVuO1xufVxuXG4uY2xvY2twaWNrZXItdGljayB7XG4gICAgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgIGNvbG9yOiAkY2xvY2twaWNrZXItdGljay1jb2xvcjtcbiAgICBsaW5lLWhlaWdodDogNDBweDtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgd2lkdGg6IDQwcHg7XG4gICAgaGVpZ2h0OiA0MHB4O1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgLXdlYmtpdC10cmFuc2l0aW9uOiBiYWNrZ3JvdW5kLWNvbG9yIDMwMG1zO1xuICAgIC1tb3otdHJhbnNpdGlvbjogYmFja2dyb3VuZC1jb2xvciAzMDBtcztcbiAgICAtbXMtdHJhbnNpdGlvbjogYmFja2dyb3VuZC1jb2xvciAzMDBtcztcbiAgICAtby10cmFuc2l0aW9uOiBiYWNrZ3JvdW5kLWNvbG9yIDMwMG1zO1xuICAgIHRyYW5zaXRpb246IGJhY2tncm91bmQtY29sb3IgMzAwbXM7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJGNsb2NrcGlja2VyLXRpY2stYmFja2dyb3VuZC1jb2xvcjtcbiAgICAmLmFjdGl2ZSxcbiAgICAmOmhvdmVyIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogJGNsb2NrcGlja2VyLXRpY2stYmFja2dyb3VuZC1jb2xvci1hY3RpdmU7XG4gICAgfVxufVxuXG4uY2xvY2twaWNrZXItZGlhbCB7XG4gICAgLXdlYmtpdC10cmFuc2l0aW9uOiAtd2Via2l0LXRyYW5zZm9ybSAzNTBtcywgb3BhY2l0eSAzNTBtcztcbiAgICAtbW96LXRyYW5zaXRpb246IC1tb3otdHJhbnNmb3JtIDM1MG1zLCBvcGFjaXR5IDM1MG1zO1xuICAgIC1tcy10cmFuc2l0aW9uOiAtbXMtdHJhbnNmb3JtIDM1MG1zLCBvcGFjaXR5IDM1MG1zO1xuICAgIC1vLXRyYW5zaXRpb246IC1vLXRyYW5zZm9ybSAzNTBtcywgb3BhY2l0eSAzNTBtcztcbiAgICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMzUwbXMsIG9wYWNpdHkgMzUwbXM7XG59XG5cbi5jbG9ja3BpY2tlci1kaWFsLW91dCB7XG4gICAgb3BhY2l0eTogMDtcbn1cblxuLmNsb2NrcGlja2VyLWhvdXJzLmNsb2NrcGlja2VyLWRpYWwtb3V0IHtcbiAgICAtd2Via2l0LXRyYW5zZm9ybTogc2NhbGUoMS4yLCAxLjIpO1xuICAgIC1tb3otdHJhbnNmb3JtOiBzY2FsZSgxLjIsIDEuMik7XG4gICAgLW1zLXRyYW5zZm9ybTogc2NhbGUoMS4yLCAxLjIpO1xuICAgIC1vLXRyYW5zZm9ybTogc2NhbGUoMS4yLCAxLjIpO1xuICAgIHRyYW5zZm9ybTogc2NhbGUoMS4yLCAxLjIpO1xufVxuXG4uY2xvY2twaWNrZXItbWludXRlcy5jbG9ja3BpY2tlci1kaWFsLW91dCB7XG4gICAgLXdlYmtpdC10cmFuc2Zvcm06IHNjYWxlKC44LCAuOCk7XG4gICAgLW1vei10cmFuc2Zvcm06IHNjYWxlKC44LCAuOCk7XG4gICAgLW1zLXRyYW5zZm9ybTogc2NhbGUoLjgsIC44KTtcbiAgICAtby10cmFuc2Zvcm06IHNjYWxlKC44LCAuOCk7XG4gICAgdHJhbnNmb3JtOiBzY2FsZSguOCwgLjgpO1xufVxuXG4uY2xvY2twaWNrZXItY2FudmFzIHtcbiAgICAtd2Via2l0LXRyYW5zaXRpb246IG9wYWNpdHkgMzAwbXM7XG4gICAgLW1vei10cmFuc2l0aW9uOiBvcGFjaXR5IDMwMG1zO1xuICAgIC1tcy10cmFuc2l0aW9uOiBvcGFjaXR5IDMwMG1zO1xuICAgIC1vLXRyYW5zaXRpb246IG9wYWNpdHkgMzAwbXM7XG4gICAgdHJhbnNpdGlvbjogb3BhY2l0eSAzMDBtcztcbn1cblxuLmNsb2NrcGlja2VyLWNhbnZhcy1vdXQge1xuICAgIG9wYWNpdHk6IDAuMjU7XG59XG5cbi5jbG9ja3BpY2tlci1jYW52YXMtYmVhcmluZyB7XG4gICAgc3Ryb2tlOiBub25lO1xuICAgIGZpbGw6ICRjbG9ja3BpY2tlci1jYW52YXMtYmVhcmluZy1maWxsO1xufVxuXG4uY2xvY2twaWNrZXItY2FudmFzLWZnIHtcbiAgICBzdHJva2U6IG5vbmU7XG4gICAgZmlsbDogcmdiYSgkY2xvY2twaWNrZXItY2FudmFzLWZnLWZpbGwsIDApO1xuICAgICYuYWN0aXZlIHtcbiAgICAgICAgZmlsbDogcmdiYSgkY2xvY2twaWNrZXItY2FudmFzLWZnLWZpbGwsIDAuNSk7XG4gICAgfVxufVxuXG4uY2xvY2twaWNrZXItY2FudmFzLWJnIHtcbiAgICBzdHJva2U6IG5vbmU7XG4gICAgZmlsbDogJGNsb2NrcGlja2VyLWNhbnZhcy1iZy1maWxsO1xufVxuXG4uY2xvY2twaWNrZXItY2FudmFzLWJnLXRyYW5zIHtcbiAgICBmaWxsOiAkY2xvY2twaWNrZXItY2FudmFzLWJnLWZpbGw7XG59XG5cbi5jbG9ja3BpY2tlci1jYW52YXMgbGluZSB7XG4gICAgc3Ryb2tlOiAkY2xvY2twaWNrZXItY2FudmFzLWJnLXN0cm9rZTtcbiAgICBzdHJva2Utd2lkdGg6IDE7XG4gICAgc3Ryb2tlLWxpbmVjYXA6IHJvdW5kO1xuICAgIC8qc2hhcGUtcmVuZGVyaW5nOiBjcmlzcEVkZ2VzOyovXG59XG5cbi5jbG9ja3BpY2tlci1hbS1wbS1ibG9jayB7XG4gICAgbWFyZ2luLXRvcDogLTEwcHg7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiA1MHB4O1xufVxuXG4vL0FNIFBNIGJ1dHRvbnNcbi5jbG9ja3BpY2tlci1idXR0b24ge1xuICAgICYuYW0tYnV0dG9uIHtcbiAgICAgICAgaGVpZ2h0OiA0NXB4O1xuICAgICAgICB3aWR0aDogNDVweDtcbiAgICAgICAgZmxvYXQ6IGxlZnQ7XG4gICAgfVxuICAgICYucG0tYnV0dG9uIHtcbiAgICAgICAgaGVpZ2h0OiA0NXB4O1xuICAgICAgICB3aWR0aDogNDVweDtcbiAgICAgICAgZmxvYXQ6IHJpZ2h0O1xuICAgIH1cbn1cblxuYnV0dG9uIHtcbiAgICBjb2xvcjogJGNsb2NrcGlja2VyLWJ1dHRvbi1jb2xvcjtcbn1cblxuLy9idXR0b25zXG4uYnRuLWZsb2F0aW5nIHtcbiAgICAmLmJ0bi1mbGF0IHtcbiAgICAgICAgJjpmb2N1cyxcbiAgICAgICAgJjp2aXNpdGVkIHtcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xuICAgICAgICB9XG4gICAgICAgICY6aG92ZXIge1xuICAgICAgICAgICAgYm94LXNoYWRvdzogbm9uZTtcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xuICAgICAgICB9XG4gICAgICAgICYuYWN0aXZlIHtcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoJGNsb2NrcGlja2VyLWJ1dHRvbi1iYWNrZ3JvdW5kLWNvbG9yLCAwLjI1KTtcbiAgICAgICAgfVxuICAgICAgICAmOmFjdGl2ZSB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKCRjbG9ja3BpY2tlci1idXR0b24tYmFja2dyb3VuZC1jb2xvciwgMC41KTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLy9mb290ZXJcbi5waWNrZXJfX2Zvb3RlciB7XG4gICAgLmNsb2NrcGlja2VyLWJ1dHRvbiB7XG4gICAgICAgIG1hcmdpbjogYXV0bztcbiAgICAgICAgbWFyZ2luLXRvcDogMTVweDtcbiAgICAgICAgJjpmb2N1cyB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgICAgICAgfVxuICAgICAgICAmOmFjdGl2ZSB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKCRjbG9ja3BpY2tlci1idXR0b24tYmFja2dyb3VuZC1jb2xvciwgMC4yNSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvL2JveFxuJGNsb2NrcGlja2VyLXBpY2tlci1ib3gtYmFja2dyb3VuZDogI2ZmZiAhZGVmYXVsdDtcbiRjbG9ja3BpY2tlci1waWNrZXItYm94LWRhdGUtZGlzcGxheS1iYWNrZ3JvdW5kLWNvbG9yOiBjb2xvcihcInRlYWxcIiwgXCJsaWdodGVuLTFcIikgIWRlZmF1bHQ7XG4kY2xvY2twaWNrZXItcHJpbWFyeS1jb2xvcjogY29sb3IoXCJ0ZWFsXCIsIFwibGlnaHRlbi00XCIpICFkZWZhdWx0O1xuLy90aWNrXG4kY2xvY2twaWNrZXItdGljay1iYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKGNvbG9yKFwidGVhbFwiLCBcImJhc2VcIiksIDApICFkZWZhdWx0O1xuJGNsb2NrcGlja2VyLXRpY2stYmFja2dyb3VuZC1jb2xvci1hY3RpdmU6IHJnYmEoY29sb3IoXCJ0ZWFsXCIsIFwiYmFzZVwiKSwgMC4yNSkgIWRlZmF1bHQ7XG4kY2xvY2twaWNrZXItdGljay1jb2xvcjogIzY2NiAhZGVmYXVsdDtcbi8vY2FudmFzXG4kY2xvY2twaWNrZXItY2FudmFzLWJlYXJpbmctZmlsbDogcmdiYShjb2xvcihcInRlYWxcIiwgXCJkYXJrZW4tNFwiKSwgMC43NSkgIWRlZmF1bHQ7XG4kY2xvY2twaWNrZXItY2FudmFzLWZnLWZpbGw6IGNvbG9yKFwidGVhbFwiLCBcImRhcmtlbi00XCIpICFkZWZhdWx0O1xuJGNsb2NrcGlja2VyLWNhbnZhcy1iZy1maWxsOiByZ2JhKGNvbG9yKFwidGVhbFwiLCBcImJhc2VcIiksIDAuMjUpICFkZWZhdWx0O1xuJGNsb2NrcGlja2VyLWNhbnZhcy1iZy1zdHJva2U6ICRjbG9ja3BpY2tlci1jYW52YXMtYmctZmlsbCAhZGVmYXVsdDtcbi8vYnV0dG9uc1xuJGNsb2NrcGlja2VyLWJ1dHRvbi1iYWNrZ3JvdW5kLWNvbG9yOiBjb2xvcihcInRlYWxcIiwgXCJiYXNlXCIpICFkZWZhdWx0O1xuJGNsb2NrcGlja2VyLWJ1dHRvbi1jb2xvcjogJGJ1dHRvbi1mbGF0LWNvbG9yICFkZWZhdWx0OyIsIi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICBNYXRlcmlhbGl6ZSB2YXJpYWJsZXNcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG4vKipcbiAqIFRhYmxlIG9mIENvbnRlbnRzOlxuICpcbiAqICAxLiBDb2xvcnNcbiAqICAyLiBCYWRnZXNcbiAqICAzLiBCdXR0b25zXG4gKiAgNC4gQ2FyZHNcbiAqICA1LiBDb2xsYXBzaWJsZVxuICogIDYuIENoaXBzXG4gKiAgNy4gRGF0ZSBQaWNrZXJcbiAqICA4LiBEcm9wZG93blxuICogIDEwLiBGb3Jtc1xuICogIDExLiBHbG9iYWxcbiAqICAxMi4gR3JpZFxuICogIDEzLiBOYXZpZ2F0aW9uIEJhclxuICogIDE0LiBTaWRlIE5hdmlnYXRpb25cbiAqICAxNS4gUGhvdG8gU2xpZGVyXG4gKiAgMTYuIFNwaW5uZXJzIHwgTG9hZGVyc1xuICogIDE3LiBUYWJzXG4gKiAgMTguIFRhYmxlc1xuICogIDE5LiBUb2FzdHNcbiAqICAyMC4gVHlwb2dyYXBoeVxuICogIDIxLiBGb290ZXJcbiAqICAyMi4gRmxvdyBUZXh0XG4gKiAgMjMuIENvbGxlY3Rpb25zXG4gKiAgMjQuIFByb2dyZXNzIEJhclxuICovXG5cblxuLyogMS4gQ29sb3JzXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kcHJpbWFyeS1jb2xvcjogY29sb3IoXCJtYXRlcmlhbGl6ZS1yZWRcIiwgXCJsaWdodGVuLTJcIikgIWRlZmF1bHQ7XG4kcHJpbWFyeS1jb2xvci1saWdodDogbGlnaHRlbigkcHJpbWFyeS1jb2xvciwgMTUlKSAhZGVmYXVsdDtcbiRwcmltYXJ5LWNvbG9yLWRhcms6IGRhcmtlbigkcHJpbWFyeS1jb2xvciwgMTUlKSAhZGVmYXVsdDtcblxuJHNlY29uZGFyeS1jb2xvcjogY29sb3IoXCJ0ZWFsXCIsIFwibGlnaHRlbi0xXCIpICFkZWZhdWx0O1xuJHN1Y2Nlc3MtY29sb3I6IGNvbG9yKFwiZ3JlZW5cIiwgXCJiYXNlXCIpICFkZWZhdWx0O1xuJGVycm9yLWNvbG9yOiBjb2xvcihcInJlZFwiLCBcImJhc2VcIikgIWRlZmF1bHQ7XG4kbGluay1jb2xvcjogY29sb3IoXCJsaWdodC1ibHVlXCIsIFwiZGFya2VuLTFcIikgIWRlZmF1bHQ7XG5cblxuLyogMi4gQmFkZ2VzXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kYmFkZ2UtYmctY29sb3I6ICRzZWNvbmRhcnktY29sb3IgIWRlZmF1bHQ7XG5cblxuLyogMy4gQnV0dG9uc1xuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuLy8gU2hhcmVkIHN0eWxlc1xuJGJ1dHRvbi1ib3JkZXI6IG5vbmUgIWRlZmF1bHQ7XG4kYnV0dG9uLWJhY2tncm91bmQtZm9jdXM6IGxpZ2h0ZW4oJHNlY29uZGFyeS1jb2xvciwgNCUpICFkZWZhdWx0O1xuJGJ1dHRvbi1mb250LXNpemU6IDEuM3JlbSAhZGVmYXVsdDtcbiRidXR0b24taGVpZ2h0OiAzNnB4ICFkZWZhdWx0O1xuJGJ1dHRvbi1wYWRkaW5nOiAwIDJyZW0gIWRlZmF1bHQ7XG4kYnV0dG9uLXJhZGl1czogMnB4ICFkZWZhdWx0O1xuXG4vLyBEaXNhYmxlZCBzdHlsZXNcbiRidXR0b24tZGlzYWJsZWQtYmFja2dyb3VuZDogI0RGREZERiAhZGVmYXVsdDtcbiRidXR0b24tZGlzYWJsZWQtY29sb3I6ICM5RjlGOUYgIWRlZmF1bHQ7XG5cbi8vIFJhaXNlZCBidXR0b25zXG4kYnV0dG9uLXJhaXNlZC1iYWNrZ3JvdW5kOiAkc2Vjb25kYXJ5LWNvbG9yICFkZWZhdWx0O1xuJGJ1dHRvbi1yYWlzZWQtYmFja2dyb3VuZC1ob3ZlcjogbGlnaHRlbigkYnV0dG9uLXJhaXNlZC1iYWNrZ3JvdW5kLCA1JSkgIWRlZmF1bHQ7XG4kYnV0dG9uLXJhaXNlZC1jb2xvcjogI2ZmZiAhZGVmYXVsdDtcblxuLy8gTGFyZ2UgYnV0dG9uc1xuJGJ1dHRvbi1sYXJnZS1pY29uLWZvbnQtc2l6ZTogMS42cmVtICFkZWZhdWx0O1xuJGJ1dHRvbi1sYXJnZS1oZWlnaHQ6ICRidXR0b24taGVpZ2h0ICogMS41ICFkZWZhdWx0O1xuXG4vLyBGbGF0IGJ1dHRvbnNcbiRidXR0b24tZmxhdC1jb2xvcjogIzM0MzQzNCAhZGVmYXVsdDtcbiRidXR0b24tZmxhdC1kaXNhYmxlZC1jb2xvcjogbGlnaHRlbigjOTk5LCAxMCUpICFkZWZhdWx0O1xuXG4vLyBGbG9hdGluZyBidXR0b25zXG4kYnV0dG9uLWZsb2F0aW5nLWJhY2tncm91bmQ6ICRzZWNvbmRhcnktY29sb3IgIWRlZmF1bHQ7XG4kYnV0dG9uLWZsb2F0aW5nLWJhY2tncm91bmQtaG92ZXI6ICRidXR0b24tZmxvYXRpbmctYmFja2dyb3VuZCAhZGVmYXVsdDtcbiRidXR0b24tZmxvYXRpbmctY29sb3I6ICNmZmYgIWRlZmF1bHQ7XG4kYnV0dG9uLWZsb2F0aW5nLXNpemU6IDM3cHggIWRlZmF1bHQ7XG4kYnV0dG9uLWZsb2F0aW5nLWxhcmdlLXNpemU6ICRidXR0b24tZmxvYXRpbmctc2l6ZSAqIDEuNSAhZGVmYXVsdDtcbiRidXR0b24tZmxvYXRpbmctcmFkaXVzOiA1MCUgIWRlZmF1bHQ7XG5cblxuLyogNC4gQ2FyZHNcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbiRjYXJkLXBhZGRpbmc6IDIwcHggIWRlZmF1bHQ7XG4kY2FyZC1iZy1jb2xvcjogI2ZmZiAhZGVmYXVsdDtcbiRjYXJkLWxpbmstY29sb3I6IGNvbG9yKFwib3JhbmdlXCIsIFwiYWNjZW50LTJcIikgIWRlZmF1bHQ7XG4kY2FyZC1saW5rLWNvbG9yLWxpZ2h0OiBsaWdodGVuKCRjYXJkLWxpbmstY29sb3IsIDIwJSkgIWRlZmF1bHQ7XG5cblxuLyogNS4gQ29sbGFwc2libGVcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbiRjb2xsYXBzaWJsZS1oZWlnaHQ6IDNyZW0gIWRlZmF1bHQ7XG4kY29sbGFwc2libGUtaGVhZGVyLWNvbG9yOiAjZmZmICFkZWZhdWx0O1xuJGNvbGxhcHNpYmxlLWJvcmRlci1jb2xvcjogI2RkZCAhZGVmYXVsdDtcblxuXG4vKiA2LiBDaGlwc1xuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuJGNoaXAtYmctY29sb3I6ICNlNGU0ZTQgIWRlZmF1bHQ7XG5cblxuLyogNy4gRGF0ZSBQaWNrZXJcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbiRkYXRlcGlja2VyLXdlZWtkYXktYmc6IGRhcmtlbigkc2Vjb25kYXJ5X2NvbG9yLCA3JSkgIWRlZmF1bHQ7XG4kZGF0ZXBpY2tlci1kYXRlLWJnOiAkc2Vjb25kYXJ5X2NvbG9yICFkZWZhdWx0O1xuJGRhdGVwaWNrZXIteWVhcjogcmdiYSgyNTUsIDI1NSwgMjU1LCAuNCkgIWRlZmF1bHQ7XG4kZGF0ZXBpY2tlci1mb2N1czogcmdiYSgwLDAsMCwgLjA1KSAhZGVmYXVsdDtcbiRkYXRlcGlja2VyLXNlbGVjdGVkOiAkc2Vjb25kYXJ5LWNvbG9yICFkZWZhdWx0O1xuJGRhdGVwaWNrZXItc2VsZWN0ZWQtb3V0Zm9jdXM6IGRlc2F0dXJhdGUobGlnaHRlbigkc2Vjb25kYXJ5LWNvbG9yLCAzNSUpLCAxNSUpICFkZWZhdWx0O1xuXG5cbi8qIDguIERyb3Bkb3duXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kZHJvcGRvd24tYmctY29sb3I6ICNmZmYgIWRlZmF1bHQ7XG4kZHJvcGRvd24taG92ZXItYmctY29sb3I6ICNlZWUgIWRlZmF1bHQ7XG4kZHJvcGRvd24tY29sb3I6ICRzZWNvbmRhcnktY29sb3IgIWRlZmF1bHQ7XG4kZHJvcGRvd24taXRlbS1oZWlnaHQ6IDUwcHggIWRlZmF1bHQ7XG5cblxuLyogOS4gRm9udHNcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbiRyb2JvdG8tZm9udC1wYXRoOiBcIi4uL2ZvbnRzL3JvYm90by9cIiAhZGVmYXVsdDtcblxuXG4vKiAxMC4gRm9ybXNcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbi8vIFRleHQgSW5wdXRzICsgVGV4dGFyZWFcbiRpbnB1dC1oZWlnaHQ6IDNyZW0gIWRlZmF1bHQ7XG4kaW5wdXQtYm9yZGVyLWNvbG9yOiBjb2xvcihcImdyZXlcIiwgXCJiYXNlXCIpICFkZWZhdWx0O1xuJGlucHV0LWJvcmRlcjogMXB4IHNvbGlkICRpbnB1dC1ib3JkZXItY29sb3IgIWRlZmF1bHQ7XG4kaW5wdXQtYmFja2dyb3VuZDogI2ZmZiAhZGVmYXVsdDtcbiRpbnB1dC1lcnJvci1jb2xvcjogJGVycm9yLWNvbG9yICFkZWZhdWx0O1xuJGlucHV0LXN1Y2Nlc3MtY29sb3I6ICRzdWNjZXNzLWNvbG9yICFkZWZhdWx0O1xuJGlucHV0LWZvY3VzLWNvbG9yOiAkc2Vjb25kYXJ5LWNvbG9yICFkZWZhdWx0O1xuJGlucHV0LWZvbnQtc2l6ZTogMXJlbSAhZGVmYXVsdDtcbiRpbnB1dC1tYXJnaW46IDAgMCAxNXB4IDAgIWRlZmF1bHQ7XG4kaW5wdXQtcGFkZGluZzogMCAhZGVmYXVsdDtcbiRpbnB1dC10cmFuc2l0aW9uOiBhbGwgLjNzICFkZWZhdWx0O1xuJGxhYmVsLWZvbnQtc2l6ZTogLjhyZW0gIWRlZmF1bHQ7XG4kaW5wdXQtZGlzYWJsZWQtY29sb3I6IHJnYmEoMCwwLDAsIC4yNikgIWRlZmF1bHQ7XG4kaW5wdXQtZGlzYWJsZWQtc29saWQtY29sb3I6ICNCREJEQkQgIWRlZmF1bHQ7XG4kaW5wdXQtZGlzYWJsZWQtYm9yZGVyOiAxcHggZG90dGVkICRpbnB1dC1kaXNhYmxlZC1jb2xvciAhZGVmYXVsdDtcbiRpbnB1dC1pbnZhbGlkLWJvcmRlcjogMXB4IHNvbGlkICRpbnB1dC1lcnJvci1jb2xvciAhZGVmYXVsdDtcbiRwbGFjZWhvbGRlci10ZXh0LWNvbG9yOiBsaWdodGVuKCRpbnB1dC1ib3JkZXItY29sb3IsIDIwJSkgIWRlZmF1bHQ7XG5cbi8vIFJhZGlvIEJ1dHRvbnNcbiRyYWRpby1maWxsLWNvbG9yOiAkc2Vjb25kYXJ5LWNvbG9yICFkZWZhdWx0O1xuJHJhZGlvLWVtcHR5LWNvbG9yOiAjNWE1YTVhICFkZWZhdWx0O1xuJHJhZGlvLWJvcmRlcjogMnB4IHNvbGlkICRyYWRpby1maWxsLWNvbG9yICFkZWZhdWx0O1xuXG4vLyBSYW5nZVxuJHJhbmdlLWhlaWdodDogMTRweCAhZGVmYXVsdDtcbiRyYW5nZS13aWR0aDogMTRweCAhZGVmYXVsdDtcbiR0cmFjay1oZWlnaHQ6IDNweCAhZGVmYXVsdDtcblxuLy8gU2VsZWN0XG4kc2VsZWN0LWJvcmRlcjogMXB4IHNvbGlkICNmMmYyZjIgIWRlZmF1bHQ7XG4kc2VsZWN0LWJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC45MCkgIWRlZmF1bHQ7XG4kc2VsZWN0LWZvY3VzOiAxcHggc29saWQgbGlnaHRlbigkc2Vjb25kYXJ5LWNvbG9yLCA0NyUpICFkZWZhdWx0O1xuJHNlbGVjdC1wYWRkaW5nOiA1cHggIWRlZmF1bHQ7XG4kc2VsZWN0LXJhZGl1czogMnB4ICFkZWZhdWx0O1xuJHNlbGVjdC1kaXNhYmxlZC1jb2xvcjogcmdiYSgwLDAsMCwuMykgIWRlZmF1bHQ7XG5cbi8vIFN3aXRjaGVzXG4kc3dpdGNoLWJnLWNvbG9yOiAkc2Vjb25kYXJ5LWNvbG9yICFkZWZhdWx0O1xuJHN3aXRjaC1jaGVja2VkLWxldmVyLWJnOiBkZXNhdHVyYXRlKGxpZ2h0ZW4oJHNlY29uZGFyeS1jb2xvciwgMjUlKSwgMjUlKSAhZGVmYXVsdDtcbiRzd2l0Y2gtdW5jaGVja2VkLWJnOiAjRjFGMUYxICFkZWZhdWx0O1xuJHN3aXRjaC11bmNoZWNrZWQtbGV2ZXItYmc6ICM4MTgxODEgIWRlZmF1bHQ7XG4kc3dpdGNoLXJhZGl1czogMTVweCAhZGVmYXVsdDtcblxuXG4vKiAxMS4gR2xvYmFsXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4vLyBNZWRpYSBRdWVyeSBSYW5nZXNcbiRzbWFsbC1zY3JlZW4tdXA6IDYwMXB4ICFkZWZhdWx0O1xuJG1lZGl1bS1zY3JlZW4tdXA6IDk5M3B4ICFkZWZhdWx0O1xuJGxhcmdlLXNjcmVlbi11cDogMTIwMXB4ICFkZWZhdWx0O1xuJHNtYWxsLXNjcmVlbjogNjAwcHggIWRlZmF1bHQ7XG4kbWVkaXVtLXNjcmVlbjogOTkycHggIWRlZmF1bHQ7XG4kbGFyZ2Utc2NyZWVuOiAxMjAwcHggIWRlZmF1bHQ7XG5cbiRtZWRpdW0tYW5kLXVwOiBcIm9ubHkgc2NyZWVuIGFuZCAobWluLXdpZHRoIDogI3skc21hbGwtc2NyZWVuLXVwfSlcIiAhZGVmYXVsdDtcbiRsYXJnZS1hbmQtdXA6IFwib25seSBzY3JlZW4gYW5kIChtaW4td2lkdGggOiAjeyRtZWRpdW0tc2NyZWVuLXVwfSlcIiAhZGVmYXVsdDtcbiRzbWFsbC1hbmQtZG93bjogXCJvbmx5IHNjcmVlbiBhbmQgKG1heC13aWR0aCA6ICN7JHNtYWxsLXNjcmVlbn0pXCIgIWRlZmF1bHQ7XG4kbWVkaXVtLWFuZC1kb3duOiBcIm9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoIDogI3skbWVkaXVtLXNjcmVlbn0pXCIgIWRlZmF1bHQ7XG4kbWVkaXVtLW9ubHk6IFwib25seSBzY3JlZW4gYW5kIChtaW4td2lkdGggOiAjeyRzbWFsbC1zY3JlZW4tdXB9KSBhbmQgKG1heC13aWR0aCA6ICN7JG1lZGl1bS1zY3JlZW59KVwiICFkZWZhdWx0O1xuXG5cbi8qIDEyLiBHcmlkXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kbnVtLWNvbHM6IDEyICFkZWZhdWx0O1xuJGd1dHRlci13aWR0aDogMS41cmVtICFkZWZhdWx0O1xuJGVsZW1lbnQtdG9wLW1hcmdpbjogJGd1dHRlci13aWR0aC8zICFkZWZhdWx0O1xuJGVsZW1lbnQtYm90dG9tLW1hcmdpbjogKCRndXR0ZXItd2lkdGgqMikvMyAhZGVmYXVsdDtcblxuXG4vKiAxMy4gTmF2aWdhdGlvbiBCYXJcbiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cbiRuYXZiYXItaGVpZ2h0OiA2NHB4ICFkZWZhdWx0O1xuJG5hdmJhci1oZWlnaHQtbW9iaWxlOiA1NnB4ICFkZWZhdWx0O1xuJG5hdmJhci1mb250LWNvbG9yOiAjZmZmICFkZWZhdWx0O1xuJG5hdmJhci1icmFuZC1mb250LXNpemU6IDIuMXJlbSAhZGVmYXVsdDtcblxuXG4vKiAxNC4gU2lkZSBOYXZpZ2F0aW9uXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kc2lkZW5hdi1mb250LWNvbG9yOiAjNDQ0ICFkZWZhdWx0O1xuJHNpZGVuYXYtYmctY29sb3I6ICNmZmYgIWRlZmF1bHQ7XG4kc2lkZW5hdi1wYWRkaW5nLXJpZ2h0OiAzMHB4ICFkZWZhdWx0O1xuJHNpZGVuYXYtaXRlbS1oZWlnaHQ6IDY0cHggIWRlZmF1bHQ7XG5cblxuLyogMTUuIFBob3RvIFNsaWRlclxuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuJHNsaWRlci1iZy1jb2xvcjogY29sb3IoJ2dyZXknLCAnYmFzZScpICFkZWZhdWx0O1xuJHNsaWRlci1iZy1jb2xvci1saWdodDogY29sb3IoJ2dyZXknLCAnbGlnaHRlbi0yJykgIWRlZmF1bHQ7XG4kc2xpZGVyLWluZGljYXRvci1jb2xvcjogY29sb3IoJ2dyZWVuJywgJ2Jhc2UnKSAhZGVmYXVsdDtcblxuXG4vKiAxNi4gU3Bpbm5lcnMgfCBMb2FkZXJzXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kc3Bpbm5lci1kZWZhdWx0LWNvbG9yOiAkc2Vjb25kYXJ5LWNvbG9yICFkZWZhdWx0O1xuXG5cbi8qIDE3LiBUYWJzXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kdGFicy11bmRlcmxpbmUtY29sb3I6ICRwcmltYXJ5LWNvbG9yLWxpZ2h0ICFkZWZhdWx0O1xuJHRhYnMtdGV4dC1jb2xvcjogJHByaW1hcnktY29sb3IgIWRlZmF1bHQ7XG4kdGFicy1iZy1jb2xvcjogI2ZmZiAhZGVmYXVsdDtcblxuXG4vKiAxOC4gVGFibGVzXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kdGFibGUtYm9yZGVyLWNvbG9yOiAjZDBkMGQwICFkZWZhdWx0O1xuJHRhYmxlLXN0cmlwZWQtY29sb3I6ICNmMmYyZjIgIWRlZmF1bHQ7XG5cblxuLyogMTkuIFRvYXN0c1xuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuJHRvYXN0LWhlaWdodDogNDhweCAhZGVmYXVsdDtcbiR0b2FzdC1jb2xvcjogIzMyMzIzMiAhZGVmYXVsdDtcbiR0b2FzdC10ZXh0LWNvbG9yOiAjZmZmICFkZWZhdWx0O1xuXG5cbi8qIDIwLiBUeXBvZ3JhcGh5XG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kb2ZmLWJsYWNrOiByZ2JhKDAsIDAsIDAsIDAuODcpICFkZWZhdWx0O1xuLy8gSGVhZGVyIFN0eWxlc1xuJGgxLWZvbnRzaXplOiA0LjJyZW0gIWRlZmF1bHQ7XG4kaDItZm9udHNpemU6IDMuNTZyZW0gIWRlZmF1bHQ7XG4kaDMtZm9udHNpemU6IDIuOTJyZW0gIWRlZmF1bHQ7XG4kaDQtZm9udHNpemU6IDIuMjhyZW0gIWRlZmF1bHQ7XG4kaDUtZm9udHNpemU6IDEuNjRyZW0gIWRlZmF1bHQ7XG4kaDYtZm9udHNpemU6IDFyZW0gIWRlZmF1bHQ7XG5cblxuLyogMjEuIEZvb3RlclxuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuJGZvb3Rlci1iZy1jb2xvcjogJHByaW1hcnktY29sb3IgIWRlZmF1bHQ7XG5cblxuLyogMjIuIEZsb3cgVGV4dFxuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuJHJhbmdlIDogJGxhcmdlLXNjcmVlbiAtICRzbWFsbC1zY3JlZW4gIWRlZmF1bHQ7XG4kaW50ZXJ2YWxzOiAyMCAhZGVmYXVsdDtcbiRpbnRlcnZhbC1zaXplOiAkcmFuZ2UgLyAkaW50ZXJ2YWxzICFkZWZhdWx0O1xuXG5cbi8qIDIzLiBDb2xsZWN0aW9uc1xuICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuJGNvbGxlY3Rpb24tYm9yZGVyLWNvbG9yOiAjZTBlMGUwICFkZWZhdWx0O1xuJGNvbGxlY3Rpb24tYmctY29sb3I6ICNmZmYgIWRlZmF1bHQ7XG4kY29sbGVjdGlvbi1hY3RpdmUtYmctY29sb3I6ICRzZWNvbmRhcnktY29sb3IgIWRlZmF1bHQ7XG4kY29sbGVjdGlvbi1hY3RpdmUtY29sb3I6IGxpZ2h0ZW4oJHNlY29uZGFyeS1jb2xvciwgNTUlKSAhZGVmYXVsdDtcbiRjb2xsZWN0aW9uLWhvdmVyLWJnLWNvbG9yOiAjZGRkICFkZWZhdWx0O1xuJGNvbGxlY3Rpb24tbGluay1jb2xvcjogJHNlY29uZGFyeS1jb2xvciAhZGVmYXVsdDtcblxuXG4vKiAyNC4gUHJvZ3Jlc3MgQmFyXG4gICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4kcHJvZ3Jlc3MtYmFyLWNvbG9yOiAkc2Vjb25kYXJ5LWNvbG9yICFkZWZhdWx0O1xuIiwiLyohXG4gKiBDbG9ja1BpY2tlciB2MC4wLjcgZm9yIGpRdWVyeSAoaHR0cDovL3dlYXJlb3V0bWFuLmdpdGh1Yi5pby9jbG9ja3BpY2tlci8pXG4gKiBDb3B5cmlnaHQgMjAxNCBXYW5nIFNoZW53ZWkuXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS93ZWFyZW91dG1hbi9jbG9ja3BpY2tlci9ibG9iL2doLXBhZ2VzL0xJQ0VOU0UpXG4gKlxuICogRnVydGhlciBtb2RpZmllZFxuICogQ29weXJpZ2h0IDIwMTUgQ2hpbmcgWWF3IEhhby5cbiAqXG4gKiBCb290c3RyYXAgdjMuMS4xIChodHRwOi8vZ2V0Ym9vdHN0cmFwLmNvbSlcbiAqIENvcHlyaWdodCAyMDExLTIwMTQgVHdpdHRlciwgSW5jLlxuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYXN0ZXIvTElDRU5TRSlcbiAqL1xuLmRhcmt0aGVtZSB7XG4gICAgLnBpY2tlcl9fYm94IHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogIzIxMjEyMTtcbiAgICB9XG5cbiAgICAucGlja2VyX19kYXRlLWRpc3BsYXkge1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgICB9XG5cbiAgICAuY2xvY2twaWNrZXItZGlzcGxheSB7XG4gICAgICAgIGNvbG9yOiB3aGl0ZTtcbiAgICB9XG5cbiAgICAuY2xvY2twaWNrZXItc3Bhbi1hbS1wbSB7XG4gICAgICAgIGNvbG9yOiB3aGl0ZTtcbiAgICB9XG5cbiAgICAuY2xvY2twaWNrZXItc3Bhbi1ob3VycyxcbiAgICAuY2xvY2twaWNrZXItc3Bhbi1taW51dGVzLFxuICAgICNjbGljay1hbSxcbiAgICAjY2xpY2stcG0ge1xuICAgICAgICAmLnRleHQtcHJpbWFyeSB7XG4gICAgICAgICAgICBjb2xvcjogI2ZmNDA4MTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC5jbG9ja3BpY2tlci1wbGF0ZSB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xuICAgIH1cblxuICAgIC5jbG9ja3BpY2tlci10aWNrIHtcbiAgICAgICAgY29sb3I6IHdoaXRlO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwgNjQsIDEyOSwgMCk7XG4gICAgfVxuXG4gICAgLmNsb2NrcGlja2VyLXRpY2suYWN0aXZlLFxuICAgIC5jbG9ja3BpY2tlci10aWNrOmhvdmVyIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyNTUsIDY0LCAxMjksIDAuMjUpO1xuICAgIH1cblxuICAgIC5jbG9ja3BpY2tlci1jYW52YXMtYmVhcmluZyB7XG4gICAgICAgIGZpbGw6IHdoaXRlO1xuICAgIH1cblxuICAgIC5jbG9ja3BpY2tlci1jYW52YXMtZmcge1xuICAgICAgICBmaWxsOiByZ2JhKDI1NSwgNjQsIDEyOSwgMCk7XG4gICAgfVxuXG4gICAgLmNsb2NrcGlja2VyLWNhbnZhcy1mZy5hY3RpdmUge1xuICAgICAgICBmaWxsOiByZ2JhKDI1NSwgNjQsIDEyOSwgMC41KTtcbiAgICB9XG5cbiAgICAuY2xvY2twaWNrZXItY2FudmFzLWJnIHtcbiAgICAgICAgZmlsbDogcmdiYSgyNTUsIDY0LCAxMjksIDAuMjUpO1xuICAgIH1cblxuICAgIC5jbG9ja3BpY2tlci1jYW52YXMtYmctdHJhbnMge1xuICAgICAgICBmaWxsOiByZ2JhKDI1NSwgNjQsIDEyOSwgMC4yNSk7XG4gICAgfVxuXG4gICAgLmNsb2NrcGlja2VyLWNhbnZhcyBsaW5lIHtcbiAgICAgICAgc3Ryb2tlOiByZ2JhKDI1NSwgNjQsIDEyOSwgMC4yNSk7XG4gICAgfVxuXG4gICAgYnV0dG9uIHtcbiAgICAgICAgY29sb3I6IHdoaXRlO1xuICAgIH1cblxuICAgIC5idG4tZmxvYXRpbmcuYnRuLWZsYXQuYWN0aXZlIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyNTUsIDY0LCAxMjksIDAuMjUpO1xuICAgIH1cblxuICAgIC5idG4tZmxvYXRpbmcuYnRuLWZsYXQ6YWN0aXZlIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyNTUsIDY0LCAxMjksIDAuNSk7XG4gICAgfVxuXG4gICAgLnBpY2tlcl9fZm9vdGVyIC5jbG9ja3BpY2tlci1idXR0b246YWN0aXZlIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyNTUsIDY0LCAxMjksIDAuMjUpO1xuICAgIH1cbn0iXSwic291cmNlUm9vdCI6Ii9zb3VyY2UvIn0= */
admin/css/materialize.min.css ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Materialize v0.97.8 (http://materializecss.com)
3
+ * Copyright 2014-2015 Materialize
4
+ * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE)
5
+ */
6
+ .materialize-red{background-color:#e51c23 !important}.materialize-red-text{color:#e51c23 !important}.materialize-red.lighten-5{background-color:#fdeaeb !important}.materialize-red-text.text-lighten-5{color:#fdeaeb !important}.materialize-red.lighten-4{background-color:#f8c1c3 !important}.materialize-red-text.text-lighten-4{color:#f8c1c3 !important}.materialize-red.lighten-3{background-color:#f3989b !important}.materialize-red-text.text-lighten-3{color:#f3989b !important}.materialize-red.lighten-2{background-color:#ee6e73 !important}.materialize-red-text.text-lighten-2{color:#ee6e73 !important}.materialize-red.lighten-1{background-color:#ea454b !important}.materialize-red-text.text-lighten-1{color:#ea454b !important}.materialize-red.darken-1{background-color:#d0181e !important}.materialize-red-text.text-darken-1{color:#d0181e !important}.materialize-red.darken-2{background-color:#b9151b !important}.materialize-red-text.text-darken-2{color:#b9151b !important}.materialize-red.darken-3{background-color:#a21318 !important}.materialize-red-text.text-darken-3{color:#a21318 !important}.materialize-red.darken-4{background-color:#8b1014 !important}.materialize-red-text.text-darken-4{color:#8b1014 !important}.red{background-color:#F44336 !important}.red-text{color:#F44336 !important}.red.lighten-5{background-color:#FFEBEE !important}.red-text.text-lighten-5{color:#FFEBEE !important}.red.lighten-4{background-color:#FFCDD2 !important}.red-text.text-lighten-4{color:#FFCDD2 !important}.red.lighten-3{background-color:#EF9A9A !important}.red-text.text-lighten-3{color:#EF9A9A !important}.red.lighten-2{background-color:#E57373 !important}.red-text.text-lighten-2{color:#E57373 !important}.red.lighten-1{background-color:#EF5350 !important}.red-text.text-lighten-1{color:#EF5350 !important}.red.darken-1{background-color:#E53935 !important}.red-text.text-darken-1{color:#E53935 !important}.red.darken-2{background-color:#D32F2F !important}.red-text.text-darken-2{color:#D32F2F !important}.red.darken-3{background-color:#C62828 !important}.red-text.text-darken-3{color:#C62828 !important}.red.darken-4{background-color:#B71C1C !important}.red-text.text-darken-4{color:#B71C1C !important}.red.accent-1{background-color:#FF8A80 !important}.red-text.text-accent-1{color:#FF8A80 !important}.red.accent-2{background-color:#FF5252 !important}.red-text.text-accent-2{color:#FF5252 !important}.red.accent-3{background-color:#FF1744 !important}.red-text.text-accent-3{color:#FF1744 !important}.red.accent-4{background-color:#D50000 !important}.red-text.text-accent-4{color:#D50000 !important}.pink{background-color:#e91e63 !important}.pink-text{color:#e91e63 !important}.pink.lighten-5{background-color:#fce4ec !important}.pink-text.text-lighten-5{color:#fce4ec !important}.pink.lighten-4{background-color:#f8bbd0 !important}.pink-text.text-lighten-4{color:#f8bbd0 !important}.pink.lighten-3{background-color:#f48fb1 !important}.pink-text.text-lighten-3{color:#f48fb1 !important}.pink.lighten-2{background-color:#f06292 !important}.pink-text.text-lighten-2{color:#f06292 !important}.pink.lighten-1{background-color:#ec407a !important}.pink-text.text-lighten-1{color:#ec407a !important}.pink.darken-1{background-color:#d81b60 !important}.pink-text.text-darken-1{color:#d81b60 !important}.pink.darken-2{background-color:#c2185b !important}.pink-text.text-darken-2{color:#c2185b !important}.pink.darken-3{background-color:#ad1457 !important}.pink-text.text-darken-3{color:#ad1457 !important}.pink.darken-4{background-color:#880e4f !important}.pink-text.text-darken-4{color:#880e4f !important}.pink.accent-1{background-color:#ff80ab !important}.pink-text.text-accent-1{color:#ff80ab !important}.pink.accent-2{background-color:#ff4081 !important}.pink-text.text-accent-2{color:#ff4081 !important}.pink.accent-3{background-color:#f50057 !important}.pink-text.text-accent-3{color:#f50057 !important}.pink.accent-4{background-color:#c51162 !important}.pink-text.text-accent-4{color:#c51162 !important}.purple{background-color:#9c27b0 !important}.purple-text{color:#9c27b0 !important}.purple.lighten-5{background-color:#f3e5f5 !important}.purple-text.text-lighten-5{color:#f3e5f5 !important}.purple.lighten-4{background-color:#e1bee7 !important}.purple-text.text-lighten-4{color:#e1bee7 !important}.purple.lighten-3{background-color:#ce93d8 !important}.purple-text.text-lighten-3{color:#ce93d8 !important}.purple.lighten-2{background-color:#ba68c8 !important}.purple-text.text-lighten-2{color:#ba68c8 !important}.purple.lighten-1{background-color:#ab47bc !important}.purple-text.text-lighten-1{color:#ab47bc !important}.purple.darken-1{background-color:#8e24aa !important}.purple-text.text-darken-1{color:#8e24aa !important}.purple.darken-2{background-color:#7b1fa2 !important}.purple-text.text-darken-2{color:#7b1fa2 !important}.purple.darken-3{background-color:#6a1b9a !important}.purple-text.text-darken-3{color:#6a1b9a !important}.purple.darken-4{background-color:#4a148c !important}.purple-text.text-darken-4{color:#4a148c !important}.purple.accent-1{background-color:#ea80fc !important}.purple-text.text-accent-1{color:#ea80fc !important}.purple.accent-2{background-color:#e040fb !important}.purple-text.text-accent-2{color:#e040fb !important}.purple.accent-3{background-color:#d500f9 !important}.purple-text.text-accent-3{color:#d500f9 !important}.purple.accent-4{background-color:#a0f !important}.purple-text.text-accent-4{color:#a0f !important}.deep-purple{background-color:#673ab7 !important}.deep-purple-text{color:#673ab7 !important}.deep-purple.lighten-5{background-color:#ede7f6 !important}.deep-purple-text.text-lighten-5{color:#ede7f6 !important}.deep-purple.lighten-4{background-color:#d1c4e9 !important}.deep-purple-text.text-lighten-4{color:#d1c4e9 !important}.deep-purple.lighten-3{background-color:#b39ddb !important}.deep-purple-text.text-lighten-3{color:#b39ddb !important}.deep-purple.lighten-2{background-color:#9575cd !important}.deep-purple-text.text-lighten-2{color:#9575cd !important}.deep-purple.lighten-1{background-color:#7e57c2 !important}.deep-purple-text.text-lighten-1{color:#7e57c2 !important}.deep-purple.darken-1{background-color:#5e35b1 !important}.deep-purple-text.text-darken-1{color:#5e35b1 !important}.deep-purple.darken-2{background-color:#512da8 !important}.deep-purple-text.text-darken-2{color:#512da8 !important}.deep-purple.darken-3{background-color:#4527a0 !important}.deep-purple-text.text-darken-3{color:#4527a0 !important}.deep-purple.darken-4{background-color:#311b92 !important}.deep-purple-text.text-darken-4{color:#311b92 !important}.deep-purple.accent-1{background-color:#b388ff !important}.deep-purple-text.text-accent-1{color:#b388ff !important}.deep-purple.accent-2{background-color:#7c4dff !important}.deep-purple-text.text-accent-2{color:#7c4dff !important}.deep-purple.accent-3{background-color:#651fff !important}.deep-purple-text.text-accent-3{color:#651fff !important}.deep-purple.accent-4{background-color:#6200ea !important}.deep-purple-text.text-accent-4{color:#6200ea !important}.indigo{background-color:#3f51b5 !important}.indigo-text{color:#3f51b5 !important}.indigo.lighten-5{background-color:#e8eaf6 !important}.indigo-text.text-lighten-5{color:#e8eaf6 !important}.indigo.lighten-4{background-color:#c5cae9 !important}.indigo-text.text-lighten-4{color:#c5cae9 !important}.indigo.lighten-3{background-color:#9fa8da !important}.indigo-text.text-lighten-3{color:#9fa8da !important}.indigo.lighten-2{background-color:#7986cb !important}.indigo-text.text-lighten-2{color:#7986cb !important}.indigo.lighten-1{background-color:#5c6bc0 !important}.indigo-text.text-lighten-1{color:#5c6bc0 !important}.indigo.darken-1{background-color:#3949ab !important}.indigo-text.text-darken-1{color:#3949ab !important}.indigo.darken-2{background-color:#303f9f !important}.indigo-text.text-darken-2{color:#303f9f !important}.indigo.darken-3{background-color:#283593 !important}.indigo-text.text-darken-3{color:#283593 !important}.indigo.darken-4{background-color:#1a237e !important}.indigo-text.text-darken-4{color:#1a237e !important}.indigo.accent-1{background-color:#8c9eff !important}.indigo-text.text-accent-1{color:#8c9eff !important}.indigo.accent-2{background-color:#536dfe !important}.indigo-text.text-accent-2{color:#536dfe !important}.indigo.accent-3{background-color:#3d5afe !important}.indigo-text.text-accent-3{color:#3d5afe !important}.indigo.accent-4{background-color:#304ffe !important}.indigo-text.text-accent-4{color:#304ffe !important}.blue{background-color:#2196F3 !important}.blue-text{color:#2196F3 !important}.blue.lighten-5{background-color:#E3F2FD !important}.blue-text.text-lighten-5{color:#E3F2FD !important}.blue.lighten-4{background-color:#BBDEFB !important}.blue-text.text-lighten-4{color:#BBDEFB !important}.blue.lighten-3{background-color:#90CAF9 !important}.blue-text.text-lighten-3{color:#90CAF9 !important}.blue.lighten-2{background-color:#64B5F6 !important}.blue-text.text-lighten-2{color:#64B5F6 !important}.blue.lighten-1{background-color:#42A5F5 !important}.blue-text.text-lighten-1{color:#42A5F5 !important}.blue.darken-1{background-color:#1E88E5 !important}.blue-text.text-darken-1{color:#1E88E5 !important}.blue.darken-2{background-color:#1976D2 !important}.blue-text.text-darken-2{color:#1976D2 !important}.blue.darken-3{background-color:#1565C0 !important}.blue-text.text-darken-3{color:#1565C0 !important}.blue.darken-4{background-color:#0D47A1 !important}.blue-text.text-darken-4{color:#0D47A1 !important}.blue.accent-1{background-color:#82B1FF !important}.blue-text.text-accent-1{color:#82B1FF !important}.blue.accent-2{background-color:#448AFF !important}.blue-text.text-accent-2{color:#448AFF !important}.blue.accent-3{background-color:#2979FF !important}.blue-text.text-accent-3{color:#2979FF !important}.blue.accent-4{background-color:#2962FF !important}.blue-text.text-accent-4{color:#2962FF !important}.light-blue{background-color:#03a9f4 !important}.light-blue-text{color:#03a9f4 !important}.light-blue.lighten-5{background-color:#e1f5fe !important}.light-blue-text.text-lighten-5{color:#e1f5fe !important}.light-blue.lighten-4{background-color:#b3e5fc !important}.light-blue-text.text-lighten-4{color:#b3e5fc !important}.light-blue.lighten-3{background-color:#81d4fa !important}.light-blue-text.text-lighten-3{color:#81d4fa !important}.light-blue.lighten-2{background-color:#4fc3f7 !important}.light-blue-text.text-lighten-2{color:#4fc3f7 !important}.light-blue.lighten-1{background-color:#29b6f6 !important}.light-blue-text.text-lighten-1{color:#29b6f6 !important}.light-blue.darken-1{background-color:#039be5 !important}.light-blue-text.text-darken-1{color:#039be5 !important}.light-blue.darken-2{background-color:#0288d1 !important}.light-blue-text.text-darken-2{color:#0288d1 !important}.light-blue.darken-3{background-color:#0277bd !important}.light-blue-text.text-darken-3{color:#0277bd !important}.light-blue.darken-4{background-color:#01579b !important}.light-blue-text.text-darken-4{color:#01579b !important}.light-blue.accent-1{background-color:#80d8ff !important}.light-blue-text.text-accent-1{color:#80d8ff !important}.light-blue.accent-2{background-color:#40c4ff !important}.light-blue-text.text-accent-2{color:#40c4ff !important}.light-blue.accent-3{background-color:#00b0ff !important}.light-blue-text.text-accent-3{color:#00b0ff !important}.light-blue.accent-4{background-color:#0091ea !important}.light-blue-text.text-accent-4{color:#0091ea !important}.cyan{background-color:#00bcd4 !important}.cyan-text{color:#00bcd4 !important}.cyan.lighten-5{background-color:#e0f7fa !important}.cyan-text.text-lighten-5{color:#e0f7fa !important}.cyan.lighten-4{background-color:#b2ebf2 !important}.cyan-text.text-lighten-4{color:#b2ebf2 !important}.cyan.lighten-3{background-color:#80deea !important}.cyan-text.text-lighten-3{color:#80deea !important}.cyan.lighten-2{background-color:#4dd0e1 !important}.cyan-text.text-lighten-2{color:#4dd0e1 !important}.cyan.lighten-1{background-color:#26c6da !important}.cyan-text.text-lighten-1{color:#26c6da !important}.cyan.darken-1{background-color:#00acc1 !important}.cyan-text.text-darken-1{color:#00acc1 !important}.cyan.darken-2{background-color:#0097a7 !important}.cyan-text.text-darken-2{color:#0097a7 !important}.cyan.darken-3{background-color:#00838f !important}.cyan-text.text-darken-3{color:#00838f !important}.cyan.darken-4{background-color:#006064 !important}.cyan-text.text-darken-4{color:#006064 !important}.cyan.accent-1{background-color:#84ffff !important}.cyan-text.text-accent-1{color:#84ffff !important}.cyan.accent-2{background-color:#18ffff !important}.cyan-text.text-accent-2{color:#18ffff !important}.cyan.accent-3{background-color:#00e5ff !important}.cyan-text.text-accent-3{color:#00e5ff !important}.cyan.accent-4{background-color:#00b8d4 !important}.cyan-text.text-accent-4{color:#00b8d4 !important}.teal{background-color:#009688 !important}.teal-text{color:#009688 !important}.teal.lighten-5{background-color:#e0f2f1 !important}.teal-text.text-lighten-5{color:#e0f2f1 !important}.teal.lighten-4{background-color:#b2dfdb !important}.teal-text.text-lighten-4{color:#b2dfdb !important}.teal.lighten-3{background-color:#80cbc4 !important}.teal-text.text-lighten-3{color:#80cbc4 !important}.teal.lighten-2{background-color:#4db6ac !important}.teal-text.text-lighten-2{color:#4db6ac !important}.teal.lighten-1{background-color:#26a69a !important}.teal-text.text-lighten-1{color:#26a69a !important}.teal.darken-1{background-color:#00897b !important}.teal-text.text-darken-1{color:#00897b !important}.teal.darken-2{background-color:#00796b !important}.teal-text.text-darken-2{color:#00796b !important}.teal.darken-3{background-color:#00695c !important}.teal-text.text-darken-3{color:#00695c !important}.teal.darken-4{background-color:#004d40 !important}.teal-text.text-darken-4{color:#004d40 !important}.teal.accent-1{background-color:#a7ffeb !important}.teal-text.text-accent-1{color:#a7ffeb !important}.teal.accent-2{background-color:#64ffda !important}.teal-text.text-accent-2{color:#64ffda !important}.teal.accent-3{background-color:#1de9b6 !important}.teal-text.text-accent-3{color:#1de9b6 !important}.teal.accent-4{background-color:#00bfa5 !important}.teal-text.text-accent-4{color:#00bfa5 !important}.green{background-color:#4CAF50 !important}.green-text{color:#4CAF50 !important}.green.lighten-5{background-color:#E8F5E9 !important}.green-text.text-lighten-5{color:#E8F5E9 !important}.green.lighten-4{background-color:#C8E6C9 !important}.green-text.text-lighten-4{color:#C8E6C9 !important}.green.lighten-3{background-color:#A5D6A7 !important}.green-text.text-lighten-3{color:#A5D6A7 !important}.green.lighten-2{background-color:#81C784 !important}.green-text.text-lighten-2{color:#81C784 !important}.green.lighten-1{background-color:#66BB6A !important}.green-text.text-lighten-1{color:#66BB6A !important}.green.darken-1{background-color:#43A047 !important}.green-text.text-darken-1{color:#43A047 !important}.green.darken-2{background-color:#388E3C !important}.green-text.text-darken-2{color:#388E3C !important}.green.darken-3{background-color:#2E7D32 !important}.green-text.text-darken-3{color:#2E7D32 !important}.green.darken-4{background-color:#1B5E20 !important}.green-text.text-darken-4{color:#1B5E20 !important}.green.accent-1{background-color:#B9F6CA !important}.green-text.text-accent-1{color:#B9F6CA !important}.green.accent-2{background-color:#69F0AE !important}.green-text.text-accent-2{color:#69F0AE !important}.green.accent-3{background-color:#00E676 !important}.green-text.text-accent-3{color:#00E676 !important}.green.accent-4{background-color:#00C853 !important}.green-text.text-accent-4{color:#00C853 !important}.light-green{background-color:#8bc34a !important}.light-green-text{color:#8bc34a !important}.light-green.lighten-5{background-color:#f1f8e9 !important}.light-green-text.text-lighten-5{color:#f1f8e9 !important}.light-green.lighten-4{background-color:#dcedc8 !important}.light-green-text.text-lighten-4{color:#dcedc8 !important}.light-green.lighten-3{background-color:#c5e1a5 !important}.light-green-text.text-lighten-3{color:#c5e1a5 !important}.light-green.lighten-2{background-color:#aed581 !important}.light-green-text.text-lighten-2{color:#aed581 !important}.light-green.lighten-1{background-color:#9ccc65 !important}.light-green-text.text-lighten-1{color:#9ccc65 !important}.light-green.darken-1{background-color:#7cb342 !important}.light-green-text.text-darken-1{color:#7cb342 !important}.light-green.darken-2{background-color:#689f38 !important}.light-green-text.text-darken-2{color:#689f38 !important}.light-green.darken-3{background-color:#558b2f !important}.light-green-text.text-darken-3{color:#558b2f !important}.light-green.darken-4{background-color:#33691e !important}.light-green-text.text-darken-4{color:#33691e !important}.light-green.accent-1{background-color:#ccff90 !important}.light-green-text.text-accent-1{color:#ccff90 !important}.light-green.accent-2{background-color:#b2ff59 !important}.light-green-text.text-accent-2{color:#b2ff59 !important}.light-green.accent-3{background-color:#76ff03 !important}.light-green-text.text-accent-3{color:#76ff03 !important}.light-green.accent-4{background-color:#64dd17 !important}.light-green-text.text-accent-4{color:#64dd17 !important}.lime{background-color:#cddc39 !important}.lime-text{color:#cddc39 !important}.lime.lighten-5{background-color:#f9fbe7 !important}.lime-text.text-lighten-5{color:#f9fbe7 !important}.lime.lighten-4{background-color:#f0f4c3 !important}.lime-text.text-lighten-4{color:#f0f4c3 !important}.lime.lighten-3{background-color:#e6ee9c !important}.lime-text.text-lighten-3{color:#e6ee9c !important}.lime.lighten-2{background-color:#dce775 !important}.lime-text.text-lighten-2{color:#dce775 !important}.lime.lighten-1{background-color:#d4e157 !important}.lime-text.text-lighten-1{color:#d4e157 !important}.lime.darken-1{background-color:#c0ca33 !important}.lime-text.text-darken-1{color:#c0ca33 !important}.lime.darken-2{background-color:#afb42b !important}.lime-text.text-darken-2{color:#afb42b !important}.lime.darken-3{background-color:#9e9d24 !important}.lime-text.text-darken-3{color:#9e9d24 !important}.lime.darken-4{background-color:#827717 !important}.lime-text.text-darken-4{color:#827717 !important}.lime.accent-1{background-color:#f4ff81 !important}.lime-text.text-accent-1{color:#f4ff81 !important}.lime.accent-2{background-color:#eeff41 !important}.lime-text.text-accent-2{color:#eeff41 !important}.lime.accent-3{background-color:#c6ff00 !important}.lime-text.text-accent-3{color:#c6ff00 !important}.lime.accent-4{background-color:#aeea00 !important}.lime-text.text-accent-4{color:#aeea00 !important}.yellow{background-color:#ffeb3b !important}.yellow-text{color:#ffeb3b !important}.yellow.lighten-5{background-color:#fffde7 !important}.yellow-text.text-lighten-5{color:#fffde7 !important}.yellow.lighten-4{background-color:#fff9c4 !important}.yellow-text.text-lighten-4{color:#fff9c4 !important}.yellow.lighten-3{background-color:#fff59d !important}.yellow-text.text-lighten-3{color:#fff59d !important}.yellow.lighten-2{background-color:#fff176 !important}.yellow-text.text-lighten-2{color:#fff176 !important}.yellow.lighten-1{background-color:#ffee58 !important}.yellow-text.text-lighten-1{color:#ffee58 !important}.yellow.darken-1{background-color:#fdd835 !important}.yellow-text.text-darken-1{color:#fdd835 !important}.yellow.darken-2{background-color:#fbc02d !important}.yellow-text.text-darken-2{color:#fbc02d !important}.yellow.darken-3{background-color:#f9a825 !important}.yellow-text.text-darken-3{color:#f9a825 !important}.yellow.darken-4{background-color:#f57f17 !important}.yellow-text.text-darken-4{color:#f57f17 !important}.yellow.accent-1{background-color:#ffff8d !important}.yellow-text.text-accent-1{color:#ffff8d !important}.yellow.accent-2{background-color:#ff0 !important}.yellow-text.text-accent-2{color:#ff0 !important}.yellow.accent-3{background-color:#ffea00 !important}.yellow-text.text-accent-3{color:#ffea00 !important}.yellow.accent-4{background-color:#ffd600 !important}.yellow-text.text-accent-4{color:#ffd600 !important}.amber{background-color:#ffc107 !important}.amber-text{color:#ffc107 !important}.amber.lighten-5{background-color:#fff8e1 !important}.amber-text.text-lighten-5{color:#fff8e1 !important}.amber.lighten-4{background-color:#ffecb3 !important}.amber-text.text-lighten-4{color:#ffecb3 !important}.amber.lighten-3{background-color:#ffe082 !important}.amber-text.text-lighten-3{color:#ffe082 !important}.amber.lighten-2{background-color:#ffd54f !important}.amber-text.text-lighten-2{color:#ffd54f !important}.amber.lighten-1{background-color:#ffca28 !important}.amber-text.text-lighten-1{color:#ffca28 !important}.amber.darken-1{background-color:#ffb300 !important}.amber-text.text-darken-1{color:#ffb300 !important}.amber.darken-2{background-color:#ffa000 !important}.amber-text.text-darken-2{color:#ffa000 !important}.amber.darken-3{background-color:#ff8f00 !important}.amber-text.text-darken-3{color:#ff8f00 !important}.amber.darken-4{background-color:#ff6f00 !important}.amber-text.text-darken-4{color:#ff6f00 !important}.amber.accent-1{background-color:#ffe57f !important}.amber-text.text-accent-1{color:#ffe57f !important}.amber.accent-2{background-color:#ffd740 !important}.amber-text.text-accent-2{color:#ffd740 !important}.amber.accent-3{background-color:#ffc400 !important}.amber-text.text-accent-3{color:#ffc400 !important}.amber.accent-4{background-color:#ffab00 !important}.amber-text.text-accent-4{color:#ffab00 !important}.orange{background-color:#ff9800 !important}.orange-text{color:#ff9800 !important}.orange.lighten-5{background-color:#fff3e0 !important}.orange-text.text-lighten-5{color:#fff3e0 !important}.orange.lighten-4{background-color:#ffe0b2 !important}.orange-text.text-lighten-4{color:#ffe0b2 !important}.orange.lighten-3{background-color:#ffcc80 !important}.orange-text.text-lighten-3{color:#ffcc80 !important}.orange.lighten-2{background-color:#ffb74d !important}.orange-text.text-lighten-2{color:#ffb74d !important}.orange.lighten-1{background-color:#ffa726 !important}.orange-text.text-lighten-1{color:#ffa726 !important}.orange.darken-1{background-color:#fb8c00 !important}.orange-text.text-darken-1{color:#fb8c00 !important}.orange.darken-2{background-color:#f57c00 !important}.orange-text.text-darken-2{color:#f57c00 !important}.orange.darken-3{background-color:#ef6c00 !important}.orange-text.text-darken-3{color:#ef6c00 !important}.orange.darken-4{background-color:#e65100 !important}.orange-text.text-darken-4{color:#e65100 !important}.orange.accent-1{background-color:#ffd180 !important}.orange-text.text-accent-1{color:#ffd180 !important}.orange.accent-2{background-color:#ffab40 !important}.orange-text.text-accent-2{color:#ffab40 !important}.orange.accent-3{background-color:#ff9100 !important}.orange-text.text-accent-3{color:#ff9100 !important}.orange.accent-4{background-color:#ff6d00 !important}.orange-text.text-accent-4{color:#ff6d00 !important}.deep-orange{background-color:#ff5722 !important}.deep-orange-text{color:#ff5722 !important}.deep-orange.lighten-5{background-color:#fbe9e7 !important}.deep-orange-text.text-lighten-5{color:#fbe9e7 !important}.deep-orange.lighten-4{background-color:#ffccbc !important}.deep-orange-text.text-lighten-4{color:#ffccbc !important}.deep-orange.lighten-3{background-color:#ffab91 !important}.deep-orange-text.text-lighten-3{color:#ffab91 !important}.deep-orange.lighten-2{background-color:#ff8a65 !important}.deep-orange-text.text-lighten-2{color:#ff8a65 !important}.deep-orange.lighten-1{background-color:#ff7043 !important}.deep-orange-text.text-lighten-1{color:#ff7043 !important}.deep-orange.darken-1{background-color:#f4511e !important}.deep-orange-text.text-darken-1{color:#f4511e !important}.deep-orange.darken-2{background-color:#e64a19 !important}.deep-orange-text.text-darken-2{color:#e64a19 !important}.deep-orange.darken-3{background-color:#d84315 !important}.deep-orange-text.text-darken-3{color:#d84315 !important}.deep-orange.darken-4{background-color:#bf360c !important}.deep-orange-text.text-darken-4{color:#bf360c !important}.deep-orange.accent-1{background-color:#ff9e80 !important}.deep-orange-text.text-accent-1{color:#ff9e80 !important}.deep-orange.accent-2{background-color:#ff6e40 !important}.deep-orange-text.text-accent-2{color:#ff6e40 !important}.deep-orange.accent-3{background-color:#ff3d00 !important}.deep-orange-text.text-accent-3{color:#ff3d00 !important}.deep-orange.accent-4{background-color:#dd2c00 !important}.deep-orange-text.text-accent-4{color:#dd2c00 !important}.brown{background-color:#795548 !important}.brown-text{color:#795548 !important}.brown.lighten-5{background-color:#efebe9 !important}.brown-text.text-lighten-5{color:#efebe9 !important}.brown.lighten-4{background-color:#d7ccc8 !important}.brown-text.text-lighten-4{color:#d7ccc8 !important}.brown.lighten-3{background-color:#bcaaa4 !important}.brown-text.text-lighten-3{color:#bcaaa4 !important}.brown.lighten-2{background-color:#a1887f !important}.brown-text.text-lighten-2{color:#a1887f !important}.brown.lighten-1{background-color:#8d6e63 !important}.brown-text.text-lighten-1{color:#8d6e63 !important}.brown.darken-1{background-color:#6d4c41 !important}.brown-text.text-darken-1{color:#6d4c41 !important}.brown.darken-2{background-color:#5d4037 !important}.brown-text.text-darken-2{color:#5d4037 !important}.brown.darken-3{background-color:#4e342e !important}.brown-text.text-darken-3{color:#4e342e !important}.brown.darken-4{background-color:#3e2723 !important}.brown-text.text-darken-4{color:#3e2723 !important}.blue-grey{background-color:#607d8b !important}.blue-grey-text{color:#607d8b !important}.blue-grey.lighten-5{background-color:#eceff1 !important}.blue-grey-text.text-lighten-5{color:#eceff1 !important}.blue-grey.lighten-4{background-color:#cfd8dc !important}.blue-grey-text.text-lighten-4{color:#cfd8dc !important}.blue-grey.lighten-3{background-color:#b0bec5 !important}.blue-grey-text.text-lighten-3{color:#b0bec5 !important}.blue-grey.lighten-2{background-color:#90a4ae !important}.blue-grey-text.text-lighten-2{color:#90a4ae !important}.blue-grey.lighten-1{background-color:#78909c !important}.blue-grey-text.text-lighten-1{color:#78909c !important}.blue-grey.darken-1{background-color:#546e7a !important}.blue-grey-text.text-darken-1{color:#546e7a !important}.blue-grey.darken-2{background-color:#455a64 !important}.blue-grey-text.text-darken-2{color:#455a64 !important}.blue-grey.darken-3{background-color:#37474f !important}.blue-grey-text.text-darken-3{color:#37474f !important}.blue-grey.darken-4{background-color:#263238 !important}.blue-grey-text.text-darken-4{color:#263238 !important}.grey{background-color:#9e9e9e !important}.grey-text{color:#9e9e9e !important}.grey.lighten-5{background-color:#fafafa !important}.grey-text.text-lighten-5{color:#fafafa !important}.grey.lighten-4{background-color:#f5f5f5 !important}.grey-text.text-lighten-4{color:#f5f5f5 !important}.grey.lighten-3{background-color:#eee !important}.grey-text.text-lighten-3{color:#eee !important}.grey.lighten-2{background-color:#e0e0e0 !important}.grey-text.text-lighten-2{color:#e0e0e0 !important}.grey.lighten-1{background-color:#bdbdbd !important}.grey-text.text-lighten-1{color:#bdbdbd !important}.grey.darken-1{background-color:#757575 !important}.grey-text.text-darken-1{color:#757575 !important}.grey.darken-2{background-color:#616161 !important}.grey-text.text-darken-2{color:#616161 !important}.grey.darken-3{background-color:#424242 !important}.grey-text.text-darken-3{color:#424242 !important}.grey.darken-4{background-color:#212121 !important}.grey-text.text-darken-4{color:#212121 !important}.black{background-color:#000 !important}.black-text{color:#000 !important}.white{background-color:#fff !important}.white-text{color:#fff !important}.transparent{background-color:transparent !important}.transparent-text{color:transparent !important}/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}ul:not(.browser-default){padding-left:0;list-style-type:none}ul:not(.browser-default) li{list-style-type:none}a{color:#039be5;text-decoration:none;-webkit-tap-highlight-color:transparent}.valign-wrapper{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.valign-wrapper .valign{display:block}.clearfix{clear:both}.z-depth-0{box-shadow:none !important}.z-depth-1,nav,.card-panel,.card,.toast,.btn,.btn-large,.btn-floating,.dropdown-content,.collapsible,.side-nav{box-shadow:0 2px 2px 0 rgba(0,0,0,0.14),0 1px 5px 0 rgba(0,0,0,0.12),0 3px 1px -2px rgba(0,0,0,0.2)}.z-depth-1-half,.btn:hover,.btn-large:hover,.btn-floating:hover{box-shadow:0 3px 3px 0 rgba(0,0,0,0.14),0 1px 7px 0 rgba(0,0,0,0.12),0 3px 1px -1px rgba(0,0,0,0.2)}.z-depth-2{box-shadow:0 4px 5px 0 rgba(0,0,0,0.14),0 1px 10px 0 rgba(0,0,0,0.12),0 2px 4px -1px rgba(0,0,0,0.3)}.z-depth-3{box-shadow:0 6px 10px 0 rgba(0,0,0,0.14),0 1px 18px 0 rgba(0,0,0,0.12),0 3px 5px -1px rgba(0,0,0,0.3)}.z-depth-4,.modal{box-shadow:0 8px 10px 1px rgba(0,0,0,0.14),0 3px 14px 2px rgba(0,0,0,0.12),0 5px 5px -3px rgba(0,0,0,0.3)}.z-depth-5{box-shadow:0 16px 24px 2px rgba(0,0,0,0.14),0 6px 30px 5px rgba(0,0,0,0.12),0 8px 10px -5px rgba(0,0,0,0.3)}.hoverable{transition:box-shadow .25s;box-shadow:0}.hoverable:hover{transition:box-shadow .25s;box-shadow:0 8px 17px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19)}.divider{height:1px;overflow:hidden;background-color:#e0e0e0}blockquote{margin:20px 0;padding-left:1.5rem;border-left:5px solid #ee6e73}i{line-height:inherit}i.left{float:left;margin-right:15px}i.right{float:right;margin-left:15px}i.tiny{font-size:1rem}i.small{font-size:2rem}i.medium{font-size:4rem}i.large{font-size:6rem}img.responsive-img,video.responsive-video{max-width:100%;height:auto}.pagination li{display:inline-block;border-radius:2px;text-align:center;vertical-align:top;height:30px}.pagination li a{color:#444;display:inline-block;font-size:1.2rem;padding:0 10px;line-height:30px}.pagination li.active a{color:#fff}.pagination li.active{background-color:#ee6e73}.pagination li.disabled a{cursor:default;color:#999}.pagination li i{font-size:2rem}.pagination li.pages ul li{display:inline-block;float:none}@media only screen and (max-width: 992px){.pagination{width:100%}.pagination li.prev,.pagination li.next{width:10%}.pagination li.pages{width:80%;overflow:hidden;white-space:nowrap}}.breadcrumb{font-size:18px;color:rgba(255,255,255,0.7)}.breadcrumb i,.breadcrumb [class^="mdi-"],.breadcrumb [class*="mdi-"],.breadcrumb i.material-icons{display:inline-block;float:left;font-size:24px}.breadcrumb:before{content:'\E5CC';color:rgba(255,255,255,0.7);vertical-align:top;display:inline-block;font-family:'Material Icons';font-weight:normal;font-style:normal;font-size:25px;margin:0 10px 0 8px;-webkit-font-smoothing:antialiased}.breadcrumb:first-child:before{display:none}.breadcrumb:last-child{color:#fff}.parallax-container{position:relative;overflow:hidden;height:500px}.parallax{position:absolute;top:0;left:0;right:0;bottom:0;z-index:-1}.parallax img{display:none;position:absolute;left:50%;bottom:0;min-width:100%;min-height:100%;-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);-webkit-transform:translateX(-50%);transform:translateX(-50%)}.pin-top,.pin-bottom{position:relative}.pinned{position:fixed !important}ul.staggered-list li{opacity:0}.fade-in{opacity:0;-webkit-transform-origin:0 50%;transform-origin:0 50%}@media only screen and (max-width: 600px){.hide-on-small-only,.hide-on-small-and-down{display:none !important}}@media only screen and (max-width: 992px){.hide-on-med-and-down{display:none !important}}@media only screen and (min-width: 601px){.hide-on-med-and-up{display:none !important}}@media only screen and (min-width: 600px) and (max-width: 992px){.hide-on-med-only{display:none !important}}@media only screen and (min-width: 993px){.hide-on-large-only{display:none !important}}@media only screen and (min-width: 993px){.show-on-large{display:block !important}}@media only screen and (min-width: 600px) and (max-width: 992px){.show-on-medium{display:block !important}}@media only screen and (max-width: 600px){.show-on-small{display:block !important}}@media only screen and (min-width: 601px){.show-on-medium-and-up{display:block !important}}@media only screen and (max-width: 992px){.show-on-medium-and-down{display:block !important}}@media only screen and (max-width: 600px){.center-on-small-only{text-align:center}}footer.page-footer{margin-top:20px;padding-top:20px;background-color:#ee6e73}footer.page-footer .footer-copyright{overflow:hidden;height:50px;line-height:50px;color:rgba(255,255,255,0.8);background-color:rgba(51,51,51,0.08)}table,th,td{border:none}table{width:100%;display:table}table.bordered>thead>tr,table.bordered>tbody>tr{border-bottom:1px solid #d0d0d0}table.striped>tbody>tr:nth-child(odd){background-color:#f2f2f2}table.striped>tbody>tr>td{border-radius:0}table.highlight>tbody>tr{transition:background-color .25s ease}table.highlight>tbody>tr:hover{background-color:#f2f2f2}table.centered thead tr th,table.centered tbody tr td{text-align:center}thead{border-bottom:1px solid #d0d0d0}td,th{padding:15px 5px;display:table-cell;text-align:left;vertical-align:middle;border-radius:2px}@media only screen and (max-width: 992px){table.responsive-table{width:100%;border-collapse:collapse;border-spacing:0;display:block;position:relative}table.responsive-table td:empty:before{content:'\00a0'}table.responsive-table th,table.responsive-table td{margin:0;vertical-align:top}table.responsive-table th{text-align:left}table.responsive-table thead{display:block;float:left}table.responsive-table thead tr{display:block;padding:0 10px 0 0}table.responsive-table thead tr th::before{content:"\00a0"}table.responsive-table tbody{display:block;width:auto;position:relative;overflow-x:auto;white-space:nowrap}table.responsive-table tbody tr{display:inline-block;vertical-align:top}table.responsive-table th{display:block;text-align:right}table.responsive-table td{display:block;min-height:1.25em;text-align:left}table.responsive-table tr{padding:0 10px}table.responsive-table thead{border:0;border-right:1px solid #d0d0d0}table.responsive-table.bordered th{border-bottom:0;border-left:0}table.responsive-table.bordered td{border-left:0;border-right:0;border-bottom:0}table.responsive-table.bordered tr{border:0}table.responsive-table.bordered tbody tr{border-right:1px solid #d0d0d0}}.collection{margin:0.5rem 0 1rem 0;border:1px solid #e0e0e0;border-radius:2px;overflow:hidden;position:relative}.collection .collection-item{background-color:#fff;line-height:1.5rem;padding:10px 20px;margin:0;border-bottom:1px solid #e0e0e0}.collection .collection-item.avatar{min-height:84px;padding-left:72px;position:relative}.collection .collection-item.avatar .circle{position:absolute;width:42px;height:42px;overflow:hidden;left:15px;display:inline-block;vertical-align:middle}.collection .collection-item.avatar i.circle{font-size:18px;line-height:42px;color:#fff;background-color:#999;text-align:center}.collection .collection-item.avatar .title{font-size:16px}.collection .collection-item.avatar p{margin:0}.collection .collection-item.avatar .secondary-content{position:absolute;top:16px;right:16px}.collection .collection-item:last-child{border-bottom:none}.collection .collection-item.active{background-color:#26a69a;color:#eafaf9}.collection .collection-item.active .secondary-content{color:#fff}.collection a.collection-item{display:block;transition:.25s;color:#26a69a}.collection a.collection-item:not(.active):hover{background-color:#ddd}.collection.with-header .collection-header{background-color:#fff;border-bottom:1px solid #e0e0e0;padding:10px 20px}.collection.with-header .collection-item{padding-left:30px}.collection.with-header .collection-item.avatar{padding-left:72px}.secondary-content{float:right;color:#26a69a}.collapsible .collection{margin:0;border:none}span.badge{min-width:3rem;padding:0 6px;margin-left:14px;text-align:center;font-size:1rem;line-height:inherit;color:#757575;float:right;box-sizing:border-box}span.badge.new{font-weight:300;font-size:0.8rem;color:#fff;background-color:#26a69a;border-radius:2px}span.badge.new:after{content:" new"}span.badge[data-badge-caption]::after{content:" " attr(data-badge-caption)}nav ul a span.badge{display:inline-block;float:none;margin-left:4px;line-height:22px;height:22px}.side-nav span.badge.new,.collapsible span.badge.new{position:relative;background-color:transparent}.side-nav span.badge.new::before,.collapsible span.badge.new::before{content:'';position:absolute;top:10px;right:0;bottom:10px;left:0;background-color:#26a69a;border-radius:2px;z-index:-1}.collapsible span.badge.new{z-index:1}.video-container{position:relative;padding-bottom:56.25%;height:0;overflow:hidden}.video-container iframe,.video-container object,.video-container embed{position:absolute;top:0;left:0;width:100%;height:100%}.progress{position:relative;height:4px;display:block;width:100%;background-color:#acece6;border-radius:2px;margin:0.5rem 0 1rem 0;overflow:hidden}.progress .determinate{position:absolute;top:0;left:0;bottom:0;background-color:#26a69a;transition:width .3s linear}.progress .indeterminate{background-color:#26a69a}.progress .indeterminate:before{content:'';position:absolute;background-color:inherit;top:0;left:0;bottom:0;will-change:left, right;-webkit-animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite}.progress .indeterminate:after{content:'';position:absolute;background-color:inherit;top:0;left:0;bottom:0;will-change:left, right;-webkit-animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;-webkit-animation-delay:1.15s;animation-delay:1.15s}@-webkit-keyframes indeterminate{0%{left:-35%;right:100%}60%{left:100%;right:-90%}100%{left:100%;right:-90%}}@keyframes indeterminate{0%{left:-35%;right:100%}60%{left:100%;right:-90%}100%{left:100%;right:-90%}}@-webkit-keyframes indeterminate-short{0%{left:-200%;right:100%}60%{left:107%;right:-8%}100%{left:107%;right:-8%}}@keyframes indeterminate-short{0%{left:-200%;right:100%}60%{left:107%;right:-8%}100%{left:107%;right:-8%}}.hide{display:none !important}.left-align{text-align:left}.right-align{text-align:right}.center,.center-align{text-align:center}.left{float:left !important}.right{float:right !important}.no-select,input[type=range],input[type=range]+.thumb{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.circle{border-radius:50%}.center-block{display:block;margin-left:auto;margin-right:auto}.truncate{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.no-padding{padding:0 !important}.material-icons{text-rendering:optimizeLegibility;-webkit-font-feature-settings:'liga';-moz-font-feature-settings:'liga';font-feature-settings:'liga'}.container{margin:0 auto;max-width:1280px;width:90%}@media only screen and (min-width: 601px){.container{width:85%}}@media only screen and (min-width: 993px){.container{width:70%}}.container .row{margin-left:-0.75rem;margin-right:-0.75rem}.section{padding-top:1rem;padding-bottom:1rem}.section.no-pad{padding:0}.section.no-pad-bot{padding-bottom:0}.section.no-pad-top{padding-top:0}.row{margin-left:auto;margin-right:auto;margin-bottom:20px}.row:after{content:"";display:table;clear:both}.row .col{float:left;box-sizing:border-box;padding:0 0.75rem;min-height:1px}.row .col[class*="push-"],.row .col[class*="pull-"]{position:relative}.row .col.s1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.s4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.s7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.s10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-s1{margin-left:8.3333333333%}.row .col.pull-s1{right:8.3333333333%}.row .col.push-s1{left:8.3333333333%}.row .col.offset-s2{margin-left:16.6666666667%}.row .col.pull-s2{right:16.6666666667%}.row .col.push-s2{left:16.6666666667%}.row .col.offset-s3{margin-left:25%}.row .col.pull-s3{right:25%}.row .col.push-s3{left:25%}.row .col.offset-s4{margin-left:33.3333333333%}.row .col.pull-s4{right:33.3333333333%}.row .col.push-s4{left:33.3333333333%}.row .col.offset-s5{margin-left:41.6666666667%}.row .col.pull-s5{right:41.6666666667%}.row .col.push-s5{left:41.6666666667%}.row .col.offset-s6{margin-left:50%}.row .col.pull-s6{right:50%}.row .col.push-s6{left:50%}.row .col.offset-s7{margin-left:58.3333333333%}.row .col.pull-s7{right:58.3333333333%}.row .col.push-s7{left:58.3333333333%}.row .col.offset-s8{margin-left:66.6666666667%}.row .col.pull-s8{right:66.6666666667%}.row .col.push-s8{left:66.6666666667%}.row .col.offset-s9{margin-left:75%}.row .col.pull-s9{right:75%}.row .col.push-s9{left:75%}.row .col.offset-s10{margin-left:83.3333333333%}.row .col.pull-s10{right:83.3333333333%}.row .col.push-s10{left:83.3333333333%}.row .col.offset-s11{margin-left:91.6666666667%}.row .col.pull-s11{right:91.6666666667%}.row .col.push-s11{left:91.6666666667%}.row .col.offset-s12{margin-left:100%}.row .col.pull-s12{right:100%}.row .col.push-s12{left:100%}@media only screen and (min-width: 601px){.row .col.m1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.m4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.m7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.m10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-m1{margin-left:8.3333333333%}.row .col.pull-m1{right:8.3333333333%}.row .col.push-m1{left:8.3333333333%}.row .col.offset-m2{margin-left:16.6666666667%}.row .col.pull-m2{right:16.6666666667%}.row .col.push-m2{left:16.6666666667%}.row .col.offset-m3{margin-left:25%}.row .col.pull-m3{right:25%}.row .col.push-m3{left:25%}.row .col.offset-m4{margin-left:33.3333333333%}.row .col.pull-m4{right:33.3333333333%}.row .col.push-m4{left:33.3333333333%}.row .col.offset-m5{margin-left:41.6666666667%}.row .col.pull-m5{right:41.6666666667%}.row .col.push-m5{left:41.6666666667%}.row .col.offset-m6{margin-left:50%}.row .col.pull-m6{right:50%}.row .col.push-m6{left:50%}.row .col.offset-m7{margin-left:58.3333333333%}.row .col.pull-m7{right:58.3333333333%}.row .col.push-m7{left:58.3333333333%}.row .col.offset-m8{margin-left:66.6666666667%}.row .col.pull-m8{right:66.6666666667%}.row .col.push-m8{left:66.6666666667%}.row .col.offset-m9{margin-left:75%}.row .col.pull-m9{right:75%}.row .col.push-m9{left:75%}.row .col.offset-m10{margin-left:83.3333333333%}.row .col.pull-m10{right:83.3333333333%}.row .col.push-m10{left:83.3333333333%}.row .col.offset-m11{margin-left:91.6666666667%}.row .col.pull-m11{right:91.6666666667%}.row .col.push-m11{left:91.6666666667%}.row .col.offset-m12{margin-left:100%}.row .col.pull-m12{right:100%}.row .col.push-m12{left:100%}}@media only screen and (min-width: 993px){.row .col.l1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.l4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.l7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.l10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-l1{margin-left:8.3333333333%}.row .col.pull-l1{right:8.3333333333%}.row .col.push-l1{left:8.3333333333%}.row .col.offset-l2{margin-left:16.6666666667%}.row .col.pull-l2{right:16.6666666667%}.row .col.push-l2{left:16.6666666667%}.row .col.offset-l3{margin-left:25%}.row .col.pull-l3{right:25%}.row .col.push-l3{left:25%}.row .col.offset-l4{margin-left:33.3333333333%}.row .col.pull-l4{right:33.3333333333%}.row .col.push-l4{left:33.3333333333%}.row .col.offset-l5{margin-left:41.6666666667%}.row .col.pull-l5{right:41.6666666667%}.row .col.push-l5{left:41.6666666667%}.row .col.offset-l6{margin-left:50%}.row .col.pull-l6{right:50%}.row .col.push-l6{left:50%}.row .col.offset-l7{margin-left:58.3333333333%}.row .col.pull-l7{right:58.3333333333%}.row .col.push-l7{left:58.3333333333%}.row .col.offset-l8{margin-left:66.6666666667%}.row .col.pull-l8{right:66.6666666667%}.row .col.push-l8{left:66.6666666667%}.row .col.offset-l9{margin-left:75%}.row .col.pull-l9{right:75%}.row .col.push-l9{left:75%}.row .col.offset-l10{margin-left:83.3333333333%}.row .col.pull-l10{right:83.3333333333%}.row .col.push-l10{left:83.3333333333%}.row .col.offset-l11{margin-left:91.6666666667%}.row .col.pull-l11{right:91.6666666667%}.row .col.push-l11{left:91.6666666667%}.row .col.offset-l12{margin-left:100%}.row .col.pull-l12{right:100%}.row .col.push-l12{left:100%}}nav{color:#fff;background-color:#ee6e73;width:100%;height:56px;line-height:56px}nav.nav-extended{height:auto}nav.nav-extended .nav-wrapper{height:auto}nav a{color:#fff}nav i,nav [class^="mdi-"],nav [class*="mdi-"],nav i.material-icons{display:block;font-size:24px;height:56px;line-height:56px}nav .nav-wrapper{position:relative;height:100%}@media only screen and (min-width: 993px){nav a.button-collapse{display:none}}nav .button-collapse{float:left;position:relative;z-index:1;height:56px;margin:0 18px}nav .button-collapse i{height:56px;line-height:56px}nav .brand-logo{position:absolute;color:#fff;display:inline-block;font-size:2.1rem;padding:0;white-space:nowrap}nav .brand-logo.center{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}@media only screen and (max-width: 992px){nav .brand-logo{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}nav .brand-logo.left,nav .brand-logo.right{padding:0;-webkit-transform:none;transform:none}nav .brand-logo.left{left:0.5rem}nav .brand-logo.right{right:0.5rem;left:auto}}nav .brand-logo.right{right:0.5rem;padding:0}nav .brand-logo i,nav .brand-logo [class^="mdi-"],nav .brand-logo [class*="mdi-"],nav .brand-logo i.material-icons{float:left;margin-right:15px}nav ul{margin:0}nav ul li{transition:background-color .3s;float:left;padding:0}nav ul li.active{background-color:rgba(0,0,0,0.1)}nav ul a{transition:background-color .3s;font-size:1rem;color:#fff;display:block;padding:0 15px;cursor:pointer}nav ul a.btn,nav ul a.btn-large,nav ul a.btn-large,nav ul a.btn-flat,nav ul a.btn-floating{margin-top:-2px;margin-left:15px;margin-right:15px}nav ul a:hover{background-color:rgba(0,0,0,0.1)}nav ul.left{float:left}nav form{height:100%}nav .input-field{margin:0;height:100%}nav .input-field input{height:100%;font-size:1.2rem;border:none;padding-left:2rem}nav .input-field input:focus,nav .input-field input[type=text]:valid,nav .input-field input[type=password]:valid,nav .input-field input[type=email]:valid,nav .input-field input[type=url]:valid,nav .input-field input[type=date]:valid{border:none;box-shadow:none}nav .input-field label{top:0;left:0}nav .input-field label i{color:rgba(255,255,255,0.7);transition:color .3s}nav .input-field label.active i{color:#fff}nav .input-field label.active{-webkit-transform:translateY(0);transform:translateY(0)}.navbar-fixed{position:relative;height:56px;z-index:997}.navbar-fixed nav{position:fixed}@media only screen and (min-width: 601px){nav,nav .nav-wrapper i,nav a.button-collapse,nav a.button-collapse i{height:64px;line-height:64px}.navbar-fixed{height:64px}}@font-face{font-family:"Roboto";src:local(Roboto Thin),url("../fonts/roboto/Roboto-Thin.eot");src:url("../fonts/roboto/Roboto-Thin.eot?#iefix") format("embedded-opentype"),url("../fonts/roboto/Roboto-Thin.woff2") format("woff2"),url("../fonts/roboto/Roboto-Thin.woff") format("woff"),url("../fonts/roboto/Roboto-Thin.ttf") format("truetype");font-weight:200}@font-face{font-family:"Roboto";src:local(Roboto Light),url("../fonts/roboto/Roboto-Light.eot");src:url("../fonts/roboto/Roboto-Light.eot?#iefix") format("embedded-opentype"),url("../fonts/roboto/Roboto-Light.woff2") format("woff2"),url("../fonts/roboto/Roboto-Light.woff") format("woff"),url("../fonts/roboto/Roboto-Light.ttf") format("truetype");font-weight:300}@font-face{font-family:"Roboto";src:local(Roboto Regular),url("../fonts/roboto/Roboto-Regular.eot");src:url("../fonts/roboto/Roboto-Regular.eot?#iefix") format("embedded-opentype"),url("../fonts/roboto/Roboto-Regular.woff2") format("woff2"),url("../fonts/roboto/Roboto-Regular.woff") format("woff"),url("../fonts/roboto/Roboto-Regular.ttf") format("truetype");font-weight:400}@font-face{font-family:"Roboto";src:url("../fonts/roboto/Roboto-Medium.eot");src:url("../fonts/roboto/Roboto-Medium.eot?#iefix") format("embedded-opentype"),url("../fonts/roboto/Roboto-Medium.woff2") format("woff2"),url("../fonts/roboto/Roboto-Medium.woff") format("woff"),url("../fonts/roboto/Roboto-Medium.ttf") format("truetype");font-weight:500}@font-face{font-family:"Roboto";src:url("../fonts/roboto/Roboto-Bold.eot");src:url("../fonts/roboto/Roboto-Bold.eot?#iefix") format("embedded-opentype"),url("../fonts/roboto/Roboto-Bold.woff2") format("woff2"),url("../fonts/roboto/Roboto-Bold.woff") format("woff"),url("../fonts/roboto/Roboto-Bold.ttf") format("truetype");font-weight:700}a{text-decoration:none}html{line-height:1.5;font-family:"Roboto", sans-serif;font-weight:normal;color:rgba(0,0,0,0.87)}@media only screen and (min-width: 0){html{font-size:14px}}@media only screen and (min-width: 992px){html{font-size:14.5px}}@media only screen and (min-width: 1200px){html{font-size:15px}}h1,h2,h3,h4,h5,h6{font-weight:400;line-height:1.1}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{font-weight:inherit}h1{font-size:4.2rem;line-height:110%;margin:2.1rem 0 1.68rem 0}h2{font-size:3.56rem;line-height:110%;margin:1.78rem 0 1.424rem 0}h3{font-size:2.92rem;line-height:110%;margin:1.46rem 0 1.168rem 0}h4{font-size:2.28rem;line-height:110%;margin:1.14rem 0 0.912rem 0}h5{font-size:1.64rem;line-height:110%;margin:0.82rem 0 0.656rem 0}h6{font-size:1rem;line-height:110%;margin:0.5rem 0 0.4rem 0}em{font-style:italic}strong{font-weight:500}small{font-size:75%}.light,footer.page-footer .footer-copyright{font-weight:300}.thin{font-weight:200}.flow-text{font-weight:300}@media only screen and (min-width: 360px){.flow-text{font-size:1.2rem}}@media only screen and (min-width: 390px){.flow-text{font-size:1.224rem}}@media only screen and (min-width: 420px){.flow-text{font-size:1.248rem}}@media only screen and (min-width: 450px){.flow-text{font-size:1.272rem}}@media only screen and (min-width: 480px){.flow-text{font-size:1.296rem}}@media only screen and (min-width: 510px){.flow-text{font-size:1.32rem}}@media only screen and (min-width: 540px){.flow-text{font-size:1.344rem}}@media only screen and (min-width: 570px){.flow-text{font-size:1.368rem}}@media only screen and (min-width: 600px){.flow-text{font-size:1.392rem}}@media only screen and (min-width: 630px){.flow-text{font-size:1.416rem}}@media only screen and (min-width: 660px){.flow-text{font-size:1.44rem}}@media only screen and (min-width: 690px){.flow-text{font-size:1.464rem}}@media only screen and (min-width: 720px){.flow-text{font-size:1.488rem}}@media only screen and (min-width: 750px){.flow-text{font-size:1.512rem}}@media only screen and (min-width: 780px){.flow-text{font-size:1.536rem}}@media only screen and (min-width: 810px){.flow-text{font-size:1.56rem}}@media only screen and (min-width: 840px){.flow-text{font-size:1.584rem}}@media only screen and (min-width: 870px){.flow-text{font-size:1.608rem}}@media only screen and (min-width: 900px){.flow-text{font-size:1.632rem}}@media only screen and (min-width: 930px){.flow-text{font-size:1.656rem}}@media only screen and (min-width: 960px){.flow-text{font-size:1.68rem}}@media only screen and (max-width: 360px){.flow-text{font-size:1.2rem}}.card-panel{transition:box-shadow .25s;padding:20px;margin:0.5rem 0 1rem 0;border-radius:2px;background-color:#fff}.card{position:relative;margin:0.5rem 0 1rem 0;background-color:#fff;transition:box-shadow .25s;border-radius:2px}.card .card-title{font-size:24px;font-weight:300}.card .card-title.activator{cursor:pointer}.card.small,.card.medium,.card.large{position:relative}.card.small .card-image,.card.medium .card-image,.card.large .card-image{max-height:60%;overflow:hidden}.card.small .card-image+.card-content,.card.medium .card-image+.card-content,.card.large .card-image+.card-content{max-height:40%}.card.small .card-content,.card.medium .card-content,.card.large .card-content{max-height:100%;overflow:hidden}.card.small .card-action,.card.medium .card-action,.card.large .card-action{position:absolute;bottom:0;left:0;right:0}.card.small{height:300px}.card.medium{height:400px}.card.large{height:500px}.card.horizontal{display:-webkit-flex;display:-ms-flexbox;display:flex}.card.horizontal.small .card-image,.card.horizontal.medium .card-image,.card.horizontal.large .card-image{height:100%;max-height:none;overflow:visible}.card.horizontal.small .card-image img,.card.horizontal.medium .card-image img,.card.horizontal.large .card-image img{height:100%}.card.horizontal .card-image{max-width:50%}.card.horizontal .card-image img{border-radius:2px 0 0 2px;max-width:100%;width:auto}.card.horizontal .card-stacked{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex:1;-ms-flex:1;flex:1;position:relative}.card.horizontal .card-stacked .card-content{-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.card.sticky-action .card-action{z-index:2}.card.sticky-action .card-reveal{z-index:1;padding-bottom:64px}.card .card-image{position:relative}.card .card-image img{display:block;border-radius:2px 2px 0 0;position:relative;left:0;right:0;top:0;bottom:0;width:100%}.card .card-image .card-title{color:#fff;position:absolute;bottom:0;left:0;padding:20px}.card .card-content{padding:20px;border-radius:0 0 2px 2px}.card .card-content p{margin:0;color:inherit}.card .card-content .card-title{line-height:48px}.card .card-action{position:relative;background-color:inherit;border-top:1px solid rgba(160,160,160,0.2);padding:20px}.card .card-action a:not(.btn):not(.btn-large):not(.btn-floating){color:#ffab40;margin-right:20px;transition:color .3s ease;text-transform:uppercase}.card .card-action a:not(.btn):not(.btn-large):not(.btn-floating):hover{color:#ffd8a6}.card .card-reveal{padding:20px;position:absolute;background-color:#fff;width:100%;overflow-y:auto;left:0;top:100%;height:100%;z-index:3;display:none}.card .card-reveal .card-title{cursor:pointer;display:block}#toast-container{display:block;position:fixed;z-index:10000}@media only screen and (max-width: 600px){#toast-container{min-width:100%;bottom:0%}}@media only screen and (min-width: 601px) and (max-width: 992px){#toast-container{left:5%;bottom:7%;max-width:90%}}@media only screen and (min-width: 993px){#toast-container{top:10%;right:7%;max-width:86%}}.toast{border-radius:2px;top:0;width:auto;clear:both;margin-top:10px;position:relative;max-width:100%;height:auto;min-height:48px;line-height:1.5em;word-break:break-all;background-color:#323232;padding:10px 25px;font-size:1.1rem;font-weight:300;color:#fff;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.toast .btn,.toast .btn-large,.toast .btn-flat{margin:0;margin-left:3rem}.toast.rounded{border-radius:24px}@media only screen and (max-width: 600px){.toast{width:100%;border-radius:0}}@media only screen and (min-width: 601px) and (max-width: 992px){.toast{float:left}}@media only screen and (min-width: 993px){.toast{float:right}}.tabs{position:relative;overflow-x:auto;overflow-y:hidden;height:48px;width:100%;background-color:#fff;margin:0 auto;white-space:nowrap}.tabs.tabs-transparent{background-color:transparent}.tabs.tabs-transparent .tab a,.tabs.tabs-transparent .tab.disabled a,.tabs.tabs-transparent .tab.disabled a:hover{color:rgba(255,255,255,0.7)}.tabs.tabs-transparent .tab a:hover,.tabs.tabs-transparent .tab a.active{color:#fff}.tabs.tabs-transparent .indicator{background-color:#fff}.tabs.tabs-fixed-width{display:-webkit-flex;display:-ms-flexbox;display:flex}.tabs.tabs-fixed-width .tab{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.tabs .tab{display:inline-block;text-align:center;line-height:48px;height:48px;padding:0;margin:0;text-transform:uppercase}.tabs .tab a{color:rgba(238,110,115,0.7);display:block;width:100%;height:100%;padding:0 24px;font-size:14px;text-overflow:ellipsis;overflow:hidden;transition:color .28s ease}.tabs .tab a:hover,.tabs .tab a.active{background-color:transparent;color:#ee6e73}.tabs .tab.disabled a,.tabs .tab.disabled a:hover{color:rgba(238,110,115,0.7);cursor:default}.tabs .indicator{position:absolute;bottom:0;height:2px;background-color:#f6b2b5;will-change:left, right}@media only screen and (max-width: 992px){.tabs{display:-webkit-flex;display:-ms-flexbox;display:flex}.tabs .tab{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.tabs .tab a{padding:0 12px}}.material-tooltip{padding:10px 8px;font-size:1rem;z-index:2000;background-color:transparent;border-radius:2px;color:#fff;min-height:36px;line-height:120%;opacity:0;display:none;position:absolute;text-align:center;max-width:calc(100% - 4px);overflow:hidden;left:0;top:0;pointer-events:none}.backdrop{position:absolute;opacity:0;display:none;height:7px;width:14px;border-radius:0 0 50% 50%;background-color:#323232;z-index:-1;-webkit-transform-origin:50% 0%;transform-origin:50% 0%;-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0)}.btn,.btn-large,.btn-flat{border:none;border-radius:2px;display:inline-block;height:36px;line-height:36px;padding:0 2rem;text-transform:uppercase;vertical-align:middle;-webkit-tap-highlight-color:transparent}.btn.disabled,.disabled.btn-large,.btn-floating.disabled,.btn-large.disabled,.btn-flat.disabled,.btn:disabled,.btn-large:disabled,.btn-floating:disabled,.btn-large:disabled,.btn-flat:disabled,.btn[disabled],[disabled].btn-large,.btn-floating[disabled],.btn-large[disabled],.btn-flat[disabled]{pointer-events:none;background-color:#DFDFDF !important;box-shadow:none;color:#9F9F9F !important;cursor:default}.btn.disabled:hover,.disabled.btn-large:hover,.btn-floating.disabled:hover,.btn-large.disabled:hover,.btn-flat.disabled:hover,.btn:disabled:hover,.btn-large:disabled:hover,.btn-floating:disabled:hover,.btn-large:disabled:hover,.btn-flat:disabled:hover,.btn[disabled]:hover,[disabled].btn-large:hover,.btn-floating[disabled]:hover,.btn-large[disabled]:hover,.btn-flat[disabled]:hover{background-color:#DFDFDF !important;color:#9F9F9F !important}.btn,.btn-large,.btn-floating,.btn-large,.btn-flat{outline:0}.btn i,.btn-large i,.btn-floating i,.btn-large i,.btn-flat i{font-size:1.3rem;line-height:inherit}.btn:focus,.btn-large:focus,.btn-floating:focus{background-color:#1d7d74}.btn,.btn-large{text-decoration:none;color:#fff;background-color:#26a69a;text-align:center;letter-spacing:.5px;transition:.2s ease-out;cursor:pointer}.btn:hover,.btn-large:hover{background-color:#2bbbad}.btn-floating{display:inline-block;color:#fff;position:relative;overflow:hidden;z-index:1;width:40px;height:40px;line-height:40px;padding:0;background-color:#26a69a;border-radius:50%;transition:.3s;cursor:pointer;vertical-align:middle}.btn-floating i{width:inherit;display:inline-block;text-align:center;color:#fff;font-size:1.6rem;line-height:40px}.btn-floating:hover{background-color:#26a69a}.btn-floating:before{border-radius:0}.btn-floating.btn-large{width:56px;height:56px}.btn-floating.btn-large i{line-height:56px}button.btn-floating{border:none}.fixed-action-btn{position:fixed;right:23px;bottom:23px;padding-top:15px;margin-bottom:0;z-index:998}.fixed-action-btn.active ul{visibility:visible}.fixed-action-btn.horizontal{padding:0 0 0 15px}.fixed-action-btn.horizontal ul{text-align:right;right:64px;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);height:100%;left:auto;width:500px}.fixed-action-btn.horizontal ul li{display:inline-block;margin:15px 15px 0 0}.fixed-action-btn.toolbar{padding:0;height:56px}.fixed-action-btn.toolbar.active>a i{opacity:0}.fixed-action-btn.toolbar ul{display:-webkit-flex;display:-ms-flexbox;display:flex;top:0;bottom:0}.fixed-action-btn.toolbar ul li{-webkit-flex:1;-ms-flex:1;flex:1;display:inline-block;margin:0;height:100%;transition:none}.fixed-action-btn.toolbar ul li a{display:block;overflow:hidden;position:relative;width:100%;height:100%;background-color:transparent;box-shadow:none;color:#fff;line-height:56px;z-index:1}.fixed-action-btn.toolbar ul li a i{line-height:inherit}.fixed-action-btn ul{left:0;right:0;text-align:center;position:absolute;bottom:64px;margin:0;visibility:hidden}.fixed-action-btn ul li{margin-bottom:15px}.fixed-action-btn ul a.btn-floating{opacity:0}.fixed-action-btn .fab-backdrop{position:absolute;top:0;left:0;z-index:-1;width:40px;height:40px;background-color:#26a69a;border-radius:50%;-webkit-transform:scale(0);transform:scale(0)}.btn-flat{box-shadow:none;background-color:transparent;color:#343434;cursor:pointer;transition:background-color .2s}.btn-flat:focus,.btn-flat:active{background-color:transparent}.btn-flat:focus,.btn-flat:hover{background-color:rgba(0,0,0,0.1);box-shadow:none}.btn-flat:active{background-color:rgba(0,0,0,0.2)}.btn-flat.disabled{background-color:transparent !important;color:#b3b3b3 !important;cursor:default}.btn-large{height:54px;line-height:54px}.btn-large i{font-size:1.6rem}.btn-block{display:block}.dropdown-content{background-color:#fff;margin:0;display:none;min-width:100px;max-height:650px;overflow-y:auto;opacity:0;position:absolute;z-index:999;will-change:width, height}.dropdown-content li{clear:both;color:rgba(0,0,0,0.87);cursor:pointer;min-height:50px;line-height:1.5rem;width:100%;text-align:left;text-transform:none}.dropdown-content li:hover,.dropdown-content li.active,.dropdown-content li.selected{background-color:#eee}.dropdown-content li.active.selected{background-color:#e1e1e1}.dropdown-content li.divider{min-height:0;height:1px}.dropdown-content li>a,.dropdown-content li>span{font-size:16px;color:#26a69a;display:block;line-height:22px;padding:14px 16px}.dropdown-content li>span>label{top:1px;left:0;height:18px}.dropdown-content li>a>i{height:inherit;line-height:inherit}.input-field.col .dropdown-content [type="checkbox"]+label{top:1px;left:0;height:18px}/*!
7
+ * Waves v0.6.0
8
+ * http://fian.my.id/Waves
9
+ *
10
+ * Copyright 2014 Alfiana E. Sibuea and other contributors
11
+ * Released under the MIT license
12
+ * https://github.com/fians/Waves/blob/master/LICENSE
13
+ */.waves-effect{position:relative;cursor:pointer;display:inline-block;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;vertical-align:middle;z-index:1;will-change:opacity, transform;transition:.3s ease-out}.waves-effect .waves-ripple{position:absolute;border-radius:50%;width:20px;height:20px;margin-top:-10px;margin-left:-10px;opacity:0;background:rgba(0,0,0,0.2);transition:all 0.7s ease-out;transition-property:opacity, -webkit-transform;transition-property:transform, opacity;transition-property:transform, opacity, -webkit-transform;-webkit-transform:scale(0);transform:scale(0);pointer-events:none}.waves-effect.waves-light .waves-ripple{background-color:rgba(255,255,255,0.45)}.waves-effect.waves-red .waves-ripple{background-color:rgba(244,67,54,0.7)}.waves-effect.waves-yellow .waves-ripple{background-color:rgba(255,235,59,0.7)}.waves-effect.waves-orange .waves-ripple{background-color:rgba(255,152,0,0.7)}.waves-effect.waves-purple .waves-ripple{background-color:rgba(156,39,176,0.7)}.waves-effect.waves-green .waves-ripple{background-color:rgba(76,175,80,0.7)}.waves-effect.waves-teal .waves-ripple{background-color:rgba(0,150,136,0.7)}.waves-effect input[type="button"],.waves-effect input[type="reset"],.waves-effect input[type="submit"]{border:0;font-style:normal;font-size:inherit;text-transform:inherit;background:none}.waves-effect img{position:relative;z-index:-1}.waves-notransition{transition:none !important}.waves-circle{-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-mask-image:-webkit-radial-gradient(circle, #fff 100%, #000 100%)}.waves-input-wrapper{border-radius:0.2em;vertical-align:bottom}.waves-input-wrapper .waves-button-input{position:relative;top:0;left:0;z-index:1}.waves-circle{text-align:center;width:2.5em;height:2.5em;line-height:2.5em;border-radius:50%;-webkit-mask-image:none}.waves-block{display:block}.waves-effect .waves-ripple{z-index:-1}.modal{display:none;position:fixed;left:0;right:0;background-color:#fafafa;padding:0;max-height:70%;width:55%;margin:auto;overflow-y:auto;border-radius:2px;will-change:top, opacity}@media only screen and (max-width: 992px){.modal{width:80%}}.modal h1,.modal h2,.modal h3,.modal h4{margin-top:0}.modal .modal-content{padding:24px}.modal .modal-close{cursor:pointer}.modal .modal-footer{border-radius:0 0 2px 2px;background-color:#fafafa;padding:4px 6px;height:56px;width:100%}.modal .modal-footer .btn,.modal .modal-footer .btn-large,.modal .modal-footer .btn-flat{float:right;margin:6px 0}.modal-overlay{position:fixed;z-index:999;top:-100px;left:0;bottom:0;right:0;height:125%;width:100%;background:#000;display:none;will-change:opacity}.modal.modal-fixed-footer{padding:0;height:70%}.modal.modal-fixed-footer .modal-content{position:absolute;height:calc(100% - 56px);max-height:100%;width:100%;overflow-y:auto}.modal.modal-fixed-footer .modal-footer{border-top:1px solid rgba(0,0,0,0.1);position:absolute;bottom:0}.modal.bottom-sheet{top:auto;bottom:-100%;margin:0;width:100%;max-height:45%;border-radius:0;will-change:bottom, opacity}.collapsible{border-top:1px solid #ddd;border-right:1px solid #ddd;border-left:1px solid #ddd;margin:0.5rem 0 1rem 0}.collapsible-header{display:block;cursor:pointer;min-height:3rem;line-height:3rem;padding:0 1rem;background-color:#fff;border-bottom:1px solid #ddd}.collapsible-header i{width:2rem;font-size:1.6rem;line-height:3rem;display:block;float:left;text-align:center;margin-right:1rem}.collapsible-body{display:none;border-bottom:1px solid #ddd;box-sizing:border-box}.collapsible-body p{margin:0;padding:2rem}.side-nav .collapsible,.side-nav.fixed .collapsible{border:none;box-shadow:none}.side-nav .collapsible li,.side-nav.fixed .collapsible li{padding:0}.side-nav .collapsible-header,.side-nav.fixed .collapsible-header{background-color:transparent;border:none;line-height:inherit;height:inherit;padding:0 16px}.side-nav .collapsible-header:hover,.side-nav.fixed .collapsible-header:hover{background-color:rgba(0,0,0,0.05)}.side-nav .collapsible-header i,.side-nav.fixed .collapsible-header i{line-height:inherit}.side-nav .collapsible-body,.side-nav.fixed .collapsible-body{border:0;background-color:#fff}.side-nav .collapsible-body li a,.side-nav.fixed .collapsible-body li a{padding:0 23.5px 0 31px}.collapsible.popout{border:none;box-shadow:none}.collapsible.popout>li{box-shadow:0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12);margin:0 24px;transition:margin 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94)}.collapsible.popout>li.active{box-shadow:0 5px 11px 0 rgba(0,0,0,0.18),0 4px 15px 0 rgba(0,0,0,0.15);margin:16px 0}.chip{display:inline-block;height:32px;font-size:13px;font-weight:500;color:rgba(0,0,0,0.6);line-height:32px;padding:0 12px;border-radius:16px;background-color:#e4e4e4;margin-bottom:5px;margin-right:5px}.chip img{float:left;margin:0 8px 0 -12px;height:32px;width:32px;border-radius:50%}.chip .close{cursor:pointer;float:right;font-size:16px;line-height:32px;padding-left:8px}.chips{border:none;border-bottom:1px solid #9e9e9e;box-shadow:none;margin:0 0 20px 0;min-height:45px;outline:none;transition:all .3s}.chips.focus{border-bottom:1px solid #26a69a;box-shadow:0 1px 0 0 #26a69a}.chips:hover{cursor:text}.chips .chip.selected{background-color:#26a69a;color:#fff}.chips .input{background:none;border:0;color:rgba(0,0,0,0.6);display:inline-block;font-size:1rem;height:3rem;line-height:32px;outline:0;margin:0;padding:0 !important;width:120px !important}.chips .input:focus{border:0 !important;box-shadow:none !important}.prefix ~ .chips{margin-left:3rem;width:92%;width:calc(100% - 3rem)}.chips:empty ~ label{font-size:0.8rem;-webkit-transform:translateY(-140%);transform:translateY(-140%)}.materialboxed{display:block;cursor:-webkit-zoom-in;cursor:zoom-in;position:relative;transition:opacity .4s}.materialboxed:hover{will-change:left, top, width, height}.materialboxed:hover:not(.active){opacity:.8}.materialboxed.active{cursor:-webkit-zoom-out;cursor:zoom-out}#materialbox-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background-color:#292929;z-index:1000;will-change:opacity}.materialbox-caption{position:fixed;display:none;color:#fff;line-height:50px;bottom:0;width:100%;text-align:center;padding:0% 15%;height:50px;z-index:1000;-webkit-font-smoothing:antialiased}select:focus{outline:1px solid #c9f3ef}button:focus{outline:none;background-color:#2ab7a9}label{font-size:0.8rem;color:#9e9e9e}::-webkit-input-placeholder{color:#d1d1d1}:-moz-placeholder{color:#d1d1d1}::-moz-placeholder{color:#d1d1d1}:-ms-input-placeholder{color:#d1d1d1}input:not([type]),input[type=text],input[type=password],input[type=email],input[type=url],input[type=time],input[type=date],input[type=datetime],input[type=datetime-local],input[type=tel],input[type=number],input[type=search],textarea.materialize-textarea{background-color:transparent;border:none;border-bottom:1px solid #9e9e9e;border-radius:0;outline:none;height:3rem;width:100%;font-size:1rem;margin:0 0 20px 0;padding:0;box-shadow:none;box-sizing:content-box;transition:all 0.3s}input:not([type]):disabled,input:not([type])[readonly="readonly"],input[type=text]:disabled,input[type=text][readonly="readonly"],input[type=password]:disabled,input[type=password][readonly="readonly"],input[type=email]:disabled,input[type=email][readonly="readonly"],input[type=url]:disabled,input[type=url][readonly="readonly"],input[type=time]:disabled,input[type=time][readonly="readonly"],input[type=date]:disabled,input[type=date][readonly="readonly"],input[type=datetime]:disabled,input[type=datetime][readonly="readonly"],input[type=datetime-local]:disabled,input[type=datetime-local][readonly="readonly"],input[type=tel]:disabled,input[type=tel][readonly="readonly"],input[type=number]:disabled,input[type=number][readonly="readonly"],input[type=search]:disabled,input[type=search][readonly="readonly"],textarea.materialize-textarea:disabled,textarea.materialize-textarea[readonly="readonly"]{color:rgba(0,0,0,0.26);border-bottom:1px dotted rgba(0,0,0,0.26)}input:not([type]):disabled+label,input:not([type])[readonly="readonly"]+label,input[type=text]:disabled+label,input[type=text][readonly="readonly"]+label,input[type=password]:disabled+label,input[type=password][readonly="readonly"]+label,input[type=email]:disabled+label,input[type=email][readonly="readonly"]+label,input[type=url]:disabled+label,input[type=url][readonly="readonly"]+label,input[type=time]:disabled+label,input[type=time][readonly="readonly"]+label,input[type=date]:disabled+label,input[type=date][readonly="readonly"]+label,input[type=datetime]:disabled+label,input[type=datetime][readonly="readonly"]+label,input[type=datetime-local]:disabled+label,input[type=datetime-local][readonly="readonly"]+label,input[type=tel]:disabled+label,input[type=tel][readonly="readonly"]+label,input[type=number]:disabled+label,input[type=number][readonly="readonly"]+label,input[type=search]:disabled+label,input[type=search][readonly="readonly"]+label,textarea.materialize-textarea:disabled+label,textarea.materialize-textarea[readonly="readonly"]+label{color:rgba(0,0,0,0.26)}input:not([type]):focus:not([readonly]),input[type=text]:focus:not([readonly]),input[type=password]:focus:not([readonly]),input[type=email]:focus:not([readonly]),input[type=url]:focus:not([readonly]),input[type=time]:focus:not([readonly]),input[type=date]:focus:not([readonly]),input[type=datetime]:focus:not([readonly]),input[type=datetime-local]:focus:not([readonly]),input[type=tel]:focus:not([readonly]),input[type=number]:focus:not([readonly]),input[type=search]:focus:not([readonly]),textarea.materialize-textarea:focus:not([readonly]){border-bottom:1px solid #26a69a;box-shadow:0 1px 0 0 #26a69a}input:not([type]):focus:not([readonly])+label,input[type=text]:focus:not([readonly])+label,input[type=password]:focus:not([readonly])+label,input[type=email]:focus:not([readonly])+label,input[type=url]:focus:not([readonly])+label,input[type=time]:focus:not([readonly])+label,input[type=date]:focus:not([readonly])+label,input[type=datetime]:focus:not([readonly])+label,input[type=datetime-local]:focus:not([readonly])+label,input[type=tel]:focus:not([readonly])+label,input[type=number]:focus:not([readonly])+label,input[type=search]:focus:not([readonly])+label,textarea.materialize-textarea:focus:not([readonly])+label{color:#26a69a}input:not([type]).valid,input:not([type]):focus.valid,input[type=text].valid,input[type=text]:focus.valid,input[type=password].valid,input[type=password]:focus.valid,input[type=email].valid,input[type=email]:focus.valid,input[type=url].valid,input[type=url]:focus.valid,input[type=time].valid,input[type=time]:focus.valid,input[type=date].valid,input[type=date]:focus.valid,input[type=datetime].valid,input[type=datetime]:focus.valid,input[type=datetime-local].valid,input[type=datetime-local]:focus.valid,input[type=tel].valid,input[type=tel]:focus.valid,input[type=number].valid,input[type=number]:focus.valid,input[type=search].valid,input[type=search]:focus.valid,textarea.materialize-textarea.valid,textarea.materialize-textarea:focus.valid{border-bottom:1px solid #4CAF50;box-shadow:0 1px 0 0 #4CAF50}input:not([type]).valid+label:after,input:not([type]):focus.valid+label:after,input[type=text].valid+label:after,input[type=text]:focus.valid+label:after,input[type=password].valid+label:after,input[type=password]:focus.valid+label:after,input[type=email].valid+label:after,input[type=email]:focus.valid+label:after,input[type=url].valid+label:after,input[type=url]:focus.valid+label:after,input[type=time].valid+label:after,input[type=time]:focus.valid+label:after,input[type=date].valid+label:after,input[type=date]:focus.valid+label:after,input[type=datetime].valid+label:after,input[type=datetime]:focus.valid+label:after,input[type=datetime-local].valid+label:after,input[type=datetime-local]:focus.valid+label:after,input[type=tel].valid+label:after,input[type=tel]:focus.valid+label:after,input[type=number].valid+label:after,input[type=number]:focus.valid+label:after,input[type=search].valid+label:after,input[type=search]:focus.valid+label:after,textarea.materialize-textarea.valid+label:after,textarea.materialize-textarea:focus.valid+label:after{content:attr(data-success);color:#4CAF50;opacity:1}input:not([type]).invalid,input:not([type]):focus.invalid,input[type=text].invalid,input[type=text]:focus.invalid,input[type=password].invalid,input[type=password]:focus.invalid,input[type=email].invalid,input[type=email]:focus.invalid,input[type=url].invalid,input[type=url]:focus.invalid,input[type=time].invalid,input[type=time]:focus.invalid,input[type=date].invalid,input[type=date]:focus.invalid,input[type=datetime].invalid,input[type=datetime]:focus.invalid,input[type=datetime-local].invalid,input[type=datetime-local]:focus.invalid,input[type=tel].invalid,input[type=tel]:focus.invalid,input[type=number].invalid,input[type=number]:focus.invalid,input[type=search].invalid,input[type=search]:focus.invalid,textarea.materialize-textarea.invalid,textarea.materialize-textarea:focus.invalid{border-bottom:1px solid #F44336;box-shadow:0 1px 0 0 #F44336}input:not([type]).invalid+label:after,input:not([type]):focus.invalid+label:after,input[type=text].invalid+label:after,input[type=text]:focus.invalid+label:after,input[type=password].invalid+label:after,input[type=password]:focus.invalid+label:after,input[type=email].invalid+label:after,input[type=email]:focus.invalid+label:after,input[type=url].invalid+label:after,input[type=url]:focus.invalid+label:after,input[type=time].invalid+label:after,input[type=time]:focus.invalid+label:after,input[type=date].invalid+label:after,input[type=date]:focus.invalid+label:after,input[type=datetime].invalid+label:after,input[type=datetime]:focus.invalid+label:after,input[type=datetime-local].invalid+label:after,input[type=datetime-local]:focus.invalid+label:after,input[type=tel].invalid+label:after,input[type=tel]:focus.invalid+label:after,input[type=number].invalid+label:after,input[type=number]:focus.invalid+label:after,input[type=search].invalid+label:after,input[type=search]:focus.invalid+label:after,textarea.materialize-textarea.invalid+label:after,textarea.materialize-textarea:focus.invalid+label:after{content:attr(data-error);color:#F44336;opacity:1}input:not([type]).validate+label,input[type=text].validate+label,input[type=password].validate+label,input[type=email].validate+label,input[type=url].validate+label,input[type=time].validate+label,input[type=date].validate+label,input[type=datetime].validate+label,input[type=datetime-local].validate+label,input[type=tel].validate+label,input[type=number].validate+label,input[type=search].validate+label,textarea.materialize-textarea.validate+label{width:100%;pointer-events:none}input:not([type])+label:after,input[type=text]+label:after,input[type=password]+label:after,input[type=email]+label:after,input[type=url]+label:after,input[type=time]+label:after,input[type=date]+label:after,input[type=datetime]+label:after,input[type=datetime-local]+label:after,input[type=tel]+label:after,input[type=number]+label:after,input[type=search]+label:after,textarea.materialize-textarea+label:after{display:block;content:"";position:absolute;top:60px;opacity:0;transition:.2s opacity ease-out, .2s color ease-out}.input-field{position:relative;margin-top:1rem}.input-field.inline{display:inline-block;vertical-align:middle;margin-left:5px}.input-field.inline input,.input-field.inline .select-dropdown{margin-bottom:1rem}.input-field.col label{left:0.75rem}.input-field.col .prefix ~ label,.input-field.col .prefix ~ .validate ~ label{width:calc(100% - 3rem - 1.5rem)}.input-field label{color:#9e9e9e;position:absolute;top:0.8rem;left:0;font-size:1rem;cursor:text;transition:.2s ease-out}.input-field label.active{font-size:0.8rem;-webkit-transform:translateY(-140%);transform:translateY(-140%)}.input-field .prefix{position:absolute;width:3rem;font-size:2rem;transition:color .2s}.input-field .prefix.active{color:#26a69a}.input-field .prefix ~ input,.input-field .prefix ~ textarea,.input-field .prefix ~ label,.input-field .prefix ~ .validate ~ label,.input-field .prefix ~ .autocomplete-content{margin-left:3rem;width:92%;width:calc(100% - 3rem)}.input-field .prefix ~ label{margin-left:3rem}@media only screen and (max-width: 992px){.input-field .prefix ~ input{width:86%;width:calc(100% - 3rem)}}@media only screen and (max-width: 600px){.input-field .prefix ~ input{width:80%;width:calc(100% - 3rem)}}.input-field input[type=search]{display:block;line-height:inherit;padding-left:4rem;width:calc(100% - 4rem)}.input-field input[type=search]:focus{background-color:#fff;border:0;box-shadow:none;color:#444}.input-field input[type=search]:focus+label i,.input-field input[type=search]:focus ~ .mdi-navigation-close,.input-field input[type=search]:focus ~ .material-icons{color:#444}.input-field input[type=search]+label{left:1rem}.input-field input[type=search] ~ .mdi-navigation-close,.input-field input[type=search] ~ .material-icons{position:absolute;top:0;right:1rem;color:transparent;cursor:pointer;font-size:2rem;transition:.3s color}textarea{width:100%;height:3rem;background-color:transparent}textarea.materialize-textarea{overflow-y:hidden;padding:.8rem 0 1.6rem 0;resize:none;min-height:3rem}.hiddendiv{display:none;white-space:pre-wrap;word-wrap:break-word;overflow-wrap:break-word;padding-top:1.2rem}.autocomplete-content{margin-top:-15px;display:block;opacity:1;position:static}.autocomplete-content li .highlight{color:#444}.autocomplete-content li img{height:40px;width:40px;margin:5px 15px}[type="radio"]:not(:checked),[type="radio"]:checked{position:absolute;left:-9999px;opacity:0}[type="radio"]:not(:checked)+label,[type="radio"]:checked+label{position:relative;padding-left:35px;cursor:pointer;display:inline-block;height:25px;line-height:25px;font-size:1rem;transition:.28s ease;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}[type="radio"]+label:before,[type="radio"]+label:after{content:'';position:absolute;left:0;top:0;margin:4px;width:16px;height:16px;z-index:0;transition:.28s ease}[type="radio"]:not(:checked)+label:before,[type="radio"]:not(:checked)+label:after,[type="radio"]:checked+label:before,[type="radio"]:checked+label:after,[type="radio"].with-gap:checked+label:before,[type="radio"].with-gap:checked+label:after{border-radius:50%}[type="radio"]:not(:checked)+label:before,[type="radio"]:not(:checked)+label:after{border:2px solid #5a5a5a}[type="radio"]:not(:checked)+label:after{-webkit-transform:scale(0);transform:scale(0)}[type="radio"]:checked+label:before{border:2px solid transparent}[type="radio"]:checked+label:after,[type="radio"].with-gap:checked+label:before,[type="radio"].with-gap:checked+label:after{border:2px solid #26a69a}[type="radio"]:checked+label:after,[type="radio"].with-gap:checked+label:after{background-color:#26a69a}[type="radio"]:checked+label:after{-webkit-transform:scale(1.02);transform:scale(1.02)}[type="radio"].with-gap:checked+label:after{-webkit-transform:scale(0.5);transform:scale(0.5)}[type="radio"].tabbed:focus+label:before{box-shadow:0 0 0 10px rgba(0,0,0,0.1)}[type="radio"].with-gap:disabled:checked+label:before{border:2px solid rgba(0,0,0,0.26)}[type="radio"].with-gap:disabled:checked+label:after{border:none;background-color:rgba(0,0,0,0.26)}[type="radio"]:disabled:not(:checked)+label:before,[type="radio"]:disabled:checked+label:before{background-color:transparent;border-color:rgba(0,0,0,0.26)}[type="radio"]:disabled+label{color:rgba(0,0,0,0.26)}[type="radio"]:disabled:not(:checked)+label:before{border-color:rgba(0,0,0,0.26)}[type="radio"]:disabled:checked+label:after{background-color:rgba(0,0,0,0.26);border-color:#BDBDBD}form p{margin-bottom:10px;text-align:left}form p:last-child{margin-bottom:0}[type="checkbox"]:not(:checked),[type="checkbox"]:checked{position:absolute;left:-9999px;opacity:0}[type="checkbox"]+label{position:relative;padding-left:35px;cursor:pointer;display:inline-block;height:25px;line-height:25px;font-size:1rem;-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}[type="checkbox"]+label:before,[type="checkbox"]:not(.filled-in)+label:after{content:'';position:absolute;top:0;left:0;width:18px;height:18px;z-index:0;border:2px solid #5a5a5a;border-radius:1px;margin-top:2px;transition:.2s}[type="checkbox"]:not(.filled-in)+label:after{border:0;-webkit-transform:scale(0);transform:scale(0)}[type="checkbox"]:not(:checked):disabled+label:before{border:none;background-color:rgba(0,0,0,0.26)}[type="checkbox"].tabbed:focus+label:after{-webkit-transform:scale(1);transform:scale(1);border:0;border-radius:50%;box-shadow:0 0 0 10px rgba(0,0,0,0.1);background-color:rgba(0,0,0,0.1)}[type="checkbox"]:checked+label:before{top:-4px;left:-5px;width:12px;height:22px;border-top:2px solid transparent;border-left:2px solid transparent;border-right:2px solid #26a69a;border-bottom:2px solid #26a69a;-webkit-transform:rotate(40deg);transform:rotate(40deg);-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"]:checked:disabled+label:before{border-right:2px solid rgba(0,0,0,0.26);border-bottom:2px solid rgba(0,0,0,0.26)}[type="checkbox"]:indeterminate+label:before{top:-11px;left:-12px;width:10px;height:22px;border-top:none;border-left:none;border-right:2px solid #26a69a;border-bottom:none;-webkit-transform:rotate(90deg);transform:rotate(90deg);-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"]:indeterminate:disabled+label:before{border-right:2px solid rgba(0,0,0,0.26);background-color:transparent}[type="checkbox"].filled-in+label:after{border-radius:2px}[type="checkbox"].filled-in+label:before,[type="checkbox"].filled-in+label:after{content:'';left:0;position:absolute;transition:border .25s, background-color .25s, width .20s .1s, height .20s .1s, top .20s .1s, left .20s .1s;z-index:1}[type="checkbox"].filled-in:not(:checked)+label:before{width:0;height:0;border:3px solid transparent;left:6px;top:10px;-webkit-transform:rotateZ(37deg);transform:rotateZ(37deg);-webkit-transform-origin:20% 40%;transform-origin:100% 100%}[type="checkbox"].filled-in:not(:checked)+label:after{height:20px;width:20px;background-color:transparent;border:2px solid #5a5a5a;top:0px;z-index:0}[type="checkbox"].filled-in:checked+label:before{top:0;left:1px;width:8px;height:13px;border-top:2px solid transparent;border-left:2px solid transparent;border-right:2px solid #fff;border-bottom:2px solid #fff;-webkit-transform:rotateZ(37deg);transform:rotateZ(37deg);-webkit-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"].filled-in:checked+label:after{top:0;width:20px;height:20px;border:2px solid #26a69a;background-color:#26a69a;z-index:0}[type="checkbox"].filled-in.tabbed:focus+label:after{border-radius:2px;border-color:#5a5a5a;background-color:rgba(0,0,0,0.1)}[type="checkbox"].filled-in.tabbed:checked:focus+label:after{border-radius:2px;background-color:#26a69a;border-color:#26a69a}[type="checkbox"].filled-in:disabled:not(:checked)+label:before{background-color:transparent;border:2px solid transparent}[type="checkbox"].filled-in:disabled:not(:checked)+label:after{border-color:transparent;background-color:#BDBDBD}[type="checkbox"].filled-in:disabled:checked+label:before{background-color:transparent}[type="checkbox"].filled-in:disabled:checked+label:after{background-color:#BDBDBD;border-color:#BDBDBD}.switch,.switch *{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}.switch label{cursor:pointer}.switch label input[type=checkbox]{opacity:0;width:0;height:0}.switch label input[type=checkbox]:checked+.lever{background-color:#84c7c1}.switch label input[type=checkbox]:checked+.lever:after{background-color:#26a69a;left:24px}.switch label .lever{content:"";display:inline-block;position:relative;width:40px;height:15px;background-color:#818181;border-radius:15px;margin-right:10px;transition:background 0.3s ease;vertical-align:middle;margin:0 16px}.switch label .lever:after{content:"";position:absolute;display:inline-block;width:21px;height:21px;background-color:#F1F1F1;border-radius:21px;box-shadow:0 1px 3px 1px rgba(0,0,0,0.4);left:-5px;top:-3px;transition:left 0.3s ease, background .3s ease, box-shadow 0.1s ease}input[type=checkbox]:checked:not(:disabled) ~ .lever:active::after,input[type=checkbox]:checked:not(:disabled).tabbed:focus ~ .lever::after{box-shadow:0 1px 3px 1px rgba(0,0,0,0.4),0 0 0 15px rgba(38,166,154,0.1)}input[type=checkbox]:not(:disabled) ~ .lever:active:after,input[type=checkbox]:not(:disabled).tabbed:focus ~ .lever::after{box-shadow:0 1px 3px 1px rgba(0,0,0,0.4),0 0 0 15px rgba(0,0,0,0.08)}.switch input[type=checkbox][disabled]+.lever{cursor:default}.switch label input[type=checkbox][disabled]+.lever:after,.switch label input[type=checkbox][disabled]:checked+.lever:after{background-color:#BDBDBD}select{display:none}select.browser-default{display:block}select{background-color:rgba(255,255,255,0.9);width:100%;padding:5px;border:1px solid #f2f2f2;border-radius:2px;height:3rem}.select-label{position:absolute}.select-wrapper{position:relative}.select-wrapper input.select-dropdown{position:relative;cursor:pointer;background-color:transparent;border:none;border-bottom:1px solid #9e9e9e;outline:none;height:3rem;line-height:3rem;width:100%;font-size:1rem;margin:0 0 20px 0;padding:0;display:block}.select-wrapper span.caret{color:initial;position:absolute;right:0;top:0;bottom:0;height:10px;margin:auto 0;font-size:10px;line-height:10px}.select-wrapper span.caret.disabled{color:rgba(0,0,0,0.26)}.select-wrapper+label{position:absolute;top:-14px;font-size:0.8rem}select:disabled{color:rgba(0,0,0,0.3)}.select-wrapper input.select-dropdown:disabled{color:rgba(0,0,0,0.3);cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;border-bottom:1px solid rgba(0,0,0,0.3)}.select-wrapper i{color:rgba(0,0,0,0.3)}.select-dropdown li.disabled,.select-dropdown li.disabled>span,.select-dropdown li.optgroup{color:rgba(0,0,0,0.3);background-color:transparent}.prefix ~ .select-wrapper{margin-left:3rem;width:92%;width:calc(100% - 3rem)}.prefix ~ label{margin-left:3rem}.select-dropdown li img{height:40px;width:40px;margin:5px 15px;float:right}.select-dropdown li.optgroup{border-top:1px solid #eee}.select-dropdown li.optgroup.selected>span{color:rgba(0,0,0,0.7)}.select-dropdown li.optgroup>span{color:rgba(0,0,0,0.4)}.select-dropdown li.optgroup ~ li.optgroup-option{padding-left:1rem}.file-field{position:relative}.file-field .file-path-wrapper{overflow:hidden;padding-left:10px}.file-field input.file-path{width:100%}.file-field .btn,.file-field .btn-large{float:left;height:3rem;line-height:3rem}.file-field span{cursor:pointer}.file-field input[type=file]{position:absolute;top:0;right:0;left:0;bottom:0;width:100%;margin:0;padding:0;font-size:20px;cursor:pointer;opacity:0;filter:alpha(opacity=0)}.range-field{position:relative}input[type=range],input[type=range]+.thumb{cursor:pointer}input[type=range]{position:relative;background-color:transparent;border:none;outline:none;width:100%;margin:15px 0;padding:0}input[type=range]:focus{outline:none}input[type=range]+.thumb{position:absolute;border:none;height:0;width:0;border-radius:50%;background-color:#26a69a;top:10px;margin-left:-6px;-webkit-transform-origin:50% 50%;transform-origin:50% 50%;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}input[type=range]+.thumb .value{display:block;width:30px;text-align:center;color:#26a69a;font-size:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}input[type=range]+.thumb.active{border-radius:50% 50% 50% 0}input[type=range]+.thumb.active .value{color:#fff;margin-left:-1px;margin-top:8px;font-size:10px}input[type=range]{-webkit-appearance:none}input[type=range]::-webkit-slider-runnable-track{height:3px;background:#c2c0c2;border:none}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;border:none;height:14px;width:14px;border-radius:50%;background-color:#26a69a;-webkit-transform-origin:50% 50%;transform-origin:50% 50%;margin:-5px 0 0 0;transition:.3s}input[type=range]:focus::-webkit-slider-runnable-track{background:#ccc}input[type=range]{border:1px solid white}input[type=range]::-moz-range-track{height:3px;background:#ddd;border:none}input[type=range]::-moz-range-thumb{border:none;height:14px;width:14px;border-radius:50%;background:#26a69a;margin-top:-5px}input[type=range]:-moz-focusring{outline:1px solid #fff;outline-offset:-1px}input[type=range]:focus::-moz-range-track{background:#ccc}input[type=range]::-ms-track{height:3px;background:transparent;border-color:transparent;border-width:6px 0;color:transparent}input[type=range]::-ms-fill-lower{background:#777}input[type=range]::-ms-fill-upper{background:#ddd}input[type=range]::-ms-thumb{border:none;height:14px;width:14px;border-radius:50%;background:#26a69a}input[type=range]:focus::-ms-fill-lower{background:#888}input[type=range]:focus::-ms-fill-upper{background:#ccc}.table-of-contents.fixed{position:fixed}.table-of-contents li{padding:2px 0}.table-of-contents a{display:inline-block;font-weight:300;color:#757575;padding-left:20px;height:1.5rem;line-height:1.5rem;letter-spacing:.4;display:inline-block}.table-of-contents a:hover{color:#a8a8a8;padding-left:19px;border-left:1px solid #ea4a4f}.table-of-contents a.active{font-weight:500;padding-left:18px;border-left:2px solid #ea4a4f}.side-nav{position:fixed;width:300px;left:0;top:0;margin:0;-webkit-transform:translateX(-100%);transform:translateX(-100%);height:100%;height:calc(100% + 60px);height:-moz-calc(100%);padding-bottom:60px;background-color:#fff;z-index:999;overflow-y:auto;will-change:transform;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform:translateX(-105%);transform:translateX(-105%)}.side-nav.right-aligned{right:0;-webkit-transform:translateX(105%);transform:translateX(105%);left:auto;-webkit-transform:translateX(100%);transform:translateX(100%)}.side-nav .collapsible{margin:0}.side-nav li{float:none;line-height:48px}.side-nav li.active{background-color:rgba(0,0,0,0.05)}.side-nav a{color:rgba(0,0,0,0.87);display:block;font-size:14px;font-weight:500;height:48px;line-height:48px;padding:0 32px}.side-nav a:hover{background-color:rgba(0,0,0,0.05)}.side-nav a.btn,.side-nav a.btn-large,.side-nav a.btn-large,.side-nav a.btn-flat,.side-nav a.btn-floating{margin:10px 15px}.side-nav a.btn,.side-nav a.btn-large,.side-nav a.btn-large,.side-nav a.btn-floating{color:#fff}.side-nav a.btn-flat{color:#343434}.side-nav a.btn:hover,.side-nav a.btn-large:hover,.side-nav a.btn-large:hover{background-color:#2bbbad}.side-nav a.btn-floating:hover{background-color:#26a69a}.side-nav li>a>i,.side-nav li>a>[class^="mdi-"],.side-nav li>a>[class*="mdi-"],.side-nav li>a>i.material-icons{float:left;height:48px;line-height:48px;margin:0 32px 0 0;width:24px;color:rgba(0,0,0,0.54)}.side-nav .divider{margin:8px 0 0 0}.side-nav .subheader{cursor:initial;pointer-events:none;color:rgba(0,0,0,0.54);font-size:14px;font-weight:500;line-height:48px}.side-nav .subheader:hover{background-color:transparent}.side-nav .userView{position:relative;padding:32px 32px 0;margin-bottom:8px}.side-nav .userView>a{height:auto;padding:0}.side-nav .userView>a:hover{background-color:transparent}.side-nav .userView .background{overflow:hidden;position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1}.side-nav .userView .circle,.side-nav .userView .name,.side-nav .userView .email{display:block}.side-nav .userView .circle{height:64px;width:64px}.side-nav .userView .name,.side-nav .userView .email{font-size:14px;line-height:24px}.side-nav .userView .name{margin-top:16px;font-weight:500}.side-nav .userView .email{padding-bottom:16px;font-weight:400}.drag-target{height:100%;width:10px;position:fixed;top:0;z-index:998}.side-nav.fixed{left:0;-webkit-transform:translateX(0);transform:translateX(0);position:fixed}.side-nav.fixed.right-aligned{right:0;left:auto}@media only screen and (max-width: 992px){.side-nav.fixed{-webkit-transform:translateX(-105%);transform:translateX(-105%)}.side-nav.fixed.right-aligned{-webkit-transform:translateX(105%);transform:translateX(105%)}.side-nav a{padding:0 16px}.side-nav .userView{padding:16px 16px 0}}.side-nav .collapsible-body>ul:not(.collapsible)>li.active,.side-nav.fixed .collapsible-body>ul:not(.collapsible)>li.active{background-color:#ee6e73}.side-nav .collapsible-body>ul:not(.collapsible)>li.active a,.side-nav.fixed .collapsible-body>ul:not(.collapsible)>li.active a{color:#fff}#sidenav-overlay{position:fixed;top:0;left:0;right:0;height:120vh;background-color:rgba(0,0,0,0.5);z-index:997;will-change:opacity}.preloader-wrapper{display:inline-block;position:relative;width:48px;height:48px}.preloader-wrapper.small{width:36px;height:36px}.preloader-wrapper.big{width:64px;height:64px}.preloader-wrapper.active{-webkit-animation:container-rotate 1568ms linear infinite;animation:container-rotate 1568ms linear infinite}@-webkit-keyframes container-rotate{to{-webkit-transform:rotate(360deg)}}@keyframes container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-layer{position:absolute;width:100%;height:100%;opacity:0;border-color:#26a69a}.spinner-blue,.spinner-blue-only{border-color:#4285f4}.spinner-red,.spinner-red-only{border-color:#db4437}.spinner-yellow,.spinner-yellow-only{border-color:#f4b400}.spinner-green,.spinner-green-only{border-color:#0f9d58}.active .spinner-layer.spinner-blue{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-red{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-yellow{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-green{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer,.active .spinner-layer.spinner-blue-only,.active .spinner-layer.spinner-red-only,.active .spinner-layer.spinner-yellow-only,.active .spinner-layer.spinner-green-only{opacity:1;-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}@-webkit-keyframes fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg)}}@keyframes fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@-webkit-keyframes blue-fade-in-out{from{opacity:1}25%{opacity:1}26%{opacity:0}89%{opacity:0}90%{opacity:1}100%{opacity:1}}@keyframes blue-fade-in-out{from{opacity:1}25%{opacity:1}26%{opacity:0}89%{opacity:0}90%{opacity:1}100%{opacity:1}}@-webkit-keyframes red-fade-in-out{from{opacity:0}15%{opacity:0}25%{opacity:1}50%{opacity:1}51%{opacity:0}}@keyframes red-fade-in-out{from{opacity:0}15%{opacity:0}25%{opacity:1}50%{opacity:1}51%{opacity:0}}@-webkit-keyframes yellow-fade-in-out{from{opacity:0}40%{opacity:0}50%{opacity:1}75%{opacity:1}76%{opacity:0}}@keyframes yellow-fade-in-out{from{opacity:0}40%{opacity:0}50%{opacity:1}75%{opacity:1}76%{opacity:0}}@-webkit-keyframes green-fade-in-out{from{opacity:0}65%{opacity:0}75%{opacity:1}90%{opacity:1}100%{opacity:0}}@keyframes green-fade-in-out{from{opacity:0}65%{opacity:0}75%{opacity:1}90%{opacity:1}100%{opacity:0}}.gap-patch{position:absolute;top:0;left:45%;width:10%;height:100%;overflow:hidden;border-color:inherit}.gap-patch .circle{width:1000%;left:-450%}.circle-clipper{display:inline-block;position:relative;width:50%;height:100%;overflow:hidden;border-color:inherit}.circle-clipper .circle{width:200%;height:100%;border-width:3px;border-style:solid;border-color:inherit;border-bottom-color:transparent !important;border-radius:50%;-webkit-animation:none;animation:none;position:absolute;top:0;right:0;bottom:0}.circle-clipper.left .circle{left:0;border-right-color:transparent !important;-webkit-transform:rotate(129deg);transform:rotate(129deg)}.circle-clipper.right .circle{left:-100%;border-left-color:transparent !important;-webkit-transform:rotate(-129deg);transform:rotate(-129deg)}.active .circle-clipper.left .circle{-webkit-animation:left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .circle-clipper.right .circle{-webkit-animation:right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}@-webkit-keyframes left-spin{from{-webkit-transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg)}}@keyframes left-spin{from{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}}@-webkit-keyframes right-spin{from{-webkit-transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg)}}@keyframes right-spin{from{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}}#spinnerContainer.cooldown{-webkit-animation:container-rotate 1568ms linear infinite,fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1);animation:container-rotate 1568ms linear infinite,fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1)}@-webkit-keyframes fade-out{from{opacity:1}to{opacity:0}}@keyframes fade-out{from{opacity:1}to{opacity:0}}.slider{position:relative;height:400px;width:100%}.slider.fullscreen{height:100%;width:100%;position:absolute;top:0;left:0;right:0;bottom:0}.slider.fullscreen ul.slides{height:100%}.slider.fullscreen ul.indicators{z-index:2;bottom:30px}.slider .slides{background-color:#9e9e9e;margin:0;height:400px}.slider .slides li{opacity:0;position:absolute;top:0;left:0;z-index:1;width:100%;height:inherit;overflow:hidden}.slider .slides li img{height:100%;width:100%;background-size:cover;background-position:center}.slider .slides li .caption{color:#fff;position:absolute;top:15%;left:15%;width:70%;opacity:0}.slider .slides li .caption p{color:#e0e0e0}.slider .slides li.active{z-index:2}.slider .indicators{position:absolute;text-align:center;left:0;right:0;bottom:0;margin:0}.slider .indicators .indicator-item{display:inline-block;position:relative;cursor:pointer;height:16px;width:16px;margin:0 12px;background-color:#e0e0e0;transition:background-color .3s;border-radius:50%}.slider .indicators .indicator-item.active{background-color:#4CAF50}.carousel{overflow:hidden;position:relative;width:100%;height:400px;-webkit-perspective:500px;perspective:500px;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform-origin:0% 50%;transform-origin:0% 50%}.carousel.carousel-slider{top:0;left:0;height:0}.carousel.carousel-slider .carousel-fixed-item{position:absolute;left:0;right:0;bottom:20px;z-index:1}.carousel.carousel-slider .carousel-fixed-item.with-indicators{bottom:68px}.carousel.carousel-slider .carousel-item{width:100%;height:100%;min-height:400px;position:absolute;top:0;left:0}.carousel.carousel-slider .carousel-item h2{font-size:24px;font-weight:500;line-height:32px}.carousel.carousel-slider .carousel-item p{font-size:15px}.carousel .carousel-item{display:none;width:200px;height:400px;position:absolute;top:0;left:0}.carousel .carousel-item img{width:100%}.carousel .indicators{position:absolute;text-align:center;left:0;right:0;bottom:0;margin:0}.carousel .indicators .indicator-item{display:inline-block;position:relative;cursor:pointer;height:8px;width:8px;margin:24px 4px;background-color:rgba(255,255,255,0.5);transition:background-color .3s;border-radius:50%}.carousel .indicators .indicator-item.active{background-color:#fff}.picker{font-size:16px;text-align:left;line-height:1.2;color:#000000;position:absolute;z-index:10000;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.picker__input{cursor:default}.picker__input.picker__input--active{border-color:#0089ec}.picker__holder{width:100%;overflow-y:auto;-webkit-overflow-scrolling:touch}/*!
14
+ * Default mobile-first, responsive styling for pickadate.js
15
+ * Demo: http://amsul.github.io/pickadate.js
16
+ */.picker__holder,.picker__frame{bottom:0;left:0;right:0;top:100%}.picker__holder{position:fixed;transition:background 0.15s ease-out, top 0s 0.15s;-webkit-backface-visibility:hidden}.picker__frame{position:absolute;margin:0 auto;min-width:256px;width:300px;max-height:350px;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:alpha(opacity=0);-moz-opacity:0;opacity:0;transition:all 0.15s ease-out}@media (min-height: 28.875em){.picker__frame{overflow:visible;top:auto;bottom:-100%;max-height:80%}}@media (min-height: 40.125em){.picker__frame{margin-bottom:7.5%}}.picker__wrap{display:table;width:100%;height:100%}@media (min-height: 28.875em){.picker__wrap{display:block}}.picker__box{background:#ffffff;display:table-cell;vertical-align:middle}@media (min-height: 28.875em){.picker__box{display:block;border:1px solid #777777;border-top-color:#898989;border-bottom-width:0;border-radius:5px 5px 0 0;box-shadow:0 12px 36px 16px rgba(0,0,0,0.24)}}.picker--opened .picker__holder{top:0;background:transparent;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#1E000000,endColorstr=#1E000000)";zoom:1;background:rgba(0,0,0,0.32);transition:background 0.15s ease-out}.picker--opened .picker__frame{top:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";filter:alpha(opacity=100);-moz-opacity:1;opacity:1}@media (min-height: 35.875em){.picker--opened .picker__frame{top:10%;bottom:auto}}.picker__input.picker__input--active{border-color:#E3F2FD}.picker__frame{margin:0 auto;max-width:325px}@media (min-height: 38.875em){.picker--opened .picker__frame{top:10%;bottom:auto}}.picker__box{padding:0 1em}.picker__header{text-align:center;position:relative;margin-top:.75em}.picker__month,.picker__year{display:inline-block;margin-left:.25em;margin-right:.25em}.picker__select--month,.picker__select--year{height:2em;padding:0;margin-left:.25em;margin-right:.25em}.picker__select--month.browser-default{display:inline;background-color:#FFFFFF;width:40%}.picker__select--year.browser-default{display:inline;background-color:#FFFFFF;width:26%}.picker__select--month:focus,.picker__select--year:focus{border-color:rgba(0,0,0,0.05)}.picker__nav--prev,.picker__nav--next{position:absolute;padding:.5em 1.25em;width:1em;height:1em;box-sizing:content-box;top:-0.25em}.picker__nav--prev{left:-1em;padding-right:1.25em}.picker__nav--next{right:-1em;padding-left:1.25em}.picker__nav--disabled,.picker__nav--disabled:hover,.picker__nav--disabled:before,.picker__nav--disabled:before:hover{cursor:default;background:none;border-right-color:#f5f5f5;border-left-color:#f5f5f5}.picker__table{text-align:center;border-collapse:collapse;border-spacing:0;table-layout:fixed;font-size:1rem;width:100%;margin-top:.75em;margin-bottom:.5em}.picker__table th,.picker__table td{text-align:center}.picker__table td{margin:0;padding:0}.picker__weekday{width:14.285714286%;font-size:.75em;padding-bottom:.25em;color:#999999;font-weight:500}@media (min-height: 33.875em){.picker__weekday{padding-bottom:.5em}}.picker__day--today{position:relative;color:#595959;letter-spacing:-.3;padding:.75rem 0;font-weight:400;border:1px solid transparent}.picker__day--disabled:before{border-top-color:#aaaaaa}.picker__day--infocus:hover{cursor:pointer;color:#000;font-weight:500}.picker__day--outfocus{display:none;padding:.75rem 0;color:#fff}.picker__day--outfocus:hover{cursor:pointer;color:#dddddd;font-weight:500}.picker__day--highlighted:hover,.picker--focused .picker__day--highlighted{cursor:pointer}.picker__day--selected,.picker__day--selected:hover,.picker--focused .picker__day--selected{border-radius:50%;-webkit-transform:scale(0.75);transform:scale(0.75);background:#0089ec;color:#ffffff}.picker__day--disabled,.picker__day--disabled:hover,.picker--focused .picker__day--disabled{background:#f5f5f5;border-color:#f5f5f5;color:#dddddd;cursor:default}.picker__day--highlighted.picker__day--disabled,.picker__day--highlighted.picker__day--disabled:hover{background:#bbbbbb}.picker__footer{text-align:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.picker__button--today,.picker__button--clear,.picker__button--close{border:1px solid #ffffff;background:#ffffff;font-size:.8em;padding:.66em 0;font-weight:bold;width:33%;display:inline-block;vertical-align:bottom}.picker__button--today:hover,.picker__button--clear:hover,.picker__button--close:hover{cursor:pointer;color:#000000;background:#b1dcfb;border-bottom-color:#b1dcfb}.picker__button--today:focus,.picker__button--clear:focus,.picker__button--close:focus{background:#b1dcfb;border-color:rgba(0,0,0,0.05);outline:none}.picker__button--today:before,.picker__button--clear:before,.picker__button--close:before{position:relative;display:inline-block;height:0}.picker__button--today:before,.picker__button--clear:before{content:" ";margin-right:.45em}.picker__button--today:before{top:-0.05em;width:0;border-top:0.66em solid #0059bc;border-left:.66em solid transparent}.picker__button--clear:before{top:-0.25em;width:.66em;border-top:3px solid #ee2200}.picker__button--close:before{content:"\D7";top:-0.1em;vertical-align:top;font-size:1.1em;margin-right:.35em;color:#777777}.picker__button--today[disabled],.picker__button--today[disabled]:hover{background:#f5f5f5;border-color:#f5f5f5;color:#dddddd;cursor:default}.picker__button--today[disabled]:before{border-top-color:#aaaaaa}.picker__box{border-radius:2px;overflow:hidden}.picker__date-display{text-align:center;background-color:#26a69a;color:#fff;padding-bottom:15px;font-weight:300}.picker__nav--prev:hover,.picker__nav--next:hover{cursor:pointer;color:#000000;background:#a1ded8}.picker__weekday-display{background-color:#1f897f;padding:10px;font-weight:200;letter-spacing:.5;font-size:1rem;margin-bottom:15px}.picker__month-display{text-transform:uppercase;font-size:2rem}.picker__day-display{font-size:4.5rem;font-weight:400}.picker__year-display{font-size:1.8rem;color:rgba(255,255,255,0.4)}.picker__box{padding:0}.picker__calendar-container{padding:0 1rem}.picker__calendar-container thead{border:none}.picker__table{margin-top:0;margin-bottom:.5em}.picker__day--infocus{color:#595959;letter-spacing:-.3;padding:.75rem 0;font-weight:400;border:1px solid transparent}.picker__day.picker__day--today{color:#26a69a}.picker__day.picker__day--today.picker__day--selected{color:#fff}.picker__weekday{font-size:.9rem}.picker__day--selected,.picker__day--selected:hover,.picker--focused .picker__day--selected{border-radius:50%;-webkit-transform:scale(0.9);transform:scale(0.9);background-color:#26a69a;color:#ffffff}.picker__day--selected.picker__day--outfocus,.picker__day--selected:hover.picker__day--outfocus,.picker--focused .picker__day--selected.picker__day--outfocus{background-color:#a1ded8}.picker__footer{text-align:right;padding:5px 10px}.picker__close,.picker__today{font-size:1.1rem;padding:0 1rem;color:#26a69a}.picker__nav--prev:before,.picker__nav--next:before{content:" ";border-top:.5em solid transparent;border-bottom:.5em solid transparent;border-right:0.75em solid #676767;width:0;height:0;display:block;margin:0 auto}.picker__nav--next:before{border-right:0;border-left:0.75em solid #676767}button.picker__today:focus,button.picker__clear:focus,button.picker__close:focus{background-color:#a1ded8}.picker__list{list-style:none;padding:0.75em 0 4.2em;margin:0}.picker__list-item{border-bottom:1px solid #dddddd;border-top:1px solid #dddddd;margin-bottom:-1px;position:relative;background:#ffffff;padding:.75em 1.25em}@media (min-height: 46.75em){.picker__list-item{padding:.5em 1em}}.picker__list-item:hover{cursor:pointer;color:#000000;background:#b1dcfb;border-color:#0089ec;z-index:10}.picker__list-item--highlighted{border-color:#0089ec;z-index:10}.picker__list-item--highlighted:hover,.picker--focused .picker__list-item--highlighted{cursor:pointer;color:#000000;background:#b1dcfb}.picker__list-item--selected,.picker__list-item--selected:hover,.picker--focused .picker__list-item--selected{background:#0089ec;color:#ffffff;z-index:10}.picker__list-item--disabled,.picker__list-item--disabled:hover,.picker--focused .picker__list-item--disabled{background:#f5f5f5;border-color:#f5f5f5;color:#dddddd;cursor:default;border-color:#dddddd;z-index:auto}.picker--time .picker__button--clear{display:block;width:80%;margin:1em auto 0;padding:1em 1.25em;background:none;border:0;font-weight:500;font-size:.67em;text-align:center;text-transform:uppercase;color:#666}.picker--time .picker__button--clear:hover,.picker--time .picker__button--clear:focus{color:#000000;background:#b1dcfb;background:#ee2200;border-color:#ee2200;cursor:pointer;color:#ffffff;outline:none}.picker--time .picker__button--clear:before{top:-0.25em;color:#666;font-size:1.25em;font-weight:bold}.picker--time .picker__button--clear:hover:before,.picker--time .picker__button--clear:focus:before{color:#ffffff}.picker--time .picker__frame{min-width:256px;max-width:320px}.picker--time .picker__box{font-size:1em;background:#f2f2f2;padding:0}@media (min-height: 40.125em){.picker--time .picker__box{margin-bottom:5em}}
admin/css/responsive.dataTables.css ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ table.dataTable.dtr-inline.collapsed > tbody > tr > td.child,
2
+ table.dataTable.dtr-inline.collapsed > tbody > tr > th.child,
3
+ table.dataTable.dtr-inline.collapsed > tbody > tr > td.dataTables_empty {
4
+ cursor: default !important;
5
+ }
6
+ table.dataTable.dtr-inline.collapsed > tbody > tr > td.child:before,
7
+ table.dataTable.dtr-inline.collapsed > tbody > tr > th.child:before,
8
+ table.dataTable.dtr-inline.collapsed > tbody > tr > td.dataTables_empty:before {
9
+ display: none !important;
10
+ }
11
+ table.dataTable.dtr-inline.collapsed > tbody > tr > td:first-child,
12
+ table.dataTable.dtr-inline.collapsed > tbody > tr > th:first-child {
13
+ position: relative;
14
+ padding-left: 30px;
15
+ cursor: pointer;
16
+ }
17
+ table.dataTable.dtr-inline.collapsed > tbody > tr > td:first-child:before,
18
+ table.dataTable.dtr-inline.collapsed > tbody > tr > th:first-child:before {
19
+ top: 9px;
20
+ left: 4px;
21
+ height: 14px;
22
+ width: 14px;
23
+ display: block;
24
+ position: absolute;
25
+ color: white;
26
+ border: 2px solid white;
27
+ border-radius: 14px;
28
+ box-shadow: 0 0 3px #444;
29
+ box-sizing: content-box;
30
+ text-align: center;
31
+ font-family: 'Courier New', Courier, monospace;
32
+ line-height: 14px;
33
+ content: '+';
34
+ background-color: #31b131;
35
+ }
36
+ table.dataTable.dtr-inline.collapsed > tbody > tr.parent > td:first-child:before,
37
+ table.dataTable.dtr-inline.collapsed > tbody > tr.parent > th:first-child:before {
38
+ content: '-';
39
+ background-color: #d33333;
40
+ }
41
+ table.dataTable.dtr-inline.collapsed > tbody > tr.child td:before {
42
+ display: none;
43
+ }
44
+ table.dataTable.dtr-inline.collapsed.compact > tbody > tr > td:first-child,
45
+ table.dataTable.dtr-inline.collapsed.compact > tbody > tr > th:first-child {
46
+ padding-left: 27px;
47
+ }
48
+ table.dataTable.dtr-inline.collapsed.compact > tbody > tr > td:first-child:before,
49
+ table.dataTable.dtr-inline.collapsed.compact > tbody > tr > th:first-child:before {
50
+ top: 5px;
51
+ left: 4px;
52
+ height: 14px;
53
+ width: 14px;
54
+ border-radius: 14px;
55
+ line-height: 14px;
56
+ text-indent: 3px;
57
+ }
58
+ table.dataTable.dtr-column > tbody > tr > td.control,
59
+ table.dataTable.dtr-column > tbody > tr > th.control {
60
+ position: relative;
61
+ cursor: pointer;
62
+ }
63
+ table.dataTable.dtr-column > tbody > tr > td.control:before,
64
+ table.dataTable.dtr-column > tbody > tr > th.control:before {
65
+ top: 50%;
66
+ left: 50%;
67
+ height: 16px;
68
+ width: 16px;
69
+ margin-top: -10px;
70
+ margin-left: -10px;
71
+ display: block;
72
+ position: absolute;
73
+ color: white;
74
+ border: 2px solid white;
75
+ border-radius: 14px;
76
+ box-shadow: 0 0 3px #444;
77
+ box-sizing: content-box;
78
+ text-align: center;
79
+ font-family: 'Courier New', Courier, monospace;
80
+ line-height: 14px;
81
+ content: '+';
82
+ background-color: #31b131;
83
+ }
84
+ table.dataTable.dtr-column > tbody > tr.parent td.control:before,
85
+ table.dataTable.dtr-column > tbody > tr.parent th.control:before {
86
+ content: '-';
87
+ background-color: #d33333;
88
+ }
89
+ table.dataTable > tbody > tr.child {
90
+ padding: 0.5em 1em;
91
+ }
92
+ table.dataTable > tbody > tr.child:hover {
93
+ background: transparent !important;
94
+ }
95
+ table.dataTable > tbody > tr.child ul {
96
+ display: inline-block;
97
+ list-style-type: none;
98
+ margin: 0;
99
+ padding: 0;
100
+ }
101
+ table.dataTable > tbody > tr.child ul li {
102
+ border-bottom: 1px solid #efefef;
103
+ padding: 0.5em 0;
104
+ }
105
+ table.dataTable > tbody > tr.child ul li:first-child {
106
+ padding-top: 0;
107
+ }
108
+ table.dataTable > tbody > tr.child ul li:last-child {
109
+ border-bottom: none;
110
+ }
111
+ table.dataTable > tbody > tr.child span.dtr-title {
112
+ display: inline-block;
113
+ min-width: 75px;
114
+ font-weight: bold;
115
+ }
116
+
117
+ div.dtr-modal {
118
+ position: fixed;
119
+ box-sizing: border-box;
120
+ top: 0;
121
+ left: 0;
122
+ height: 100%;
123
+ width: 100%;
124
+ z-index: 100;
125
+ padding: 10em 1em;
126
+ }
127
+ div.dtr-modal div.dtr-modal-display {
128
+ position: absolute;
129
+ top: 0;
130
+ left: 0;
131
+ bottom: 0;
132
+ right: 0;
133
+ width: 50%;
134
+ height: 50%;
135
+ overflow: auto;
136
+ margin: auto;
137
+ z-index: 102;
138
+ overflow: auto;
139
+ background-color: #f5f5f7;
140
+ border: 1px solid black;
141
+ border-radius: 0.5em;
142
+ box-shadow: 0 12px 30px rgba(0, 0, 0, 0.6);
143
+ }
144
+ div.dtr-modal div.dtr-modal-content {
145
+ position: relative;
146
+ padding: 1em;
147
+ }
148
+ div.dtr-modal div.dtr-modal-close {
149
+ position: absolute;
150
+ top: 6px;
151
+ right: 6px;
152
+ width: 22px;
153
+ height: 22px;
154
+ border: 1px solid #eaeaea;
155
+ background-color: #f9f9f9;
156
+ text-align: center;
157
+ border-radius: 3px;
158
+ cursor: pointer;
159
+ z-index: 12;
160
+ }
161
+ div.dtr-modal div.dtr-modal-close:hover {
162
+ background-color: #eaeaea;
163
+ }
164
+ div.dtr-modal div.dtr-modal-background {
165
+ position: fixed;
166
+ top: 0;
167
+ left: 0;
168
+ right: 0;
169
+ bottom: 0;
170
+ z-index: 101;
171
+ background: rgba(0, 0, 0, 0.6);
172
+ }
173
+
174
+ @media screen and (max-width: 767px) {
175
+ div.dtr-modal div.dtr-modal-display {
176
+ width: 95%;
177
+ }
178
+ }
admin/css/xcloner-admin.css ADDED
@@ -0,0 +1,370 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * All of the CSS for your admin-specific functionality should be
3
+ * included in this file.
4
+ */
5
+ /* fallback */
6
+
7
+ html {
8
+ font-family: GillSans, Calibri, Trebuchet, sans-serif;
9
+ }
10
+ /*
11
+ @font-face {
12
+ font-family: 'Material Icons';
13
+ font-style: normal;
14
+ font-weight: 400;
15
+ src: url(../fonts/MaterialIcons-Regular.eot);
16
+ src: local('Material Icons'),
17
+ local('MaterialIcons-Regular'),
18
+ url(../fonts/MaterialIcons-Regular.woff2) format('woff2'),
19
+ url(../fonts/MaterialIcons-Regular.woff) format('woff'),
20
+ url(../fontsMaterialIcons-Regular.ttf) format('truetype');
21
+ }*/
22
+
23
+
24
+
25
+ h1{
26
+ font-size: 23px;
27
+ }
28
+
29
+ h2{
30
+ font-size: 18px;
31
+ }
32
+
33
+ .input-field{
34
+ margin-top: 0px;
35
+ }
36
+
37
+ td, th {
38
+ padding-top: 0px !important;
39
+ }
40
+
41
+ .form-table th {
42
+ padding-top: 10px !important;
43
+ }
44
+
45
+ a.nav-tab.col {
46
+ padding: 10px;
47
+ }
48
+
49
+
50
+ span.shorten_string{
51
+ cursor: pointer;
52
+ }
53
+
54
+ .card-panel{
55
+ min-height: 60px;
56
+ }
57
+
58
+
59
+ .dashboard .additional_system_info{
60
+ display: none;
61
+ }
62
+
63
+ .nav-tab-wrapper li{
64
+ margin-bottom: 0px;
65
+ }
66
+
67
+ .nav-tab-wrapper-content .tab-content{
68
+ display: none;
69
+ }
70
+
71
+ .nav-tab-wrapper-content .tab-content.active{
72
+ display: block;
73
+ }
74
+
75
+ .input-field label.active {
76
+ font-size: 1rem;
77
+ }
78
+
79
+ .xcloner-debugger .console{
80
+ height: 450px;
81
+ min-height: 300px;
82
+ overflow: auto;
83
+ }
84
+
85
+ #error_modal textarea{
86
+ height: 150px;
87
+ }
88
+
89
+ #error_modal .msg{
90
+ font-size: 14px;
91
+ }
92
+
93
+ #generate_backup .backup-status, #generate_backup ul.backup-status > li{
94
+ display: none;
95
+ }
96
+
97
+ ul.backup-name{
98
+ margin-top: 1.78rem;
99
+ }
100
+
101
+ #generate_backup .status-body ul.backup-name li, #generate_backup ul.logged-databases li{
102
+ font-weight: bold;
103
+ }
104
+
105
+ #generate_backup .backup-done .collapsible-body {
106
+ margin-top: 1.83rem;
107
+ }
108
+
109
+ #generate_backup .status-body > ul, #generate_backup .status-body ul.logged-tables{
110
+ margin: 5px 10px;
111
+ max-height: 200px;
112
+ overflow-y: auto;
113
+ margin-top: 1.78rem;
114
+ }
115
+
116
+ #generate_backup .action-buttons .cancel,
117
+ #generate_backup .action-buttons .restart{
118
+ display: none;
119
+ }
120
+
121
+ .modal-footer .modal-close.btn-flat{
122
+ color: #fff;
123
+ }
124
+
125
+ .collapsible-body{
126
+ padding: 0px 10px;
127
+ }
128
+
129
+ .select-wrapper+label {
130
+ font-size: 1rem;
131
+ }
132
+
133
+ #schedule_backup .server-time h2{
134
+ color: #fff;
135
+ }
136
+
137
+ #schedule_backup_success{
138
+ display: none;
139
+ }
140
+
141
+ #scheduled_backups_wrapper .dataTables_length,
142
+ #manage_backups_wrapper .dataTables_length{
143
+ display: none;
144
+ }
145
+
146
+ table#scheduled_backups{
147
+ font-size: 16px;
148
+ }
149
+
150
+ #scheduled_backups td, #scheduled_backups th{
151
+ padding-top: 8px !important;
152
+ }
153
+
154
+ #scheduled_backups i.status{
155
+ color: #fff;
156
+ }
157
+
158
+ .site-backup_page_xcloner_scheduled_backups_page #server_time h2 {
159
+ color: #fff;
160
+ margin: 9px 0px;
161
+ padding: 10px 10px 5px 10px;
162
+ }
163
+
164
+ textarea.materialize-textarea{
165
+ overflow: auto;
166
+ resize: auto;
167
+ }
168
+
169
+ #scheduled_backups .edit, #scheduled_backups .status.active, #scheduled_backups .delete,
170
+ #manage_backups .download, #manage_backups .cloud-upload, #manage_backups .delete, #manage_backups .list-backup-content,
171
+ .backup-done .download, .backup-done .cloud-upload, .backup-done .delete, .backup-done .list-backup-content{
172
+ color: #4db6ac;
173
+ }
174
+
175
+ #scheduled_backups .status.inactive{
176
+ color: #d32f2f ;
177
+ }
178
+
179
+ table.dataTable thead th, table.dataTable tfoot th{
180
+ padding-left: 10px;
181
+ }
182
+
183
+ table.dataTable tr.odd { background-color: #fff; }
184
+ table.dataTable tr.even { background-color: #f3f3f3; }
185
+
186
+ #manage_backups ul.multipart{
187
+ margin-left: 20px;
188
+ display: none;
189
+ }
190
+
191
+ #manage_backups ul.multipart li{
192
+ padding: 5px;
193
+ list-style-type: square;
194
+ }
195
+
196
+ a.expand-multipart.remove{
197
+ display: none;
198
+ }
199
+
200
+ .remote-storage .label label{
201
+ font-size:16px;
202
+ }
203
+ .remote-storage .label{
204
+ padding-top: 25px;
205
+ }
206
+
207
+
208
+ #manage_backups td.checkbox{
209
+ vertical-align: top;
210
+ }
211
+
212
+ #remote_storage_modal{
213
+ min-height: 350px;
214
+ }
215
+
216
+ #remote_storage_modal .label label{
217
+ font-size: 16px;
218
+ }
219
+
220
+ #remote_storage_modal .label{
221
+ padding-top: 25px;
222
+ }
223
+
224
+ #remote_storage_modal .status{
225
+ display: none;
226
+ }
227
+
228
+ #remote_storage_modal .status-text.error{
229
+ color: red;
230
+ }
231
+
232
+ #remote_storage_modal .status-text{
233
+ font-weight: bold;
234
+ }
235
+
236
+ #backup-status h5{
237
+ font-size: 18px;
238
+ }
239
+
240
+ #backup-status .row .item .title{
241
+ width: 100px;
242
+ display: inline-block;
243
+ font-weight: bold;
244
+ }
245
+
246
+ .xcloner-restore li.steps{
247
+ display: none;
248
+ }
249
+
250
+ .xcloner-restore .steps.show{
251
+ display: block;
252
+ }
253
+
254
+ .xcloner-restore li .collapsible-body{
255
+ padding: 25px 10px 15px 10px;
256
+ }
257
+
258
+ .xcloner-restore select.browser-default{
259
+ height: 36px;
260
+ font-size: 18px;
261
+ }
262
+
263
+ .xcloner-restore .steps .progress{
264
+ display: none;
265
+ }
266
+
267
+ .xcloner-restore .status > div{
268
+ margin: 10px 0px 0px 0px;
269
+ }
270
+
271
+ .xcloner-restore .toggler{
272
+ display: inline-block;
273
+ }
274
+
275
+ .xcloner-restore .toggler .normal{
276
+ display: block;
277
+ }
278
+
279
+ .xcloner-restore .toggler .cancel{
280
+ display: none;
281
+ }
282
+
283
+ .xcloner-restore .toggler.cancel .normal{
284
+ display: none;
285
+ }
286
+
287
+ .xcloner-restore .toggler.cancel .cancel{
288
+ display: block;
289
+ }
290
+
291
+ .xcloner-restore ul.text-steps li{
292
+ list-style-type: decimal;
293
+ }
294
+
295
+ .xcloner-restore ul.text-steps ul li{
296
+ list-style-type: disc;
297
+ }
298
+
299
+ .xcloner-restore ul.text-steps ul{
300
+ margin: 10px;
301
+ }
302
+
303
+ .xcloner-restore ul.text-steps{
304
+ margin-left: 20px;
305
+ }
306
+
307
+ .xcloner-restore .restore-remote-backup-step .files-list{
308
+ max-height: 250px;
309
+ overflow: auto;
310
+ margin: 10px 5px;
311
+ }
312
+
313
+ #backup_cotent_modal .modal-content .files-list span{
314
+ cursor: pointer;
315
+ }
316
+
317
+ .xcloner-restore .query-box{
318
+ display: none;
319
+ }
320
+
321
+ .xcloner-restore .query-box .query-list{
322
+ height: 10rem;
323
+ }
324
+
325
+ .xcloner-restore .restore-remote-database-step h5{
326
+ margin-top: -10px;
327
+ margin-bottom: 25px;
328
+ }
329
+
330
+
331
+ .regex_pattern{
332
+ cursor: pointer;
333
+ font-weight: bold;
334
+ }
335
+
336
+ .jstree-icon.jstree-checkbox.jstree-checkbox-disabled{
337
+ opacity: 0.3;
338
+ }
339
+
340
+ #xcloner_regex_exclude{
341
+ height: 5rem;
342
+ }
343
+
344
+ ul.xcloner_regex_exclude_limit li:nth-of-type(n+2) {
345
+ display:none;
346
+ }
347
+
348
+ .xcloner-restore .btn.waves-effect.waves-light.grey{
349
+ margin-top: -2px;
350
+ }
351
+
352
+ .xcloner-restore #xcloner_restore_finish{
353
+ display: none;
354
+ }
355
+
356
+ ul.files-list li{
357
+ padding: 0px;
358
+ white-space: pre;
359
+ }
360
+
361
+ #manage_backups_wrapper #manage_backups_filter{
362
+ min-width: 250px;
363
+ }
364
+
365
+
366
+ @media only screen and (min-width: 993px){
367
+ .dashboard .backup-ready{
368
+ float: right;
369
+ }
370
+ }
admin/fonts/roboto/Roboto-Bold.eot ADDED
Binary file
admin/fonts/roboto/Roboto-Bold.ttf ADDED
Binary file
admin/fonts/roboto/Roboto-Bold.woff ADDED
Binary file
admin/fonts/roboto/Roboto-Bold.woff2 ADDED
Binary file
admin/fonts/roboto/Roboto-Light.eot ADDED
Binary file
admin/fonts/roboto/Roboto-Light.ttf ADDED
Binary file
admin/fonts/roboto/Roboto-Light.woff ADDED
Binary file
admin/fonts/roboto/Roboto-Light.woff2 ADDED
Binary file
admin/fonts/roboto/Roboto-Medium.eot ADDED
Binary file
admin/fonts/roboto/Roboto-Medium.ttf ADDED
Binary file
admin/fonts/roboto/Roboto-Medium.woff ADDED
Binary file
admin/fonts/roboto/Roboto-Medium.woff2 ADDED
Binary file
admin/fonts/roboto/Roboto-Regular.eot ADDED
Binary file
admin/fonts/roboto/Roboto-Regular.ttf ADDED
Binary file
admin/fonts/roboto/Roboto-Regular.woff ADDED
Binary file
admin/fonts/roboto/Roboto-Regular.woff2 ADDED
Binary file
admin/fonts/roboto/Roboto-Thin.eot ADDED
Binary file
admin/fonts/roboto/Roboto-Thin.ttf ADDED
Binary file
admin/fonts/roboto/Roboto-Thin.woff ADDED
Binary file
admin/fonts/roboto/Roboto-Thin.woff2 ADDED
Binary file
admin/images/Sorting icons.psd ADDED
Binary file
admin/images/favicon.ico ADDED
Binary file
admin/images/sort_asc.png ADDED
Binary file
admin/images/sort_asc_disabled.png ADDED
Binary file
admin/images/sort_both.png ADDED
Binary file
admin/images/sort_desc.png ADDED
Binary file
admin/images/sort_desc_disabled.png ADDED
Binary file
admin/index.php ADDED
@@ -0,0 +1 @@
 
1
+ <?php // Silence is golden
admin/js/dataTables.responsive.js ADDED
@@ -0,0 +1,1232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! Responsive 2.1.0
2
+ * 2014-2016 SpryMedia Ltd - datatables.net/license
3
+ */
4
+
5
+ /**
6
+ * @summary Responsive
7
+ * @description Responsive tables plug-in for DataTables
8
+ * @version 2.1.0
9
+ * @file dataTables.responsive.js
10
+ * @author SpryMedia Ltd (www.sprymedia.co.uk)
11
+ * @contact www.sprymedia.co.uk/contact
12
+ * @copyright Copyright 2014-2016 SpryMedia Ltd.
13
+ *
14
+ * This source file is free software, available under the following license:
15
+ * MIT license - http://datatables.net/license/mit
16
+ *
17
+ * This source file is distributed in the hope that it will be useful, but
18
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
20
+ *
21
+ * For details please refer to: http://www.datatables.net
22
+ */
23
+ (function( factory ){
24
+ if ( typeof define === 'function' && define.amd ) {
25
+ // AMD
26
+ define( ['jquery', 'datatables.net'], function ( $ ) {
27
+ return factory( $, window, document );
28
+ } );
29
+ }
30
+ else if ( typeof exports === 'object' ) {
31
+ // CommonJS
32
+ module.exports = function (root, $) {
33
+ if ( ! root ) {
34
+ root = window;
35
+ }
36
+
37
+ if ( ! $ || ! $.fn.dataTable ) {
38
+ $ = require('datatables.net')(root, $).$;
39
+ }
40
+
41
+ return factory( $, root, root.document );
42
+ };
43
+ }
44
+ else {
45
+ // Browser
46
+ factory( jQuery, window, document );
47
+ }
48
+ }(function( $, window, document, undefined ) {
49
+ 'use strict';
50
+ var DataTable = $.fn.dataTable;
51
+
52
+
53
+ /**
54
+ * Responsive is a plug-in for the DataTables library that makes use of
55
+ * DataTables' ability to change the visibility of columns, changing the
56
+ * visibility of columns so the displayed columns fit into the table container.
57
+ * The end result is that complex tables will be dynamically adjusted to fit
58
+ * into the viewport, be it on a desktop, tablet or mobile browser.
59
+ *
60
+ * Responsive for DataTables has two modes of operation, which can used
61
+ * individually or combined:
62
+ *
63
+ * * Class name based control - columns assigned class names that match the
64
+ * breakpoint logic can be shown / hidden as required for each breakpoint.
65
+ * * Automatic control - columns are automatically hidden when there is no
66
+ * room left to display them. Columns removed from the right.
67
+ *
68
+ * In additional to column visibility control, Responsive also has built into
69
+ * options to use DataTables' child row display to show / hide the information
70
+ * from the table that has been hidden. There are also two modes of operation
71
+ * for this child row display:
72
+ *
73
+ * * Inline - when the control element that the user can use to show / hide
74
+ * child rows is displayed inside the first column of the table.
75
+ * * Column - where a whole column is dedicated to be the show / hide control.
76
+ *
77
+ * Initialisation of Responsive is performed by:
78
+ *
79
+ * * Adding the class `responsive` or `dt-responsive` to the table. In this case
80
+ * Responsive will automatically be initialised with the default configuration
81
+ * options when the DataTable is created.
82
+ * * Using the `responsive` option in the DataTables configuration options. This
83
+ * can also be used to specify the configuration options, or simply set to
84
+ * `true` to use the defaults.
85
+ *
86
+ * @class
87
+ * @param {object} settings DataTables settings object for the host table
88
+ * @param {object} [opts] Configuration options
89
+ * @requires jQuery 1.7+
90
+ * @requires DataTables 1.10.3+
91
+ *
92
+ * @example
93
+ * $('#example').DataTable( {
94
+ * responsive: true
95
+ * } );
96
+ * } );
97
+ */
98
+ var Responsive = function ( settings, opts ) {
99
+ // Sanity check that we are using DataTables 1.10 or newer
100
+ if ( ! DataTable.versionCheck || ! DataTable.versionCheck( '1.10.3' ) ) {
101
+ throw 'DataTables Responsive requires DataTables 1.10.3 or newer';
102
+ }
103
+
104
+ this.s = {
105
+ dt: new DataTable.Api( settings ),
106
+ columns: [],
107
+ current: []
108
+ };
109
+
110
+ // Check if responsive has already been initialised on this table
111
+ if ( this.s.dt.settings()[0].responsive ) {
112
+ return;
113
+ }
114
+
115
+ // details is an object, but for simplicity the user can give it as a string
116
+ // or a boolean
117
+ if ( opts && typeof opts.details === 'string' ) {
118
+ opts.details = { type: opts.details };
119
+ }
120
+ else if ( opts && opts.details === false ) {
121
+ opts.details = { type: false };
122
+ }
123
+ else if ( opts && opts.details === true ) {
124
+ opts.details = { type: 'inline' };
125
+ }
126
+
127
+ this.c = $.extend( true, {}, Responsive.defaults, DataTable.defaults.responsive, opts );
128
+ settings.responsive = this;
129
+ this._constructor();
130
+ };
131
+
132
+ $.extend( Responsive.prototype, {
133
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
134
+ * Constructor
135
+ */
136
+
137
+ /**
138
+ * Initialise the Responsive instance
139
+ *
140
+ * @private
141
+ */
142
+ _constructor: function ()
143
+ {
144
+ var that = this;
145
+ var dt = this.s.dt;
146
+ var dtPrivateSettings = dt.settings()[0];
147
+ var oldWindowWidth = $(window).width();
148
+
149
+ dt.settings()[0]._responsive = this;
150
+
151
+ // Use DataTables' throttle function to avoid processor thrashing on
152
+ // resize
153
+ $(window).on( 'resize.dtr orientationchange.dtr', DataTable.util.throttle( function () {
154
+ // iOS has a bug whereby resize can fire when only scrolling
155
+ // See: http://stackoverflow.com/questions/8898412
156
+ var width = $(window).width();
157
+
158
+ if ( width !== oldWindowWidth ) {
159
+ that._resize();
160
+ oldWindowWidth = width;
161
+ }
162
+ } ) );
163
+
164
+ // DataTables doesn't currently trigger an event when a row is added, so
165
+ // we need to hook into its private API to enforce the hidden rows when
166
+ // new data is added
167
+ dtPrivateSettings.oApi._fnCallbackReg( dtPrivateSettings, 'aoRowCreatedCallback', function (tr, data, idx) {
168
+ if ( $.inArray( false, that.s.current ) !== -1 ) {
169
+ $('td, th', tr).each( function ( i ) {
170
+ var idx = dt.column.index( 'toData', i );
171
+
172
+ if ( that.s.current[idx] === false ) {
173
+ $(this).css('display', 'none');
174
+ }
175
+ } );
176
+ }
177
+ } );
178
+
179
+ // Destroy event handler
180
+ dt.on( 'destroy.dtr', function () {
181
+ dt.off( '.dtr' );
182
+ $( dt.table().body() ).off( '.dtr' );
183
+ $(window).off( 'resize.dtr orientationchange.dtr' );
184
+
185
+ // Restore the columns that we've hidden
186
+ $.each( that.s.current, function ( i, val ) {
187
+ if ( val === false ) {
188
+ that._setColumnVis( i, true );
189
+ }
190
+ } );
191
+ } );
192
+
193
+ // Reorder the breakpoints array here in case they have been added out
194
+ // of order
195
+ this.c.breakpoints.sort( function (a, b) {
196
+ return a.width < b.width ? 1 :
197
+ a.width > b.width ? -1 : 0;
198
+ } );
199
+
200
+ this._classLogic();
201
+ this._resizeAuto();
202
+
203
+ // Details handler
204
+ var details = this.c.details;
205
+
206
+ if ( details.type !== false ) {
207
+ that._detailsInit();
208
+
209
+ // DataTables will trigger this event on every column it shows and
210
+ // hides individually
211
+ dt.on( 'column-visibility.dtr', function (e, ctx, col, vis) {
212
+ that._classLogic();
213
+ that._resizeAuto();
214
+ that._resize();
215
+ } );
216
+
217
+ // Redraw the details box on each draw which will happen if the data
218
+ // has changed. This is used until DataTables implements a native
219
+ // `updated` event for rows
220
+ dt.on( 'draw.dtr', function () {
221
+ that._redrawChildren();
222
+ } );
223
+
224
+ $(dt.table().node()).addClass( 'dtr-'+details.type );
225
+ }
226
+
227
+ dt.on( 'column-reorder.dtr', function (e, settings, details) {
228
+ that._classLogic();
229
+ that._resizeAuto();
230
+ that._resize();
231
+ } );
232
+
233
+ // Change in column sizes means we need to calc
234
+ dt.on( 'column-sizing.dtr', function () {
235
+ that._resizeAuto();
236
+ that._resize();
237
+ });
238
+
239
+ dt.on( 'init.dtr', function (e, settings, details) {
240
+ that._resizeAuto();
241
+ that._resize();
242
+
243
+ // If columns were hidden, then DataTables needs to adjust the
244
+ // column sizing
245
+ if ( $.inArray( false, that.s.current ) ) {
246
+ dt.columns.adjust();
247
+ }
248
+ } );
249
+
250
+ // First pass - draw the table for the current viewport size
251
+ this._resize();
252
+ },
253
+
254
+
255
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
256
+ * Private methods
257
+ */
258
+
259
+ /**
260
+ * Calculate the visibility for the columns in a table for a given
261
+ * breakpoint. The result is pre-determined based on the class logic if
262
+ * class names are used to control all columns, but the width of the table
263
+ * is also used if there are columns which are to be automatically shown
264
+ * and hidden.
265
+ *
266
+ * @param {string} breakpoint Breakpoint name to use for the calculation
267
+ * @return {array} Array of boolean values initiating the visibility of each
268
+ * column.
269
+ * @private
270
+ */
271
+ _columnsVisiblity: function ( breakpoint )
272
+ {
273
+ var dt = this.s.dt;
274
+ var columns = this.s.columns;
275
+ var i, ien;
276
+
277
+ // Create an array that defines the column ordering based first on the
278
+ // column's priority, and secondly the column index. This allows the
279
+ // columns to be removed from the right if the priority matches
280
+ var order = columns
281
+ .map( function ( col, idx ) {
282
+ return {
283
+ columnIdx: idx,
284
+ priority: col.priority
285
+ };
286
+ } )
287
+ .sort( function ( a, b ) {
288
+ if ( a.priority !== b.priority ) {
289
+ return a.priority - b.priority;
290
+ }
291
+ return a.columnIdx - b.columnIdx;
292
+ } );
293
+
294
+ // Class logic - determine which columns are in this breakpoint based
295
+ // on the classes. If no class control (i.e. `auto`) then `-` is used
296
+ // to indicate this to the rest of the function
297
+ var display = $.map( columns, function ( col ) {
298
+ return col.auto && col.minWidth === null ?
299
+ false :
300
+ col.auto === true ?
301
+ '-' :
302
+ $.inArray( breakpoint, col.includeIn ) !== -1;
303
+ } );
304
+
305
+ // Auto column control - first pass: how much width is taken by the
306
+ // ones that must be included from the non-auto columns
307
+ var requiredWidth = 0;
308
+ for ( i=0, ien=display.length ; i<ien ; i++ ) {
309
+ if ( display[i] === true ) {
310
+ requiredWidth += columns[i].minWidth;
311
+ }
312
+ }
313
+
314
+ // Second pass, use up any remaining width for other columns. For
315
+ // scrolling tables we need to subtract the width of the scrollbar. It
316
+ // may not be requires which makes this sub-optimal, but it would
317
+ // require another full redraw to make complete use of those extra few
318
+ // pixels
319
+ var scrolling = dt.settings()[0].oScroll;
320
+ var bar = scrolling.sY || scrolling.sX ? scrolling.iBarWidth : 0;
321
+ var widthAvailable = dt.table().container().offsetWidth - bar;
322
+ var usedWidth = widthAvailable - requiredWidth;
323
+
324
+ // Control column needs to always be included. This makes it sub-
325
+ // optimal in terms of using the available with, but to stop layout
326
+ // thrashing or overflow. Also we need to account for the control column
327
+ // width first so we know how much width is available for the other
328
+ // columns, since the control column might not be the first one shown
329
+ for ( i=0, ien=display.length ; i<ien ; i++ ) {
330
+ if ( columns[i].control ) {
331
+ usedWidth -= columns[i].minWidth;
332
+ }
333
+ }
334
+
335
+ // Allow columns to be shown (counting by priority and then right to
336
+ // left) until we run out of room
337
+ var empty = false;
338
+ for ( i=0, ien=order.length ; i<ien ; i++ ) {
339
+ var colIdx = order[i].columnIdx;
340
+
341
+ if ( display[colIdx] === '-' && ! columns[colIdx].control && columns[colIdx].minWidth ) {
342
+ // Once we've found a column that won't fit we don't let any
343
+ // others display either, or columns might disappear in the
344
+ // middle of the table
345
+ if ( empty || usedWidth - columns[colIdx].minWidth < 0 ) {
346
+ empty = true;
347
+ display[colIdx] = false;
348
+ }
349
+ else {
350
+ display[colIdx] = true;
351
+ }
352
+
353
+ usedWidth -= columns[colIdx].minWidth;
354
+ }
355
+ }
356
+
357
+ // Determine if the 'control' column should be shown (if there is one).
358
+ // This is the case when there is a hidden column (that is not the
359
+ // control column). The two loops look inefficient here, but they are
360
+ // trivial and will fly through. We need to know the outcome from the
361
+ // first , before the action in the second can be taken
362
+ var showControl = false;
363
+
364
+ for ( i=0, ien=columns.length ; i<ien ; i++ ) {
365
+ if ( ! columns[i].control && ! columns[i].never && ! display[i] ) {
366
+ showControl = true;
367
+ break;
368
+ }
369
+ }
370
+
371
+ for ( i=0, ien=columns.length ; i<ien ; i++ ) {
372
+ if ( columns[i].control ) {
373
+ display[i] = showControl;
374
+ }
375
+ }
376
+
377
+ // Finally we need to make sure that there is at least one column that
378
+ // is visible
379
+ if ( $.inArray( true, display ) === -1 ) {
380
+ display[0] = true;
381
+ }
382
+
383
+ return display;
384
+ },
385
+
386
+
387
+ /**
388
+ * Create the internal `columns` array with information about the columns
389
+ * for the table. This includes determining which breakpoints the column
390
+ * will appear in, based upon class names in the column, which makes up the
391
+ * vast majority of this method.
392
+ *
393
+ * @private
394
+ */
395
+ _classLogic: function ()
396
+ {
397
+ var that = this;
398
+ var calc = {};
399
+ var breakpoints = this.c.breakpoints;
400
+ var dt = this.s.dt;
401
+ var columns = dt.columns().eq(0).map( function (i) {
402
+ var column = this.column(i);
403
+ var className = column.header().className;
404
+ var priority = dt.settings()[0].aoColumns[i].responsivePriority;
405
+
406
+ if ( priority === undefined ) {
407
+ var dataPriority = $(column.header()).data('priority');
408
+
409
+ priority = dataPriority !== undefined ?
410
+ dataPriority * 1 :
411
+ 10000;
412
+ }
413
+
414
+ return {
415
+ className: className,
416
+ includeIn: [],
417
+ auto: false,
418
+ control: false,
419
+ never: className.match(/\bnever\b/) ? true : false,
420
+ priority: priority
421
+ };
422
+ } );
423
+
424
+ // Simply add a breakpoint to `includeIn` array, ensuring that there are
425
+ // no duplicates
426
+ var add = function ( colIdx, name ) {
427
+ var includeIn = columns[ colIdx ].includeIn;
428
+
429
+ if ( $.inArray( name, includeIn ) === -1 ) {
430
+ includeIn.push( name );
431
+ }
432
+ };
433
+
434
+ var column = function ( colIdx, name, operator, matched ) {
435
+ var size, i, ien;
436
+
437
+ if ( ! operator ) {
438
+ columns[ colIdx ].includeIn.push( name );
439
+ }
440
+ else if ( operator === 'max-' ) {
441
+ // Add this breakpoint and all smaller
442
+ size = that._find( name ).width;
443
+
444
+ for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
445
+ if ( breakpoints[i].width <= size ) {
446
+ add( colIdx, breakpoints[i].name );
447
+ }
448
+ }
449
+ }
450
+ else if ( operator === 'min-' ) {
451
+ // Add this breakpoint and all larger
452
+ size = that._find( name ).width;
453
+
454
+ for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
455
+ if ( breakpoints[i].width >= size ) {
456
+ add( colIdx, breakpoints[i].name );
457
+ }
458
+ }
459
+ }
460
+ else if ( operator === 'not-' ) {
461
+ // Add all but this breakpoint
462
+ for ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {
463
+ if ( breakpoints[i].name.indexOf( matched ) === -1 ) {
464
+ add( colIdx, breakpoints[i].name );
465
+ }
466
+ }
467
+ }
468
+ };
469
+
470
+ // Loop over each column and determine if it has a responsive control
471
+ // class
472
+ columns.each( function ( col, i ) {
473
+ var classNames = col.className.split(' ');
474
+ var hasClass = false;
475
+
476
+ // Split the class name up so multiple rules can be applied if needed
477
+ for ( var k=0, ken=classNames.length ; k<ken ; k++ ) {
478
+ var className = $.trim( classNames[k] );
479
+
480
+ if ( className === 'all' ) {
481
+ // Include in all
482
+ hasClass = true;
483
+ col.includeIn = $.map( breakpoints, function (a) {
484
+ return a.name;
485
+ } );
486
+ return;
487
+ }
488
+ else if ( className === 'none' || col.never ) {
489
+ // Include in none (default) and no auto
490
+ hasClass = true;
491
+ return;
492
+ }
493
+ else if ( className === 'control' ) {
494
+ // Special column that is only visible, when one of the other
495
+ // columns is hidden. This is used for the details control
496
+ hasClass = true;
497
+ col.control = true;
498
+ return;
499
+ }
500
+
501
+ $.each( breakpoints, function ( j, breakpoint ) {
502
+ // Does this column have a class that matches this breakpoint?
503
+ var brokenPoint = breakpoint.name.split('-');
504
+ var re = new RegExp( '(min\\-|max\\-|not\\-)?('+brokenPoint[0]+')(\\-[_a-zA-Z0-9])?' );
505
+ var match = className.match( re );
506
+
507
+ if ( match ) {
508
+ hasClass = true;
509
+
510
+ if ( match[2] === brokenPoint[0] && match[3] === '-'+brokenPoint[1] ) {
511
+ // Class name matches breakpoint name fully
512
+ column( i, breakpoint.name, match[1], match[2]+match[3] );
513
+ }
514
+ else if ( match[2] === brokenPoint[0] && ! match[3] ) {
515
+ // Class name matched primary breakpoint name with no qualifier
516
+ column( i, breakpoint.name, match[1], match[2] );
517
+ }
518
+ }
519
+ } );
520
+ }
521
+
522
+ // If there was no control class, then automatic sizing is used
523
+ if ( ! hasClass ) {
524
+ col.auto = true;
525
+ }
526
+ } );
527
+
528
+ this.s.columns = columns;
529
+ },
530
+
531
+
532
+ /**
533
+ * Show the details for the child row
534
+ *
535
+ * @param {DataTables.Api} row API instance for the row
536
+ * @param {boolean} update Update flag
537
+ * @private
538
+ */
539
+ _detailsDisplay: function ( row, update )
540
+ {
541
+ var that = this;
542
+ var dt = this.s.dt;
543
+ var details = this.c.details;
544
+
545
+ if ( details && details.type !== false ) {
546
+ var res = details.display( row, update, function () {
547
+ return details.renderer(
548
+ dt, row[0], that._detailsObj(row[0])
549
+ );
550
+ } );
551
+
552
+ if ( res === true || res === false ) {
553
+ $(dt.table().node()).triggerHandler( 'responsive-display.dt', [dt, row, res, update] );
554
+ }
555
+ }
556
+ },
557
+
558
+
559
+ /**
560
+ * Initialisation for the details handler
561
+ *
562
+ * @private
563
+ */
564
+ _detailsInit: function ()
565
+ {
566
+ var that = this;
567
+ var dt = this.s.dt;
568
+ var details = this.c.details;
569
+
570
+ // The inline type always uses the first child as the target
571
+ if ( details.type === 'inline' ) {
572
+ details.target = 'td:first-child, th:first-child';
573
+ }
574
+
575
+ // Keyboard accessibility
576
+ dt.on( 'draw.dtr', function () {
577
+ that._tabIndexes();
578
+ } );
579
+ that._tabIndexes(); // Initial draw has already happened
580
+
581
+ $( dt.table().body() ).on( 'keyup.dtr', 'td, th', function (e) {
582
+ if ( e.keyCode === 13 && $(this).data('dtr-keyboard') ) {
583
+ $(this).click();
584
+ }
585
+ } );
586
+
587
+ // type.target can be a string jQuery selector or a column index
588
+ var target = details.target;
589
+ var selector = typeof target === 'string' ? target : 'td, th';
590
+
591
+ // Click handler to show / hide the details rows when they are available
592
+ $( dt.table().body() )
593
+ .on( 'click.dtr mousedown.dtr mouseup.dtr', selector, function (e) {
594
+ // If the table is not collapsed (i.e. there is no hidden columns)
595
+ // then take no action
596
+ if ( ! $(dt.table().node()).hasClass('collapsed' ) ) {
597
+ return;
598
+ }
599
+
600
+ // Check that the row is actually a DataTable's controlled node
601
+ if ( ! dt.row( $(this).closest('tr') ).length ) {
602
+ return;
603
+ }
604
+
605
+ // For column index, we determine if we should act or not in the
606
+ // handler - otherwise it is already okay
607
+ if ( typeof target === 'number' ) {
608
+ var targetIdx = target < 0 ?
609
+ dt.columns().eq(0).length + target :
610
+ target;
611
+
612
+ if ( dt.cell( this ).index().column !== targetIdx ) {
613
+ return;
614
+ }
615
+ }
616
+
617
+ // $().closest() includes itself in its check
618
+ var row = dt.row( $(this).closest('tr') );
619
+
620
+ // Check event type to do an action
621
+ if ( e.type === 'click' ) {
622
+ // The renderer is given as a function so the caller can execute it
623
+ // only when they need (i.e. if hiding there is no point is running
624
+ // the renderer)
625
+ that._detailsDisplay( row, false );
626
+ }
627
+ else if ( e.type === 'mousedown' ) {
628
+ // For mouse users, prevent the focus ring from showing
629
+ $(this).css('outline', 'none');
630
+ }
631
+ else if ( e.type === 'mouseup' ) {
632
+ // And then re-allow at the end of the click
633
+ $(this).blur().css('outline', '');
634
+ }
635
+ } );
636
+ },
637
+
638
+
639
+ /**
640
+ * Get the details to pass to a renderer for a row
641
+ * @param {int} rowIdx Row index
642
+ * @private
643
+ */
644
+ _detailsObj: function ( rowIdx )
645
+ {
646
+ var that = this;
647
+ var dt = this.s.dt;
648
+
649
+ return $.map( this.s.columns, function( col, i ) {
650
+ // Never and control columns should not be passed to the renderer
651
+ if ( col.never || col.control ) {
652
+ return;
653
+ }
654
+
655
+ return {
656
+ title: dt.settings()[0].aoColumns[ i ].sTitle,
657
+ data: dt.cell( rowIdx, i ).render( that.c.orthogonal ),
658
+ hidden: dt.column( i ).visible() && !that.s.current[ i ],
659
+ columnIndex: i,
660
+ rowIndex: rowIdx
661
+ };
662
+ } );
663
+ },
664
+
665
+
666
+ /**
667
+ * Find a breakpoint object from a name
668
+ *
669
+ * @param {string} name Breakpoint name to find
670
+ * @return {object} Breakpoint description object
671
+ * @private
672
+ */
673
+ _find: function ( name )
674
+ {
675
+ var breakpoints = this.c.breakpoints;
676
+
677
+ for ( var i=0, ien=breakpoints.length ; i<ien ; i++ ) {
678
+ if ( breakpoints[i].name === name ) {
679
+ return breakpoints[i];
680
+ }
681
+ }
682
+ },
683
+
684
+
685
+ /**
686
+ * Re-create the contents of the child rows as the display has changed in
687
+ * some way.
688
+ *
689
+ * @private
690
+ */
691
+ _redrawChildren: function ()
692
+ {
693
+ var that = this;
694
+ var dt = this.s.dt;
695
+
696
+ dt.rows( {page: 'current'} ).iterator( 'row', function ( settings, idx ) {
697
+ var row = dt.row( idx );
698
+
699
+ that._detailsDisplay( dt.row( idx ), true );
700
+ } );
701
+ },
702
+
703
+
704
+ /**
705
+ * Alter the table display for a resized viewport. This involves first
706
+ * determining what breakpoint the window currently is in, getting the
707
+ * column visibilities to apply and then setting them.
708
+ *
709
+ * @private
710
+ */
711
+ _resize: function ()
712
+ {
713
+ var that = this;
714
+ var dt = this.s.dt;
715
+ var width = $(window).width();
716
+ var breakpoints = this.c.breakpoints;
717
+ var breakpoint = breakpoints[0].name;
718
+ var columns = this.s.columns;
719
+ var i, ien;
720
+ var oldVis = this.s.current.slice();
721
+
722
+ // Determine what breakpoint we are currently at
723
+ for ( i=breakpoints.length-1 ; i>=0 ; i-- ) {
724
+ if ( width <= breakpoints[i].width ) {
725
+ breakpoint = breakpoints[i].name;
726
+ break;
727
+ }
728
+ }
729
+
730
+ // Show the columns for that break point
731
+ var columnsVis = this._columnsVisiblity( breakpoint );
732
+ this.s.current = columnsVis;
733
+
734
+ // Set the class before the column visibility is changed so event
735
+ // listeners know what the state is. Need to determine if there are
736
+ // any columns that are not visible but can be shown
737
+ var collapsedClass = false;
738
+ for ( i=0, ien=columns.length ; i<ien ; i++ ) {
739
+ if ( columnsVis[i] === false && ! columns[i].never && ! columns[i].control ) {
740
+ collapsedClass = true;
741
+ break;
742
+ }
743
+ }
744
+
745
+ $( dt.table().node() ).toggleClass( 'collapsed', collapsedClass );
746
+
747
+ var changed = false;
748
+
749
+ dt.columns().eq(0).each( function ( colIdx, i ) {
750
+ if ( columnsVis[i] !== oldVis[i] ) {
751
+ changed = true;
752
+ that._setColumnVis( colIdx, columnsVis[i] );
753
+ }
754
+ } );
755
+
756
+ if ( changed ) {
757
+ this._redrawChildren();
758
+
759
+ // Inform listeners of the change
760
+ $(dt.table().node()).trigger( 'responsive-resize.dt', [dt, this.s.current] );
761
+ }
762
+ },
763
+
764
+
765
+ /**
766
+ * Determine the width of each column in the table so the auto column hiding
767
+ * has that information to work with. This method is never going to be 100%
768
+ * perfect since column widths can change slightly per page, but without
769
+ * seriously compromising performance this is quite effective.
770
+ *
771
+ * @private
772
+ */
773
+ _resizeAuto: function ()
774
+ {
775
+ var dt = this.s.dt;
776
+ var columns = this.s.columns;
777
+
778
+ // Are we allowed to do auto sizing?
779
+ if ( ! this.c.auto ) {
780
+ return;
781
+ }
782
+
783
+ // Are there any columns that actually need auto-sizing, or do they all
784
+ // have classes defined
785
+ if ( $.inArray( true, $.map( columns, function (c) { return c.auto; } ) ) === -1 ) {
786
+ return;
787
+ }
788
+
789
+ // Clone the table with the current data in it
790
+ var tableWidth = dt.table().node().offsetWidth;
791
+ var columnWidths = dt.columns;
792
+ var clonedTable = dt.table().node().cloneNode( false );
793
+ var clonedHeader = $( dt.table().header().cloneNode( false ) ).appendTo( clonedTable );
794
+ var clonedBody = $( dt.table().body() ).clone( false, false ).empty().appendTo( clonedTable ); // use jQuery because of IE8
795
+
796
+ // Header
797
+ var headerCells = dt.columns()
798
+ .header()
799
+ .filter( function (idx) {
800
+ return dt.column(idx).visible();
801
+ } )
802
+ .to$()
803
+ .clone( false )
804
+ .css( 'display', 'table-cell' );
805
+
806
+ // Body rows - we don't need to take account of DataTables' column
807
+ // visibility since we implement our own here (hence the `display` set)
808
+ $(clonedBody)
809
+ .append( $(dt.rows( { page: 'current' } ).nodes()).clone( false ) )
810
+ .find( 'th, td' ).css( 'display', '' );
811
+
812
+ // Footer
813
+ var footer = dt.table().footer();
814
+ if ( footer ) {
815
+ var clonedFooter = $( footer.cloneNode( false ) ).appendTo( clonedTable );
816
+ var footerCells = dt.columns()
817
+ .footer()
818
+ .filter( function (idx) {
819
+ return dt.column(idx).visible();
820
+ } )
821
+ .to$()
822
+ .clone( false )
823
+ .css( 'display', 'table-cell' );
824
+
825
+ $('<tr/>')
826
+ .append( footerCells )
827
+ .appendTo( clonedFooter );
828
+ }
829
+
830
+ $('<tr/>')
831
+ .append( headerCells )
832
+ .appendTo( clonedHeader );
833
+
834
+ // In the inline case extra padding is applied to the first column to
835
+ // give space for the show / hide icon. We need to use this in the
836
+ // calculation
837
+ if ( this.c.details.type === 'inline' ) {
838
+ $(clonedTable).addClass( 'dtr-inline collapsed' );
839
+ }
840
+
841
+ // It is unsafe to insert elements with the same name into the DOM
842
+ // multiple times. For example, cloning and inserting a checked radio
843
+ // clears the chcecked state of the original radio.
844
+ $( clonedTable ).find( '[name]' ).removeAttr( 'name' );
845
+
846
+ var inserted = $('<div/>')
847
+ .css( {
848
+ width: 1,
849
+ height: 1,
850
+ overflow: 'hidden'
851
+ } )
852
+ .append( clonedTable );
853
+
854
+ inserted.insertBefore( dt.table().node() );
855
+
856
+ // The cloned header now contains the smallest that each column can be
857
+ headerCells.each( function (i) {
858
+ var idx = dt.column.index( 'fromVisible', i );
859
+ columns[ idx ].minWidth = this.offsetWidth || 0;
860
+ } );
861
+
862
+ inserted.remove();
863
+ },
864
+
865
+ /**
866
+ * Set a column's visibility.
867
+ *
868
+ * We don't use DataTables' column visibility controls in order to ensure
869
+ * that column visibility can Responsive can no-exist. Since only IE8+ is
870
+ * supported (and all evergreen browsers of course) the control of the
871
+ * display attribute works well.
872
+ *
873
+ * @param {integer} col Column index
874
+ * @param {boolean} showHide Show or hide (true or false)
875
+ * @private
876
+ */
877
+ _setColumnVis: function ( col, showHide )
878
+ {
879
+ var dt = this.s.dt;
880
+ var display = showHide ? '' : 'none'; // empty string will remove the attr
881
+
882
+ $( dt.column( col ).header() ).css( 'display', display );
883
+ $( dt.column( col ).footer() ).css( 'display', display );
884
+ dt.column( col ).nodes().to$().css( 'display', display );
885
+ },
886
+
887
+
888
+ /**
889
+ * Update the cell tab indexes for keyboard accessibility. This is called on
890
+ * every table draw - that is potentially inefficient, but also the least
891
+ * complex option given that column visibility can change on the fly. Its a
892
+ * shame user-focus was removed from CSS 3 UI, as it would have solved this
893
+ * issue with a single CSS statement.
894
+ *
895
+ * @private
896
+ */
897
+ _tabIndexes: function ()
898
+ {
899
+ var dt = this.s.dt;
900
+ var cells = dt.cells( { page: 'current' } ).nodes().to$();
901
+ var ctx = dt.settings()[0];
902
+ var target = this.c.details.target;
903
+
904
+ cells.filter( '[data-dtr-keyboard]' ).removeData( '[data-dtr-keyboard]' );
905
+
906
+ var selector = typeof target === 'number' ?
907
+ ':eq('+target+')' :
908
+ target;
909
+
910
+ $( selector, dt.rows( { page: 'current' } ).nodes() )
911
+ .attr( 'tabIndex', ctx.iTabIndex )
912
+ .data( 'dtr-keyboard', 1 );
913
+ }
914
+ } );
915
+
916
+
917
+ /**
918
+ * List of default breakpoints. Each item in the array is an object with two
919
+ * properties:
920
+ *
921
+ * * `name` - the breakpoint name.
922
+ * * `width` - the breakpoint width
923
+ *
924
+ * @name Responsive.breakpoints
925
+ * @static
926
+ */
927
+ Responsive.breakpoints = [
928
+ { name: 'desktop', width: Infinity },
929
+ { name: 'tablet-l', width: 1024 },
930
+ { name: 'tablet-p', width: 768 },
931
+ { name: 'mobile-l', width: 480 },
932
+ { name: 'mobile-p', width: 320 }
933
+ ];
934
+
935
+
936
+ /**
937
+ * Display methods - functions which define how the hidden data should be shown
938
+ * in the table.
939
+ *
940
+ * @namespace
941
+ * @name Responsive.defaults
942
+ * @static
943
+ */
944
+ Responsive.display = {
945
+ childRow: function ( row, update, render ) {
946
+ if ( update ) {
947
+ if ( $(row.node()).hasClass('parent') ) {
948
+ row.child( render(), 'child' ).show();
949
+
950
+ return true;
951
+ }
952
+ }
953
+ else {
954
+ if ( ! row.child.isShown() ) {
955
+ row.child( render(), 'child' ).show();
956
+ $( row.node() ).addClass( 'parent' );
957
+
958
+ return true;
959
+ }
960
+ else {
961
+ row.child( false );
962
+ $( row.node() ).removeClass( 'parent' );
963
+
964
+ return false;
965
+ }
966
+ }
967
+ },
968
+
969
+ childRowImmediate: function ( row, update, render ) {
970
+ if ( (! update && row.child.isShown()) || ! row.responsive.hasHidden() ) {
971
+ // User interaction and the row is show, or nothing to show
972
+ row.child( false );
973
+ $( row.node() ).removeClass( 'parent' );
974
+
975
+ return false;
976
+ }
977
+ else {
978
+ // Display
979
+ row.child( render(), 'child' ).show();
980
+ $( row.node() ).addClass( 'parent' );
981
+
982
+ return true;
983
+ }
984
+ },
985
+
986
+ // This is a wrapper so the modal options for Bootstrap and jQuery UI can
987
+ // have options passed into them. This specific one doesn't need to be a
988
+ // function but it is for consistency in the `modal` name
989
+ modal: function ( options ) {
990
+ return function ( row, update, render ) {
991
+ if ( ! update ) {
992
+ // Show a modal
993
+ var close = function () {
994
+ modal.remove(); // will tidy events for us
995
+ $(document).off( 'keypress.dtr' );
996
+ };
997
+
998
+ var modal = $('<div class="dtr-modal"/>')
999
+ .append( $('<div class="dtr-modal-display"/>')
1000
+ .append( $('<div class="dtr-modal-content"/>')
1001
+ .append( render() )
1002
+ )
1003
+ .append( $('<div class="dtr-modal-close">&times;</div>' )
1004
+ .click( function () {
1005
+ close();
1006
+ } )
1007
+ )
1008
+ )
1009
+ .append( $('<div class="dtr-modal-background"/>')
1010
+ .click( function () {
1011
+ close();
1012
+ } )
1013
+ )
1014
+ .appendTo( 'body' );
1015
+
1016
+ $(document).on( 'keyup.dtr', function (e) {
1017
+ if ( e.keyCode === 27 ) {
1018
+ e.stopPropagation();
1019
+
1020
+ close();
1021
+ }
1022
+ } );
1023
+ }
1024
+ else {
1025
+ $('div.dtr-modal-content')
1026
+ .empty()
1027
+ .append( render() );
1028
+ }
1029
+
1030
+ if ( options && options.header ) {
1031
+ $('div.dtr-modal-content').prepend(
1032
+ '<h2>'+options.header( row )+'</h2>'
1033
+ );
1034
+ }
1035
+ };
1036
+ }
1037
+ };
1038
+
1039
+
1040
+ /**
1041
+ * Display methods - functions which define how the hidden data should be shown
1042
+ * in the table.
1043
+ *
1044
+ * @namespace
1045
+ * @name Responsive.defaults
1046
+ * @static
1047
+ */
1048
+ Responsive.renderer = {
1049
+ listHidden: function () {
1050
+ return function ( api, rowIdx, columns ) {
1051
+ var data = $.map( columns, function ( col ) {
1052
+ return col.hidden ?
1053
+ '<li data-dtr-index="'+col.columnIndex+'" data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+
1054
+ '<span class="dtr-title">'+
1055
+ col.title+
1056
+ '</span> '+
1057
+ '<span class="dtr-data">'+
1058
+ col.data+
1059
+ '</span>'+
1060
+ '</li>' :
1061
+ '';
1062
+ } ).join('');
1063
+
1064
+ return data ?
1065
+ $('<ul data-dtr-index="'+rowIdx+'"/>').append( data ) :
1066
+ false;
1067
+ }
1068
+ },
1069
+
1070
+ tableAll: function ( options ) {
1071
+ options = $.extend( {
1072
+ tableClass: ''
1073
+ }, options );
1074
+
1075
+ return function ( api, rowIdx, columns ) {
1076
+ var data = $.map( columns, function ( col ) {
1077
+ return '<tr data-dt-row="'+col.rowIndex+'" data-dt-column="'+col.columnIndex+'">'+
1078
+ '<td>'+col.title+':'+'</td> '+
1079
+ '<td>'+col.data+'</td>'+
1080
+ '</tr>';
1081
+ } ).join('');
1082
+
1083
+ return $('<table class="'+options.tableClass+'" width="100%"/>').append( data );
1084
+ }
1085
+ }
1086
+ };
1087
+
1088
+ /**
1089
+ * Responsive default settings for initialisation
1090
+ *
1091
+ * @namespace
1092
+ * @name Responsive.defaults
1093
+ * @static
1094
+ */
1095
+ Responsive.defaults = {
1096
+ /**
1097
+ * List of breakpoints for the instance. Note that this means that each
1098
+ * instance can have its own breakpoints. Additionally, the breakpoints
1099
+ * cannot be changed once an instance has been creased.
1100
+ *
1101
+ * @type {Array}
1102
+ * @default Takes the value of `Responsive.breakpoints`
1103
+ */
1104
+ breakpoints: Responsive.breakpoints,
1105
+
1106
+ /**
1107
+ * Enable / disable auto hiding calculations. It can help to increase
1108
+ * performance slightly if you disable this option, but all columns would
1109
+ * need to have breakpoint classes assigned to them
1110
+ *
1111
+ * @type {Boolean}
1112
+ * @default `true`
1113
+ */
1114
+ auto: true,
1115
+
1116
+ /**
1117
+ * Details control. If given as a string value, the `type` property of the
1118
+ * default object is set to that value, and the defaults used for the rest
1119
+ * of the object - this is for ease of implementation.
1120
+ *
1121
+ * The object consists of the following properties:
1122
+ *
1123
+ * * `display` - A function that is used to show and hide the hidden details
1124
+ * * `renderer` - function that is called for display of the child row data.
1125
+ * The default function will show the data from the hidden columns
1126
+ * * `target` - Used as the selector for what objects to attach the child
1127
+ * open / close to
1128
+ * * `type` - `false` to disable the details display, `inline` or `column`
1129
+ * for the two control types
1130
+ *
1131
+ * @type {Object|string}
1132
+ */
1133
+ details: {
1134
+ display: Responsive.display.childRow,
1135
+
1136
+ renderer: Responsive.renderer.listHidden(),
1137
+
1138
+ target: 0,
1139
+
1140
+ type: 'inline'
1141
+ },
1142
+
1143
+ /**
1144
+ * Orthogonal data request option. This is used to define the data type
1145
+ * requested when Responsive gets the data to show in the child row.
1146
+ *
1147
+ * @type {String}
1148
+ */
1149
+ orthogonal: 'display'
1150
+ };
1151
+
1152
+
1153
+ /*
1154
+ * API
1155
+ */
1156
+ var Api = $.fn.dataTable.Api;
1157
+
1158
+ // Doesn't do anything - work around for a bug in DT... Not documented
1159
+ Api.register( 'responsive()', function () {
1160
+ return this;
1161
+ } );
1162
+
1163
+ Api.register( 'responsive.index()', function ( li ) {
1164
+ li = $(li);
1165
+
1166
+ return {
1167
+ column: li.data('dtr-index'),
1168
+ row: li.parent().data('dtr-index')
1169
+ };
1170
+ } );
1171
+
1172
+ Api.register( 'responsive.rebuild()', function () {
1173
+ return this.iterator( 'table', function ( ctx ) {
1174
+ if ( ctx._responsive ) {
1175
+ ctx._responsive._classLogic();
1176
+ }
1177
+ } );
1178
+ } );
1179
+
1180
+ Api.register( 'responsive.recalc()', function () {
1181
+ return this.iterator( 'table', function ( ctx ) {
1182
+ if ( ctx._responsive ) {
1183
+ ctx._responsive._resizeAuto();
1184
+ ctx._responsive._resize();
1185
+ }
1186
+ } );
1187
+ } );
1188
+
1189
+ Api.register( 'responsive.hasHidden()', function () {
1190
+ var ctx = this.context[0];
1191
+
1192
+ return ctx._responsive ?
1193
+ $.inArray( false, ctx._responsive.s.current ) !== -1 :
1194
+ false;
1195
+ } );
1196
+
1197
+
1198
+ /**
1199
+ * Version information
1200
+ *
1201
+ * @name Responsive.version
1202
+ * @static
1203
+ */
1204
+ Responsive.version = '2.1.0';
1205
+
1206
+
1207
+ $.fn.dataTable.Responsive = Responsive;
1208
+ $.fn.DataTable.Responsive = Responsive;
1209
+
1210
+ // Attach a listener to the document which listens for DataTables initialisation
1211
+ // events so we can automatically initialise
1212
+ $(document).on( 'preInit.dt.dtr', function (e, settings, json) {
1213
+ if ( e.namespace !== 'dt' ) {
1214
+ return;
1215
+ }
1216
+
1217
+ if ( $(settings.nTable).hasClass( 'responsive' ) ||
1218
+ $(settings.nTable).hasClass( 'dt-responsive' ) ||
1219
+ settings.oInit.responsive ||
1220
+ DataTable.defaults.responsive
1221
+ ) {
1222
+ var init = settings.oInit.responsive;
1223
+
1224
+ if ( init !== false ) {
1225
+ new Responsive( settings, $.isPlainObject( init ) ? init : {} );
1226
+ }
1227
+ }
1228
+ } );
1229
+
1230
+
1231
+ return Responsive;
1232
+ }));
admin/js/jquery.dataTables.min.js ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ DataTables 1.10.13
3
+ ©2008-2016 SpryMedia Ltd - datatables.net/license
4
+ */
5
+ (function(h){"function"===typeof define&&define.amd?define(["jquery"],function(E){return h(E,window,document)}):"object"===typeof exports?module.exports=function(E,H){E||(E=window);H||(H="undefined"!==typeof window?require("jquery"):require("jquery")(E));return h(H,E,E.document)}:h(jQuery,window,document)})(function(h,E,H,k){function Y(a){var b,c,d={};h.each(a,function(e){if((b=e.match(/^([^A-Z]+?)([A-Z])/))&&-1!=="a aa ai ao as b fn i m o s ".indexOf(b[1]+" "))c=e.replace(b[0],b[2].toLowerCase()),
6
+ d[c]=e,"o"===b[1]&&Y(a[e])});a._hungarianMap=d}function J(a,b,c){a._hungarianMap||Y(a);var d;h.each(b,function(e){d=a._hungarianMap[e];if(d!==k&&(c||b[d]===k))"o"===d.charAt(0)?(b[d]||(b[d]={}),h.extend(!0,b[d],b[e]),J(a[d],b[d],c)):b[d]=b[e]})}function Fa(a){var b=m.defaults.oLanguage,c=a.sZeroRecords;!a.sEmptyTable&&(c&&"No data available in table"===b.sEmptyTable)&&F(a,a,"sZeroRecords","sEmptyTable");!a.sLoadingRecords&&(c&&"Loading..."===b.sLoadingRecords)&&F(a,a,"sZeroRecords","sLoadingRecords");
7
+ a.sInfoThousands&&(a.sThousands=a.sInfoThousands);(a=a.sDecimal)&&fb(a)}function gb(a){A(a,"ordering","bSort");A(a,"orderMulti","bSortMulti");A(a,"orderClasses","bSortClasses");A(a,"orderCellsTop","bSortCellsTop");A(a,"order","aaSorting");A(a,"orderFixed","aaSortingFixed");A(a,"paging","bPaginate");A(a,"pagingType","sPaginationType");A(a,"pageLength","iDisplayLength");A(a,"searching","bFilter");"boolean"===typeof a.sScrollX&&(a.sScrollX=a.sScrollX?"100%":"");"boolean"===typeof a.scrollX&&(a.scrollX=
8
+ a.scrollX?"100%":"");if(a=a.aoSearchCols)for(var b=0,c=a.length;b<c;b++)a[b]&&J(m.models.oSearch,a[b])}function hb(a){A(a,"orderable","bSortable");A(a,"orderData","aDataSort");A(a,"orderSequence","asSorting");A(a,"orderDataType","sortDataType");var b=a.aDataSort;b&&!h.isArray(b)&&(a.aDataSort=[b])}function ib(a){if(!m.__browser){var b={};m.__browser=b;var c=h("<div/>").css({position:"fixed",top:0,left:-1*h(E).scrollLeft(),height:1,width:1,overflow:"hidden"}).append(h("<div/>").css({position:"absolute",
9
+ top:1,left:1,width:100,overflow:"scroll"}).append(h("<div/>").css({width:"100%",height:10}))).appendTo("body"),d=c.children(),e=d.children();b.barWidth=d[0].offsetWidth-d[0].clientWidth;b.bScrollOversize=100===e[0].offsetWidth&&100!==d[0].clientWidth;b.bScrollbarLeft=1!==Math.round(e.offset().left);b.bBounding=c[0].getBoundingClientRect().width?!0:!1;c.remove()}h.extend(a.oBrowser,m.__browser);a.oScroll.iBarWidth=m.__browser.barWidth}function jb(a,b,c,d,e,f){var g,j=!1;c!==k&&(g=c,j=!0);for(;d!==
10
+ e;)a.hasOwnProperty(d)&&(g=j?b(g,a[d],d,a):a[d],j=!0,d+=f);return g}function Ga(a,b){var c=m.defaults.column,d=a.aoColumns.length,c=h.extend({},m.models.oColumn,c,{nTh:b?b:H.createElement("th"),sTitle:c.sTitle?c.sTitle:b?b.innerHTML:"",aDataSort:c.aDataSort?c.aDataSort:[d],mData:c.mData?c.mData:d,idx:d});a.aoColumns.push(c);c=a.aoPreSearchCols;c[d]=h.extend({},m.models.oSearch,c[d]);la(a,d,h(b).data())}function la(a,b,c){var b=a.aoColumns[b],d=a.oClasses,e=h(b.nTh);if(!b.sWidthOrig){b.sWidthOrig=
11
+ e.attr("width")||null;var f=(e.attr("style")||"").match(/width:\s*(\d+[pxem%]+)/);f&&(b.sWidthOrig=f[1])}c!==k&&null!==c&&(hb(c),J(m.defaults.column,c),c.mDataProp!==k&&!c.mData&&(c.mData=c.mDataProp),c.sType&&(b._sManualType=c.sType),c.className&&!c.sClass&&(c.sClass=c.className),h.extend(b,c),F(b,c,"sWidth","sWidthOrig"),c.iDataSort!==k&&(b.aDataSort=[c.iDataSort]),F(b,c,"aDataSort"));var g=b.mData,j=R(g),i=b.mRender?R(b.mRender):null,c=function(a){return"string"===typeof a&&-1!==a.indexOf("@")};
12
+ b._bAttrSrc=h.isPlainObject(g)&&(c(g.sort)||c(g.type)||c(g.filter));b._setter=null;b.fnGetData=function(a,b,c){var d=j(a,b,k,c);return i&&b?i(d,b,a,c):d};b.fnSetData=function(a,b,c){return S(g)(a,b,c)};"number"!==typeof g&&(a._rowReadObject=!0);a.oFeatures.bSort||(b.bSortable=!1,e.addClass(d.sSortableNone));a=-1!==h.inArray("asc",b.asSorting);c=-1!==h.inArray("desc",b.asSorting);!b.bSortable||!a&&!c?(b.sSortingClass=d.sSortableNone,b.sSortingClassJUI=""):a&&!c?(b.sSortingClass=d.sSortableAsc,b.sSortingClassJUI=
13
+ d.sSortJUIAscAllowed):!a&&c?(b.sSortingClass=d.sSortableDesc,b.sSortingClassJUI=d.sSortJUIDescAllowed):(b.sSortingClass=d.sSortable,b.sSortingClassJUI=d.sSortJUI)}function Z(a){if(!1!==a.oFeatures.bAutoWidth){var b=a.aoColumns;Ha(a);for(var c=0,d=b.length;c<d;c++)b[c].nTh.style.width=b[c].sWidth}b=a.oScroll;(""!==b.sY||""!==b.sX)&&ma(a);s(a,null,"column-sizing",[a])}function $(a,b){var c=na(a,"bVisible");return"number"===typeof c[b]?c[b]:null}function aa(a,b){var c=na(a,"bVisible"),c=h.inArray(b,
14
+ c);return-1!==c?c:null}function ba(a){var b=0;h.each(a.aoColumns,function(a,d){d.bVisible&&"none"!==h(d.nTh).css("display")&&b++});return b}function na(a,b){var c=[];h.map(a.aoColumns,function(a,e){a[b]&&c.push(e)});return c}function Ia(a){var b=a.aoColumns,c=a.aoData,d=m.ext.type.detect,e,f,g,j,i,h,l,q,r;e=0;for(f=b.length;e<f;e++)if(l=b[e],r=[],!l.sType&&l._sManualType)l.sType=l._sManualType;else if(!l.sType){g=0;for(j=d.length;g<j;g++){i=0;for(h=c.length;i<h;i++){r[i]===k&&(r[i]=B(a,i,e,"type"));
15
+ q=d[g](r[i],a);if(!q&&g!==d.length-1)break;if("html"===q)break}if(q){l.sType=q;break}}l.sType||(l.sType="string")}}function kb(a,b,c,d){var e,f,g,j,i,n,l=a.aoColumns;if(b)for(e=b.length-1;0<=e;e--){n=b[e];var q=n.targets!==k?n.targets:n.aTargets;h.isArray(q)||(q=[q]);f=0;for(g=q.length;f<g;f++)if("number"===typeof q[f]&&0<=q[f]){for(;l.length<=q[f];)Ga(a);d(q[f],n)}else if("number"===typeof q[f]&&0>q[f])d(l.length+q[f],n);else if("string"===typeof q[f]){j=0;for(i=l.length;j<i;j++)("_all"==q[f]||h(l[j].nTh).hasClass(q[f]))&&
16
+ d(j,n)}}if(c){e=0;for(a=c.length;e<a;e++)d(e,c[e])}}function N(a,b,c,d){var e=a.aoData.length,f=h.extend(!0,{},m.models.oRow,{src:c?"dom":"data",idx:e});f._aData=b;a.aoData.push(f);for(var g=a.aoColumns,j=0,i=g.length;j<i;j++)g[j].sType=null;a.aiDisplayMaster.push(e);b=a.rowIdFn(b);b!==k&&(a.aIds[b]=f);(c||!a.oFeatures.bDeferRender)&&Ja(a,e,c,d);return e}function oa(a,b){var c;b instanceof h||(b=h(b));return b.map(function(b,e){c=Ka(a,e);return N(a,c.data,e,c.cells)})}function B(a,b,c,d){var e=a.iDraw,
17
+ f=a.aoColumns[c],g=a.aoData[b]._aData,j=f.sDefaultContent,i=f.fnGetData(g,d,{settings:a,row:b,col:c});if(i===k)return a.iDrawError!=e&&null===j&&(K(a,0,"Requested unknown parameter "+("function"==typeof f.mData?"{function}":"'"+f.mData+"'")+" for row "+b+", column "+c,4),a.iDrawError=e),j;if((i===g||null===i)&&null!==j&&d!==k)i=j;else if("function"===typeof i)return i.call(g);return null===i&&"display"==d?"":i}function lb(a,b,c,d){a.aoColumns[c].fnSetData(a.aoData[b]._aData,d,{settings:a,row:b,col:c})}
18
+ function La(a){return h.map(a.match(/(\\.|[^\.])+/g)||[""],function(a){return a.replace(/\\\./g,".")})}function R(a){if(h.isPlainObject(a)){var b={};h.each(a,function(a,c){c&&(b[a]=R(c))});return function(a,c,f,g){var j=b[c]||b._;return j!==k?j(a,c,f,g):a}}if(null===a)return function(a){return a};if("function"===typeof a)return function(b,c,f,g){return a(b,c,f,g)};if("string"===typeof a&&(-1!==a.indexOf(".")||-1!==a.indexOf("[")||-1!==a.indexOf("("))){var c=function(a,b,f){var g,j;if(""!==f){j=La(f);
19
+ for(var i=0,n=j.length;i<n;i++){f=j[i].match(ca);g=j[i].match(V);if(f){j[i]=j[i].replace(ca,"");""!==j[i]&&(a=a[j[i]]);g=[];j.splice(0,i+1);j=j.join(".");if(h.isArray(a)){i=0;for(n=a.length;i<n;i++)g.push(c(a[i],b,j))}a=f[0].substring(1,f[0].length-1);a=""===a?g:g.join(a);break}else if(g){j[i]=j[i].replace(V,"");a=a[j[i]]();continue}if(null===a||a[j[i]]===k)return k;a=a[j[i]]}}return a};return function(b,e){return c(b,e,a)}}return function(b){return b[a]}}function S(a){if(h.isPlainObject(a))return S(a._);
20
+ if(null===a)return function(){};if("function"===typeof a)return function(b,d,e){a(b,"set",d,e)};if("string"===typeof a&&(-1!==a.indexOf(".")||-1!==a.indexOf("[")||-1!==a.indexOf("("))){var b=function(a,d,e){var e=La(e),f;f=e[e.length-1];for(var g,j,i=0,n=e.length-1;i<n;i++){g=e[i].match(ca);j=e[i].match(V);if(g){e[i]=e[i].replace(ca,"");a[e[i]]=[];f=e.slice();f.splice(0,i+1);g=f.join(".");if(h.isArray(d)){j=0;for(n=d.length;j<n;j++)f={},b(f,d[j],g),a[e[i]].push(f)}else a[e[i]]=d;return}j&&(e[i]=e[i].replace(V,
21
+ ""),a=a[e[i]](d));if(null===a[e[i]]||a[e[i]]===k)a[e[i]]={};a=a[e[i]]}if(f.match(V))a[f.replace(V,"")](d);else a[f.replace(ca,"")]=d};return function(c,d){return b(c,d,a)}}return function(b,d){b[a]=d}}function Ma(a){return D(a.aoData,"_aData")}function pa(a){a.aoData.length=0;a.aiDisplayMaster.length=0;a.aiDisplay.length=0;a.aIds={}}function qa(a,b,c){for(var d=-1,e=0,f=a.length;e<f;e++)a[e]==b?d=e:a[e]>b&&a[e]--; -1!=d&&c===k&&a.splice(d,1)}function da(a,b,c,d){var e=a.aoData[b],f,g=function(c,d){for(;c.childNodes.length;)c.removeChild(c.firstChild);
22
+ c.innerHTML=B(a,b,d,"display")};if("dom"===c||(!c||"auto"===c)&&"dom"===e.src)e._aData=Ka(a,e,d,d===k?k:e._aData).data;else{var j=e.anCells;if(j)if(d!==k)g(j[d],d);else{c=0;for(f=j.length;c<f;c++)g(j[c],c)}}e._aSortData=null;e._aFilterData=null;g=a.aoColumns;if(d!==k)g[d].sType=null;else{c=0;for(f=g.length;c<f;c++)g[c].sType=null;Na(a,e)}}function Ka(a,b,c,d){var e=[],f=b.firstChild,g,j,i=0,n,l=a.aoColumns,q=a._rowReadObject,d=d!==k?d:q?{}:[],r=function(a,b){if("string"===typeof a){var c=a.indexOf("@");
23
+ -1!==c&&(c=a.substring(c+1),S(a)(d,b.getAttribute(c)))}},m=function(a){if(c===k||c===i)j=l[i],n=h.trim(a.innerHTML),j&&j._bAttrSrc?(S(j.mData._)(d,n),r(j.mData.sort,a),r(j.mData.type,a),r(j.mData.filter,a)):q?(j._setter||(j._setter=S(j.mData)),j._setter(d,n)):d[i]=n;i++};if(f)for(;f;){g=f.nodeName.toUpperCase();if("TD"==g||"TH"==g)m(f),e.push(f);f=f.nextSibling}else{e=b.anCells;f=0;for(g=e.length;f<g;f++)m(e[f])}if(b=b.firstChild?b:b.nTr)(b=b.getAttribute("id"))&&S(a.rowId)(d,b);return{data:d,cells:e}}
24
+ function Ja(a,b,c,d){var e=a.aoData[b],f=e._aData,g=[],j,i,n,l,q;if(null===e.nTr){j=c||H.createElement("tr");e.nTr=j;e.anCells=g;j._DT_RowIndex=b;Na(a,e);l=0;for(q=a.aoColumns.length;l<q;l++){n=a.aoColumns[l];i=c?d[l]:H.createElement(n.sCellType);i._DT_CellIndex={row:b,column:l};g.push(i);if((!c||n.mRender||n.mData!==l)&&(!h.isPlainObject(n.mData)||n.mData._!==l+".display"))i.innerHTML=B(a,b,l,"display");n.sClass&&(i.className+=" "+n.sClass);n.bVisible&&!c?j.appendChild(i):!n.bVisible&&c&&i.parentNode.removeChild(i);
25
+ n.fnCreatedCell&&n.fnCreatedCell.call(a.oInstance,i,B(a,b,l),f,b,l)}s(a,"aoRowCreatedCallback",null,[j,f,b])}e.nTr.setAttribute("role","row")}function Na(a,b){var c=b.nTr,d=b._aData;if(c){var e=a.rowIdFn(d);e&&(c.id=e);d.DT_RowClass&&(e=d.DT_RowClass.split(" "),b.__rowc=b.__rowc?sa(b.__rowc.concat(e)):e,h(c).removeClass(b.__rowc.join(" ")).addClass(d.DT_RowClass));d.DT_RowAttr&&h(c).attr(d.DT_RowAttr);d.DT_RowData&&h(c).data(d.DT_RowData)}}function mb(a){var b,c,d,e,f,g=a.nTHead,j=a.nTFoot,i=0===
26
+ h("th, td",g).length,n=a.oClasses,l=a.aoColumns;i&&(e=h("<tr/>").appendTo(g));b=0;for(c=l.length;b<c;b++)f=l[b],d=h(f.nTh).addClass(f.sClass),i&&d.appendTo(e),a.oFeatures.bSort&&(d.addClass(f.sSortingClass),!1!==f.bSortable&&(d.attr("tabindex",a.iTabIndex).attr("aria-controls",a.sTableId),Oa(a,f.nTh,b))),f.sTitle!=d[0].innerHTML&&d.html(f.sTitle),Pa(a,"header")(a,d,f,n);i&&ea(a.aoHeader,g);h(g).find(">tr").attr("role","row");h(g).find(">tr>th, >tr>td").addClass(n.sHeaderTH);h(j).find(">tr>th, >tr>td").addClass(n.sFooterTH);
27
+ if(null!==j){a=a.aoFooter[0];b=0;for(c=a.length;b<c;b++)f=l[b],f.nTf=a[b].cell,f.sClass&&h(f.nTf).addClass(f.sClass)}}function fa(a,b,c){var d,e,f,g=[],j=[],i=a.aoColumns.length,n;if(b){c===k&&(c=!1);d=0;for(e=b.length;d<e;d++){g[d]=b[d].slice();g[d].nTr=b[d].nTr;for(f=i-1;0<=f;f--)!a.aoColumns[f].bVisible&&!c&&g[d].splice(f,1);j.push([])}d=0;for(e=g.length;d<e;d++){if(a=g[d].nTr)for(;f=a.firstChild;)a.removeChild(f);f=0;for(b=g[d].length;f<b;f++)if(n=i=1,j[d][f]===k){a.appendChild(g[d][f].cell);
28
+ for(j[d][f]=1;g[d+i]!==k&&g[d][f].cell==g[d+i][f].cell;)j[d+i][f]=1,i++;for(;g[d][f+n]!==k&&g[d][f].cell==g[d][f+n].cell;){for(c=0;c<i;c++)j[d+c][f+n]=1;n++}h(g[d][f].cell).attr("rowspan",i).attr("colspan",n)}}}}function O(a){var b=s(a,"aoPreDrawCallback","preDraw",[a]);if(-1!==h.inArray(!1,b))C(a,!1);else{var b=[],c=0,d=a.asStripeClasses,e=d.length,f=a.oLanguage,g=a.iInitDisplayStart,j="ssp"==y(a),i=a.aiDisplay;a.bDrawing=!0;g!==k&&-1!==g&&(a._iDisplayStart=j?g:g>=a.fnRecordsDisplay()?0:g,a.iInitDisplayStart=
29
+ -1);var g=a._iDisplayStart,n=a.fnDisplayEnd();if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++,C(a,!1);else if(j){if(!a.bDestroying&&!nb(a))return}else a.iDraw++;if(0!==i.length){f=j?a.aoData.length:n;for(j=j?0:g;j<f;j++){var l=i[j],q=a.aoData[l];null===q.nTr&&Ja(a,l);l=q.nTr;if(0!==e){var r=d[c%e];q._sRowStripe!=r&&(h(l).removeClass(q._sRowStripe).addClass(r),q._sRowStripe=r)}s(a,"aoRowCallback",null,[l,q._aData,c,j]);b.push(l);c++}}else c=f.sZeroRecords,1==a.iDraw&&"ajax"==y(a)?c=f.sLoadingRecords:
30
+ f.sEmptyTable&&0===a.fnRecordsTotal()&&(c=f.sEmptyTable),b[0]=h("<tr/>",{"class":e?d[0]:""}).append(h("<td />",{valign:"top",colSpan:ba(a),"class":a.oClasses.sRowEmpty}).html(c))[0];s(a,"aoHeaderCallback","header",[h(a.nTHead).children("tr")[0],Ma(a),g,n,i]);s(a,"aoFooterCallback","footer",[h(a.nTFoot).children("tr")[0],Ma(a),g,n,i]);d=h(a.nTBody);d.children().detach();d.append(h(b));s(a,"aoDrawCallback","draw",[a]);a.bSorted=!1;a.bFiltered=!1;a.bDrawing=!1}}function T(a,b){var c=a.oFeatures,d=c.bFilter;
31
+ c.bSort&&ob(a);d?ga(a,a.oPreviousSearch):a.aiDisplay=a.aiDisplayMaster.slice();!0!==b&&(a._iDisplayStart=0);a._drawHold=b;O(a);a._drawHold=!1}function pb(a){var b=a.oClasses,c=h(a.nTable),c=h("<div/>").insertBefore(c),d=a.oFeatures,e=h("<div/>",{id:a.sTableId+"_wrapper","class":b.sWrapper+(a.nTFoot?"":" "+b.sNoFooter)});a.nHolding=c[0];a.nTableWrapper=e[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var f=a.sDom.split(""),g,j,i,n,l,q,k=0;k<f.length;k++){g=null;j=f[k];if("<"==j){i=h("<div/>")[0];
32
+ n=f[k+1];if("'"==n||'"'==n){l="";for(q=2;f[k+q]!=n;)l+=f[k+q],q++;"H"==l?l=b.sJUIHeader:"F"==l&&(l=b.sJUIFooter);-1!=l.indexOf(".")?(n=l.split("."),i.id=n[0].substr(1,n[0].length-1),i.className=n[1]):"#"==l.charAt(0)?i.id=l.substr(1,l.length-1):i.className=l;k+=q}e.append(i);e=h(i)}else if(">"==j)e=e.parent();else if("l"==j&&d.bPaginate&&d.bLengthChange)g=qb(a);else if("f"==j&&d.bFilter)g=rb(a);else if("r"==j&&d.bProcessing)g=sb(a);else if("t"==j)g=tb(a);else if("i"==j&&d.bInfo)g=ub(a);else if("p"==
33
+ j&&d.bPaginate)g=vb(a);else if(0!==m.ext.feature.length){i=m.ext.feature;q=0;for(n=i.length;q<n;q++)if(j==i[q].cFeature){g=i[q].fnInit(a);break}}g&&(i=a.aanFeatures,i[j]||(i[j]=[]),i[j].push(g),e.append(g))}c.replaceWith(e);a.nHolding=null}function ea(a,b){var c=h(b).children("tr"),d,e,f,g,j,i,n,l,q,k;a.splice(0,a.length);f=0;for(i=c.length;f<i;f++)a.push([]);f=0;for(i=c.length;f<i;f++){d=c[f];for(e=d.firstChild;e;){if("TD"==e.nodeName.toUpperCase()||"TH"==e.nodeName.toUpperCase()){l=1*e.getAttribute("colspan");
34
+ q=1*e.getAttribute("rowspan");l=!l||0===l||1===l?1:l;q=!q||0===q||1===q?1:q;g=0;for(j=a[f];j[g];)g++;n=g;k=1===l?!0:!1;for(j=0;j<l;j++)for(g=0;g<q;g++)a[f+g][n+j]={cell:e,unique:k},a[f+g].nTr=d}e=e.nextSibling}}}function ta(a,b,c){var d=[];c||(c=a.aoHeader,b&&(c=[],ea(c,b)));for(var b=0,e=c.length;b<e;b++)for(var f=0,g=c[b].length;f<g;f++)if(c[b][f].unique&&(!d[f]||!a.bSortCellsTop))d[f]=c[b][f].cell;return d}function ua(a,b,c){s(a,"aoServerParams","serverParams",[b]);if(b&&h.isArray(b)){var d={},
35
+ e=/(.*?)\[\]$/;h.each(b,function(a,b){var c=b.name.match(e);c?(c=c[0],d[c]||(d[c]=[]),d[c].push(b.value)):d[b.name]=b.value});b=d}var f,g=a.ajax,j=a.oInstance,i=function(b){s(a,null,"xhr",[a,b,a.jqXHR]);c(b)};if(h.isPlainObject(g)&&g.data){f=g.data;var n=h.isFunction(f)?f(b,a):f,b=h.isFunction(f)&&n?n:h.extend(!0,b,n);delete g.data}n={data:b,success:function(b){var c=b.error||b.sError;c&&K(a,0,c);a.json=b;i(b)},dataType:"json",cache:!1,type:a.sServerMethod,error:function(b,c){var d=s(a,null,"xhr",
36
+ [a,null,a.jqXHR]);-1===h.inArray(!0,d)&&("parsererror"==c?K(a,0,"Invalid JSON response",1):4===b.readyState&&K(a,0,"Ajax error",7));C(a,!1)}};a.oAjaxData=b;s(a,null,"preXhr",[a,b]);a.fnServerData?a.fnServerData.call(j,a.sAjaxSource,h.map(b,function(a,b){return{name:b,value:a}}),i,a):a.sAjaxSource||"string"===typeof g?a.jqXHR=h.ajax(h.extend(n,{url:g||a.sAjaxSource})):h.isFunction(g)?a.jqXHR=g.call(j,b,i,a):(a.jqXHR=h.ajax(h.extend(n,g)),g.data=f)}function nb(a){return a.bAjaxDataGet?(a.iDraw++,C(a,
37
+ !0),ua(a,wb(a),function(b){xb(a,b)}),!1):!0}function wb(a){var b=a.aoColumns,c=b.length,d=a.oFeatures,e=a.oPreviousSearch,f=a.aoPreSearchCols,g,j=[],i,n,l,k=W(a);g=a._iDisplayStart;i=!1!==d.bPaginate?a._iDisplayLength:-1;var r=function(a,b){j.push({name:a,value:b})};r("sEcho",a.iDraw);r("iColumns",c);r("sColumns",D(b,"sName").join(","));r("iDisplayStart",g);r("iDisplayLength",i);var ra={draw:a.iDraw,columns:[],order:[],start:g,length:i,search:{value:e.sSearch,regex:e.bRegex}};for(g=0;g<c;g++)n=b[g],
38
+ l=f[g],i="function"==typeof n.mData?"function":n.mData,ra.columns.push({data:i,name:n.sName,searchable:n.bSearchable,orderable:n.bSortable,search:{value:l.sSearch,regex:l.bRegex}}),r("mDataProp_"+g,i),d.bFilter&&(r("sSearch_"+g,l.sSearch),r("bRegex_"+g,l.bRegex),r("bSearchable_"+g,n.bSearchable)),d.bSort&&r("bSortable_"+g,n.bSortable);d.bFilter&&(r("sSearch",e.sSearch),r("bRegex",e.bRegex));d.bSort&&(h.each(k,function(a,b){ra.order.push({column:b.col,dir:b.dir});r("iSortCol_"+a,b.col);r("sSortDir_"+
39
+ a,b.dir)}),r("iSortingCols",k.length));b=m.ext.legacy.ajax;return null===b?a.sAjaxSource?j:ra:b?j:ra}function xb(a,b){var c=va(a,b),d=b.sEcho!==k?b.sEcho:b.draw,e=b.iTotalRecords!==k?b.iTotalRecords:b.recordsTotal,f=b.iTotalDisplayRecords!==k?b.iTotalDisplayRecords:b.recordsFiltered;if(d){if(1*d<a.iDraw)return;a.iDraw=1*d}pa(a);a._iRecordsTotal=parseInt(e,10);a._iRecordsDisplay=parseInt(f,10);d=0;for(e=c.length;d<e;d++)N(a,c[d]);a.aiDisplay=a.aiDisplayMaster.slice();a.bAjaxDataGet=!1;O(a);a._bInitComplete||
40
+ wa(a,b);a.bAjaxDataGet=!0;C(a,!1)}function va(a,b){var c=h.isPlainObject(a.ajax)&&a.ajax.dataSrc!==k?a.ajax.dataSrc:a.sAjaxDataProp;return"data"===c?b.aaData||b[c]:""!==c?R(c)(b):b}function rb(a){var b=a.oClasses,c=a.sTableId,d=a.oLanguage,e=a.oPreviousSearch,f=a.aanFeatures,g='<input type="search" class="'+b.sFilterInput+'"/>',j=d.sSearch,j=j.match(/_INPUT_/)?j.replace("_INPUT_",g):j+g,b=h("<div/>",{id:!f.f?c+"_filter":null,"class":b.sFilter}).append(h("<label/>").append(j)),f=function(){var b=!this.value?
41
+ "":this.value;b!=e.sSearch&&(ga(a,{sSearch:b,bRegex:e.bRegex,bSmart:e.bSmart,bCaseInsensitive:e.bCaseInsensitive}),a._iDisplayStart=0,O(a))},g=null!==a.searchDelay?a.searchDelay:"ssp"===y(a)?400:0,i=h("input",b).val(e.sSearch).attr("placeholder",d.sSearchPlaceholder).on("keyup.DT search.DT input.DT paste.DT cut.DT",g?Qa(f,g):f).on("keypress.DT",function(a){if(13==a.keyCode)return!1}).attr("aria-controls",c);h(a.nTable).on("search.dt.DT",function(b,c){if(a===c)try{i[0]!==H.activeElement&&i.val(e.sSearch)}catch(d){}});
42
+ return b[0]}function ga(a,b,c){var d=a.oPreviousSearch,e=a.aoPreSearchCols,f=function(a){d.sSearch=a.sSearch;d.bRegex=a.bRegex;d.bSmart=a.bSmart;d.bCaseInsensitive=a.bCaseInsensitive};Ia(a);if("ssp"!=y(a)){yb(a,b.sSearch,c,b.bEscapeRegex!==k?!b.bEscapeRegex:b.bRegex,b.bSmart,b.bCaseInsensitive);f(b);for(b=0;b<e.length;b++)zb(a,e[b].sSearch,b,e[b].bEscapeRegex!==k?!e[b].bEscapeRegex:e[b].bRegex,e[b].bSmart,e[b].bCaseInsensitive);Ab(a)}else f(b);a.bFiltered=!0;s(a,null,"search",[a])}function Ab(a){for(var b=
43
+ m.ext.search,c=a.aiDisplay,d,e,f=0,g=b.length;f<g;f++){for(var j=[],i=0,n=c.length;i<n;i++)e=c[i],d=a.aoData[e],b[f](a,d._aFilterData,e,d._aData,i)&&j.push(e);c.length=0;h.merge(c,j)}}function zb(a,b,c,d,e,f){if(""!==b){for(var g=[],j=a.aiDisplay,d=Ra(b,d,e,f),e=0;e<j.length;e++)b=a.aoData[j[e]]._aFilterData[c],d.test(b)&&g.push(j[e]);a.aiDisplay=g}}function yb(a,b,c,d,e,f){var d=Ra(b,d,e,f),f=a.oPreviousSearch.sSearch,g=a.aiDisplayMaster,j,e=[];0!==m.ext.search.length&&(c=!0);j=Bb(a);if(0>=b.length)a.aiDisplay=
44
+ g.slice();else{if(j||c||f.length>b.length||0!==b.indexOf(f)||a.bSorted)a.aiDisplay=g.slice();b=a.aiDisplay;for(c=0;c<b.length;c++)d.test(a.aoData[b[c]]._sFilterRow)&&e.push(b[c]);a.aiDisplay=e}}function Ra(a,b,c,d){a=b?a:Sa(a);c&&(a="^(?=.*?"+h.map(a.match(/"[^"]+"|[^ ]+/g)||[""],function(a){if('"'===a.charAt(0))var b=a.match(/^"(.*)"$/),a=b?b[1]:a;return a.replace('"',"")}).join(")(?=.*?")+").*$");return RegExp(a,d?"i":"")}function Bb(a){var b=a.aoColumns,c,d,e,f,g,j,i,h,l=m.ext.type.search;c=!1;
45
+ d=0;for(f=a.aoData.length;d<f;d++)if(h=a.aoData[d],!h._aFilterData){j=[];e=0;for(g=b.length;e<g;e++)c=b[e],c.bSearchable?(i=B(a,d,e,"filter"),l[c.sType]&&(i=l[c.sType](i)),null===i&&(i=""),"string"!==typeof i&&i.toString&&(i=i.toString())):i="",i.indexOf&&-1!==i.indexOf("&")&&(xa.innerHTML=i,i=$b?xa.textContent:xa.innerText),i.replace&&(i=i.replace(/[\r\n]/g,"")),j.push(i);h._aFilterData=j;h._sFilterRow=j.join(" ");c=!0}return c}function Cb(a){return{search:a.sSearch,smart:a.bSmart,regex:a.bRegex,
46
+ caseInsensitive:a.bCaseInsensitive}}function Db(a){return{sSearch:a.search,bSmart:a.smart,bRegex:a.regex,bCaseInsensitive:a.caseInsensitive}}function ub(a){var b=a.sTableId,c=a.aanFeatures.i,d=h("<div/>",{"class":a.oClasses.sInfo,id:!c?b+"_info":null});c||(a.aoDrawCallback.push({fn:Eb,sName:"information"}),d.attr("role","status").attr("aria-live","polite"),h(a.nTable).attr("aria-describedby",b+"_info"));return d[0]}function Eb(a){var b=a.aanFeatures.i;if(0!==b.length){var c=a.oLanguage,d=a._iDisplayStart+
47
+ 1,e=a.fnDisplayEnd(),f=a.fnRecordsTotal(),g=a.fnRecordsDisplay(),j=g?c.sInfo:c.sInfoEmpty;g!==f&&(j+=" "+c.sInfoFiltered);j+=c.sInfoPostFix;j=Fb(a,j);c=c.fnInfoCallback;null!==c&&(j=c.call(a.oInstance,a,d,e,f,g,j));h(b).html(j)}}function Fb(a,b){var c=a.fnFormatNumber,d=a._iDisplayStart+1,e=a._iDisplayLength,f=a.fnRecordsDisplay(),g=-1===e;return b.replace(/_START_/g,c.call(a,d)).replace(/_END_/g,c.call(a,a.fnDisplayEnd())).replace(/_MAX_/g,c.call(a,a.fnRecordsTotal())).replace(/_TOTAL_/g,c.call(a,
48
+ f)).replace(/_PAGE_/g,c.call(a,g?1:Math.ceil(d/e))).replace(/_PAGES_/g,c.call(a,g?1:Math.ceil(f/e)))}function ha(a){var b,c,d=a.iInitDisplayStart,e=a.aoColumns,f;c=a.oFeatures;var g=a.bDeferLoading;if(a.bInitialised){pb(a);mb(a);fa(a,a.aoHeader);fa(a,a.aoFooter);C(a,!0);c.bAutoWidth&&Ha(a);b=0;for(c=e.length;b<c;b++)f=e[b],f.sWidth&&(f.nTh.style.width=v(f.sWidth));s(a,null,"preInit",[a]);T(a);e=y(a);if("ssp"!=e||g)"ajax"==e?ua(a,[],function(c){var f=va(a,c);for(b=0;b<f.length;b++)N(a,f[b]);a.iInitDisplayStart=
49
+ d;T(a);C(a,!1);wa(a,c)},a):(C(a,!1),wa(a))}else setTimeout(function(){ha(a)},200)}function wa(a,b){a._bInitComplete=!0;(b||a.oInit.aaData)&&Z(a);s(a,null,"plugin-init",[a,b]);s(a,"aoInitComplete","init",[a,b])}function Ta(a,b){var c=parseInt(b,10);a._iDisplayLength=c;Ua(a);s(a,null,"length",[a,c])}function qb(a){for(var b=a.oClasses,c=a.sTableId,d=a.aLengthMenu,e=h.isArray(d[0]),f=e?d[0]:d,d=e?d[1]:d,e=h("<select/>",{name:c+"_length","aria-controls":c,"class":b.sLengthSelect}),g=0,j=f.length;g<j;g++)e[0][g]=
50
+ new Option(d[g],f[g]);var i=h("<div><label/></div>").addClass(b.sLength);a.aanFeatures.l||(i[0].id=c+"_length");i.children().append(a.oLanguage.sLengthMenu.replace("_MENU_",e[0].outerHTML));h("select",i).val(a._iDisplayLength).on("change.DT",function(){Ta(a,h(this).val());O(a)});h(a.nTable).on("length.dt.DT",function(b,c,d){a===c&&h("select",i).val(d)});return i[0]}function vb(a){var b=a.sPaginationType,c=m.ext.pager[b],d="function"===typeof c,e=function(a){O(a)},b=h("<div/>").addClass(a.oClasses.sPaging+
51
+ b)[0],f=a.aanFeatures;d||c.fnInit(a,b,e);f.p||(b.id=a.sTableId+"_paginate",a.aoDrawCallback.push({fn:function(a){if(d){var b=a._iDisplayStart,i=a._iDisplayLength,h=a.fnRecordsDisplay(),l=-1===i,b=l?0:Math.ceil(b/i),i=l?1:Math.ceil(h/i),h=c(b,i),k,l=0;for(k=f.p.length;l<k;l++)Pa(a,"pageButton")(a,f.p[l],l,h,b,i)}else c.fnUpdate(a,e)},sName:"pagination"}));return b}function Va(a,b,c){var d=a._iDisplayStart,e=a._iDisplayLength,f=a.fnRecordsDisplay();0===f||-1===e?d=0:"number"===typeof b?(d=b*e,d>f&&
52
+ (d=0)):"first"==b?d=0:"previous"==b?(d=0<=e?d-e:0,0>d&&(d=0)):"next"==b?d+e<f&&(d+=e):"last"==b?d=Math.floor((f-1)/e)*e:K(a,0,"Unknown paging action: "+b,5);b=a._iDisplayStart!==d;a._iDisplayStart=d;b&&(s(a,null,"page",[a]),c&&O(a));return b}function sb(a){return h("<div/>",{id:!a.aanFeatures.r?a.sTableId+"_processing":null,"class":a.oClasses.sProcessing}).html(a.oLanguage.sProcessing).insertBefore(a.nTable)[0]}function C(a,b){a.oFeatures.bProcessing&&h(a.aanFeatures.r).css("display",b?"block":"none");
53
+ s(a,null,"processing",[a,b])}function tb(a){var b=h(a.nTable);b.attr("role","grid");var c=a.oScroll;if(""===c.sX&&""===c.sY)return a.nTable;var d=c.sX,e=c.sY,f=a.oClasses,g=b.children("caption"),j=g.length?g[0]._captionSide:null,i=h(b[0].cloneNode(!1)),n=h(b[0].cloneNode(!1)),l=b.children("tfoot");l.length||(l=null);i=h("<div/>",{"class":f.sScrollWrapper}).append(h("<div/>",{"class":f.sScrollHead}).css({overflow:"hidden",position:"relative",border:0,width:d?!d?null:v(d):"100%"}).append(h("<div/>",
54
+ {"class":f.sScrollHeadInner}).css({"box-sizing":"content-box",width:c.sXInner||"100%"}).append(i.removeAttr("id").css("margin-left",0).append("top"===j?g:null).append(b.children("thead"))))).append(h("<div/>",{"class":f.sScrollBody}).css({position:"relative",overflow:"auto",width:!d?null:v(d)}).append(b));l&&i.append(h("<div/>",{"class":f.sScrollFoot}).css({overflow:"hidden",border:0,width:d?!d?null:v(d):"100%"}).append(h("<div/>",{"class":f.sScrollFootInner}).append(n.removeAttr("id").css("margin-left",
55
+ 0).append("bottom"===j?g:null).append(b.children("tfoot")))));var b=i.children(),k=b[0],f=b[1],r=l?b[2]:null;if(d)h(f).on("scroll.DT",function(){var a=this.scrollLeft;k.scrollLeft=a;l&&(r.scrollLeft=a)});h(f).css(e&&c.bCollapse?"max-height":"height",e);a.nScrollHead=k;a.nScrollBody=f;a.nScrollFoot=r;a.aoDrawCallback.push({fn:ma,sName:"scrolling"});return i[0]}function ma(a){var b=a.oScroll,c=b.sX,d=b.sXInner,e=b.sY,b=b.iBarWidth,f=h(a.nScrollHead),g=f[0].style,j=f.children("div"),i=j[0].style,n=j.children("table"),
56
+ j=a.nScrollBody,l=h(j),q=j.style,r=h(a.nScrollFoot).children("div"),m=r.children("table"),p=h(a.nTHead),o=h(a.nTable),u=o[0],s=u.style,t=a.nTFoot?h(a.nTFoot):null,x=a.oBrowser,U=x.bScrollOversize,ac=D(a.aoColumns,"nTh"),P,L,Q,w,Wa=[],y=[],z=[],A=[],B,C=function(a){a=a.style;a.paddingTop="0";a.paddingBottom="0";a.borderTopWidth="0";a.borderBottomWidth="0";a.height=0};L=j.scrollHeight>j.clientHeight;if(a.scrollBarVis!==L&&a.scrollBarVis!==k)a.scrollBarVis=L,Z(a);else{a.scrollBarVis=L;o.children("thead, tfoot").remove();
57
+ t&&(Q=t.clone().prependTo(o),P=t.find("tr"),Q=Q.find("tr"));w=p.clone().prependTo(o);p=p.find("tr");L=w.find("tr");w.find("th, td").removeAttr("tabindex");c||(q.width="100%",f[0].style.width="100%");h.each(ta(a,w),function(b,c){B=$(a,b);c.style.width=a.aoColumns[B].sWidth});t&&I(function(a){a.style.width=""},Q);f=o.outerWidth();if(""===c){s.width="100%";if(U&&(o.find("tbody").height()>j.offsetHeight||"scroll"==l.css("overflow-y")))s.width=v(o.outerWidth()-b);f=o.outerWidth()}else""!==d&&(s.width=
58
+ v(d),f=o.outerWidth());I(C,L);I(function(a){z.push(a.innerHTML);Wa.push(v(h(a).css("width")))},L);I(function(a,b){if(h.inArray(a,ac)!==-1)a.style.width=Wa[b]},p);h(L).height(0);t&&(I(C,Q),I(function(a){A.push(a.innerHTML);y.push(v(h(a).css("width")))},Q),I(function(a,b){a.style.width=y[b]},P),h(Q).height(0));I(function(a,b){a.innerHTML='<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+z[b]+"</div>";a.style.width=Wa[b]},L);t&&I(function(a,b){a.innerHTML='<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+
59
+ A[b]+"</div>";a.style.width=y[b]},Q);if(o.outerWidth()<f){P=j.scrollHeight>j.offsetHeight||"scroll"==l.css("overflow-y")?f+b:f;if(U&&(j.scrollHeight>j.offsetHeight||"scroll"==l.css("overflow-y")))s.width=v(P-b);(""===c||""!==d)&&K(a,1,"Possible column misalignment",6)}else P="100%";q.width=v(P);g.width=v(P);t&&(a.nScrollFoot.style.width=v(P));!e&&U&&(q.height=v(u.offsetHeight+b));c=o.outerWidth();n[0].style.width=v(c);i.width=v(c);d=o.height()>j.clientHeight||"scroll"==l.css("overflow-y");e="padding"+
60
+ (x.bScrollbarLeft?"Left":"Right");i[e]=d?b+"px":"0px";t&&(m[0].style.width=v(c),r[0].style.width=v(c),r[0].style[e]=d?b+"px":"0px");o.children("colgroup").insertBefore(o.children("thead"));l.scroll();if((a.bSorted||a.bFiltered)&&!a._drawHold)j.scrollTop=0}}function I(a,b,c){for(var d=0,e=0,f=b.length,g,j;e<f;){g=b[e].firstChild;for(j=c?c[e].firstChild:null;g;)1===g.nodeType&&(c?a(g,j,d):a(g,d),d++),g=g.nextSibling,j=c?j.nextSibling:null;e++}}function Ha(a){var b=a.nTable,c=a.aoColumns,d=a.oScroll,
61
+ e=d.sY,f=d.sX,g=d.sXInner,j=c.length,i=na(a,"bVisible"),n=h("th",a.nTHead),l=b.getAttribute("width"),k=b.parentNode,r=!1,m,p,o=a.oBrowser,d=o.bScrollOversize;(m=b.style.width)&&-1!==m.indexOf("%")&&(l=m);for(m=0;m<i.length;m++)p=c[i[m]],null!==p.sWidth&&(p.sWidth=Gb(p.sWidthOrig,k),r=!0);if(d||!r&&!f&&!e&&j==ba(a)&&j==n.length)for(m=0;m<j;m++)i=$(a,m),null!==i&&(c[i].sWidth=v(n.eq(m).width()));else{j=h(b).clone().css("visibility","hidden").removeAttr("id");j.find("tbody tr").remove();var u=h("<tr/>").appendTo(j.find("tbody"));
62
+ j.find("thead, tfoot").remove();j.append(h(a.nTHead).clone()).append(h(a.nTFoot).clone());j.find("tfoot th, tfoot td").css("width","");n=ta(a,j.find("thead")[0]);for(m=0;m<i.length;m++)p=c[i[m]],n[m].style.width=null!==p.sWidthOrig&&""!==p.sWidthOrig?v(p.sWidthOrig):"",p.sWidthOrig&&f&&h(n[m]).append(h("<div/>").css({width:p.sWidthOrig,margin:0,padding:0,border:0,height:1}));if(a.aoData.length)for(m=0;m<i.length;m++)r=i[m],p=c[r],h(Hb(a,r)).clone(!1).append(p.sContentPadding).appendTo(u);h("[name]",
63
+ j).removeAttr("name");p=h("<div/>").css(f||e?{position:"absolute",top:0,left:0,height:1,right:0,overflow:"hidden"}:{}).append(j).appendTo(k);f&&g?j.width(g):f?(j.css("width","auto"),j.removeAttr("width"),j.width()<k.clientWidth&&l&&j.width(k.clientWidth)):e?j.width(k.clientWidth):l&&j.width(l);for(m=e=0;m<i.length;m++)k=h(n[m]),g=k.outerWidth()-k.width(),k=o.bBounding?Math.ceil(n[m].getBoundingClientRect().width):k.outerWidth(),e+=k,c[i[m]].sWidth=v(k-g);b.style.width=v(e);p.remove()}l&&(b.style.width=
64
+ v(l));if((l||f)&&!a._reszEvt)b=function(){h(E).on("resize.DT-"+a.sInstance,Qa(function(){Z(a)}))},d?setTimeout(b,1E3):b(),a._reszEvt=!0}function Gb(a,b){if(!a)return 0;var c=h("<div/>").css("width",v(a)).appendTo(b||H.body),d=c[0].offsetWidth;c.remove();return d}function Hb(a,b){var c=Ib(a,b);if(0>c)return null;var d=a.aoData[c];return!d.nTr?h("<td/>").html(B(a,c,b,"display"))[0]:d.anCells[b]}function Ib(a,b){for(var c,d=-1,e=-1,f=0,g=a.aoData.length;f<g;f++)c=B(a,f,b,"display")+"",c=c.replace(bc,
65
+ ""),c=c.replace(/&nbsp;/g," "),c.length>d&&(d=c.length,e=f);return e}function v(a){return null===a?"0px":"number"==typeof a?0>a?"0px":a+"px":a.match(/\d$/)?a+"px":a}function W(a){var b,c,d=[],e=a.aoColumns,f,g,j,i;b=a.aaSortingFixed;c=h.isPlainObject(b);var n=[];f=function(a){a.length&&!h.isArray(a[0])?n.push(a):h.merge(n,a)};h.isArray(b)&&f(b);c&&b.pre&&f(b.pre);f(a.aaSorting);c&&b.post&&f(b.post);for(a=0;a<n.length;a++){i=n[a][0];f=e[i].aDataSort;b=0;for(c=f.length;b<c;b++)g=f[b],j=e[g].sType||
66
+ "string",n[a]._idx===k&&(n[a]._idx=h.inArray(n[a][1],e[g].asSorting)),d.push({src:i,col:g,dir:n[a][1],index:n[a]._idx,type:j,formatter:m.ext.type.order[j+"-pre"]})}return d}function ob(a){var b,c,d=[],e=m.ext.type.order,f=a.aoData,g=0,j,i=a.aiDisplayMaster,h;Ia(a);h=W(a);b=0;for(c=h.length;b<c;b++)j=h[b],j.formatter&&g++,Jb(a,j.col);if("ssp"!=y(a)&&0!==h.length){b=0;for(c=i.length;b<c;b++)d[i[b]]=b;g===h.length?i.sort(function(a,b){var c,e,g,j,i=h.length,k=f[a]._aSortData,m=f[b]._aSortData;for(g=
67
+ 0;g<i;g++)if(j=h[g],c=k[j.col],e=m[j.col],c=c<e?-1:c>e?1:0,0!==c)return"asc"===j.dir?c:-c;c=d[a];e=d[b];return c<e?-1:c>e?1:0}):i.sort(function(a,b){var c,g,j,i,k=h.length,m=f[a]._aSortData,p=f[b]._aSortData;for(j=0;j<k;j++)if(i=h[j],c=m[i.col],g=p[i.col],i=e[i.type+"-"+i.dir]||e["string-"+i.dir],c=i(c,g),0!==c)return c;c=d[a];g=d[b];return c<g?-1:c>g?1:0})}a.bSorted=!0}function Kb(a){for(var b,c,d=a.aoColumns,e=W(a),a=a.oLanguage.oAria,f=0,g=d.length;f<g;f++){c=d[f];var j=c.asSorting;b=c.sTitle.replace(/<.*?>/g,
68
+ "");var i=c.nTh;i.removeAttribute("aria-sort");c.bSortable&&(0<e.length&&e[0].col==f?(i.setAttribute("aria-sort","asc"==e[0].dir?"ascending":"descending"),c=j[e[0].index+1]||j[0]):c=j[0],b+="asc"===c?a.sSortAscending:a.sSortDescending);i.setAttribute("aria-label",b)}}function Xa(a,b,c,d){var e=a.aaSorting,f=a.aoColumns[b].asSorting,g=function(a,b){var c=a._idx;c===k&&(c=h.inArray(a[1],f));return c+1<f.length?c+1:b?null:0};"number"===typeof e[0]&&(e=a.aaSorting=[e]);c&&a.oFeatures.bSortMulti?(c=h.inArray(b,
69
+ D(e,"0")),-1!==c?(b=g(e[c],!0),null===b&&1===e.length&&(b=0),null===b?e.splice(c,1):(e[c][1]=f[b],e[c]._idx=b)):(e.push([b,f[0],0]),e[e.length-1]._idx=0)):e.length&&e[0][0]==b?(b=g(e[0]),e.length=1,e[0][1]=f[b],e[0]._idx=b):(e.length=0,e.push([b,f[0]]),e[0]._idx=0);T(a);"function"==typeof d&&d(a)}function Oa(a,b,c,d){var e=a.aoColumns[c];Ya(b,{},function(b){!1!==e.bSortable&&(a.oFeatures.bProcessing?(C(a,!0),setTimeout(function(){Xa(a,c,b.shiftKey,d);"ssp"!==y(a)&&C(a,!1)},0)):Xa(a,c,b.shiftKey,d))})}
70
+ function ya(a){var b=a.aLastSort,c=a.oClasses.sSortColumn,d=W(a),e=a.oFeatures,f,g;if(e.bSort&&e.bSortClasses){e=0;for(f=b.length;e<f;e++)g=b[e].src,h(D(a.aoData,"anCells",g)).removeClass(c+(2>e?e+1:3));e=0;for(f=d.length;e<f;e++)g=d[e].src,h(D(a.aoData,"anCells",g)).addClass(c+(2>e?e+1:3))}a.aLastSort=d}function Jb(a,b){var c=a.aoColumns[b],d=m.ext.order[c.sSortDataType],e;d&&(e=d.call(a.oInstance,a,b,aa(a,b)));for(var f,g=m.ext.type.order[c.sType+"-pre"],j=0,i=a.aoData.length;j<i;j++)if(c=a.aoData[j],
71
+ c._aSortData||(c._aSortData=[]),!c._aSortData[b]||d)f=d?e[j]:B(a,j,b,"sort"),c._aSortData[b]=g?g(f):f}function za(a){if(a.oFeatures.bStateSave&&!a.bDestroying){var b={time:+new Date,start:a._iDisplayStart,length:a._iDisplayLength,order:h.extend(!0,[],a.aaSorting),search:Cb(a.oPreviousSearch),columns:h.map(a.aoColumns,function(b,d){return{visible:b.bVisible,search:Cb(a.aoPreSearchCols[d])}})};s(a,"aoStateSaveParams","stateSaveParams",[a,b]);a.oSavedState=b;a.fnStateSaveCallback.call(a.oInstance,a,
72
+ b)}}function Lb(a,b,c){var d,e,f=a.aoColumns,b=function(b){if(b&&b.time){var i=s(a,"aoStateLoadParams","stateLoadParams",[a,g]);if(-1===h.inArray(!1,i)&&(i=a.iStateDuration,!(0<i&&b.time<+new Date-1E3*i)&&!(b.columns&&f.length!==b.columns.length))){a.oLoadedState=h.extend(!0,{},g);b.start!==k&&(a._iDisplayStart=b.start,a.iInitDisplayStart=b.start);b.length!==k&&(a._iDisplayLength=b.length);b.order!==k&&(a.aaSorting=[],h.each(b.order,function(b,c){a.aaSorting.push(c[0]>=f.length?[0,c[1]]:c)}));b.search!==
73
+ k&&h.extend(a.oPreviousSearch,Db(b.search));if(b.columns){d=0;for(e=b.columns.length;d<e;d++)i=b.columns[d],i.visible!==k&&(f[d].bVisible=i.visible),i.search!==k&&h.extend(a.aoPreSearchCols[d],Db(i.search))}s(a,"aoStateLoaded","stateLoaded",[a,g])}}c()};if(a.oFeatures.bStateSave){var g=a.fnStateLoadCallback.call(a.oInstance,a,b);g!==k&&b(g)}else c()}function Aa(a){var b=m.settings,a=h.inArray(a,D(b,"nTable"));return-1!==a?b[a]:null}function K(a,b,c,d){c="DataTables warning: "+(a?"table id="+a.sTableId+
74
+ " - ":"")+c;d&&(c+=". For more information about this error, please see http://datatables.net/tn/"+d);if(b)E.console&&console.log&&console.log(c);else if(b=m.ext,b=b.sErrMode||b.errMode,a&&s(a,null,"error",[a,d,c]),"alert"==b)alert(c);else{if("throw"==b)throw Error(c);"function"==typeof b&&b(a,d,c)}}function F(a,b,c,d){h.isArray(c)?h.each(c,function(c,d){h.isArray(d)?F(a,b,d[0],d[1]):F(a,b,d)}):(d===k&&(d=c),b[c]!==k&&(a[d]=b[c]))}function Mb(a,b,c){var d,e;for(e in b)b.hasOwnProperty(e)&&(d=b[e],
75
+ h.isPlainObject(d)?(h.isPlainObject(a[e])||(a[e]={}),h.extend(!0,a[e],d)):a[e]=c&&"data"!==e&&"aaData"!==e&&h.isArray(d)?d.slice():d);return a}function Ya(a,b,c){h(a).on("click.DT",b,function(b){a.blur();c(b)}).on("keypress.DT",b,function(a){13===a.which&&(a.preventDefault(),c(a))}).on("selectstart.DT",function(){return!1})}function z(a,b,c,d){c&&a[b].push({fn:c,sName:d})}function s(a,b,c,d){var e=[];b&&(e=h.map(a[b].slice().reverse(),function(b){return b.fn.apply(a.oInstance,d)}));null!==c&&(b=h.Event(c+
76
+ ".dt"),h(a.nTable).trigger(b,d),e.push(b.result));return e}function Ua(a){var b=a._iDisplayStart,c=a.fnDisplayEnd(),d=a._iDisplayLength;b>=c&&(b=c-d);b-=b%d;if(-1===d||0>b)b=0;a._iDisplayStart=b}function Pa(a,b){var c=a.renderer,d=m.ext.renderer[b];return h.isPlainObject(c)&&c[b]?d[c[b]]||d._:"string"===typeof c?d[c]||d._:d._}function y(a){return a.oFeatures.bServerSide?"ssp":a.ajax||a.sAjaxSource?"ajax":"dom"}function ia(a,b){var c=[],c=Nb.numbers_length,d=Math.floor(c/2);b<=c?c=X(0,b):a<=d?(c=X(0,
77
+ c-2),c.push("ellipsis"),c.push(b-1)):(a>=b-1-d?c=X(b-(c-2),b):(c=X(a-d+2,a+d-1),c.push("ellipsis"),c.push(b-1)),c.splice(0,0,"ellipsis"),c.splice(0,0,0));c.DT_el="span";return c}function fb(a){h.each({num:function(b){return Ba(b,a)},"num-fmt":function(b){return Ba(b,a,Za)},"html-num":function(b){return Ba(b,a,Ca)},"html-num-fmt":function(b){return Ba(b,a,Ca,Za)}},function(b,c){x.type.order[b+a+"-pre"]=c;b.match(/^html\-/)&&(x.type.search[b+a]=x.type.search.html)})}function Ob(a){return function(){var b=
78
+ [Aa(this[m.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return m.ext.internal[a].apply(this,b)}}var m=function(a){this.$=function(a,b){return this.api(!0).$(a,b)};this._=function(a,b){return this.api(!0).rows(a,b).data()};this.api=function(a){return a?new u(Aa(this[x.iApiIndex])):new u(this)};this.fnAddData=function(a,b){var c=this.api(!0),d=h.isArray(a)&&(h.isArray(a[0])||h.isPlainObject(a[0]))?c.rows.add(a):c.row.add(a);(b===k||b)&&c.draw();return d.flatten().toArray()};this.fnAdjustColumnSizing=
79
+ function(a){var b=this.api(!0).columns.adjust(),c=b.settings()[0],d=c.oScroll;a===k||a?b.draw(!1):(""!==d.sX||""!==d.sY)&&ma(c)};this.fnClearTable=function(a){var b=this.api(!0).clear();(a===k||a)&&b.draw()};this.fnClose=function(a){this.api(!0).row(a).child.hide()};this.fnDeleteRow=function(a,b,c){var d=this.api(!0),a=d.rows(a),e=a.settings()[0],h=e.aoData[a[0][0]];a.remove();b&&b.call(this,e,h);(c===k||c)&&d.draw();return h};this.fnDestroy=function(a){this.api(!0).destroy(a)};this.fnDraw=function(a){this.api(!0).draw(a)};
80
+ this.fnFilter=function(a,b,c,d,e,h){e=this.api(!0);null===b||b===k?e.search(a,c,d,h):e.column(b).search(a,c,d,h);e.draw()};this.fnGetData=function(a,b){var c=this.api(!0);if(a!==k){var d=a.nodeName?a.nodeName.toLowerCase():"";return b!==k||"td"==d||"th"==d?c.cell(a,b).data():c.row(a).data()||null}return c.data().toArray()};this.fnGetNodes=function(a){var b=this.api(!0);return a!==k?b.row(a).node():b.rows().nodes().flatten().toArray()};this.fnGetPosition=function(a){var b=this.api(!0),c=a.nodeName.toUpperCase();
81
+ return"TR"==c?b.row(a).index():"TD"==c||"TH"==c?(a=b.cell(a).index(),[a.row,a.columnVisible,a.column]):null};this.fnIsOpen=function(a){return this.api(!0).row(a).child.isShown()};this.fnOpen=function(a,b,c){return this.api(!0).row(a).child(b,c).show().child()[0]};this.fnPageChange=function(a,b){var c=this.api(!0).page(a);(b===k||b)&&c.draw(!1)};this.fnSetColumnVis=function(a,b,c){a=this.api(!0).column(a).visible(b);(c===k||c)&&a.columns.adjust().draw()};this.fnSettings=function(){return Aa(this[x.iApiIndex])};
82
+ this.fnSort=function(a){this.api(!0).order(a).draw()};this.fnSortListener=function(a,b,c){this.api(!0).order.listener(a,b,c)};this.fnUpdate=function(a,b,c,d,e){var h=this.api(!0);c===k||null===c?h.row(b).data(a):h.cell(b,c).data(a);(e===k||e)&&h.columns.adjust();(d===k||d)&&h.draw();return 0};this.fnVersionCheck=x.fnVersionCheck;var b=this,c=a===k,d=this.length;c&&(a={});this.oApi=this.internal=x.internal;for(var e in m.ext.internal)e&&(this[e]=Ob(e));this.each(function(){var e={},g=1<d?Mb(e,a,!0):
83
+ a,j=0,i,e=this.getAttribute("id"),n=!1,l=m.defaults,q=h(this);if("table"!=this.nodeName.toLowerCase())K(null,0,"Non-table node initialisation ("+this.nodeName+")",2);else{gb(l);hb(l.column);J(l,l,!0);J(l.column,l.column,!0);J(l,h.extend(g,q.data()));var r=m.settings,j=0;for(i=r.length;j<i;j++){var p=r[j];if(p.nTable==this||p.nTHead.parentNode==this||p.nTFoot&&p.nTFoot.parentNode==this){var u=g.bRetrieve!==k?g.bRetrieve:l.bRetrieve;if(c||u)return p.oInstance;if(g.bDestroy!==k?g.bDestroy:l.bDestroy){p.oInstance.fnDestroy();
84
+ break}else{K(p,0,"Cannot reinitialise DataTable",3);return}}if(p.sTableId==this.id){r.splice(j,1);break}}if(null===e||""===e)this.id=e="DataTables_Table_"+m.ext._unique++;var o=h.extend(!0,{},m.models.oSettings,{sDestroyWidth:q[0].style.width,sInstance:e,sTableId:e});o.nTable=this;o.oApi=b.internal;o.oInit=g;r.push(o);o.oInstance=1===b.length?b:q.dataTable();gb(g);g.oLanguage&&Fa(g.oLanguage);g.aLengthMenu&&!g.iDisplayLength&&(g.iDisplayLength=h.isArray(g.aLengthMenu[0])?g.aLengthMenu[0][0]:g.aLengthMenu[0]);
85
+ g=Mb(h.extend(!0,{},l),g);F(o.oFeatures,g,"bPaginate bLengthChange bFilter bSort bSortMulti bInfo bProcessing bAutoWidth bSortClasses bServerSide bDeferRender".split(" "));F(o,g,["asStripeClasses","ajax","fnServerData","fnFormatNumber","sServerMethod","aaSorting","aaSortingFixed","aLengthMenu","sPaginationType","sAjaxSource","sAjaxDataProp","iStateDuration","sDom","bSortCellsTop","iTabIndex","fnStateLoadCallback","fnStateSaveCallback","renderer","searchDelay","rowId",["iCookieDuration","iStateDuration"],
86
+ ["oSearch","oPreviousSearch"],["aoSearchCols","aoPreSearchCols"],["iDisplayLength","_iDisplayLength"],["bJQueryUI","bJUI"]]);F(o.oScroll,g,[["sScrollX","sX"],["sScrollXInner","sXInner"],["sScrollY","sY"],["bScrollCollapse","bCollapse"]]);F(o.oLanguage,g,"fnInfoCallback");z(o,"aoDrawCallback",g.fnDrawCallback,"user");z(o,"aoServerParams",g.fnServerParams,"user");z(o,"aoStateSaveParams",g.fnStateSaveParams,"user");z(o,"aoStateLoadParams",g.fnStateLoadParams,"user");z(o,"aoStateLoaded",g.fnStateLoaded,
87
+ "user");z(o,"aoRowCallback",g.fnRowCallback,"user");z(o,"aoRowCreatedCallback",g.fnCreatedRow,"user");z(o,"aoHeaderCallback",g.fnHeaderCallback,"user");z(o,"aoFooterCallback",g.fnFooterCallback,"user");z(o,"aoInitComplete",g.fnInitComplete,"user");z(o,"aoPreDrawCallback",g.fnPreDrawCallback,"user");o.rowIdFn=R(g.rowId);ib(o);var t=o.oClasses;g.bJQueryUI?(h.extend(t,m.ext.oJUIClasses,g.oClasses),g.sDom===l.sDom&&"lfrtip"===l.sDom&&(o.sDom='<"H"lfr>t<"F"ip>'),o.renderer)?h.isPlainObject(o.renderer)&&
88
+ !o.renderer.header&&(o.renderer.header="jqueryui"):o.renderer="jqueryui":h.extend(t,m.ext.classes,g.oClasses);q.addClass(t.sTable);o.iInitDisplayStart===k&&(o.iInitDisplayStart=g.iDisplayStart,o._iDisplayStart=g.iDisplayStart);null!==g.iDeferLoading&&(o.bDeferLoading=!0,e=h.isArray(g.iDeferLoading),o._iRecordsDisplay=e?g.iDeferLoading[0]:g.iDeferLoading,o._iRecordsTotal=e?g.iDeferLoading[1]:g.iDeferLoading);var v=o.oLanguage;h.extend(!0,v,g.oLanguage);v.sUrl&&(h.ajax({dataType:"json",url:v.sUrl,success:function(a){Fa(a);
89
+ J(l.oLanguage,a);h.extend(true,v,a);ha(o)},error:function(){ha(o)}}),n=!0);null===g.asStripeClasses&&(o.asStripeClasses=[t.sStripeOdd,t.sStripeEven]);var e=o.asStripeClasses,x=q.children("tbody").find("tr").eq(0);-1!==h.inArray(!0,h.map(e,function(a){return x.hasClass(a)}))&&(h("tbody tr",this).removeClass(e.join(" ")),o.asDestroyStripes=e.slice());e=[];r=this.getElementsByTagName("thead");0!==r.length&&(ea(o.aoHeader,r[0]),e=ta(o));if(null===g.aoColumns){r=[];j=0;for(i=e.length;j<i;j++)r.push(null)}else r=
90
+ g.aoColumns;j=0;for(i=r.length;j<i;j++)Ga(o,e?e[j]:null);kb(o,g.aoColumnDefs,r,function(a,b){la(o,a,b)});if(x.length){var w=function(a,b){return a.getAttribute("data-"+b)!==null?b:null};h(x[0]).children("th, td").each(function(a,b){var c=o.aoColumns[a];if(c.mData===a){var d=w(b,"sort")||w(b,"order"),e=w(b,"filter")||w(b,"search");if(d!==null||e!==null){c.mData={_:a+".display",sort:d!==null?a+".@data-"+d:k,type:d!==null?a+".@data-"+d:k,filter:e!==null?a+".@data-"+e:k};la(o,a)}}})}var U=o.oFeatures,
91
+ e=function(){if(g.aaSorting===k){var a=o.aaSorting;j=0;for(i=a.length;j<i;j++)a[j][1]=o.aoColumns[j].asSorting[0]}ya(o);U.bSort&&z(o,"aoDrawCallback",function(){if(o.bSorted){var a=W(o),b={};h.each(a,function(a,c){b[c.src]=c.dir});s(o,null,"order",[o,a,b]);Kb(o)}});z(o,"aoDrawCallback",function(){(o.bSorted||y(o)==="ssp"||U.bDeferRender)&&ya(o)},"sc");var a=q.children("caption").each(function(){this._captionSide=h(this).css("caption-side")}),b=q.children("thead");b.length===0&&(b=h("<thead/>").appendTo(q));
92
+ o.nTHead=b[0];b=q.children("tbody");b.length===0&&(b=h("<tbody/>").appendTo(q));o.nTBody=b[0];b=q.children("tfoot");if(b.length===0&&a.length>0&&(o.oScroll.sX!==""||o.oScroll.sY!==""))b=h("<tfoot/>").appendTo(q);if(b.length===0||b.children().length===0)q.addClass(t.sNoFooter);else if(b.length>0){o.nTFoot=b[0];ea(o.aoFooter,o.nTFoot)}if(g.aaData)for(j=0;j<g.aaData.length;j++)N(o,g.aaData[j]);else(o.bDeferLoading||y(o)=="dom")&&oa(o,h(o.nTBody).children("tr"));o.aiDisplay=o.aiDisplayMaster.slice();
93
+ o.bInitialised=true;n===false&&ha(o)};g.bStateSave?(U.bStateSave=!0,z(o,"aoDrawCallback",za,"state_save"),Lb(o,g,e)):e()}});b=null;return this},x,u,p,t,$a={},Pb=/[\r\n]/g,Ca=/<.*?>/g,cc=/^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/,dc=RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^|\\-)","g"),Za=/[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi,M=function(a){return!a||!0===a||"-"===a?!0:!1},Qb=function(a){var b=parseInt(a,10);return!isNaN(b)&&
94
+ isFinite(a)?b:null},Rb=function(a,b){$a[b]||($a[b]=RegExp(Sa(b),"g"));return"string"===typeof a&&"."!==b?a.replace(/\./g,"").replace($a[b],"."):a},ab=function(a,b,c){var d="string"===typeof a;if(M(a))return!0;b&&d&&(a=Rb(a,b));c&&d&&(a=a.replace(Za,""));return!isNaN(parseFloat(a))&&isFinite(a)},Sb=function(a,b,c){return M(a)?!0:!(M(a)||"string"===typeof a)?null:ab(a.replace(Ca,""),b,c)?!0:null},D=function(a,b,c){var d=[],e=0,f=a.length;if(c!==k)for(;e<f;e++)a[e]&&a[e][b]&&d.push(a[e][b][c]);else for(;e<
95
+ f;e++)a[e]&&d.push(a[e][b]);return d},ja=function(a,b,c,d){var e=[],f=0,g=b.length;if(d!==k)for(;f<g;f++)a[b[f]][c]&&e.push(a[b[f]][c][d]);else for(;f<g;f++)e.push(a[b[f]][c]);return e},X=function(a,b){var c=[],d;b===k?(b=0,d=a):(d=b,b=a);for(var e=b;e<d;e++)c.push(e);return c},Tb=function(a){for(var b=[],c=0,d=a.length;c<d;c++)a[c]&&b.push(a[c]);return b},sa=function(a){var b=[],c,d,e=a.length,f,g=0;d=0;a:for(;d<e;d++){c=a[d];for(f=0;f<g;f++)if(b[f]===c)continue a;b.push(c);g++}return b};m.util=
96
+ {throttle:function(a,b){var c=b!==k?b:200,d,e;return function(){var b=this,g=+new Date,h=arguments;d&&g<d+c?(clearTimeout(e),e=setTimeout(function(){d=k;a.apply(b,h)},c)):(d=g,a.apply(b,h))}},escapeRegex:function(a){return a.replace(dc,"\\$1")}};var A=function(a,b,c){a[b]!==k&&(a[c]=a[b])},ca=/\[.*?\]$/,V=/\(\)$/,Sa=m.util.escapeRegex,xa=h("<div>")[0],$b=xa.textContent!==k,bc=/<.*?>/g,Qa=m.util.throttle,Ub=[],w=Array.prototype,ec=function(a){var b,c,d=m.settings,e=h.map(d,function(a){return a.nTable});
97
+ if(a){if(a.nTable&&a.oApi)return[a];if(a.nodeName&&"table"===a.nodeName.toLowerCase())return b=h.inArray(a,e),-1!==b?[d[b]]:null;if(a&&"function"===typeof a.settings)return a.settings().toArray();"string"===typeof a?c=h(a):a instanceof h&&(c=a)}else return[];if(c)return c.map(function(){b=h.inArray(this,e);return-1!==b?d[b]:null}).toArray()};u=function(a,b){if(!(this instanceof u))return new u(a,b);var c=[],d=function(a){(a=ec(a))&&(c=c.concat(a))};if(h.isArray(a))for(var e=0,f=a.length;e<f;e++)d(a[e]);
98
+ else d(a);this.context=sa(c);b&&h.merge(this,b);this.selector={rows:null,cols:null,opts:null};u.extend(this,this,Ub)};m.Api=u;h.extend(u.prototype,{any:function(){return 0!==this.count()},concat:w.concat,context:[],count:function(){return this.flatten().length},each:function(a){for(var b=0,c=this.length;b<c;b++)a.call(this,this[b],b,this);return this},eq:function(a){var b=this.context;return b.length>a?new u(b[a],this[a]):null},filter:function(a){var b=[];if(w.filter)b=w.filter.call(this,a,this);
99
+ else for(var c=0,d=this.length;c<d;c++)a.call(this,this[c],c,this)&&b.push(this[c]);return new u(this.context,b)},flatten:function(){var a=[];return new u(this.context,a.concat.apply(a,this.toArray()))},join:w.join,indexOf:w.indexOf||function(a,b){for(var c=b||0,d=this.length;c<d;c++)if(this[c]===a)return c;return-1},iterator:function(a,b,c,d){var e=[],f,g,h,i,n,l=this.context,m,p,t=this.selector;"string"===typeof a&&(d=c,c=b,b=a,a=!1);g=0;for(h=l.length;g<h;g++){var s=new u(l[g]);if("table"===b)f=
100
+ c.call(s,l[g],g),f!==k&&e.push(f);else if("columns"===b||"rows"===b)f=c.call(s,l[g],this[g],g),f!==k&&e.push(f);else if("column"===b||"column-rows"===b||"row"===b||"cell"===b){p=this[g];"column-rows"===b&&(m=Da(l[g],t.opts));i=0;for(n=p.length;i<n;i++)f=p[i],f="cell"===b?c.call(s,l[g],f.row,f.column,g,i):c.call(s,l[g],f,g,i,m),f!==k&&e.push(f)}}return e.length||d?(a=new u(l,a?e.concat.apply([],e):e),b=a.selector,b.rows=t.rows,b.cols=t.cols,b.opts=t.opts,a):this},lastIndexOf:w.lastIndexOf||function(a,
101
+ b){return this.indexOf.apply(this.toArray.reverse(),arguments)},length:0,map:function(a){var b=[];if(w.map)b=w.map.call(this,a,this);else for(var c=0,d=this.length;c<d;c++)b.push(a.call(this,this[c],c));return new u(this.context,b)},pluck:function(a){return this.map(function(b){return b[a]})},pop:w.pop,push:w.push,reduce:w.reduce||function(a,b){return jb(this,a,b,0,this.length,1)},reduceRight:w.reduceRight||function(a,b){return jb(this,a,b,this.length-1,-1,-1)},reverse:w.reverse,selector:null,shift:w.shift,
102
+ sort:w.sort,splice:w.splice,toArray:function(){return w.slice.call(this)},to$:function(){return h(this)},toJQuery:function(){return h(this)},unique:function(){return new u(this.context,sa(this))},unshift:w.unshift});u.extend=function(a,b,c){if(c.length&&b&&(b instanceof u||b.__dt_wrapper)){var d,e,f,g=function(a,b,c){return function(){var d=b.apply(a,arguments);u.extend(d,d,c.methodExt);return d}};d=0;for(e=c.length;d<e;d++)f=c[d],b[f.name]="function"===typeof f.val?g(a,f.val,f):h.isPlainObject(f.val)?
103
+ {}:f.val,b[f.name].__dt_wrapper=!0,u.extend(a,b[f.name],f.propExt)}};u.register=p=function(a,b){if(h.isArray(a))for(var c=0,d=a.length;c<d;c++)u.register(a[c],b);else for(var e=a.split("."),f=Ub,g,j,c=0,d=e.length;c<d;c++){g=(j=-1!==e[c].indexOf("()"))?e[c].replace("()",""):e[c];var i;a:{i=0;for(var n=f.length;i<n;i++)if(f[i].name===g){i=f[i];break a}i=null}i||(i={name:g,val:{},methodExt:[],propExt:[]},f.push(i));c===d-1?i.val=b:f=j?i.methodExt:i.propExt}};u.registerPlural=t=function(a,b,c){u.register(a,
104
+ c);u.register(b,function(){var a=c.apply(this,arguments);return a===this?this:a instanceof u?a.length?h.isArray(a[0])?new u(a.context,a[0]):a[0]:k:a})};p("tables()",function(a){var b;if(a){b=u;var c=this.context;if("number"===typeof a)a=[c[a]];else var d=h.map(c,function(a){return a.nTable}),a=h(d).filter(a).map(function(){var a=h.inArray(this,d);return c[a]}).toArray();b=new b(a)}else b=this;return b});p("table()",function(a){var a=this.tables(a),b=a.context;return b.length?new u(b[0]):a});t("tables().nodes()",
105
+ "table().node()",function(){return this.iterator("table",function(a){return a.nTable},1)});t("tables().body()","table().body()",function(){return this.iterator("table",function(a){return a.nTBody},1)});t("tables().header()","table().header()",function(){return this.iterator("table",function(a){return a.nTHead},1)});t("tables().footer()","table().footer()",function(){return this.iterator("table",function(a){return a.nTFoot},1)});t("tables().containers()","table().container()",function(){return this.iterator("table",
106
+ function(a){return a.nTableWrapper},1)});p("draw()",function(a){return this.iterator("table",function(b){"page"===a?O(b):("string"===typeof a&&(a="full-hold"===a?!1:!0),T(b,!1===a))})});p("page()",function(a){return a===k?this.page.info().page:this.iterator("table",function(b){Va(b,a)})});p("page.info()",function(){if(0===this.context.length)return k;var a=this.context[0],b=a._iDisplayStart,c=a.oFeatures.bPaginate?a._iDisplayLength:-1,d=a.fnRecordsDisplay(),e=-1===c;return{page:e?0:Math.floor(b/c),
107
+ pages:e?1:Math.ceil(d/c),start:b,end:a.fnDisplayEnd(),length:c,recordsTotal:a.fnRecordsTotal(),recordsDisplay:d,serverSide:"ssp"===y(a)}});p("page.len()",function(a){return a===k?0!==this.context.length?this.context[0]._iDisplayLength:k:this.iterator("table",function(b){Ta(b,a)})});var Vb=function(a,b,c){if(c){var d=new u(a);d.one("draw",function(){c(d.ajax.json())})}if("ssp"==y(a))T(a,b);else{C(a,!0);var e=a.jqXHR;e&&4!==e.readyState&&e.abort();ua(a,[],function(c){pa(a);for(var c=va(a,c),d=0,e=c.length;d<
108
+ e;d++)N(a,c[d]);T(a,b);C(a,!1)})}};p("ajax.json()",function(){var a=this.context;if(0<a.length)return a[0].json});p("ajax.params()",function(){var a=this.context;if(0<a.length)return a[0].oAjaxData});p("ajax.reload()",function(a,b){return this.iterator("table",function(c){Vb(c,!1===b,a)})});p("ajax.url()",function(a){var b=this.context;if(a===k){if(0===b.length)return k;b=b[0];return b.ajax?h.isPlainObject(b.ajax)?b.ajax.url:b.ajax:b.sAjaxSource}return this.iterator("table",function(b){h.isPlainObject(b.ajax)?
109
+ b.ajax.url=a:b.ajax=a})});p("ajax.url().load()",function(a,b){return this.iterator("table",function(c){Vb(c,!1===b,a)})});var bb=function(a,b,c,d,e){var f=[],g,j,i,n,l,m;i=typeof b;if(!b||"string"===i||"function"===i||b.length===k)b=[b];i=0;for(n=b.length;i<n;i++){j=b[i]&&b[i].split&&!b[i].match(/[\[\(:]/)?b[i].split(","):[b[i]];l=0;for(m=j.length;l<m;l++)(g=c("string"===typeof j[l]?h.trim(j[l]):j[l]))&&g.length&&(f=f.concat(g))}a=x.selector[a];if(a.length){i=0;for(n=a.length;i<n;i++)f=a[i](d,e,f)}return sa(f)},
110
+ cb=function(a){a||(a={});a.filter&&a.search===k&&(a.search=a.filter);return h.extend({search:"none",order:"current",page:"all"},a)},db=function(a){for(var b=0,c=a.length;b<c;b++)if(0<a[b].length)return a[0]=a[b],a[0].length=1,a.length=1,a.context=[a.context[b]],a;a.length=0;return a},Da=function(a,b){var c,d,e,f=[],g=a.aiDisplay;c=a.aiDisplayMaster;var j=b.search;d=b.order;e=b.page;if("ssp"==y(a))return"removed"===j?[]:X(0,c.length);if("current"==e){c=a._iDisplayStart;for(d=a.fnDisplayEnd();c<d;c++)f.push(g[c])}else if("current"==
111
+ d||"applied"==d)f="none"==j?c.slice():"applied"==j?g.slice():h.map(c,function(a){return-1===h.inArray(a,g)?a:null});else if("index"==d||"original"==d){c=0;for(d=a.aoData.length;c<d;c++)"none"==j?f.push(c):(e=h.inArray(c,g),(-1===e&&"removed"==j||0<=e&&"applied"==j)&&f.push(c))}return f};p("rows()",function(a,b){a===k?a="":h.isPlainObject(a)&&(b=a,a="");var b=cb(b),c=this.iterator("table",function(c){var e=b,f;return bb("row",a,function(a){var b=Qb(a);if(b!==null&&!e)return[b];f||(f=Da(c,e));if(b!==
112
+ null&&h.inArray(b,f)!==-1)return[b];if(a===null||a===k||a==="")return f;if(typeof a==="function")return h.map(f,function(b){var e=c.aoData[b];return a(b,e._aData,e.nTr)?b:null});b=Tb(ja(c.aoData,f,"nTr"));if(a.nodeName){if(a._DT_RowIndex!==k)return[a._DT_RowIndex];if(a._DT_CellIndex)return[a._DT_CellIndex.row];b=h(a).closest("*[data-dt-row]");return b.length?[b.data("dt-row")]:[]}if(typeof a==="string"&&a.charAt(0)==="#"){var i=c.aIds[a.replace(/^#/,"")];if(i!==k)return[i.idx]}return h(b).filter(a).map(function(){return this._DT_RowIndex}).toArray()},
113
+ c,e)},1);c.selector.rows=a;c.selector.opts=b;return c});p("rows().nodes()",function(){return this.iterator("row",function(a,b){return a.aoData[b].nTr||k},1)});p("rows().data()",function(){return this.iterator(!0,"rows",function(a,b){return ja(a.aoData,b,"_aData")},1)});t("rows().cache()","row().cache()",function(a){return this.iterator("row",function(b,c){var d=b.aoData[c];return"search"===a?d._aFilterData:d._aSortData},1)});t("rows().invalidate()","row().invalidate()",function(a){return this.iterator("row",
114
+ function(b,c){da(b,c,a)})});t("rows().indexes()","row().index()",function(){return this.iterator("row",function(a,b){return b},1)});t("rows().ids()","row().id()",function(a){for(var b=[],c=this.context,d=0,e=c.length;d<e;d++)for(var f=0,g=this[d].length;f<g;f++){var h=c[d].rowIdFn(c[d].aoData[this[d][f]]._aData);b.push((!0===a?"#":"")+h)}return new u(c,b)});t("rows().remove()","row().remove()",function(){var a=this;this.iterator("row",function(b,c,d){var e=b.aoData,f=e[c],g,h,i,n,l;e.splice(c,1);
115
+ g=0;for(h=e.length;g<h;g++)if(i=e[g],l=i.anCells,null!==i.nTr&&(i.nTr._DT_RowIndex=g),null!==l){i=0;for(n=l.length;i<n;i++)l[i]._DT_CellIndex.row=g}qa(b.aiDisplayMaster,c);qa(b.aiDisplay,c);qa(a[d],c,!1);Ua(b);c=b.rowIdFn(f._aData);c!==k&&delete b.aIds[c]});this.iterator("table",function(a){for(var c=0,d=a.aoData.length;c<d;c++)a.aoData[c].idx=c});return this});p("rows.add()",function(a){var b=this.iterator("table",function(b){var c,f,g,h=[];f=0;for(g=a.length;f<g;f++)c=a[f],c.nodeName&&"TR"===c.nodeName.toUpperCase()?
116
+ h.push(oa(b,c)[0]):h.push(N(b,c));return h},1),c=this.rows(-1);c.pop();h.merge(c,b);return c});p("row()",function(a,b){return db(this.rows(a,b))});p("row().data()",function(a){var b=this.context;if(a===k)return b.length&&this.length?b[0].aoData[this[0]]._aData:k;b[0].aoData[this[0]]._aData=a;da(b[0],this[0],"data");return this});p("row().node()",function(){var a=this.context;return a.length&&this.length?a[0].aoData[this[0]].nTr||null:null});p("row.add()",function(a){a instanceof h&&a.length&&(a=a[0]);
117
+ var b=this.iterator("table",function(b){return a.nodeName&&"TR"===a.nodeName.toUpperCase()?oa(b,a)[0]:N(b,a)});return this.row(b[0])});var eb=function(a,b){var c=a.context;if(c.length&&(c=c[0].aoData[b!==k?b:a[0]])&&c._details)c._details.remove(),c._detailsShow=k,c._details=k},Wb=function(a,b){var c=a.context;if(c.length&&a.length){var d=c[0].aoData[a[0]];if(d._details){(d._detailsShow=b)?d._details.insertAfter(d.nTr):d._details.detach();var e=c[0],f=new u(e),g=e.aoData;f.off("draw.dt.DT_details column-visibility.dt.DT_details destroy.dt.DT_details");
118
+ 0<D(g,"_details").length&&(f.on("draw.dt.DT_details",function(a,b){e===b&&f.rows({page:"current"}).eq(0).each(function(a){a=g[a];a._detailsShow&&a._details.insertAfter(a.nTr)})}),f.on("column-visibility.dt.DT_details",function(a,b){if(e===b)for(var c,d=ba(b),f=0,h=g.length;f<h;f++)c=g[f],c._details&&c._details.children("td[colspan]").attr("colspan",d)}),f.on("destroy.dt.DT_details",function(a,b){if(e===b)for(var c=0,d=g.length;c<d;c++)g[c]._details&&eb(f,c)}))}}};p("row().child()",function(a,b){var c=
119
+ this.context;if(a===k)return c.length&&this.length?c[0].aoData[this[0]]._details:k;if(!0===a)this.child.show();else if(!1===a)eb(this);else if(c.length&&this.length){var d=c[0],c=c[0].aoData[this[0]],e=[],f=function(a,b){if(h.isArray(a)||a instanceof h)for(var c=0,k=a.length;c<k;c++)f(a[c],b);else a.nodeName&&"tr"===a.nodeName.toLowerCase()?e.push(a):(c=h("<tr><td/></tr>").addClass(b),h("td",c).addClass(b).html(a)[0].colSpan=ba(d),e.push(c[0]))};f(a,b);c._details&&c._details.detach();c._details=h(e);
120
+ c._detailsShow&&c._details.insertAfter(c.nTr)}return this});p(["row().child.show()","row().child().show()"],function(){Wb(this,!0);return this});p(["row().child.hide()","row().child().hide()"],function(){Wb(this,!1);return this});p(["row().child.remove()","row().child().remove()"],function(){eb(this);return this});p("row().child.isShown()",function(){var a=this.context;return a.length&&this.length?a[0].aoData[this[0]]._detailsShow||!1:!1});var fc=/^([^:]+):(name|visIdx|visible)$/,Xb=function(a,b,
121
+ c,d,e){for(var c=[],d=0,f=e.length;d<f;d++)c.push(B(a,e[d],b));return c};p("columns()",function(a,b){a===k?a="":h.isPlainObject(a)&&(b=a,a="");var b=cb(b),c=this.iterator("table",function(c){var e=a,f=b,g=c.aoColumns,j=D(g,"sName"),i=D(g,"nTh");return bb("column",e,function(a){var b=Qb(a);if(a==="")return X(g.length);if(b!==null)return[b>=0?b:g.length+b];if(typeof a==="function"){var e=Da(c,f);return h.map(g,function(b,f){return a(f,Xb(c,f,0,0,e),i[f])?f:null})}var k=typeof a==="string"?a.match(fc):
122
+ "";if(k)switch(k[2]){case "visIdx":case "visible":b=parseInt(k[1],10);if(b<0){var m=h.map(g,function(a,b){return a.bVisible?b:null});return[m[m.length+b]]}return[$(c,b)];case "name":return h.map(j,function(a,b){return a===k[1]?b:null});default:return[]}if(a.nodeName&&a._DT_CellIndex)return[a._DT_CellIndex.column];b=h(i).filter(a).map(function(){return h.inArray(this,i)}).toArray();if(b.length||!a.nodeName)return b;b=h(a).closest("*[data-dt-column]");return b.length?[b.data("dt-column")]:[]},c,f)},
123
+ 1);c.selector.cols=a;c.selector.opts=b;return c});t("columns().header()","column().header()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].nTh},1)});t("columns().footer()","column().footer()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].nTf},1)});t("columns().data()","column().data()",function(){return this.iterator("column-rows",Xb,1)});t("columns().dataSrc()","column().dataSrc()",function(){return this.iterator("column",function(a,b){return a.aoColumns[b].mData},
124
+ 1)});t("columns().cache()","column().cache()",function(a){return this.iterator("column-rows",function(b,c,d,e,f){return ja(b.aoData,f,"search"===a?"_aFilterData":"_aSortData",c)},1)});t("columns().nodes()","column().nodes()",function(){return this.iterator("column-rows",function(a,b,c,d,e){return ja(a.aoData,e,"anCells",b)},1)});t("columns().visible()","column().visible()",function(a,b){var c=this.iterator("column",function(b,c){if(a===k)return b.aoColumns[c].bVisible;var f=b.aoColumns,g=f[c],j=b.aoData,
125
+ i,n,l;if(a!==k&&g.bVisible!==a){if(a){var m=h.inArray(!0,D(f,"bVisible"),c+1);i=0;for(n=j.length;i<n;i++)l=j[i].nTr,f=j[i].anCells,l&&l.insertBefore(f[c],f[m]||null)}else h(D(b.aoData,"anCells",c)).detach();g.bVisible=a;fa(b,b.aoHeader);fa(b,b.aoFooter);za(b)}});a!==k&&(this.iterator("column",function(c,e){s(c,null,"column-visibility",[c,e,a,b])}),(b===k||b)&&this.columns.adjust());return c});t("columns().indexes()","column().index()",function(a){return this.iterator("column",function(b,c){return"visible"===
126
+ a?aa(b,c):c},1)});p("columns.adjust()",function(){return this.iterator("table",function(a){Z(a)},1)});p("column.index()",function(a,b){if(0!==this.context.length){var c=this.context[0];if("fromVisible"===a||"toData"===a)return $(c,b);if("fromData"===a||"toVisible"===a)return aa(c,b)}});p("column()",function(a,b){return db(this.columns(a,b))});p("cells()",function(a,b,c){h.isPlainObject(a)&&(a.row===k?(c=a,a=null):(c=b,b=null));h.isPlainObject(b)&&(c=b,b=null);if(null===b||b===k)return this.iterator("table",
127
+ function(b){var d=a,e=cb(c),f=b.aoData,g=Da(b,e),i=Tb(ja(f,g,"anCells")),j=h([].concat.apply([],i)),l,n=b.aoColumns.length,m,p,t,u,s,v;return bb("cell",d,function(a){var c=typeof a==="function";if(a===null||a===k||c){m=[];p=0;for(t=g.length;p<t;p++){l=g[p];for(u=0;u<n;u++){s={row:l,column:u};if(c){v=f[l];a(s,B(b,l,u),v.anCells?v.anCells[u]:null)&&m.push(s)}else m.push(s)}}return m}if(h.isPlainObject(a))return[a];c=j.filter(a).map(function(a,b){return{row:b._DT_CellIndex.row,column:b._DT_CellIndex.column}}).toArray();
128
+ if(c.length||!a.nodeName)return c;v=h(a).closest("*[data-dt-row]");return v.length?[{row:v.data("dt-row"),column:v.data("dt-column")}]:[]},b,e)});var d=this.columns(b,c),e=this.rows(a,c),f,g,j,i,n,l=this.iterator("table",function(a,b){f=[];g=0;for(j=e[b].length;g<j;g++){i=0;for(n=d[b].length;i<n;i++)f.push({row:e[b][g],column:d[b][i]})}return f},1);h.extend(l.selector,{cols:b,rows:a,opts:c});return l});t("cells().nodes()","cell().node()",function(){return this.iterator("cell",function(a,b,c){return(a=
129
+ a.aoData[b])&&a.anCells?a.anCells[c]:k},1)});p("cells().data()",function(){return this.iterator("cell",function(a,b,c){return B(a,b,c)},1)});t("cells().cache()","cell().cache()",function(a){a="search"===a?"_aFilterData":"_aSortData";return this.iterator("cell",function(b,c,d){return b.aoData[c][a][d]},1)});t("cells().render()","cell().render()",function(a){return this.iterator("cell",function(b,c,d){return B(b,c,d,a)},1)});t("cells().indexes()","cell().index()",function(){return this.iterator("cell",
130
+ function(a,b,c){return{row:b,column:c,columnVisible:aa(a,c)}},1)});t("cells().invalidate()","cell().invalidate()",function(a){return this.iterator("cell",function(b,c,d){da(b,c,a,d)})});p("cell()",function(a,b,c){return db(this.cells(a,b,c))});p("cell().data()",function(a){var b=this.context,c=this[0];if(a===k)return b.length&&c.length?B(b[0],c[0].row,c[0].column):k;lb(b[0],c[0].row,c[0].column,a);da(b[0],c[0].row,"data",c[0].column);return this});p("order()",function(a,b){var c=this.context;if(a===
131
+ k)return 0!==c.length?c[0].aaSorting:k;"number"===typeof a?a=[[a,b]]:a.length&&!h.isArray(a[0])&&(a=Array.prototype.slice.call(arguments));return this.iterator("table",function(b){b.aaSorting=a.slice()})});p("order.listener()",function(a,b,c){return this.iterator("table",function(d){Oa(d,a,b,c)})});p("order.fixed()",function(a){if(!a){var b=this.context,b=b.length?b[0].aaSortingFixed:k;return h.isArray(b)?{pre:b}:b}return this.iterator("table",function(b){b.aaSortingFixed=h.extend(!0,{},a)})});p(["columns().order()",
132
+ "column().order()"],function(a){var b=this;return this.iterator("table",function(c,d){var e=[];h.each(b[d],function(b,c){e.push([c,a])});c.aaSorting=e})});p("search()",function(a,b,c,d){var e=this.context;return a===k?0!==e.length?e[0].oPreviousSearch.sSearch:k:this.iterator("table",function(e){e.oFeatures.bFilter&&ga(e,h.extend({},e.oPreviousSearch,{sSearch:a+"",bRegex:null===b?!1:b,bSmart:null===c?!0:c,bCaseInsensitive:null===d?!0:d}),1)})});t("columns().search()","column().search()",function(a,
133
+ b,c,d){return this.iterator("column",function(e,f){var g=e.aoPreSearchCols;if(a===k)return g[f].sSearch;e.oFeatures.bFilter&&(h.extend(g[f],{sSearch:a+"",bRegex:null===b?!1:b,bSmart:null===c?!0:c,bCaseInsensitive:null===d?!0:d}),ga(e,e.oPreviousSearch,1))})});p("state()",function(){return this.context.length?this.context[0].oSavedState:null});p("state.clear()",function(){return this.iterator("table",function(a){a.fnStateSaveCallback.call(a.oInstance,a,{})})});p("state.loaded()",function(){return this.context.length?
134
+ this.context[0].oLoadedState:null});p("state.save()",function(){return this.iterator("table",function(a){za(a)})});m.versionCheck=m.fnVersionCheck=function(a){for(var b=m.version.split("."),a=a.split("."),c,d,e=0,f=a.length;e<f;e++)if(c=parseInt(b[e],10)||0,d=parseInt(a[e],10)||0,c!==d)return c>d;return!0};m.isDataTable=m.fnIsDataTable=function(a){var b=h(a).get(0),c=!1;if(a instanceof m.Api)return!0;h.each(m.settings,function(a,e){var f=e.nScrollHead?h("table",e.nScrollHead)[0]:null,g=e.nScrollFoot?
135
+ h("table",e.nScrollFoot)[0]:null;if(e.nTable===b||f===b||g===b)c=!0});return c};m.tables=m.fnTables=function(a){var b=!1;h.isPlainObject(a)&&(b=a.api,a=a.visible);var c=h.map(m.settings,function(b){if(!a||a&&h(b.nTable).is(":visible"))return b.nTable});return b?new u(c):c};m.camelToHungarian=J;p("$()",function(a,b){var c=this.rows(b).nodes(),c=h(c);return h([].concat(c.filter(a).toArray(),c.find(a).toArray()))});h.each(["on","one","off"],function(a,b){p(b+"()",function(){var a=Array.prototype.slice.call(arguments);
136
+ a[0]=h.map(a[0].split(/\s/),function(a){return!a.match(/\.dt\b/)?a+".dt":a}).join(" ");var d=h(this.tables().nodes());d[b].apply(d,a);return this})});p("clear()",function(){return this.iterator("table",function(a){pa(a)})});p("settings()",function(){return new u(this.context,this.context)});p("init()",function(){var a=this.context;return a.length?a[0].oInit:null});p("data()",function(){return this.iterator("table",function(a){return D(a.aoData,"_aData")}).flatten()});p("destroy()",function(a){a=a||
137
+ !1;return this.iterator("table",function(b){var c=b.nTableWrapper.parentNode,d=b.oClasses,e=b.nTable,f=b.nTBody,g=b.nTHead,j=b.nTFoot,i=h(e),f=h(f),k=h(b.nTableWrapper),l=h.map(b.aoData,function(a){return a.nTr}),p;b.bDestroying=!0;s(b,"aoDestroyCallback","destroy",[b]);a||(new u(b)).columns().visible(!0);k.off(".DT").find(":not(tbody *)").off(".DT");h(E).off(".DT-"+b.sInstance);e!=g.parentNode&&(i.children("thead").detach(),i.append(g));j&&e!=j.parentNode&&(i.children("tfoot").detach(),i.append(j));
138
+ b.aaSorting=[];b.aaSortingFixed=[];ya(b);h(l).removeClass(b.asStripeClasses.join(" "));h("th, td",g).removeClass(d.sSortable+" "+d.sSortableAsc+" "+d.sSortableDesc+" "+d.sSortableNone);b.bJUI&&(h("th span."+d.sSortIcon+", td span."+d.sSortIcon,g).detach(),h("th, td",g).each(function(){var a=h("div."+d.sSortJUIWrapper,this);h(this).append(a.contents());a.detach()}));f.children().detach();f.append(l);g=a?"remove":"detach";i[g]();k[g]();!a&&c&&(c.insertBefore(e,b.nTableReinsertBefore),i.css("width",
139
+ b.sDestroyWidth).removeClass(d.sTable),(p=b.asDestroyStripes.length)&&f.children().each(function(a){h(this).addClass(b.asDestroyStripes[a%p])}));c=h.inArray(b,m.settings);-1!==c&&m.settings.splice(c,1)})});h.each(["column","row","cell"],function(a,b){p(b+"s().every()",function(a){var d=this.selector.opts,e=this;return this.iterator(b,function(f,g,h,i,m){a.call(e[b](g,"cell"===b?h:d,"cell"===b?d:k),g,h,i,m)})})});p("i18n()",function(a,b,c){var d=this.context[0],a=R(a)(d.oLanguage);a===k&&(a=b);c!==
140
+ k&&h.isPlainObject(a)&&(a=a[c]!==k?a[c]:a._);return a.replace("%d",c)});m.version="1.10.13";m.settings=[];m.models={};m.models.oSearch={bCaseInsensitive:!0,sSearch:"",bRegex:!1,bSmart:!0};m.models.oRow={nTr:null,anCells:null,_aData:[],_aSortData:null,_aFilterData:null,_sFilterRow:null,_sRowStripe:"",src:null,idx:-1};m.models.oColumn={idx:null,aDataSort:null,asSorting:null,bSearchable:null,bSortable:null,bVisible:null,_sManualType:null,_bAttrSrc:!1,fnCreatedCell:null,fnGetData:null,fnSetData:null,
141
+ mData:null,mRender:null,nTh:null,nTf:null,sClass:null,sContentPadding:null,sDefaultContent:null,sName:null,sSortDataType:"std",sSortingClass:null,sSortingClassJUI:null,sTitle:null,sType:null,sWidth:null,sWidthOrig:null};m.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:[],ajax:null,aLengthMenu:[10,25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],asStripeClasses:null,bAutoWidth:!0,bDeferRender:!1,bDestroy:!1,bFilter:!0,bInfo:!0,bJQueryUI:!1,bLengthChange:!0,bPaginate:!0,bProcessing:!1,
142
+ bRetrieve:!1,bScrollCollapse:!1,bServerSide:!1,bSort:!0,bSortMulti:!0,bSortCellsTop:!1,bSortClasses:!0,bStateSave:!1,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,fnFormatNumber:function(a){return a.toString().replace(/\B(?=(\d{3})+(?!\d))/g,this.oLanguage.sThousands)},fnHeaderCallback:null,fnInfoCallback:null,fnInitComplete:null,fnPreDrawCallback:null,fnRowCallback:null,fnServerData:null,fnServerParams:null,fnStateLoadCallback:function(a){try{return JSON.parse((-1===a.iStateDuration?
143
+ sessionStorage:localStorage).getItem("DataTables_"+a.sInstance+"_"+location.pathname))}catch(b){}},fnStateLoadParams:null,fnStateLoaded:null,fnStateSaveCallback:function(a,b){try{(-1===a.iStateDuration?sessionStorage:localStorage).setItem("DataTables_"+a.sInstance+"_"+location.pathname,JSON.stringify(b))}catch(c){}},fnStateSaveParams:null,iStateDuration:7200,iDeferLoading:null,iDisplayLength:10,iDisplayStart:0,iTabIndex:0,oClasses:{},oLanguage:{oAria:{sSortAscending:": activate to sort column ascending",
144
+ sSortDescending:": activate to sort column descending"},oPaginate:{sFirst:"First",sLast:"Last",sNext:"Next",sPrevious:"Previous"},sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sDecimal:"",sThousands:",",sLengthMenu:"Show _MENU_ entries",sLoadingRecords:"Loading...",sProcessing:"Processing...",sSearch:"Search:",sSearchPlaceholder:"",sUrl:"",sZeroRecords:"No matching records found"},
145
+ oSearch:h.extend({},m.models.oSearch),sAjaxDataProp:"data",sAjaxSource:null,sDom:"lfrtip",searchDelay:null,sPaginationType:"simple_numbers",sScrollX:"",sScrollXInner:"",sScrollY:"",sServerMethod:"GET",renderer:null,rowId:"DT_RowId"};Y(m.defaults);m.defaults.column={aDataSort:null,iDataSort:-1,asSorting:["asc","desc"],bSearchable:!0,bSortable:!0,bVisible:!0,fnCreatedCell:null,mData:null,mRender:null,sCellType:"td",sClass:"",sContentPadding:"",sDefaultContent:null,sName:"",sSortDataType:"std",sTitle:null,
146
+ sType:null,sWidth:null};Y(m.defaults.column);m.models.oSettings={oFeatures:{bAutoWidth:null,bDeferRender:null,bFilter:null,bInfo:null,bLengthChange:null,bPaginate:null,bProcessing:null,bServerSide:null,bSort:null,bSortMulti:null,bSortClasses:null,bStateSave:null},oScroll:{bCollapse:null,iBarWidth:0,sX:null,sXInner:null,sY:null},oLanguage:{fnInfoCallback:null},oBrowser:{bScrollOversize:!1,bScrollbarLeft:!1,bBounding:!1,barWidth:0},ajax:null,aanFeatures:[],aoData:[],aiDisplay:[],aiDisplayMaster:[],
147
+ aIds:{},aoColumns:[],aoHeader:[],aoFooter:[],oPreviousSearch:{},aoPreSearchCols:[],aaSorting:null,aaSortingFixed:[],asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],aoFooterCallback:[],aoDrawCallback:[],aoRowCreatedCallback:[],aoPreDrawCallback:[],aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:!1,bInitialised:!1,aoOpenRows:[],sDom:null,
148
+ searchDelay:null,sPaginationType:"two_button",iStateDuration:0,aoStateSave:[],aoStateLoad:[],oSavedState:null,oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,bAjaxDataGet:!0,jqXHR:null,json:k,oAjaxData:k,fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0,bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iRecordsTotal:0,_iRecordsDisplay:0,bJUI:null,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],
149
+ fnRecordsTotal:function(){return"ssp"==y(this)?1*this._iRecordsTotal:this.aiDisplayMaster.length},fnRecordsDisplay:function(){return"ssp"==y(this)?1*this._iRecordsDisplay:this.aiDisplay.length},fnDisplayEnd:function(){var a=this._iDisplayLength,b=this._iDisplayStart,c=b+a,d=this.aiDisplay.length,e=this.oFeatures,f=e.bPaginate;return e.bServerSide?!1===f||-1===a?b+d:Math.min(b+a,this._iRecordsDisplay):!f||c>d||-1===a?d:c},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null,
150
+ aLastSort:[],oPlugins:{},rowIdFn:null,rowId:null};m.ext=x={buttons:{},classes:{},builder:"-source-",errMode:"alert",feature:[],search:[],selector:{cell:[],column:[],row:[]},internal:{},legacy:{ajax:null},pager:{},renderer:{pageButton:{},header:{}},order:{},type:{detect:[],search:{},order:{}},_unique:0,fnVersionCheck:m.fnVersionCheck,iApiIndex:0,oJUIClasses:{},sVersion:m.version};h.extend(x,{afnFiltering:x.search,aTypes:x.type.detect,ofnSearch:x.type.search,oSort:x.type.order,afnSortData:x.order,aoFeatures:x.feature,
151
+ oApi:x.internal,oStdClasses:x.classes,oPagination:x.pager});h.extend(m.ext.classes,{sTable:"dataTable",sNoFooter:"no-footer",sPageButton:"paginate_button",sPageButtonActive:"current",sPageButtonDisabled:"disabled",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",
152
+ sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",sSortableDesc:"sorting_desc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sFilterInput:"",sLengthSelect:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sHeaderTH:"",sFooterTH:"",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",
153
+ sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"",sJUIHeader:"",sJUIFooter:""});var Ea="",Ea="",G=Ea+"ui-state-default",ka=Ea+"css_right ui-icon ui-icon-",Yb=Ea+"fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix";h.extend(m.ext.oJUIClasses,m.ext.classes,{sPageButton:"fg-button ui-button "+G,sPageButtonActive:"ui-state-disabled",sPageButtonDisabled:"ui-state-disabled",sPaging:"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",sSortAsc:G+" sorting_asc",
154
+ sSortDesc:G+" sorting_desc",sSortable:G+" sorting",sSortableAsc:G+" sorting_asc_disabled",sSortableDesc:G+" sorting_desc_disabled",sSortableNone:G+" sorting_disabled",sSortJUIAsc:ka+"triangle-1-n",sSortJUIDesc:ka+"triangle-1-s",sSortJUI:ka+"carat-2-n-s",sSortJUIAscAllowed:ka+"carat-1-n",sSortJUIDescAllowed:ka+"carat-1-s",sSortJUIWrapper:"DataTables_sort_wrapper",sSortIcon:"DataTables_sort_icon",sScrollHead:"dataTables_scrollHead "+G,sScrollFoot:"dataTables_scrollFoot "+G,sHeaderTH:G,sFooterTH:G,sJUIHeader:Yb+
155
+ " ui-corner-tl ui-corner-tr",sJUIFooter:Yb+" ui-corner-bl ui-corner-br"});var Nb=m.ext.pager;h.extend(Nb,{simple:function(){return["previous","next"]},full:function(){return["first","previous","next","last"]},numbers:function(a,b){return[ia(a,b)]},simple_numbers:function(a,b){return["previous",ia(a,b),"next"]},full_numbers:function(a,b){return["first","previous",ia(a,b),"next","last"]},first_last_numbers:function(a,b){return["first",ia(a,b),"last"]},_numbers:ia,numbers_length:7});h.extend(!0,m.ext.renderer,
156
+ {pageButton:{_:function(a,b,c,d,e,f){var g=a.oClasses,j=a.oLanguage.oPaginate,i=a.oLanguage.oAria.paginate||{},m,l,p=0,r=function(b,d){var k,t,u,s,v=function(b){Va(a,b.data.action,true)};k=0;for(t=d.length;k<t;k++){s=d[k];if(h.isArray(s)){u=h("<"+(s.DT_el||"div")+"/>").appendTo(b);r(u,s)}else{m=null;l="";switch(s){case "ellipsis":b.append('<span class="ellipsis">&#x2026;</span>');break;case "first":m=j.sFirst;l=s+(e>0?"":" "+g.sPageButtonDisabled);break;case "previous":m=j.sPrevious;l=s+(e>0?"":" "+
157
+ g.sPageButtonDisabled);break;case "next":m=j.sNext;l=s+(e<f-1?"":" "+g.sPageButtonDisabled);break;case "last":m=j.sLast;l=s+(e<f-1?"":" "+g.sPageButtonDisabled);break;default:m=s+1;l=e===s?g.sPageButtonActive:""}if(m!==null){u=h("<a>",{"class":g.sPageButton+" "+l,"aria-controls":a.sTableId,"aria-label":i[s],"data-dt-idx":p,tabindex:a.iTabIndex,id:c===0&&typeof s==="string"?a.sTableId+"_"+s:null}).html(m).appendTo(b);Ya(u,{action:s},v);p++}}}},t;try{t=h(b).find(H.activeElement).data("dt-idx")}catch(u){}r(h(b).empty(),
158
+ d);t!==k&&h(b).find("[data-dt-idx="+t+"]").focus()}}});h.extend(m.ext.type.detect,[function(a,b){var c=b.oLanguage.sDecimal;return ab(a,c)?"num"+c:null},function(a){if(a&&!(a instanceof Date)&&!cc.test(a))return null;var b=Date.parse(a);return null!==b&&!isNaN(b)||M(a)?"date":null},function(a,b){var c=b.oLanguage.sDecimal;return ab(a,c,!0)?"num-fmt"+c:null},function(a,b){var c=b.oLanguage.sDecimal;return Sb(a,c)?"html-num"+c:null},function(a,b){var c=b.oLanguage.sDecimal;return Sb(a,c,!0)?"html-num-fmt"+
159
+ c:null},function(a){return M(a)||"string"===typeof a&&-1!==a.indexOf("<")?"html":null}]);h.extend(m.ext.type.search,{html:function(a){return M(a)?a:"string"===typeof a?a.replace(Pb," ").replace(Ca,""):""},string:function(a){return M(a)?a:"string"===typeof a?a.replace(Pb," "):a}});var Ba=function(a,b,c,d){if(0!==a&&(!a||"-"===a))return-Infinity;b&&(a=Rb(a,b));a.replace&&(c&&(a=a.replace(c,"")),d&&(a=a.replace(d,"")));return 1*a};h.extend(x.type.order,{"date-pre":function(a){return Date.parse(a)||-Infinity},
160
+ "html-pre":function(a){return M(a)?"":a.replace?a.replace(/<.*?>/g,"").toLowerCase():a+""},"string-pre":function(a){return M(a)?"":"string"===typeof a?a.toLowerCase():!a.toString?"":a.toString()},"string-asc":function(a,b){return a<b?-1:a>b?1:0},"string-desc":function(a,b){return a<b?1:a>b?-1:0}});fb("");h.extend(!0,m.ext.renderer,{header:{_:function(a,b,c,d){h(a.nTable).on("order.dt.DT",function(e,f,g,h){if(a===f){e=c.idx;b.removeClass(c.sSortingClass+" "+d.sSortAsc+" "+d.sSortDesc).addClass(h[e]==
161
+ "asc"?d.sSortAsc:h[e]=="desc"?d.sSortDesc:c.sSortingClass)}})},jqueryui:function(a,b,c,d){h("<div/>").addClass(d.sSortJUIWrapper).append(b.contents()).append(h("<span/>").addClass(d.sSortIcon+" "+c.sSortingClassJUI)).appendTo(b);h(a.nTable).on("order.dt.DT",function(e,f,g,h){if(a===f){e=c.idx;b.removeClass(d.sSortAsc+" "+d.sSortDesc).addClass(h[e]=="asc"?d.sSortAsc:h[e]=="desc"?d.sSortDesc:c.sSortingClass);b.find("span."+d.sSortIcon).removeClass(d.sSortJUIAsc+" "+d.sSortJUIDesc+" "+d.sSortJUI+" "+
162
+ d.sSortJUIAscAllowed+" "+d.sSortJUIDescAllowed).addClass(h[e]=="asc"?d.sSortJUIAsc:h[e]=="desc"?d.sSortJUIDesc:c.sSortingClassJUI)}})}}});var Zb=function(a){return"string"===typeof a?a.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):a};m.render={number:function(a,b,c,d,e){return{display:function(f){if("number"!==typeof f&&"string"!==typeof f)return f;var g=0>f?"-":"",h=parseFloat(f);if(isNaN(h))return Zb(f);h=h.toFixed(c);f=Math.abs(h);h=parseInt(f,10);f=c?b+(f-h).toFixed(c).substring(2):
163
+ "";return g+(d||"")+h.toString().replace(/\B(?=(\d{3})+(?!\d))/g,a)+f+(e||"")}}},text:function(){return{display:Zb}}};h.extend(m.ext.internal,{_fnExternApiFunc:Ob,_fnBuildAjax:ua,_fnAjaxUpdate:nb,_fnAjaxParameters:wb,_fnAjaxUpdateDraw:xb,_fnAjaxDataSrc:va,_fnAddColumn:Ga,_fnColumnOptions:la,_fnAdjustColumnSizing:Z,_fnVisibleToColumnIndex:$,_fnColumnIndexToVisible:aa,_fnVisbleColumns:ba,_fnGetColumns:na,_fnColumnTypes:Ia,_fnApplyColumnDefs:kb,_fnHungarianMap:Y,_fnCamelToHungarian:J,_fnLanguageCompat:Fa,
164
+ _fnBrowserDetect:ib,_fnAddData:N,_fnAddTr:oa,_fnNodeToDataIndex:function(a,b){return b._DT_RowIndex!==k?b._DT_RowIndex:null},_fnNodeToColumnIndex:function(a,b,c){return h.inArray(c,a.aoData[b].anCells)},_fnGetCellData:B,_fnSetCellData:lb,_fnSplitObjNotation:La,_fnGetObjectDataFn:R,_fnSetObjectDataFn:S,_fnGetDataMaster:Ma,_fnClearTable:pa,_fnDeleteIndex:qa,_fnInvalidate:da,_fnGetRowElements:Ka,_fnCreateTr:Ja,_fnBuildHead:mb,_fnDrawHead:fa,_fnDraw:O,_fnReDraw:T,_fnAddOptionsHtml:pb,_fnDetectHeader:ea,
165
+ _fnGetUniqueThs:ta,_fnFeatureHtmlFilter:rb,_fnFilterComplete:ga,_fnFilterCustom:Ab,_fnFilterColumn:zb,_fnFilter:yb,_fnFilterCreateSearch:Ra,_fnEscapeRegex:Sa,_fnFilterData:Bb,_fnFeatureHtmlInfo:ub,_fnUpdateInfo:Eb,_fnInfoMacros:Fb,_fnInitialise:ha,_fnInitComplete:wa,_fnLengthChange:Ta,_fnFeatureHtmlLength:qb,_fnFeatureHtmlPaginate:vb,_fnPageChange:Va,_fnFeatureHtmlProcessing:sb,_fnProcessingDisplay:C,_fnFeatureHtmlTable:tb,_fnScrollDraw:ma,_fnApplyToChildren:I,_fnCalculateColumnWidths:Ha,_fnThrottle:Qa,
166
+ _fnConvertToWidth:Gb,_fnGetWidestNode:Hb,_fnGetMaxLenString:Ib,_fnStringToCss:v,_fnSortFlatten:W,_fnSort:ob,_fnSortAria:Kb,_fnSortListener:Xa,_fnSortAttachListener:Oa,_fnSortingClasses:ya,_fnSortData:Jb,_fnSaveState:za,_fnLoadState:Lb,_fnSettingsFromNode:Aa,_fnLog:K,_fnMap:F,_fnBindAction:Ya,_fnCallbackReg:z,_fnCallbackFire:s,_fnLengthOverflow:Ua,_fnRenderer:Pa,_fnDataSource:y,_fnRowAttributes:Na,_fnCalculateEnd:function(){}});h.fn.dataTable=m;m.$=h;h.fn.dataTableSettings=m.settings;h.fn.dataTableExt=
167
+ m.ext;h.fn.DataTable=function(a){return h(this).dataTable(a).api()};h.each(m,function(a,b){h.fn.DataTable[a]=b});return h.fn.dataTable});
admin/js/materialize.clockpicker.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(){function t(t){return document.createElementNS(r,t)}function i(t){return(t<10?"0":"")+t}function e(t){var i=++v+"";return t?t+i:i}function s(s,n){function r(t,i){var e=h.offset(),s=/^touch/.test(t.type),o=e.left+f,c=e.top+f,r=(s?t.originalEvent.touches[0]:t).pageX-o,l=(s?t.originalEvent.touches[0]:t).pageY-c,u=Math.sqrt(r*r+l*l),m=!1;if(!i||!(u<b-w||u>b+w)){t.preventDefault();var v=setTimeout(function(){V.popover.addClass("clockpicker-moving")},200);p&&h.append(V.canvas),V.setHand(r,l,!i,!0),a.off(d).on(d,function(t){t.preventDefault();var i=/^touch/.test(t.type),e=(i?t.originalEvent.touches[0]:t).pageX-o,s=(i?t.originalEvent.touches[0]:t).pageY-c;(m||e!==r||s!==l)&&(m=!0,V.setHand(e,s,!1,!0))}),a.off(k).on(k,function(t){a.off(k),t.preventDefault();var e=/^touch/.test(t.type),s=(e?t.originalEvent.changedTouches[0]:t).pageX-o,p=(e?t.originalEvent.changedTouches[0]:t).pageY-c;(i||m)&&s===r&&p===l&&V.setHand(s,p),"hours"===V.currentView?V.toggleView("minutes",A/2):n.autoclose&&(V.minutesView.addClass("clockpicker-dial-out"),setTimeout(function(){V.done()},A/2)),h.prepend(z),clearTimeout(v),V.popover.removeClass("clockpicker-moving"),a.off(d)})}}var l=c(M),h=l.find(".clockpicker-plate"),m=l.find(".picker__holder"),v=l.find(".clockpicker-hours"),P=l.find(".clockpicker-minutes"),C=l.find(".clockpicker-am-pm-block"),x="INPUT"===s.prop("tagName"),T=x?s:s.find("input"),_=c("label[for="+T.attr("id")+"]"),V=this;if(this.id=e("cp"),this.element=s,this.holder=m,this.options=n,this.isAppended=!1,this.isShown=!1,this.currentView="hours",this.isInput=x,this.input=T,this.label=_,this.popover=l,this.plate=h,this.hoursView=v,this.minutesView=P,this.amPmBlock=C,this.spanHours=l.find(".clockpicker-span-hours"),this.spanMinutes=l.find(".clockpicker-span-minutes"),this.spanAmPm=l.find(".clockpicker-span-am-pm"),this.footer=l.find(".picker__footer"),this.amOrPm="PM",n.twelvehour){var H=['<div class="clockpicker-am-pm-block">','<button type="button" class="btn-floating btn-flat clockpicker-button clockpicker-am-button">',"AM","</button>",'<button type="button" class="btn-floating btn-flat clockpicker-button clockpicker-pm-button">',"PM","</button>","</div>"].join("");c(H);n.ampmclickable?(this.spanAmPm.empty(),c('<div id="click-am">AM</div>').on("click",function(){V.spanAmPm.children("#click-am").addClass("text-primary"),V.spanAmPm.children("#click-pm").removeClass("text-primary"),V.amOrPm="AM"}).appendTo(this.spanAmPm),c('<div id="click-pm">PM</div>').on("click",function(){V.spanAmPm.children("#click-pm").addClass("text-primary"),V.spanAmPm.children("#click-am").removeClass("text-primary"),V.amOrPm="PM"}).appendTo(this.spanAmPm)):(c('<button type="button" class="btn-floating btn-flat clockpicker-button am-button" tabindex="1">AM</button>').on("click",function(){V.amOrPm="AM",V.amPmBlock.children(".pm-button").removeClass("active"),V.amPmBlock.children(".am-button").addClass("active"),V.spanAmPm.empty().append("AM")}).appendTo(this.amPmBlock),c('<button type="button" class="btn-floating btn-flat clockpicker-button pm-button" tabindex="2">PM</button>').on("click",function(){V.amOrPm="PM",V.amPmBlock.children(".am-button").removeClass("active"),V.amPmBlock.children(".pm-button").addClass("active"),V.spanAmPm.empty().append("PM")}).appendTo(this.amPmBlock))}T.attr("type","text"),n.darktheme&&l.addClass("darktheme"),c('<button type="button" class="btn-flat clockpicker-button" tabindex="'+(n.twelvehour?"3":"1")+'">'+n.donetext+"</button>").click(c.proxy(this.done,this)).appendTo(this.footer),this.spanHours.click(c.proxy(this.toggleView,this,"hours")),this.spanMinutes.click(c.proxy(this.toggleView,this,"minutes")),T.on("focus.clockpicker click.clockpicker",c.proxy(this.show,this));var S,B,D,E,I=c('<div class="clockpicker-tick"></div>');if(n.twelvehour)for(S=1;S<13;S+=1)B=I.clone(),D=S/6*Math.PI,E=b,B.css("font-size","140%"),B.css({left:f+Math.sin(D)*E-w,top:f-Math.cos(D)*E-w}),B.html(0===S?"00":S),v.append(B),B.on(u,r);else for(S=0;S<24;S+=1){B=I.clone(),D=S/6*Math.PI;var O=S>0&&S<13;E=O?g:b,B.css({left:f+Math.sin(D)*E-w,top:f-Math.cos(D)*E-w}),O&&B.css("font-size","120%"),B.html(0===S?"00":S),v.append(B),B.on(u,r)}for(S=0;S<60;S+=5)B=I.clone(),D=S/30*Math.PI,B.css({left:f+Math.sin(D)*b-w,top:f-Math.cos(D)*b-w}),B.css("font-size","140%"),B.html(i(S)),P.append(B),B.on(u,r);if(h.on(u,function(t){0===c(t.target).closest(".clockpicker-tick").length&&r(t,!0)}),p){var z=l.find(".clockpicker-canvas"),U=t("svg");U.setAttribute("class","clockpicker-svg"),U.setAttribute("width",y),U.setAttribute("height",y);var j=t("g");j.setAttribute("transform","translate("+f+","+f+")");var L=t("circle");L.setAttribute("class","clockpicker-canvas-bearing"),L.setAttribute("cx",0),L.setAttribute("cy",0),L.setAttribute("r",2);var N=t("line");N.setAttribute("x1",0),N.setAttribute("y1",0);var X=t("circle");X.setAttribute("class","clockpicker-canvas-bg"),X.setAttribute("r",w);var Y=t("circle");Y.setAttribute("class","clockpicker-canvas-fg"),Y.setAttribute("r",5),j.appendChild(N),j.appendChild(X),j.appendChild(Y),j.appendChild(L),U.appendChild(j),z.append(U),this.hand=N,this.bg=X,this.fg=Y,this.bearing=L,this.g=j,this.canvas=z}o(this.options.init)}function o(t){t&&"function"==typeof t&&t()}var c=window.jQuery,n=c(window),a=c(document),r="http://www.w3.org/2000/svg",p="SVGAngle"in window&&function(){var t,i=document.createElement("div");return i.innerHTML="<svg/>",t=(i.firstChild&&i.firstChild.namespaceURI)==r,i.innerHTML="",t}(),l=function(){var t=document.createElement("div").style;return"transition"in t||"WebkitTransition"in t||"MozTransition"in t||"msTransition"in t||"OTransition"in t}(),h="ontouchstart"in window,u="mousedown"+(h?" touchstart":""),d="mousemove.clockpicker"+(h?" touchmove.clockpicker":""),k="mouseup.clockpicker"+(h?" touchend.clockpicker":""),m=navigator.vibrate?"vibrate":navigator.webkitVibrate?"webkitVibrate":null,v=0,f=135,b=110,g=80,w=20,y=2*f,A=l?350:1,M=['<div class="clockpicker picker">','<div class="picker__holder">','<div class="picker__frame">','<div class="picker__wrap">','<div class="picker__box">','<div class="picker__date-display">','<div class="clockpicker-display">','<div class="clockpicker-display-column">','<span class="clockpicker-span-hours text-primary"></span>',":",'<span class="clockpicker-span-minutes"></span>',"</div>",'<div class="clockpicker-display-column clockpicker-display-am-pm">','<div class="clockpicker-span-am-pm"></div>',"</div>","</div>","</div>",'<div class="picker__calendar-container">','<div class="clockpicker-plate">','<div class="clockpicker-canvas"></div>','<div class="clockpicker-dial clockpicker-hours"></div>','<div class="clockpicker-dial clockpicker-minutes clockpicker-dial-out"></div>',"</div>",'<div class="clockpicker-am-pm-block">',"</div>","</div>",'<div class="picker__footer">',"</div>","</div>","</div>","</div>","</div>","</div>"].join("");s.DEFAULTS={"default":"",fromnow:0,donetext:"Done",autoclose:!1,ampmclickable:!1,darktheme:!1,twelvehour:!0,vibrate:!0},s.prototype.toggle=function(){this[this.isShown?"hide":"show"]()},s.prototype.locate=function(){var t=this.element,i=this.popover;t.offset(),t.outerWidth(),t.outerHeight(),this.options.align;i.show()},s.prototype.show=function(t){if(this.setAMorPM=function(t){var i=t,e="pm"==t?"am":"pm";this.options.twelvehour&&(this.amOrPm=i.toUpperCase(),this.options.ampmclickable?(this.spanAmPm.children("#click-"+i).addClass("text-primary"),this.spanAmPm.children("#click-"+e).removeClass("text-primary")):(this.amPmBlock.children("."+e+"-button").removeClass("active"),this.amPmBlock.children("."+i+"-button").addClass("active"),this.spanAmPm.empty().append(this.amOrPm)))},!this.isShown){o(this.options.beforeShow),c(":input").each(function(){c(this).attr("tabindex",-1)});var e=this;this.input.blur(),this.popover.addClass("picker--opened"),this.input.addClass("picker__input picker__input--active"),c(document.body).css("overflow","hidden"),this.isAppended||(this.options.hasOwnProperty("container")?this.popover.appendTo(this.options.container):this.popover.insertAfter(this.input),this.setAMorPM("pm"),n.on("resize.clockpicker"+this.id,function(){e.isShown&&e.locate()}),this.isAppended=!0);var s=((this.input.prop("value")||this.options["default"]||"")+"").split(":");if(this.options.twelvehour&&"undefined"!=typeof s[1]&&(s[1].includes("AM")?this.setAMorPM("am"):this.setAMorPM("pm"),s[1]=s[1].replace("AM","").replace("PM","")),"now"===s[0]){var r=new Date(+new Date+this.options.fromnow);r.getHours()>=12?this.setAMorPM("pm"):this.setAMorPM("am"),s=[r.getHours(),r.getMinutes()]}this.hours=+s[0]||0,this.minutes=+s[1]||0,this.spanHours.html(i(this.hours)),this.spanMinutes.html(i(this.minutes)),this.toggleView("hours"),this.locate(),this.isShown=!0,a.on("click.clockpicker."+this.id+" focusin.clockpicker."+this.id,function(t){var i=c(t.target);0===i.closest(e.popover.find(".picker__wrap")).length&&0===i.closest(e.input).length&&e.hide()}),a.on("keyup.clockpicker."+this.id,function(t){27===t.keyCode&&e.hide()}),o(this.options.afterShow)}},s.prototype.hide=function(){o(this.options.beforeHide),this.input.removeClass("picker__input picker__input--active"),this.popover.removeClass("picker--opened"),c(document.body).css("overflow","visible"),this.isShown=!1,c(":input").each(function(t){c(this).attr("tabindex",t+1)}),a.off("click.clockpicker."+this.id+" focusin.clockpicker."+this.id),a.off("keyup.clockpicker."+this.id),this.popover.hide(),o(this.options.afterHide)},s.prototype.toggleView=function(t,i){var e=!1;"minutes"===t&&"visible"===c(this.hoursView).css("visibility")&&(o(this.options.beforeHourSelect),e=!0);var s="hours"===t,n=s?this.hoursView:this.minutesView,a=s?this.minutesView:this.hoursView;this.currentView=t,this.spanHours.toggleClass("text-primary",s),this.spanMinutes.toggleClass("text-primary",!s),a.addClass("clockpicker-dial-out"),n.css("visibility","visible").removeClass("clockpicker-dial-out"),this.resetClock(i),clearTimeout(this.toggleViewTimer),this.toggleViewTimer=setTimeout(function(){a.css("visibility","hidden")},A),e&&o(this.options.afterHourSelect)},s.prototype.resetClock=function(t){var i=this.currentView,e=this[i],s="hours"===i,o=Math.PI/(s?6:30),c=e*o,n=s&&e>0&&e<13?g:b,a=Math.sin(c)*n,r=-Math.cos(c)*n,l=this;p&&t?(l.canvas.addClass("clockpicker-canvas-out"),setTimeout(function(){l.canvas.removeClass("clockpicker-canvas-out"),l.setHand(a,r)},t)):this.setHand(a,r)},s.prototype.setHand=function(t,e,s,o){var n,a=Math.atan2(t,-e),r="hours"===this.currentView,l=Math.PI/(r||s?6:30),h=Math.sqrt(t*t+e*e),u=this.options,d=r&&h<(b+g)/2,k=d?g:b;if(u.twelvehour&&(k=b),a<0&&(a=2*Math.PI+a),n=Math.round(a/l),a=n*l,u.twelvehour?r?0===n&&(n=12):(s&&(n*=5),60===n&&(n=0)):r?(12===n&&(n=0),n=d?0===n?12:n:0===n?0:n+12):(s&&(n*=5),60===n&&(n=0)),r?this.fg.setAttribute("class","clockpicker-canvas-fg"):n%5==0?this.fg.setAttribute("class","clockpicker-canvas-fg"):this.fg.setAttribute("class","clockpicker-canvas-fg active"),this[this.currentView]!==n&&m&&this.options.vibrate&&(this.vibrateTimer||(navigator[m](10),this.vibrateTimer=setTimeout(c.proxy(function(){this.vibrateTimer=null},this),100))),this[this.currentView]=n,this[r?"spanHours":"spanMinutes"].html(i(n)),!p)return void this[r?"hoursView":"minutesView"].find(".clockpicker-tick").each(function(){var t=c(this);t.toggleClass("active",n===+t.html())});o||!r&&n%5?(this.g.insertBefore(this.hand,this.bearing),this.g.insertBefore(this.bg,this.fg),this.bg.setAttribute("class","clockpicker-canvas-bg clockpicker-canvas-bg-trans")):(this.g.insertBefore(this.hand,this.bg),this.g.insertBefore(this.fg,this.bg),this.bg.setAttribute("class","clockpicker-canvas-bg"));var v=Math.sin(a)*(k-w),f=-Math.cos(a)*(k-w),y=Math.sin(a)*k,A=-Math.cos(a)*k;this.hand.setAttribute("x2",v),this.hand.setAttribute("y2",f),this.bg.setAttribute("cx",y),this.bg.setAttribute("cy",A),this.fg.setAttribute("cx",y),this.fg.setAttribute("cy",A)},s.prototype.done=function(){o(this.options.beforeDone),this.hide(),this.label.addClass("active");var t=this.input.prop("value"),e=i(this.hours)+":"+i(this.minutes);this.options.twelvehour&&(e+=this.amOrPm),this.input.prop("value",e),e!==t&&(this.input.triggerHandler("change"),this.isInput||this.element.trigger("change")),this.options.autoclose&&this.input.trigger("blur"),o(this.options.afterDone)},s.prototype.remove=function(){this.element.removeData("clockpicker"),this.input.off("focus.clockpicker click.clockpicker"),this.isShown&&this.hide(),this.isAppended&&(n.off("resize.clockpicker"+this.id),this.popover.remove())},c.fn.pickatime=function(t){var i=Array.prototype.slice.call(arguments,1);return this.each(function(){var e=c(this),o=e.data("clockpicker");if(o)"function"==typeof o[t]&&o[t].apply(o,i);else{var n=c.extend({},s.DEFAULTS,e.data(),"object"==typeof t&&t);e.data("clockpicker",new s(e,n))}})}}();
admin/js/materialize.min.js ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Materialize v0.97.8 (http://materializecss.com)
3
+ * Copyright 2014-2015 Materialize
4
+ * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE)
5
+ */
6
+ if("undefined"==typeof jQuery){var jQuery;jQuery="function"==typeof require?$=require("jquery"):$}jQuery.easing.jswing=jQuery.easing.swing,jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(a,b,c,d,e){return jQuery.easing[jQuery.easing.def](a,b,c,d,e)},easeInQuad:function(a,b,c,d,e){return d*(b/=e)*b+c},easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c},easeInOutQuad:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b+c:-d/2*(--b*(b-2)-1)+c},easeInCubic:function(a,b,c,d,e){return d*(b/=e)*b*b+c},easeOutCubic:function(a,b,c,d,e){return d*((b=b/e-1)*b*b+1)+c},easeInOutCubic:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b+c:d/2*((b-=2)*b*b+2)+c},easeInQuart:function(a,b,c,d,e){return d*(b/=e)*b*b*b+c},easeOutQuart:function(a,b,c,d,e){return-d*((b=b/e-1)*b*b*b-1)+c},easeInOutQuart:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b*b+c:-d/2*((b-=2)*b*b*b-2)+c},easeInQuint:function(a,b,c,d,e){return d*(b/=e)*b*b*b*b+c},easeOutQuint:function(a,b,c,d,e){return d*((b=b/e-1)*b*b*b*b+1)+c},easeInOutQuint:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b*b*b+c:d/2*((b-=2)*b*b*b*b+2)+c},easeInSine:function(a,b,c,d,e){return-d*Math.cos(b/e*(Math.PI/2))+d+c},easeOutSine:function(a,b,c,d,e){return d*Math.sin(b/e*(Math.PI/2))+c},easeInOutSine:function(a,b,c,d,e){return-d/2*(Math.cos(Math.PI*b/e)-1)+c},easeInExpo:function(a,b,c,d,e){return 0==b?c:d*Math.pow(2,10*(b/e-1))+c},easeOutExpo:function(a,b,c,d,e){return b==e?c+d:d*(-Math.pow(2,-10*b/e)+1)+c},easeInOutExpo:function(a,b,c,d,e){return 0==b?c:b==e?c+d:(b/=e/2)<1?d/2*Math.pow(2,10*(b-1))+c:d/2*(-Math.pow(2,-10*--b)+2)+c},easeInCirc:function(a,b,c,d,e){return-d*(Math.sqrt(1-(b/=e)*b)-1)+c},easeOutCirc:function(a,b,c,d,e){return d*Math.sqrt(1-(b=b/e-1)*b)+c},easeInOutCirc:function(a,b,c,d,e){return(b/=e/2)<1?-d/2*(Math.sqrt(1-b*b)-1)+c:d/2*(Math.sqrt(1-(b-=2)*b)+1)+c},easeInElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(0==b)return c;if(1==(b/=e))return c+d;if(g||(g=.3*e),h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return-(h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*(2*Math.PI)/g))+c},easeOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(0==b)return c;if(1==(b/=e))return c+d;if(g||(g=.3*e),h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*b)*Math.sin((b*e-f)*(2*Math.PI)/g)+d+c},easeInOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(0==b)return c;if(2==(b/=e/2))return c+d;if(g||(g=e*(.3*1.5)),h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return 1>b?-.5*(h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*(2*Math.PI)/g))+c:h*Math.pow(2,-10*(b-=1))*Math.sin((b*e-f)*(2*Math.PI)/g)*.5+d+c},easeInBack:function(a,b,c,d,e,f){return void 0==f&&(f=1.70158),d*(b/=e)*b*((f+1)*b-f)+c},easeOutBack:function(a,b,c,d,e,f){return void 0==f&&(f=1.70158),d*((b=b/e-1)*b*((f+1)*b+f)+1)+c},easeInOutBack:function(a,b,c,d,e,f){return void 0==f&&(f=1.70158),(b/=e/2)<1?d/2*(b*b*(((f*=1.525)+1)*b-f))+c:d/2*((b-=2)*b*(((f*=1.525)+1)*b+f)+2)+c},easeInBounce:function(a,b,c,d,e){return d-jQuery.easing.easeOutBounce(a,e-b,0,d,e)+c},easeOutBounce:function(a,b,c,d,e){return(b/=e)<1/2.75?d*(7.5625*b*b)+c:2/2.75>b?d*(7.5625*(b-=1.5/2.75)*b+.75)+c:2.5/2.75>b?d*(7.5625*(b-=2.25/2.75)*b+.9375)+c:d*(7.5625*(b-=2.625/2.75)*b+.984375)+c},easeInOutBounce:function(a,b,c,d,e){return e/2>b?.5*jQuery.easing.easeInBounce(a,2*b,0,d,e)+c:.5*jQuery.easing.easeOutBounce(a,2*b-e,0,d,e)+.5*d+c}}),jQuery.extend(jQuery.easing,{easeInOutMaterial:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b+c:d/4*((b-=2)*b*b+2)+c}}),jQuery.Velocity?console.log("Velocity is already loaded. You may be needlessly importing Velocity again; note that Materialize includes Velocity."):(!function(a){function b(a){var b=a.length,d=c.type(a);return"function"===d||c.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===d||0===b||"number"==typeof b&&b>0&&b-1 in a}if(!a.jQuery){var c=function(a,b){return new c.fn.init(a,b)};c.isWindow=function(a){return null!=a&&a==a.window},c.type=function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?e[g.call(a)]||"object":typeof a},c.isArray=Array.isArray||function(a){return"array"===c.type(a)},c.isPlainObject=function(a){var b;if(!a||"object"!==c.type(a)||a.nodeType||c.isWindow(a))return!1;try{if(a.constructor&&!f.call(a,"constructor")&&!f.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(d){return!1}for(b in a);return void 0===b||f.call(a,b)},c.each=function(a,c,d){var e,f=0,g=a.length,h=b(a);if(d){if(h)for(;g>f&&(e=c.apply(a[f],d),e!==!1);f++);else for(f in a)if(e=c.apply(a[f],d),e===!1)break}else if(h)for(;g>f&&(e=c.call(a[f],f,a[f]),e!==!1);f++);else for(f in a)if(e=c.call(a[f],f,a[f]),e===!1)break;return a},c.data=function(a,b,e){if(void 0===e){var f=a[c.expando],g=f&&d[f];if(void 0===b)return g;if(g&&b in g)return g[b]}else if(void 0!==b){var f=a[c.expando]||(a[c.expando]=++c.uuid);return d[f]=d[f]||{},d[f][b]=e,e}},c.removeData=function(a,b){var e=a[c.expando],f=e&&d[e];f&&c.each(b,function(a,b){delete f[b]})},c.extend=function(){var a,b,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;for("boolean"==typeof h&&(k=h,h=arguments[i]||{},i++),"object"!=typeof h&&"function"!==c.type(h)&&(h={}),i===j&&(h=this,i--);j>i;i++)if(null!=(f=arguments[i]))for(e in f)a=h[e],d=f[e],h!==d&&(k&&d&&(c.isPlainObject(d)||(b=c.isArray(d)))?(b?(b=!1,g=a&&c.isArray(a)?a:[]):g=a&&c.isPlainObject(a)?a:{},h[e]=c.extend(k,g,d)):void 0!==d&&(h[e]=d));return h},c.queue=function(a,d,e){function f(a,c){var d=c||[];return null!=a&&(b(Object(a))?!function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;)a[e++]=b[d++];if(c!==c)for(;void 0!==b[d];)a[e++]=b[d++];return a.length=e,a}(d,"string"==typeof a?[a]:a):[].push.call(d,a)),d}if(a){d=(d||"fx")+"queue";var g=c.data(a,d);return e?(!g||c.isArray(e)?g=c.data(a,d,f(e)):g.push(e),g):g||[]}},c.dequeue=function(a,b){c.each(a.nodeType?[a]:a,function(a,d){b=b||"fx";var e=c.queue(d,b),f=e.shift();"inprogress"===f&&(f=e.shift()),f&&("fx"===b&&e.unshift("inprogress"),f.call(d,function(){c.dequeue(d,b)}))})},c.fn=c.prototype={init:function(a){if(a.nodeType)return this[0]=a,this;throw new Error("Not a DOM node.")},offset:function(){var b=this[0].getBoundingClientRect?this[0].getBoundingClientRect():{top:0,left:0};return{top:b.top+(a.pageYOffset||document.scrollTop||0)-(document.clientTop||0),left:b.left+(a.pageXOffset||document.scrollLeft||0)-(document.clientLeft||0)}},position:function(){function a(){for(var a=this.offsetParent||document;a&&"html"===!a.nodeType.toLowerCase&&"static"===a.style.position;)a=a.offsetParent;return a||document}var b=this[0],a=a.apply(b),d=this.offset(),e=/^(?:body|html)$/i.test(a.nodeName)?{top:0,left:0}:c(a).offset();return d.top-=parseFloat(b.style.marginTop)||0,d.left-=parseFloat(b.style.marginLeft)||0,a.style&&(e.top+=parseFloat(a.style.borderTopWidth)||0,e.left+=parseFloat(a.style.borderLeftWidth)||0),{top:d.top-e.top,left:d.left-e.left}}};var d={};c.expando="velocity"+(new Date).getTime(),c.uuid=0;for(var e={},f=e.hasOwnProperty,g=e.toString,h="Boolean Number String Function Array Date RegExp Object Error".split(" "),i=0;i<h.length;i++)e["[object "+h[i]+"]"]=h[i].toLowerCase();c.fn.init.prototype=c.fn,a.Velocity={Utilities:c}}}(window),function(a){"object"==typeof module&&"object"==typeof module.exports?module.exports=a():"function"==typeof define&&define.amd?define(a):a()}(function(){return function(a,b,c,d){function e(a){for(var b=-1,c=a?a.length:0,d=[];++b<c;){var e=a[b];e&&d.push(e)}return d}function f(a){return p.isWrapped(a)?a=[].slice.call(a):p.isNode(a)&&(a=[a]),a}function g(a){var b=m.data(a,"velocity");return null===b?d:b}function h(a){return function(b){return Math.round(b*a)*(1/a)}}function i(a,c,d,e){function f(a,b){return 1-3*b+3*a}function g(a,b){return 3*b-6*a}function h(a){return 3*a}function i(a,b,c){return((f(b,c)*a+g(b,c))*a+h(b))*a}function j(a,b,c){return 3*f(b,c)*a*a+2*g(b,c)*a+h(b)}function k(b,c){for(var e=0;p>e;++e){var f=j(c,a,d);if(0===f)return c;var g=i(c,a,d)-b;c-=g/f}return c}function l(){for(var b=0;t>b;++b)x[b]=i(b*u,a,d)}function m(b,c,e){var f,g,h=0;do g=c+(e-c)/2,f=i(g,a,d)-b,f>0?e=g:c=g;while(Math.abs(f)>r&&++h<s);return g}function n(b){for(var c=0,e=1,f=t-1;e!=f&&x[e]<=b;++e)c+=u;--e;var g=(b-x[e])/(x[e+1]-x[e]),h=c+g*u,i=j(h,a,d);return i>=q?k(b,h):0==i?h:m(b,c,c+u)}function o(){y=!0,(a!=c||d!=e)&&l()}var p=4,q=.001,r=1e-7,s=10,t=11,u=1/(t-1),v="Float32Array"in b;if(4!==arguments.length)return!1;for(var w=0;4>w;++w)if("number"!=typeof arguments[w]||isNaN(arguments[w])||!isFinite(arguments[w]))return!1;a=Math.min(a,1),d=Math.min(d,1),a=Math.max(a,0),d=Math.max(d,0);var x=v?new Float32Array(t):new Array(t),y=!1,z=function(b){return y||o(),a===c&&d===e?b:0===b?0:1===b?1:i(n(b),c,e)};z.getControlPoints=function(){return[{x:a,y:c},{x:d,y:e}]};var A="generateBezier("+[a,c,d,e]+")";return z.toString=function(){return A},z}function j(a,b){var c=a;return p.isString(a)?t.Easings[a]||(c=!1):c=p.isArray(a)&&1===a.length?h.apply(null,a):p.isArray(a)&&2===a.length?u.apply(null,a.concat([b])):p.isArray(a)&&4===a.length?i.apply(null,a):!1,c===!1&&(c=t.Easings[t.defaults.easing]?t.defaults.easing:s),c}function k(a){if(a){var b=(new Date).getTime(),c=t.State.calls.length;c>1e4&&(t.State.calls=e(t.State.calls));for(var f=0;c>f;f++)if(t.State.calls[f]){var h=t.State.calls[f],i=h[0],j=h[2],n=h[3],o=!!n,q=null;n||(n=t.State.calls[f][3]=b-16);for(var r=Math.min((b-n)/j.duration,1),s=0,u=i.length;u>s;s++){var w=i[s],y=w.element;if(g(y)){var z=!1;if(j.display!==d&&null!==j.display&&"none"!==j.display){if("flex"===j.display){var A=["-webkit-box","-moz-box","-ms-flexbox","-webkit-flex"];m.each(A,function(a,b){v.setPropertyValue(y,"display",b)})}v.setPropertyValue(y,"display",j.display)}j.visibility!==d&&"hidden"!==j.visibility&&v.setPropertyValue(y,"visibility",j.visibility);for(var B in w)if("element"!==B){var C,D=w[B],E=p.isString(D.easing)?t.Easings[D.easing]:D.easing;if(1===r)C=D.endValue;else{var F=D.endValue-D.startValue;if(C=D.startValue+F*E(r,j,F),!o&&C===D.currentValue)continue}if(D.currentValue=C,"tween"===B)q=C;else{if(v.Hooks.registered[B]){var G=v.Hooks.getRoot(B),H=g(y).rootPropertyValueCache[G];H&&(D.rootPropertyValue=H)}var I=v.setPropertyValue(y,B,D.currentValue+(0===parseFloat(C)?"":D.unitType),D.rootPropertyValue,D.scrollData);v.Hooks.registered[B]&&(g(y).rootPropertyValueCache[G]=v.Normalizations.registered[G]?v.Normalizations.registered[G]("extract",null,I[1]):I[1]),"transform"===I[0]&&(z=!0)}}j.mobileHA&&g(y).transformCache.translate3d===d&&(g(y).transformCache.translate3d="(0px, 0px, 0px)",z=!0),z&&v.flushTransformCache(y)}}j.display!==d&&"none"!==j.display&&(t.State.calls[f][2].display=!1),j.visibility!==d&&"hidden"!==j.visibility&&(t.State.calls[f][2].visibility=!1),j.progress&&j.progress.call(h[1],h[1],r,Math.max(0,n+j.duration-b),n,q),1===r&&l(f)}}t.State.isTicking&&x(k)}function l(a,b){if(!t.State.calls[a])return!1;for(var c=t.State.calls[a][0],e=t.State.calls[a][1],f=t.State.calls[a][2],h=t.State.calls[a][4],i=!1,j=0,k=c.length;k>j;j++){var l=c[j].element;if(b||f.loop||("none"===f.display&&v.setPropertyValue(l,"display",f.display),"hidden"===f.visibility&&v.setPropertyValue(l,"visibility",f.visibility)),f.loop!==!0&&(m.queue(l)[1]===d||!/\.velocityQueueEntryFlag/i.test(m.queue(l)[1]))&&g(l)){g(l).isAnimating=!1,g(l).rootPropertyValueCache={};var n=!1;m.each(v.Lists.transforms3D,function(a,b){var c=/^scale/.test(b)?1:0,e=g(l).transformCache[b];g(l).transformCache[b]!==d&&new RegExp("^\\("+c+"[^.]").test(e)&&(n=!0,delete g(l).transformCache[b])}),f.mobileHA&&(n=!0,delete g(l).transformCache.translate3d),n&&v.flushTransformCache(l),v.Values.removeClass(l,"velocity-animating")}if(!b&&f.complete&&!f.loop&&j===k-1)try{f.complete.call(e,e)}catch(o){setTimeout(function(){throw o},1)}h&&f.loop!==!0&&h(e),g(l)&&f.loop===!0&&!b&&(m.each(g(l).tweensContainer,function(a,b){/^rotate/.test(a)&&360===parseFloat(b.endValue)&&(b.endValue=0,b.startValue=360),/^backgroundPosition/.test(a)&&100===parseFloat(b.endValue)&&"%"===b.unitType&&(b.endValue=0,b.startValue=100)}),t(l,"reverse",{loop:!0,delay:f.delay})),f.queue!==!1&&m.dequeue(l,f.queue)}t.State.calls[a]=!1;for(var p=0,q=t.State.calls.length;q>p;p++)if(t.State.calls[p]!==!1){i=!0;break}i===!1&&(t.State.isTicking=!1,delete t.State.calls,t.State.calls=[])}var m,n=function(){if(c.documentMode)return c.documentMode;for(var a=7;a>4;a--){var b=c.createElement("div");if(b.innerHTML="<!--[if IE "+a+"]><span></span><![endif]-->",b.getElementsByTagName("span").length)return b=null,a}return d}(),o=function(){var a=0;return b.webkitRequestAnimationFrame||b.mozRequestAnimationFrame||function(b){var c,d=(new Date).getTime();return c=Math.max(0,16-(d-a)),a=d+c,setTimeout(function(){b(d+c)},c)}}(),p={isString:function(a){return"string"==typeof a},isArray:Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)},isFunction:function(a){return"[object Function]"===Object.prototype.toString.call(a)},isNode:function(a){return a&&a.nodeType},isNodeList:function(a){return"object"==typeof a&&/^\[object (HTMLCollection|NodeList|Object)\]$/.test(Object.prototype.toString.call(a))&&a.length!==d&&(0===a.length||"object"==typeof a[0]&&a[0].nodeType>0)},isWrapped:function(a){return a&&(a.jquery||b.Zepto&&b.Zepto.zepto.isZ(a))},isSVG:function(a){return b.SVGElement&&a instanceof b.SVGElement},isEmptyObject:function(a){for(var b in a)return!1;return!0}},q=!1;if(a.fn&&a.fn.jquery?(m=a,q=!0):m=b.Velocity.Utilities,8>=n&&!q)throw new Error("Velocity: IE8 and below require jQuery to be loaded before Velocity.");if(7>=n)return void(jQuery.fn.velocity=jQuery.fn.animate);var r=400,s="swing",t={State:{isMobile:/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),isAndroid:/Android/i.test(navigator.userAgent),isGingerbread:/Android 2\.3\.[3-7]/i.test(navigator.userAgent),isChrome:b.chrome,isFirefox:/Firefox/i.test(navigator.userAgent),prefixElement:c.createElement("div"),prefixMatches:{},scrollAnchor:null,scrollPropertyLeft:null,scrollPropertyTop:null,isTicking:!1,calls:[]},CSS:{},Utilities:m,Redirects:{},Easings:{},Promise:b.Promise,defaults:{queue:"",duration:r,easing:s,begin:d,complete:d,progress:d,display:d,visibility:d,loop:!1,delay:!1,mobileHA:!0,_cacheValues:!0},init:function(a){m.data(a,"velocity",{isSVG:p.isSVG(a),isAnimating:!1,computedStyle:null,tweensContainer:null,rootPropertyValueCache:{},transformCache:{}})},hook:null,mock:!1,version:{major:1,minor:2,patch:2},debug:!1};b.pageYOffset!==d?(t.State.scrollAnchor=b,t.State.scrollPropertyLeft="pageXOffset",t.State.scrollPropertyTop="pageYOffset"):(t.State.scrollAnchor=c.documentElement||c.body.parentNode||c.body,t.State.scrollPropertyLeft="scrollLeft",t.State.scrollPropertyTop="scrollTop");var u=function(){function a(a){return-a.tension*a.x-a.friction*a.v}function b(b,c,d){var e={x:b.x+d.dx*c,v:b.v+d.dv*c,tension:b.tension,friction:b.friction};return{dx:e.v,dv:a(e)}}function c(c,d){var e={dx:c.v,dv:a(c)},f=b(c,.5*d,e),g=b(c,.5*d,f),h=b(c,d,g),i=1/6*(e.dx+2*(f.dx+g.dx)+h.dx),j=1/6*(e.dv+2*(f.dv+g.dv)+h.dv);return c.x=c.x+i*d,c.v=c.v+j*d,c}return function d(a,b,e){var f,g,h,i={x:-1,v:0,tension:null,friction:null},j=[0],k=0,l=1e-4,m=.016;for(a=parseFloat(a)||500,b=parseFloat(b)||20,e=e||null,i.tension=a,i.friction=b,f=null!==e,f?(k=d(a,b),g=k/e*m):g=m;h=c(h||i,g),j.push(1+h.x),k+=16,Math.abs(h.x)>l&&Math.abs(h.v)>l;);return f?function(a){return j[a*(j.length-1)|0]}:k}}();t.Easings={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},spring:function(a){return 1-Math.cos(4.5*a*Math.PI)*Math.exp(6*-a)}},m.each([["ease",[.25,.1,.25,1]],["ease-in",[.42,0,1,1]],["ease-out",[0,0,.58,1]],["ease-in-out",[.42,0,.58,1]],["easeInSine",[.47,0,.745,.715]],["easeOutSine",[.39,.575,.565,1]],["easeInOutSine",[.445,.05,.55,.95]],["easeInQuad",[.55,.085,.68,.53]],["easeOutQuad",[.25,.46,.45,.94]],["easeInOutQuad",[.455,.03,.515,.955]],["easeInCubic",[.55,.055,.675,.19]],["easeOutCubic",[.215,.61,.355,1]],["easeInOutCubic",[.645,.045,.355,1]],["easeInQuart",[.895,.03,.685,.22]],["easeOutQuart",[.165,.84,.44,1]],["easeInOutQuart",[.77,0,.175,1]],["easeInQuint",[.755,.05,.855,.06]],["easeOutQuint",[.23,1,.32,1]],["easeInOutQuint",[.86,0,.07,1]],["easeInExpo",[.95,.05,.795,.035]],["easeOutExpo",[.19,1,.22,1]],["easeInOutExpo",[1,0,0,1]],["easeInCirc",[.6,.04,.98,.335]],["easeOutCirc",[.075,.82,.165,1]],["easeInOutCirc",[.785,.135,.15,.86]]],function(a,b){t.Easings[b[0]]=i.apply(null,b[1])});var v=t.CSS={RegEx:{isHex:/^#([A-f\d]{3}){1,2}$/i,valueUnwrap:/^[A-z]+\((.*)\)$/i,wrappedValueAlreadyExtracted:/[0-9.]+ [0-9.]+ [0-9.]+( [0-9.]+)?/,valueSplit:/([A-z]+\(.+\))|(([A-z0-9#-.]+?)(?=\s|$))/gi},Lists:{colors:["fill","stroke","stopColor","color","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],transformsBase:["translateX","translateY","scale","scaleX","scaleY","skewX","skewY","rotateZ"],transforms3D:["transformPerspective","translateZ","scaleZ","rotateX","rotateY"]},Hooks:{templates:{textShadow:["Color X Y Blur","black 0px 0px 0px"],boxShadow:["Color X Y Blur Spread","black 0px 0px 0px 0px"],clip:["Top Right Bottom Left","0px 0px 0px 0px"],backgroundPosition:["X Y","0% 0%"],transformOrigin:["X Y Z","50% 50% 0px"],perspectiveOrigin:["X Y","50% 50%"]},registered:{},register:function(){for(var a=0;a<v.Lists.colors.length;a++){var b="color"===v.Lists.colors[a]?"0 0 0 1":"255 255 255 1";v.Hooks.templates[v.Lists.colors[a]]=["Red Green Blue Alpha",b]}var c,d,e;if(n)for(c in v.Hooks.templates){d=v.Hooks.templates[c],e=d[0].split(" ");var f=d[1].match(v.RegEx.valueSplit);"Color"===e[0]&&(e.push(e.shift()),f.push(f.shift()),v.Hooks.templates[c]=[e.join(" "),f.join(" ")])}for(c in v.Hooks.templates){d=v.Hooks.templates[c],e=d[0].split(" ");for(var a in e){var g=c+e[a],h=a;v.Hooks.registered[g]=[c,h]}}},getRoot:function(a){var b=v.Hooks.registered[a];return b?b[0]:a},cleanRootPropertyValue:function(a,b){return v.RegEx.valueUnwrap.test(b)&&(b=b.match(v.RegEx.valueUnwrap)[1]),v.Values.isCSSNullValue(b)&&(b=v.Hooks.templates[a][1]),b},extractValue:function(a,b){var c=v.Hooks.registered[a];if(c){var d=c[0],e=c[1];return b=v.Hooks.cleanRootPropertyValue(d,b),b.toString().match(v.RegEx.valueSplit)[e]}return b},injectValue:function(a,b,c){var d=v.Hooks.registered[a];if(d){var e,f,g=d[0],h=d[1];return c=v.Hooks.cleanRootPropertyValue(g,c),e=c.toString().match(v.RegEx.valueSplit),e[h]=b,f=e.join(" ")}return c}},Normalizations:{registered:{clip:function(a,b,c){switch(a){case"name":return"clip";case"extract":var d;return v.RegEx.wrappedValueAlreadyExtracted.test(c)?d=c:(d=c.toString().match(v.RegEx.valueUnwrap),d=d?d[1].replace(/,(\s+)?/g," "):c),d;case"inject":return"rect("+c+")"}},blur:function(a,b,c){switch(a){case"name":return t.State.isFirefox?"filter":"-webkit-filter";case"extract":var d=parseFloat(c);if(!d&&0!==d){var e=c.toString().match(/blur\(([0-9]+[A-z]+)\)/i);d=e?e[1]:0}return d;case"inject":return parseFloat(c)?"blur("+c+")":"none"}},opacity:function(a,b,c){if(8>=n)switch(a){case"name":return"filter";case"extract":var d=c.toString().match(/alpha\(opacity=(.*)\)/i);return c=d?d[1]/100:1;case"inject":return b.style.zoom=1,parseFloat(c)>=1?"":"alpha(opacity="+parseInt(100*parseFloat(c),10)+")"}else switch(a){case"name":return"opacity";case"extract":return c;case"inject":return c}}},register:function(){9>=n||t.State.isGingerbread||(v.Lists.transformsBase=v.Lists.transformsBase.concat(v.Lists.transforms3D));for(var a=0;a<v.Lists.transformsBase.length;a++)!function(){var b=v.Lists.transformsBase[a];v.Normalizations.registered[b]=function(a,c,e){switch(a){case"name":return"transform";case"extract":return g(c)===d||g(c).transformCache[b]===d?/^scale/i.test(b)?1:0:g(c).transformCache[b].replace(/[()]/g,"");case"inject":var f=!1;switch(b.substr(0,b.length-1)){case"translate":f=!/(%|px|em|rem|vw|vh|\d)$/i.test(e);break;case"scal":case"scale":t.State.isAndroid&&g(c).transformCache[b]===d&&1>e&&(e=1),f=!/(\d)$/i.test(e);break;case"skew":f=!/(deg|\d)$/i.test(e);break;case"rotate":f=!/(deg|\d)$/i.test(e)}return f||(g(c).transformCache[b]="("+e+")"),g(c).transformCache[b]}}}();for(var a=0;a<v.Lists.colors.length;a++)!function(){var b=v.Lists.colors[a];v.Normalizations.registered[b]=function(a,c,e){switch(a){case"name":return b;case"extract":var f;if(v.RegEx.wrappedValueAlreadyExtracted.test(e))f=e;else{var g,h={black:"rgb(0, 0, 0)",blue:"rgb(0, 0, 255)",gray:"rgb(128, 128, 128)",green:"rgb(0, 128, 0)",red:"rgb(255, 0, 0)",white:"rgb(255, 255, 255)"};/^[A-z]+$/i.test(e)?g=h[e]!==d?h[e]:h.black:v.RegEx.isHex.test(e)?g="rgb("+v.Values.hexToRgb(e).join(" ")+")":/^rgba?\(/i.test(e)||(g=h.black),f=(g||e).toString().match(v.RegEx.valueUnwrap)[1].replace(/,(\s+)?/g," ")}return 8>=n||3!==f.split(" ").length||(f+=" 1"),f;case"inject":return 8>=n?4===e.split(" ").length&&(e=e.split(/\s+/).slice(0,3).join(" ")):3===e.split(" ").length&&(e+=" 1"),(8>=n?"rgb":"rgba")+"("+e.replace(/\s+/g,",").replace(/\.(\d)+(?=,)/g,"")+")"}}}()}},Names:{camelCase:function(a){return a.replace(/-(\w)/g,function(a,b){return b.toUpperCase()})},SVGAttribute:function(a){var b="width|height|x|y|cx|cy|r|rx|ry|x1|x2|y1|y2";return(n||t.State.isAndroid&&!t.State.isChrome)&&(b+="|transform"),new RegExp("^("+b+")$","i").test(a)},prefixCheck:function(a){if(t.State.prefixMatches[a])return[t.State.prefixMatches[a],!0];for(var b=["","Webkit","Moz","ms","O"],c=0,d=b.length;d>c;c++){var e;if(e=0===c?a:b[c]+a.replace(/^\w/,function(a){return a.toUpperCase()}),p.isString(t.State.prefixElement.style[e]))return t.State.prefixMatches[a]=e,[e,!0]}return[a,!1]}},Values:{hexToRgb:function(a){var b,c=/^#?([a-f\d])([a-f\d])([a-f\d])$/i,d=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;return a=a.replace(c,function(a,b,c,d){return b+b+c+c+d+d}),b=d.exec(a),b?[parseInt(b[1],16),parseInt(b[2],16),parseInt(b[3],16)]:[0,0,0]},isCSSNullValue:function(a){return 0==a||/^(none|auto|transparent|(rgba\(0, ?0, ?0, ?0\)))$/i.test(a)},getUnitType:function(a){return/^(rotate|skew)/i.test(a)?"deg":/(^(scale|scaleX|scaleY|scaleZ|alpha|flexGrow|flexHeight|zIndex|fontWeight)$)|((opacity|red|green|blue|alpha)$)/i.test(a)?"":"px"},getDisplayType:function(a){var b=a&&a.tagName.toString().toLowerCase();return/^(b|big|i|small|tt|abbr|acronym|cite|code|dfn|em|kbd|strong|samp|var|a|bdo|br|img|map|object|q|script|span|sub|sup|button|input|label|select|textarea)$/i.test(b)?"inline":/^(li)$/i.test(b)?"list-item":/^(tr)$/i.test(b)?"table-row":/^(table)$/i.test(b)?"table":/^(tbody)$/i.test(b)?"table-row-group":"block"},addClass:function(a,b){a.classList?a.classList.add(b):a.className+=(a.className.length?" ":"")+b},removeClass:function(a,b){a.classList?a.classList.remove(b):a.className=a.className.toString().replace(new RegExp("(^|\\s)"+b.split(" ").join("|")+"(\\s|$)","gi")," ")}},getPropertyValue:function(a,c,e,f){function h(a,c){function e(){j&&v.setPropertyValue(a,"display","none")}var i=0;if(8>=n)i=m.css(a,c);else{var j=!1;if(/^(width|height)$/.test(c)&&0===v.getPropertyValue(a,"display")&&(j=!0,v.setPropertyValue(a,"display",v.Values.getDisplayType(a))),!f){if("height"===c&&"border-box"!==v.getPropertyValue(a,"boxSizing").toString().toLowerCase()){var k=a.offsetHeight-(parseFloat(v.getPropertyValue(a,"borderTopWidth"))||0)-(parseFloat(v.getPropertyValue(a,"borderBottomWidth"))||0)-(parseFloat(v.getPropertyValue(a,"paddingTop"))||0)-(parseFloat(v.getPropertyValue(a,"paddingBottom"))||0);return e(),k}if("width"===c&&"border-box"!==v.getPropertyValue(a,"boxSizing").toString().toLowerCase()){var l=a.offsetWidth-(parseFloat(v.getPropertyValue(a,"borderLeftWidth"))||0)-(parseFloat(v.getPropertyValue(a,"borderRightWidth"))||0)-(parseFloat(v.getPropertyValue(a,"paddingLeft"))||0)-(parseFloat(v.getPropertyValue(a,"paddingRight"))||0);return e(),l}}var o;o=g(a)===d?b.getComputedStyle(a,null):g(a).computedStyle?g(a).computedStyle:g(a).computedStyle=b.getComputedStyle(a,null),"borderColor"===c&&(c="borderTopColor"),i=9===n&&"filter"===c?o.getPropertyValue(c):o[c],(""===i||null===i)&&(i=a.style[c]),e()}if("auto"===i&&/^(top|right|bottom|left)$/i.test(c)){var p=h(a,"position");("fixed"===p||"absolute"===p&&/top|left/i.test(c))&&(i=m(a).position()[c]+"px")}return i}var i;if(v.Hooks.registered[c]){var j=c,k=v.Hooks.getRoot(j);e===d&&(e=v.getPropertyValue(a,v.Names.prefixCheck(k)[0])),v.Normalizations.registered[k]&&(e=v.Normalizations.registered[k]("extract",a,e)),i=v.Hooks.extractValue(j,e)}else if(v.Normalizations.registered[c]){var l,o;l=v.Normalizations.registered[c]("name",a),"transform"!==l&&(o=h(a,v.Names.prefixCheck(l)[0]),v.Values.isCSSNullValue(o)&&v.Hooks.templates[c]&&(o=v.Hooks.templates[c][1])),i=v.Normalizations.registered[c]("extract",a,o)}if(!/^[\d-]/.test(i))if(g(a)&&g(a).isSVG&&v.Names.SVGAttribute(c))if(/^(height|width)$/i.test(c))try{i=a.getBBox()[c]}catch(p){i=0}else i=a.getAttribute(c);else i=h(a,v.Names.prefixCheck(c)[0]);return v.Values.isCSSNullValue(i)&&(i=0),t.debug>=2&&console.log("Get "+c+": "+i),i},setPropertyValue:function(a,c,d,e,f){var h=c;if("scroll"===c)f.container?f.container["scroll"+f.direction]=d:"Left"===f.direction?b.scrollTo(d,f.alternateValue):b.scrollTo(f.alternateValue,d);else if(v.Normalizations.registered[c]&&"transform"===v.Normalizations.registered[c]("name",a))v.Normalizations.registered[c]("inject",a,d),h="transform",d=g(a).transformCache[c];else{if(v.Hooks.registered[c]){var i=c,j=v.Hooks.getRoot(c);e=e||v.getPropertyValue(a,j),d=v.Hooks.injectValue(i,d,e),c=j}if(v.Normalizations.registered[c]&&(d=v.Normalizations.registered[c]("inject",a,d),c=v.Normalizations.registered[c]("name",a)),h=v.Names.prefixCheck(c)[0],8>=n)try{a.style[h]=d}catch(k){t.debug&&console.log("Browser does not support ["+d+"] for ["+h+"]")}else g(a)&&g(a).isSVG&&v.Names.SVGAttribute(c)?a.setAttribute(c,d):a.style[h]=d;t.debug>=2&&console.log("Set "+c+" ("+h+"): "+d)}return[h,d]},flushTransformCache:function(a){function b(b){return parseFloat(v.getPropertyValue(a,b))}var c="";if((n||t.State.isAndroid&&!t.State.isChrome)&&g(a).isSVG){var d={translate:[b("translateX"),b("translateY")],skewX:[b("skewX")],skewY:[b("skewY")],scale:1!==b("scale")?[b("scale"),b("scale")]:[b("scaleX"),b("scaleY")],rotate:[b("rotateZ"),0,0]};m.each(g(a).transformCache,function(a){/^translate/i.test(a)?a="translate":/^scale/i.test(a)?a="scale":/^rotate/i.test(a)&&(a="rotate"),d[a]&&(c+=a+"("+d[a].join(" ")+") ",delete d[a])})}else{var e,f;m.each(g(a).transformCache,function(b){return e=g(a).transformCache[b],"transformPerspective"===b?(f=e,!0):(9===n&&"rotateZ"===b&&(b="rotate"),void(c+=b+e+" "))}),f&&(c="perspective"+f+" "+c)}v.setPropertyValue(a,"transform",c)}};v.Hooks.register(),v.Normalizations.register(),t.hook=function(a,b,c){var e=d;return a=f(a),m.each(a,function(a,f){if(g(f)===d&&t.init(f),c===d)e===d&&(e=t.CSS.getPropertyValue(f,b));else{var h=t.CSS.setPropertyValue(f,b,c);"transform"===h[0]&&t.CSS.flushTransformCache(f),e=h}}),e};var w=function(){function a(){return h?B.promise||null:i}function e(){function a(a){function l(a,b){var c=d,e=d,g=d;return p.isArray(a)?(c=a[0],!p.isArray(a[1])&&/^[\d-]/.test(a[1])||p.isFunction(a[1])||v.RegEx.isHex.test(a[1])?g=a[1]:(p.isString(a[1])&&!v.RegEx.isHex.test(a[1])||p.isArray(a[1]))&&(e=b?a[1]:j(a[1],h.duration),a[2]!==d&&(g=a[2]))):c=a,b||(e=e||h.easing),p.isFunction(c)&&(c=c.call(f,y,x)),p.isFunction(g)&&(g=g.call(f,y,x)),[c||0,e,g]}function n(a,b){var c,d;return d=(b||"0").toString().toLowerCase().replace(/[%A-z]+$/,function(a){return c=a,""}),c||(c=v.Values.getUnitType(a)),[d,c]}function r(){var a={myParent:f.parentNode||c.body,position:v.getPropertyValue(f,"position"),fontSize:v.getPropertyValue(f,"fontSize")},d=a.position===I.lastPosition&&a.myParent===I.lastParent,e=a.fontSize===I.lastFontSize;I.lastParent=a.myParent,I.lastPosition=a.position,I.lastFontSize=a.fontSize;var h=100,i={};if(e&&d)i.emToPx=I.lastEmToPx,i.percentToPxWidth=I.lastPercentToPxWidth,i.percentToPxHeight=I.lastPercentToPxHeight;else{var j=g(f).isSVG?c.createElementNS("http://www.w3.org/2000/svg","rect"):c.createElement("div");t.init(j),a.myParent.appendChild(j),m.each(["overflow","overflowX","overflowY"],function(a,b){t.CSS.setPropertyValue(j,b,"hidden")}),t.CSS.setPropertyValue(j,"position",a.position),t.CSS.setPropertyValue(j,"fontSize",a.fontSize),t.CSS.setPropertyValue(j,"boxSizing","content-box"),m.each(["minWidth","maxWidth","width","minHeight","maxHeight","height"],function(a,b){t.CSS.setPropertyValue(j,b,h+"%")}),t.CSS.setPropertyValue(j,"paddingLeft",h+"em"),i.percentToPxWidth=I.lastPercentToPxWidth=(parseFloat(v.getPropertyValue(j,"width",null,!0))||1)/h,i.percentToPxHeight=I.lastPercentToPxHeight=(parseFloat(v.getPropertyValue(j,"height",null,!0))||1)/h,i.emToPx=I.lastEmToPx=(parseFloat(v.getPropertyValue(j,"paddingLeft"))||1)/h,a.myParent.removeChild(j)}return null===I.remToPx&&(I.remToPx=parseFloat(v.getPropertyValue(c.body,"fontSize"))||16),null===I.vwToPx&&(I.vwToPx=parseFloat(b.innerWidth)/100,I.vhToPx=parseFloat(b.innerHeight)/100),i.remToPx=I.remToPx,i.vwToPx=I.vwToPx,i.vhToPx=I.vhToPx,t.debug>=1&&console.log("Unit ratios: "+JSON.stringify(i),f),i}if(h.begin&&0===y)try{h.begin.call(o,o)}catch(u){setTimeout(function(){throw u},1)}if("scroll"===C){var w,z,A,D=/^x$/i.test(h.axis)?"Left":"Top",E=parseFloat(h.offset)||0;h.container?p.isWrapped(h.container)||p.isNode(h.container)?(h.container=h.container[0]||h.container,w=h.container["scroll"+D],A=w+m(f).position()[D.toLowerCase()]+E):h.container=null:(w=t.State.scrollAnchor[t.State["scrollProperty"+D]],z=t.State.scrollAnchor[t.State["scrollProperty"+("Left"===D?"Top":"Left")]],A=m(f).offset()[D.toLowerCase()]+E),i={scroll:{rootPropertyValue:!1,startValue:w,currentValue:w,endValue:A,unitType:"",easing:h.easing,scrollData:{container:h.container,direction:D,alternateValue:z}},element:f},t.debug&&console.log("tweensContainer (scroll): ",i.scroll,f)}else if("reverse"===C){if(!g(f).tweensContainer)return void m.dequeue(f,h.queue);"none"===g(f).opts.display&&(g(f).opts.display="auto"),"hidden"===g(f).opts.visibility&&(g(f).opts.visibility="visible"),g(f).opts.loop=!1,g(f).opts.begin=null,g(f).opts.complete=null,s.easing||delete h.easing,s.duration||delete h.duration,h=m.extend({},g(f).opts,h);var F=m.extend(!0,{},g(f).tweensContainer);for(var G in F)if("element"!==G){var H=F[G].startValue;F[G].startValue=F[G].currentValue=F[G].endValue,F[G].endValue=H,p.isEmptyObject(s)||(F[G].easing=h.easing),t.debug&&console.log("reverse tweensContainer ("+G+"): "+JSON.stringify(F[G]),f)}i=F}else if("start"===C){var F;g(f).tweensContainer&&g(f).isAnimating===!0&&(F=g(f).tweensContainer),m.each(q,function(a,b){if(RegExp("^"+v.Lists.colors.join("$|^")+"$").test(a)){var c=l(b,!0),e=c[0],f=c[1],g=c[2];if(v.RegEx.isHex.test(e)){for(var h=["Red","Green","Blue"],i=v.Values.hexToRgb(e),j=g?v.Values.hexToRgb(g):d,k=0;k<h.length;k++){var m=[i[k]];f&&m.push(f),j!==d&&m.push(j[k]),q[a+h[k]]=m}delete q[a]}}});for(var K in q){var L=l(q[K]),M=L[0],N=L[1],O=L[2];K=v.Names.camelCase(K);var P=v.Hooks.getRoot(K),Q=!1;if(g(f).isSVG||"tween"===P||v.Names.prefixCheck(P)[1]!==!1||v.Normalizations.registered[P]!==d){(h.display!==d&&null!==h.display&&"none"!==h.display||h.visibility!==d&&"hidden"!==h.visibility)&&/opacity|filter/.test(K)&&!O&&0!==M&&(O=0),h._cacheValues&&F&&F[K]?(O===d&&(O=F[K].endValue+F[K].unitType),Q=g(f).rootPropertyValueCache[P]):v.Hooks.registered[K]?O===d?(Q=v.getPropertyValue(f,P),O=v.getPropertyValue(f,K,Q)):Q=v.Hooks.templates[P][1]:O===d&&(O=v.getPropertyValue(f,K));var R,S,T,U=!1;if(R=n(K,O),O=R[0],T=R[1],R=n(K,M),M=R[0].replace(/^([+-\/*])=/,function(a,b){return U=b,""}),S=R[1],O=parseFloat(O)||0,M=parseFloat(M)||0,"%"===S&&(/^(fontSize|lineHeight)$/.test(K)?(M/=100,S="em"):/^scale/.test(K)?(M/=100,S=""):/(Red|Green|Blue)$/i.test(K)&&(M=M/100*255,S="")),/[\/*]/.test(U))S=T;else if(T!==S&&0!==O)if(0===M)S=T;else{e=e||r();var V=/margin|padding|left|right|width|text|word|letter/i.test(K)||/X$/.test(K)||"x"===K?"x":"y";
7
+ switch(T){case"%":O*="x"===V?e.percentToPxWidth:e.percentToPxHeight;break;case"px":break;default:O*=e[T+"ToPx"]}switch(S){case"%":O*=1/("x"===V?e.percentToPxWidth:e.percentToPxHeight);break;case"px":break;default:O*=1/e[S+"ToPx"]}}switch(U){case"+":M=O+M;break;case"-":M=O-M;break;case"*":M=O*M;break;case"/":M=O/M}i[K]={rootPropertyValue:Q,startValue:O,currentValue:O,endValue:M,unitType:S,easing:N},t.debug&&console.log("tweensContainer ("+K+"): "+JSON.stringify(i[K]),f)}else t.debug&&console.log("Skipping ["+P+"] due to a lack of browser support.")}i.element=f}i.element&&(v.Values.addClass(f,"velocity-animating"),J.push(i),""===h.queue&&(g(f).tweensContainer=i,g(f).opts=h),g(f).isAnimating=!0,y===x-1?(t.State.calls.push([J,o,h,null,B.resolver]),t.State.isTicking===!1&&(t.State.isTicking=!0,k())):y++)}var e,f=this,h=m.extend({},t.defaults,s),i={};switch(g(f)===d&&t.init(f),parseFloat(h.delay)&&h.queue!==!1&&m.queue(f,h.queue,function(a){t.velocityQueueEntryFlag=!0,g(f).delayTimer={setTimeout:setTimeout(a,parseFloat(h.delay)),next:a}}),h.duration.toString().toLowerCase()){case"fast":h.duration=200;break;case"normal":h.duration=r;break;case"slow":h.duration=600;break;default:h.duration=parseFloat(h.duration)||1}t.mock!==!1&&(t.mock===!0?h.duration=h.delay=1:(h.duration*=parseFloat(t.mock)||1,h.delay*=parseFloat(t.mock)||1)),h.easing=j(h.easing,h.duration),h.begin&&!p.isFunction(h.begin)&&(h.begin=null),h.progress&&!p.isFunction(h.progress)&&(h.progress=null),h.complete&&!p.isFunction(h.complete)&&(h.complete=null),h.display!==d&&null!==h.display&&(h.display=h.display.toString().toLowerCase(),"auto"===h.display&&(h.display=t.CSS.Values.getDisplayType(f))),h.visibility!==d&&null!==h.visibility&&(h.visibility=h.visibility.toString().toLowerCase()),h.mobileHA=h.mobileHA&&t.State.isMobile&&!t.State.isGingerbread,h.queue===!1?h.delay?setTimeout(a,h.delay):a():m.queue(f,h.queue,function(b,c){return c===!0?(B.promise&&B.resolver(o),!0):(t.velocityQueueEntryFlag=!0,void a(b))}),""!==h.queue&&"fx"!==h.queue||"inprogress"===m.queue(f)[0]||m.dequeue(f)}var h,i,n,o,q,s,u=arguments[0]&&(arguments[0].p||m.isPlainObject(arguments[0].properties)&&!arguments[0].properties.names||p.isString(arguments[0].properties));if(p.isWrapped(this)?(h=!1,n=0,o=this,i=this):(h=!0,n=1,o=u?arguments[0].elements||arguments[0].e:arguments[0]),o=f(o)){u?(q=arguments[0].properties||arguments[0].p,s=arguments[0].options||arguments[0].o):(q=arguments[n],s=arguments[n+1]);var x=o.length,y=0;if(!/^(stop|finish)$/i.test(q)&&!m.isPlainObject(s)){var z=n+1;s={};for(var A=z;A<arguments.length;A++)p.isArray(arguments[A])||!/^(fast|normal|slow)$/i.test(arguments[A])&&!/^\d/.test(arguments[A])?p.isString(arguments[A])||p.isArray(arguments[A])?s.easing=arguments[A]:p.isFunction(arguments[A])&&(s.complete=arguments[A]):s.duration=arguments[A]}var B={promise:null,resolver:null,rejecter:null};h&&t.Promise&&(B.promise=new t.Promise(function(a,b){B.resolver=a,B.rejecter=b}));var C;switch(q){case"scroll":C="scroll";break;case"reverse":C="reverse";break;case"finish":case"stop":m.each(o,function(a,b){g(b)&&g(b).delayTimer&&(clearTimeout(g(b).delayTimer.setTimeout),g(b).delayTimer.next&&g(b).delayTimer.next(),delete g(b).delayTimer)});var D=[];return m.each(t.State.calls,function(a,b){b&&m.each(b[1],function(c,e){var f=s===d?"":s;return f===!0||b[2].queue===f||s===d&&b[2].queue===!1?void m.each(o,function(c,d){d===e&&((s===!0||p.isString(s))&&(m.each(m.queue(d,p.isString(s)?s:""),function(a,b){p.isFunction(b)&&b(null,!0)}),m.queue(d,p.isString(s)?s:"",[])),"stop"===q?(g(d)&&g(d).tweensContainer&&f!==!1&&m.each(g(d).tweensContainer,function(a,b){b.endValue=b.currentValue}),D.push(a)):"finish"===q&&(b[2].duration=1))}):!0})}),"stop"===q&&(m.each(D,function(a,b){l(b,!0)}),B.promise&&B.resolver(o)),a();default:if(!m.isPlainObject(q)||p.isEmptyObject(q)){if(p.isString(q)&&t.Redirects[q]){var E=m.extend({},s),F=E.duration,G=E.delay||0;return E.backwards===!0&&(o=m.extend(!0,[],o).reverse()),m.each(o,function(a,b){parseFloat(E.stagger)?E.delay=G+parseFloat(E.stagger)*a:p.isFunction(E.stagger)&&(E.delay=G+E.stagger.call(b,a,x)),E.drag&&(E.duration=parseFloat(F)||(/^(callout|transition)/.test(q)?1e3:r),E.duration=Math.max(E.duration*(E.backwards?1-a/x:(a+1)/x),.75*E.duration,200)),t.Redirects[q].call(b,b,E||{},a,x,o,B.promise?B:d)}),a()}var H="Velocity: First argument ("+q+") was not a property map, a known action, or a registered redirect. Aborting.";return B.promise?B.rejecter(new Error(H)):console.log(H),a()}C="start"}var I={lastParent:null,lastPosition:null,lastFontSize:null,lastPercentToPxWidth:null,lastPercentToPxHeight:null,lastEmToPx:null,remToPx:null,vwToPx:null,vhToPx:null},J=[];m.each(o,function(a,b){p.isNode(b)&&e.call(b)});var K,E=m.extend({},t.defaults,s);if(E.loop=parseInt(E.loop),K=2*E.loop-1,E.loop)for(var L=0;K>L;L++){var M={delay:E.delay,progress:E.progress};L===K-1&&(M.display=E.display,M.visibility=E.visibility,M.complete=E.complete),w(o,"reverse",M)}return a()}};t=m.extend(w,t),t.animate=w;var x=b.requestAnimationFrame||o;return t.State.isMobile||c.hidden===d||c.addEventListener("visibilitychange",function(){c.hidden?(x=function(a){return setTimeout(function(){a(!0)},16)},k()):x=b.requestAnimationFrame||o}),a.Velocity=t,a!==b&&(a.fn.velocity=w,a.fn.velocity.defaults=t.defaults),m.each(["Down","Up"],function(a,b){t.Redirects["slide"+b]=function(a,c,e,f,g,h){var i=m.extend({},c),j=i.begin,k=i.complete,l={height:"",marginTop:"",marginBottom:"",paddingTop:"",paddingBottom:""},n={};i.display===d&&(i.display="Down"===b?"inline"===t.CSS.Values.getDisplayType(a)?"inline-block":"block":"none"),i.begin=function(){j&&j.call(g,g);for(var c in l){n[c]=a.style[c];var d=t.CSS.getPropertyValue(a,c);l[c]="Down"===b?[d,0]:[0,d]}n.overflow=a.style.overflow,a.style.overflow="hidden"},i.complete=function(){for(var b in n)a.style[b]=n[b];k&&k.call(g,g),h&&h.resolver(g)},t(a,l,i)}}),m.each(["In","Out"],function(a,b){t.Redirects["fade"+b]=function(a,c,e,f,g,h){var i=m.extend({},c),j={opacity:"In"===b?1:0},k=i.complete;i.complete=e!==f-1?i.begin=null:function(){k&&k.call(g,g),h&&h.resolver(g)},i.display===d&&(i.display="In"===b?"auto":"none"),t(this,j,i)}}),t}(window.jQuery||window.Zepto||window,window,document)})),!function(a,b,c,d){"use strict";function e(a,b,c){return setTimeout(k(a,c),b)}function f(a,b,c){return Array.isArray(a)?(g(a,c[b],c),!0):!1}function g(a,b,c){var e;if(a)if(a.forEach)a.forEach(b,c);else if(a.length!==d)for(e=0;e<a.length;)b.call(c,a[e],e,a),e++;else for(e in a)a.hasOwnProperty(e)&&b.call(c,a[e],e,a)}function h(a,b,c){for(var e=Object.keys(b),f=0;f<e.length;)(!c||c&&a[e[f]]===d)&&(a[e[f]]=b[e[f]]),f++;return a}function i(a,b){return h(a,b,!0)}function j(a,b,c){var d,e=b.prototype;d=a.prototype=Object.create(e),d.constructor=a,d._super=e,c&&h(d,c)}function k(a,b){return function(){return a.apply(b,arguments)}}function l(a,b){return typeof a==ka?a.apply(b?b[0]||d:d,b):a}function m(a,b){return a===d?b:a}function n(a,b,c){g(r(b),function(b){a.addEventListener(b,c,!1)})}function o(a,b,c){g(r(b),function(b){a.removeEventListener(b,c,!1)})}function p(a,b){for(;a;){if(a==b)return!0;a=a.parentNode}return!1}function q(a,b){return a.indexOf(b)>-1}function r(a){return a.trim().split(/\s+/g)}function s(a,b,c){if(a.indexOf&&!c)return a.indexOf(b);for(var d=0;d<a.length;){if(c&&a[d][c]==b||!c&&a[d]===b)return d;d++}return-1}function t(a){return Array.prototype.slice.call(a,0)}function u(a,b,c){for(var d=[],e=[],f=0;f<a.length;){var g=b?a[f][b]:a[f];s(e,g)<0&&d.push(a[f]),e[f]=g,f++}return c&&(d=b?d.sort(function(a,c){return a[b]>c[b]}):d.sort()),d}function v(a,b){for(var c,e,f=b[0].toUpperCase()+b.slice(1),g=0;g<ia.length;){if(c=ia[g],e=c?c+f:b,e in a)return e;g++}return d}function w(){return oa++}function x(a){var b=a.ownerDocument;return b.defaultView||b.parentWindow}function y(a,b){var c=this;this.manager=a,this.callback=b,this.element=a.element,this.target=a.options.inputTarget,this.domHandler=function(b){l(a.options.enable,[a])&&c.handler(b)},this.init()}function z(a){var b,c=a.options.inputClass;return new(b=c?c:ra?N:sa?Q:qa?S:M)(a,A)}function A(a,b,c){var d=c.pointers.length,e=c.changedPointers.length,f=b&ya&&0===d-e,g=b&(Aa|Ba)&&0===d-e;c.isFirst=!!f,c.isFinal=!!g,f&&(a.session={}),c.eventType=b,B(a,c),a.emit("hammer.input",c),a.recognize(c),a.session.prevInput=c}function B(a,b){var c=a.session,d=b.pointers,e=d.length;c.firstInput||(c.firstInput=E(b)),e>1&&!c.firstMultiple?c.firstMultiple=E(b):1===e&&(c.firstMultiple=!1);var f=c.firstInput,g=c.firstMultiple,h=g?g.center:f.center,i=b.center=F(d);b.timeStamp=na(),b.deltaTime=b.timeStamp-f.timeStamp,b.angle=J(h,i),b.distance=I(h,i),C(c,b),b.offsetDirection=H(b.deltaX,b.deltaY),b.scale=g?L(g.pointers,d):1,b.rotation=g?K(g.pointers,d):0,D(c,b);var j=a.element;p(b.srcEvent.target,j)&&(j=b.srcEvent.target),b.target=j}function C(a,b){var c=b.center,d=a.offsetDelta||{},e=a.prevDelta||{},f=a.prevInput||{};(b.eventType===ya||f.eventType===Aa)&&(e=a.prevDelta={x:f.deltaX||0,y:f.deltaY||0},d=a.offsetDelta={x:c.x,y:c.y}),b.deltaX=e.x+(c.x-d.x),b.deltaY=e.y+(c.y-d.y)}function D(a,b){var c,e,f,g,h=a.lastInterval||b,i=b.timeStamp-h.timeStamp;if(b.eventType!=Ba&&(i>xa||h.velocity===d)){var j=h.deltaX-b.deltaX,k=h.deltaY-b.deltaY,l=G(i,j,k);e=l.x,f=l.y,c=ma(l.x)>ma(l.y)?l.x:l.y,g=H(j,k),a.lastInterval=b}else c=h.velocity,e=h.velocityX,f=h.velocityY,g=h.direction;b.velocity=c,b.velocityX=e,b.velocityY=f,b.direction=g}function E(a){for(var b=[],c=0;c<a.pointers.length;)b[c]={clientX:la(a.pointers[c].clientX),clientY:la(a.pointers[c].clientY)},c++;return{timeStamp:na(),pointers:b,center:F(b),deltaX:a.deltaX,deltaY:a.deltaY}}function F(a){var b=a.length;if(1===b)return{x:la(a[0].clientX),y:la(a[0].clientY)};for(var c=0,d=0,e=0;b>e;)c+=a[e].clientX,d+=a[e].clientY,e++;return{x:la(c/b),y:la(d/b)}}function G(a,b,c){return{x:b/a||0,y:c/a||0}}function H(a,b){return a===b?Ca:ma(a)>=ma(b)?a>0?Da:Ea:b>0?Fa:Ga}function I(a,b,c){c||(c=Ka);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return Math.sqrt(d*d+e*e)}function J(a,b,c){c||(c=Ka);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return 180*Math.atan2(e,d)/Math.PI}function K(a,b){return J(b[1],b[0],La)-J(a[1],a[0],La)}function L(a,b){return I(b[0],b[1],La)/I(a[0],a[1],La)}function M(){this.evEl=Na,this.evWin=Oa,this.allow=!0,this.pressed=!1,y.apply(this,arguments)}function N(){this.evEl=Ra,this.evWin=Sa,y.apply(this,arguments),this.store=this.manager.session.pointerEvents=[]}function O(){this.evTarget=Ua,this.evWin=Va,this.started=!1,y.apply(this,arguments)}function P(a,b){var c=t(a.touches),d=t(a.changedTouches);return b&(Aa|Ba)&&(c=u(c.concat(d),"identifier",!0)),[c,d]}function Q(){this.evTarget=Xa,this.targetIds={},y.apply(this,arguments)}function R(a,b){var c=t(a.touches),d=this.targetIds;if(b&(ya|za)&&1===c.length)return d[c[0].identifier]=!0,[c,c];var e,f,g=t(a.changedTouches),h=[],i=this.target;if(f=c.filter(function(a){return p(a.target,i)}),b===ya)for(e=0;e<f.length;)d[f[e].identifier]=!0,e++;for(e=0;e<g.length;)d[g[e].identifier]&&h.push(g[e]),b&(Aa|Ba)&&delete d[g[e].identifier],e++;return h.length?[u(f.concat(h),"identifier",!0),h]:void 0}function S(){y.apply(this,arguments);var a=k(this.handler,this);this.touch=new Q(this.manager,a),this.mouse=new M(this.manager,a)}function T(a,b){this.manager=a,this.set(b)}function U(a){if(q(a,bb))return bb;var b=q(a,cb),c=q(a,db);return b&&c?cb+" "+db:b||c?b?cb:db:q(a,ab)?ab:_a}function V(a){this.id=w(),this.manager=null,this.options=i(a||{},this.defaults),this.options.enable=m(this.options.enable,!0),this.state=eb,this.simultaneous={},this.requireFail=[]}function W(a){return a&jb?"cancel":a&hb?"end":a&gb?"move":a&fb?"start":""}function X(a){return a==Ga?"down":a==Fa?"up":a==Da?"left":a==Ea?"right":""}function Y(a,b){var c=b.manager;return c?c.get(a):a}function Z(){V.apply(this,arguments)}function $(){Z.apply(this,arguments),this.pX=null,this.pY=null}function _(){Z.apply(this,arguments)}function aa(){V.apply(this,arguments),this._timer=null,this._input=null}function ba(){Z.apply(this,arguments)}function ca(){Z.apply(this,arguments)}function da(){V.apply(this,arguments),this.pTime=!1,this.pCenter=!1,this._timer=null,this._input=null,this.count=0}function ea(a,b){return b=b||{},b.recognizers=m(b.recognizers,ea.defaults.preset),new fa(a,b)}function fa(a,b){b=b||{},this.options=i(b,ea.defaults),this.options.inputTarget=this.options.inputTarget||a,this.handlers={},this.session={},this.recognizers=[],this.element=a,this.input=z(this),this.touchAction=new T(this,this.options.touchAction),ga(this,!0),g(b.recognizers,function(a){var b=this.add(new a[0](a[1]));a[2]&&b.recognizeWith(a[2]),a[3]&&b.requireFailure(a[3])},this)}function ga(a,b){var c=a.element;g(a.options.cssProps,function(a,d){c.style[v(c.style,d)]=b?a:""})}function ha(a,c){var d=b.createEvent("Event");d.initEvent(a,!0,!0),d.gesture=c,c.target.dispatchEvent(d)}var ia=["","webkit","moz","MS","ms","o"],ja=b.createElement("div"),ka="function",la=Math.round,ma=Math.abs,na=Date.now,oa=1,pa=/mobile|tablet|ip(ad|hone|od)|android/i,qa="ontouchstart"in a,ra=v(a,"PointerEvent")!==d,sa=qa&&pa.test(navigator.userAgent),ta="touch",ua="pen",va="mouse",wa="kinect",xa=25,ya=1,za=2,Aa=4,Ba=8,Ca=1,Da=2,Ea=4,Fa=8,Ga=16,Ha=Da|Ea,Ia=Fa|Ga,Ja=Ha|Ia,Ka=["x","y"],La=["clientX","clientY"];y.prototype={handler:function(){},init:function(){this.evEl&&n(this.element,this.evEl,this.domHandler),this.evTarget&&n(this.target,this.evTarget,this.domHandler),this.evWin&&n(x(this.element),this.evWin,this.domHandler)},destroy:function(){this.evEl&&o(this.element,this.evEl,this.domHandler),this.evTarget&&o(this.target,this.evTarget,this.domHandler),this.evWin&&o(x(this.element),this.evWin,this.domHandler)}};var Ma={mousedown:ya,mousemove:za,mouseup:Aa},Na="mousedown",Oa="mousemove mouseup";j(M,y,{handler:function(a){var b=Ma[a.type];b&ya&&0===a.button&&(this.pressed=!0),b&za&&1!==a.which&&(b=Aa),this.pressed&&this.allow&&(b&Aa&&(this.pressed=!1),this.callback(this.manager,b,{pointers:[a],changedPointers:[a],pointerType:va,srcEvent:a}))}});var Pa={pointerdown:ya,pointermove:za,pointerup:Aa,pointercancel:Ba,pointerout:Ba},Qa={2:ta,3:ua,4:va,5:wa},Ra="pointerdown",Sa="pointermove pointerup pointercancel";a.MSPointerEvent&&(Ra="MSPointerDown",Sa="MSPointerMove MSPointerUp MSPointerCancel"),j(N,y,{handler:function(a){var b=this.store,c=!1,d=a.type.toLowerCase().replace("ms",""),e=Pa[d],f=Qa[a.pointerType]||a.pointerType,g=f==ta,h=s(b,a.pointerId,"pointerId");e&ya&&(0===a.button||g)?0>h&&(b.push(a),h=b.length-1):e&(Aa|Ba)&&(c=!0),0>h||(b[h]=a,this.callback(this.manager,e,{pointers:b,changedPointers:[a],pointerType:f,srcEvent:a}),c&&b.splice(h,1))}});var Ta={touchstart:ya,touchmove:za,touchend:Aa,touchcancel:Ba},Ua="touchstart",Va="touchstart touchmove touchend touchcancel";j(O,y,{handler:function(a){var b=Ta[a.type];if(b===ya&&(this.started=!0),this.started){var c=P.call(this,a,b);b&(Aa|Ba)&&0===c[0].length-c[1].length&&(this.started=!1),this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:ta,srcEvent:a})}}});var Wa={touchstart:ya,touchmove:za,touchend:Aa,touchcancel:Ba},Xa="touchstart touchmove touchend touchcancel";j(Q,y,{handler:function(a){var b=Wa[a.type],c=R.call(this,a,b);c&&this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:ta,srcEvent:a})}}),j(S,y,{handler:function(a,b,c){var d=c.pointerType==ta,e=c.pointerType==va;if(d)this.mouse.allow=!1;else if(e&&!this.mouse.allow)return;b&(Aa|Ba)&&(this.mouse.allow=!0),this.callback(a,b,c)},destroy:function(){this.touch.destroy(),this.mouse.destroy()}});var Ya=v(ja.style,"touchAction"),Za=Ya!==d,$a="compute",_a="auto",ab="manipulation",bb="none",cb="pan-x",db="pan-y";T.prototype={set:function(a){a==$a&&(a=this.compute()),Za&&(this.manager.element.style[Ya]=a),this.actions=a.toLowerCase().trim()},update:function(){this.set(this.manager.options.touchAction)},compute:function(){var a=[];return g(this.manager.recognizers,function(b){l(b.options.enable,[b])&&(a=a.concat(b.getTouchAction()))}),U(a.join(" "))},preventDefaults:function(a){if(!Za){var b=a.srcEvent,c=a.offsetDirection;if(this.manager.session.prevented)return void b.preventDefault();var d=this.actions,e=q(d,bb),f=q(d,db),g=q(d,cb);return e||f&&c&Ha||g&&c&Ia?this.preventSrc(b):void 0}},preventSrc:function(a){this.manager.session.prevented=!0,a.preventDefault()}};var eb=1,fb=2,gb=4,hb=8,ib=hb,jb=16,kb=32;V.prototype={defaults:{},set:function(a){return h(this.options,a),this.manager&&this.manager.touchAction.update(),this},recognizeWith:function(a){if(f(a,"recognizeWith",this))return this;var b=this.simultaneous;return a=Y(a,this),b[a.id]||(b[a.id]=a,a.recognizeWith(this)),this},dropRecognizeWith:function(a){return f(a,"dropRecognizeWith",this)?this:(a=Y(a,this),delete this.simultaneous[a.id],this)},requireFailure:function(a){if(f(a,"requireFailure",this))return this;var b=this.requireFail;return a=Y(a,this),-1===s(b,a)&&(b.push(a),a.requireFailure(this)),this},dropRequireFailure:function(a){if(f(a,"dropRequireFailure",this))return this;a=Y(a,this);var b=s(this.requireFail,a);return b>-1&&this.requireFail.splice(b,1),this},hasRequireFailures:function(){return this.requireFail.length>0},canRecognizeWith:function(a){return!!this.simultaneous[a.id]},emit:function(a){function b(b){c.manager.emit(c.options.event+(b?W(d):""),a)}var c=this,d=this.state;hb>d&&b(!0),b(),d>=hb&&b(!0)},tryEmit:function(a){return this.canEmit()?this.emit(a):void(this.state=kb)},canEmit:function(){for(var a=0;a<this.requireFail.length;){if(!(this.requireFail[a].state&(kb|eb)))return!1;a++}return!0},recognize:function(a){var b=h({},a);return l(this.options.enable,[this,b])?(this.state&(ib|jb|kb)&&(this.state=eb),this.state=this.process(b),void(this.state&(fb|gb|hb|jb)&&this.tryEmit(b))):(this.reset(),void(this.state=kb))},process:function(){},getTouchAction:function(){},reset:function(){}},j(Z,V,{defaults:{pointers:1},attrTest:function(a){var b=this.options.pointers;return 0===b||a.pointers.length===b},process:function(a){var b=this.state,c=a.eventType,d=b&(fb|gb),e=this.attrTest(a);return d&&(c&Ba||!e)?b|jb:d||e?c&Aa?b|hb:b&fb?b|gb:fb:kb}}),j($,Z,{defaults:{event:"pan",threshold:10,pointers:1,direction:Ja},getTouchAction:function(){var a=this.options.direction,b=[];return a&Ha&&b.push(db),a&Ia&&b.push(cb),b},directionTest:function(a){var b=this.options,c=!0,d=a.distance,e=a.direction,f=a.deltaX,g=a.deltaY;return e&b.direction||(b.direction&Ha?(e=0===f?Ca:0>f?Da:Ea,c=f!=this.pX,d=Math.abs(a.deltaX)):(e=0===g?Ca:0>g?Fa:Ga,c=g!=this.pY,d=Math.abs(a.deltaY))),a.direction=e,c&&d>b.threshold&&e&b.direction},attrTest:function(a){return Z.prototype.attrTest.call(this,a)&&(this.state&fb||!(this.state&fb)&&this.directionTest(a))},emit:function(a){this.pX=a.deltaX,this.pY=a.deltaY;var b=X(a.direction);b&&this.manager.emit(this.options.event+b,a),this._super.emit.call(this,a)}}),j(_,Z,{defaults:{event:"pinch",threshold:0,pointers:2},getTouchAction:function(){return[bb]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.scale-1)>this.options.threshold||this.state&fb)},emit:function(a){if(this._super.emit.call(this,a),1!==a.scale){var b=a.scale<1?"in":"out";this.manager.emit(this.options.event+b,a)}}}),j(aa,V,{defaults:{event:"press",pointers:1,time:500,threshold:5},getTouchAction:function(){return[_a]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,f=a.deltaTime>b.time;if(this._input=a,!d||!c||a.eventType&(Aa|Ba)&&!f)this.reset();else if(a.eventType&ya)this.reset(),this._timer=e(function(){this.state=ib,this.tryEmit()},b.time,this);else if(a.eventType&Aa)return ib;return kb},reset:function(){clearTimeout(this._timer)},emit:function(a){this.state===ib&&(a&&a.eventType&Aa?this.manager.emit(this.options.event+"up",a):(this._input.timeStamp=na(),this.manager.emit(this.options.event,this._input)))}}),j(ba,Z,{defaults:{event:"rotate",threshold:0,pointers:2},getTouchAction:function(){return[bb]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.rotation)>this.options.threshold||this.state&fb)}}),j(ca,Z,{defaults:{event:"swipe",threshold:10,velocity:.65,direction:Ha|Ia,pointers:1},getTouchAction:function(){return $.prototype.getTouchAction.call(this)},attrTest:function(a){var b,c=this.options.direction;return c&(Ha|Ia)?b=a.velocity:c&Ha?b=a.velocityX:c&Ia&&(b=a.velocityY),this._super.attrTest.call(this,a)&&c&a.direction&&a.distance>this.options.threshold&&ma(b)>this.options.velocity&&a.eventType&Aa},emit:function(a){var b=X(a.direction);b&&this.manager.emit(this.options.event+b,a),this.manager.emit(this.options.event,a)}}),j(da,V,{defaults:{event:"tap",pointers:1,taps:1,interval:300,time:250,threshold:2,posThreshold:10},getTouchAction:function(){return[ab]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,f=a.deltaTime<b.time;if(this.reset(),a.eventType&ya&&0===this.count)return this.failTimeout();if(d&&f&&c){if(a.eventType!=Aa)return this.failTimeout();var g=this.pTime?a.timeStamp-this.pTime<b.interval:!0,h=!this.pCenter||I(this.pCenter,a.center)<b.posThreshold;this.pTime=a.timeStamp,this.pCenter=a.center,h&&g?this.count+=1:this.count=1,this._input=a;var i=this.count%b.taps;if(0===i)return this.hasRequireFailures()?(this._timer=e(function(){this.state=ib,this.tryEmit()},b.interval,this),fb):ib}return kb},failTimeout:function(){return this._timer=e(function(){this.state=kb},this.options.interval,this),kb},reset:function(){clearTimeout(this._timer)},emit:function(){this.state==ib&&(this._input.tapCount=this.count,this.manager.emit(this.options.event,this._input))}}),ea.VERSION="2.0.4",ea.defaults={domEvents:!1,touchAction:$a,enable:!0,inputTarget:null,inputClass:null,preset:[[ba,{enable:!1}],[_,{enable:!1},["rotate"]],[ca,{direction:Ha}],[$,{direction:Ha},["swipe"]],[da],[da,{event:"doubletap",taps:2},["tap"]],[aa]],cssProps:{userSelect:"default",touchSelect:"none",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}};var lb=1,mb=2;fa.prototype={set:function(a){return h(this.options,a),a.touchAction&&this.touchAction.update(),a.inputTarget&&(this.input.destroy(),this.input.target=a.inputTarget,this.input.init()),this},stop:function(a){this.session.stopped=a?mb:lb},recognize:function(a){var b=this.session;if(!b.stopped){this.touchAction.preventDefaults(a);var c,d=this.recognizers,e=b.curRecognizer;(!e||e&&e.state&ib)&&(e=b.curRecognizer=null);for(var f=0;f<d.length;)c=d[f],b.stopped===mb||e&&c!=e&&!c.canRecognizeWith(e)?c.reset():c.recognize(a),!e&&c.state&(fb|gb|hb)&&(e=b.curRecognizer=c),f++}},get:function(a){if(a instanceof V)return a;for(var b=this.recognizers,c=0;c<b.length;c++)if(b[c].options.event==a)return b[c];return null},add:function(a){if(f(a,"add",this))return this;var b=this.get(a.options.event);return b&&this.remove(b),this.recognizers.push(a),a.manager=this,this.touchAction.update(),a},remove:function(a){if(f(a,"remove",this))return this;var b=this.recognizers;return a=this.get(a),b.splice(s(b,a),1),this.touchAction.update(),this},on:function(a,b){var c=this.handlers;return g(r(a),function(a){c[a]=c[a]||[],c[a].push(b)}),this},off:function(a,b){var c=this.handlers;return g(r(a),function(a){b?c[a].splice(s(c[a],b),1):delete c[a]}),this},emit:function(a,b){this.options.domEvents&&ha(a,b);var c=this.handlers[a]&&this.handlers[a].slice();if(c&&c.length){b.type=a,b.preventDefault=function(){b.srcEvent.preventDefault()};for(var d=0;d<c.length;)c[d](b),d++}},destroy:function(){this.element&&ga(this,!1),this.handlers={},this.session={},this.input.destroy(),this.element=null}},h(ea,{INPUT_START:ya,INPUT_MOVE:za,INPUT_END:Aa,INPUT_CANCEL:Ba,STATE_POSSIBLE:eb,STATE_BEGAN:fb,STATE_CHANGED:gb,STATE_ENDED:hb,STATE_RECOGNIZED:ib,STATE_CANCELLED:jb,STATE_FAILED:kb,DIRECTION_NONE:Ca,DIRECTION_LEFT:Da,DIRECTION_RIGHT:Ea,DIRECTION_UP:Fa,DIRECTION_DOWN:Ga,DIRECTION_HORIZONTAL:Ha,DIRECTION_VERTICAL:Ia,DIRECTION_ALL:Ja,Manager:fa,Input:y,TouchAction:T,TouchInput:Q,MouseInput:M,PointerEventInput:N,TouchMouseInput:S,SingleTouchInput:O,Recognizer:V,AttrRecognizer:Z,Tap:da,Pan:$,Swipe:ca,Pinch:_,Rotate:ba,Press:aa,on:n,off:o,each:g,merge:i,extend:h,inherit:j,bindFn:k,prefixed:v}),typeof define==ka&&define.amd?define(function(){return ea}):"undefined"!=typeof module&&module.exports?module.exports=ea:a[c]=ea}(window,document,"Hammer"),function(a){"function"==typeof define&&define.amd?define(["jquery","hammerjs"],a):"object"==typeof exports?a(require("jquery"),require("hammerjs")):a(jQuery,Hammer)}(function(a,b){function c(c,d){var e=a(c);e.data("hammer")||e.data("hammer",new b(e[0],d))}a.fn.hammer=function(a){return this.each(function(){c(this,a)})},b.Manager.prototype.emit=function(b){return function(c,d){b.call(this,c,d),a(this.element).trigger({type:c,gesture:d})}}(b.Manager.prototype.emit)}),function(a){a.Package?Materialize={}:a.Materialize={}}(window),function(a){for(var b=0,c=["webkit","moz"],d=a.requestAnimationFrame,e=a.cancelAnimationFrame,f=c.length;--f>=0&&!d;)d=a[c[f]+"RequestAnimationFrame"],e=a[c[f]+"CancelRequestAnimationFrame"];d&&e||(d=function(a){var c=+Date.now(),d=Math.max(b+16,c);return setTimeout(function(){a(b=d)},d-c)},e=clearTimeout),a.requestAnimationFrame=d,a.cancelAnimationFrame=e}(window),Materialize.guid=function(){function a(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}return function(){return a()+a()+"-"+a()+"-"+a()+"-"+a()+"-"+a()+a()+a()}}(),Materialize.escapeHash=function(a){return a.replace(/(:|\.|\[|\]|,|=)/g,"\\$1")},Materialize.elementOrParentIsFixed=function(a){var b=$(a),c=b.add(b.parents()),d=!1;return c.each(function(){return"fixed"===$(this).css("position")?(d=!0,!1):void 0}),d};var Vel;Vel=jQuery?jQuery.Velocity:$?$.Velocity:Velocity,function(a){a.fn.collapsible=function(b){var c={accordion:void 0,onOpen:void 0,onClose:void 0};return b=a.extend(c,b),this.each(function(){function c(b){j=i.find("> li > .collapsible-header"),b.hasClass("active")?b.parent().addClass("active"):b.parent().removeClass("active"),b.parent().hasClass("active")?b.siblings(".collapsible-body").stop(!0,!1).slideDown({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height","")}}):b.siblings(".collapsible-body").stop(!0,!1).slideUp({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height","")}}),j.not(b).removeClass("active").parent().removeClass("active"),j.not(b).parent().children(".collapsible-body").stop(!0,!1).each(function(){a(this).is(":visible")&&a(this).slideUp({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height",""),f(a(this).siblings(".collapsible-header"))}})})}function d(b){b.hasClass("active")?b.parent().addClass("active"):b.parent().removeClass("active"),b.parent().hasClass("active")?b.siblings(".collapsible-body").stop(!0,!1).slideDown({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height","")}}):b.siblings(".collapsible-body").stop(!0,!1).slideUp({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height","")}})}function e(a){b.accordion||"accordion"===k||void 0===k?c(a):d(a),f(a)}function f(a){a.hasClass("active")?"function"==typeof b.onOpen&&b.onOpen.call(this,a.parent()):"function"==typeof b.onClose&&b.onClose.call(this,a.parent())}function g(a){var b=h(a);return b.length>0}function h(a){return a.closest("li > .collapsible-header")}var i=a(this),j=a(this).find("> li > .collapsible-header"),k=i.data("collapsible");i.off("click.collapse","> li > .collapsible-header"),j.off("click.collapse"),i.on("click.collapse","> li > .collapsible-header",function(b){var c=a(b.target);g(c)&&(c=h(c)),c.toggleClass("active"),e(c)}),b.accordion||"accordion"===k||void 0===k?e(j.filter(".active").first()):j.filter(".active").each(function(){e(a(this))})})},a(document).ready(function(){a(".collapsible").collapsible()})}(jQuery),function(a){a.fn.scrollTo=function(b){return a(this).scrollTop(a(this).scrollTop()-a(this).offset().top+a(b).offset().top),this},a.fn.dropdown=function(b){var c={inDuration:300,outDuration:225,constrain_width:!0,hover:!1,gutter:0,belowOrigin:!1,alignment:"left",stopPropagation:!1};return"open"===b?(this.each(function(){a(this).trigger("open")}),!1):"close"===b?(this.each(function(){a(this).trigger("close")}),!1):void this.each(function(){function d(){void 0!==g.data("induration")&&(h.inDuration=g.data("induration")),void 0!==g.data("outduration")&&(h.outDuration=g.data("outduration")),void 0!==g.data("constrainwidth")&&(h.constrain_width=g.data("constrainwidth")),void 0!==g.data("hover")&&(h.hover=g.data("hover")),void 0!==g.data("gutter")&&(h.gutter=g.data("gutter")),void 0!==g.data("beloworigin")&&(h.belowOrigin=g.data("beloworigin")),void 0!==g.data("alignment")&&(h.alignment=g.data("alignment")),void 0!==g.data("stoppropagation")&&(h.stopPropagation=g.data("stoppropagation"))}function e(b){"focus"===b&&(i=!0),d(),j.addClass("active"),g.addClass("active"),h.constrain_width===!0?j.css("width",g.outerWidth()):j.css("white-space","nowrap");var c=window.innerHeight,e=g.innerHeight(),f=g.offset().left,k=g.offset().top-a(window).scrollTop(),l=h.alignment,m=0,n=0,o=0;h.belowOrigin===!0&&(o=e);var p=0,q=0,r=g.parent();if(r.is("body")||(r[0].scrollHeight>r[0].clientHeight&&(p=r[0].scrollTop),r[0].scrollWidth>r[0].clientWidth&&(q=r[0].scrollLeft)),f+j.innerWidth()>a(window).width()?l="right":f-j.innerWidth()+g.innerWidth()<0&&(l="left"),k+j.innerHeight()>c)if(k+e-j.innerHeight()<0){var s=c-k-o;j.css("max-height",s)}else o||(o+=e),o-=j.innerHeight();if("left"===l)m=h.gutter,n=g.position().left+m;else if("right"===l){var t=g.position().left+g.outerWidth()-j.outerWidth();m=-h.gutter,n=t+m}j.css({position:"absolute",top:g.position().top+o+p,left:n+q}),j.stop(!0,!0).css("opacity",0).slideDown({queue:!1,duration:h.inDuration,easing:"easeOutCubic",complete:function(){a(this).css("height","")}}).animate({opacity:1},{queue:!1,duration:h.inDuration,easing:"easeOutSine"})}function f(){i=!1,j.fadeOut(h.outDuration),j.removeClass("active"),g.removeClass("active"),setTimeout(function(){j.css("max-height","")},h.outDuration)}var g=a(this),h=a.extend({},c,b),i=!1,j=a("#"+g.attr("data-activates"));if(d(),g.after(j),h.hover){var k=!1;g.unbind("click."+g.attr("id")),g.on("mouseenter",function(a){k===!1&&(e(),k=!0)}),g.on("mouseleave",function(b){var c=b.toElement||b.relatedTarget;a(c).closest(".dropdown-content").is(j)||(j.stop(!0,!0),f(),k=!1)}),j.on("mouseleave",function(b){var c=b.toElement||b.relatedTarget;a(c).closest(".dropdown-button").is(g)||(j.stop(!0,!0),f(),k=!1)})}else g.unbind("click."+g.attr("id")),g.bind("click."+g.attr("id"),function(b){i||(g[0]!=b.currentTarget||g.hasClass("active")||0!==a(b.target).closest(".dropdown-content").length?g.hasClass("active")&&(f(),a(document).unbind("click."+j.attr("id")+" touchstart."+j.attr("id"))):(b.preventDefault(),h.stopPropagation&&b.stopPropagation(),e("click")),j.hasClass("active")&&a(document).bind("click."+j.attr("id")+" touchstart."+j.attr("id"),function(b){j.is(b.target)||g.is(b.target)||g.find(b.target).length||(f(),a(document).unbind("click."+j.attr("id")+" touchstart."+j.attr("id")))}))});g.on("open",function(a,b){e(b)}),g.on("close",f)})},a(document).ready(function(){a(".dropdown-button").dropdown()})}(jQuery),function(a){var b=0,c=0,d=function(){return c++,"materialize-modal-overlay-"+c},e={init:function(c){var e={opacity:.5,in_duration:350,out_duration:250,ready:void 0,complete:void 0,dismissible:!0,starting_top:"4%",ending_top:"10%"};return c=a.extend(e,c),this.each(function(){var e=a(this),f=a(this).attr("id")||"#"+a(this).data("target"),g=function(){var d=e.data("overlay-id"),f=a("#"+d);e.removeClass("open"),a("body").css({overflow:"",width:""}),e.find(".modal-close").off("click.close"),a(document).off("keyup.modal"+d),f.velocity({opacity:0},{duration:c.out_duration,queue:!1,ease:"easeOutQuart"});var g={
8
+ duration:c.out_duration,queue:!1,ease:"easeOutCubic",complete:function(){a(this).css({display:"none"}),"function"==typeof c.complete&&c.complete.call(this,e),f.remove(),b--}};e.hasClass("bottom-sheet")?e.velocity({bottom:"-100%",opacity:0},g):e.velocity({top:c.starting_top,opacity:0,scaleX:.7},g)},h=function(f){var h=a("body"),i=h.innerWidth();if(h.css("overflow","hidden"),h.width(i),!e.hasClass("open")){var j=d(),k=a('<div class="modal-overlay"></div>');lStack=++b,k.attr("id",j).css("z-index",1e3+2*lStack),e.data("overlay-id",j).css("z-index",1e3+2*lStack+1),e.addClass("open"),a("body").append(k),c.dismissible&&(k.click(function(){g()}),a(document).on("keyup.modal"+j,function(a){27===a.keyCode&&g()})),e.find(".modal-close").on("click.close",function(a){g()}),k.css({display:"block",opacity:0}),e.css({display:"block",opacity:0}),k.velocity({opacity:c.opacity},{duration:c.in_duration,queue:!1,ease:"easeOutCubic"}),e.data("associated-overlay",k[0]);var l={duration:c.in_duration,queue:!1,ease:"easeOutCubic",complete:function(){"function"==typeof c.ready&&c.ready.call(this,e,f)}};e.hasClass("bottom-sheet")?e.velocity({bottom:"0",opacity:1},l):(a.Velocity.hook(e,"scaleX",.7),e.css({top:c.starting_top}),e.velocity({top:c.ending_top,opacity:1,scaleX:"1"},l))}};a(document).off("click.modalTrigger",'a[href="#'+f+'"], [data-target="'+f+'"]'),a(this).off("openModal"),a(this).off("closeModal"),a(document).on("click.modalTrigger",'a[href="#'+f+'"], [data-target="'+f+'"]',function(b){c.starting_top=(a(this).offset().top-a(window).scrollTop())/1.15,h(a(this)),b.preventDefault()}),a(this).on("openModal",function(){a(this).attr("href")||"#"+a(this).data("target");h()}),a(this).on("closeModal",function(){g()})})},open:function(){a(this).trigger("openModal")},close:function(){a(this).trigger("closeModal")}};a.fn.modal=function(b){return e[b]?e[b].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof b&&b?void a.error("Method "+b+" does not exist on jQuery.modal"):e.init.apply(this,arguments)}}(jQuery),function(a){a.fn.materialbox=function(){return this.each(function(){function b(){f=!1;var b=i.parent(".material-placeholder"),d=(window.innerWidth,window.innerHeight,i.data("width")),g=i.data("height");i.velocity("stop",!0),a("#materialbox-overlay").velocity("stop",!0),a(".materialbox-caption").velocity("stop",!0),a("#materialbox-overlay").velocity({opacity:0},{duration:h,queue:!1,easing:"easeOutQuad",complete:function(){e=!1,a(this).remove()}}),i.velocity({width:d,height:g,left:0,top:0},{duration:h,queue:!1,easing:"easeOutQuad"}),a(".materialbox-caption").velocity({opacity:0},{duration:h,queue:!1,easing:"easeOutQuad",complete:function(){b.css({height:"",width:"",position:"",top:"",left:""}),i.css({height:"",top:"",left:"",width:"","max-width":"",position:"","z-index":""}),i.removeClass("active"),f=!0,a(this).remove(),c&&c.css("overflow","")}})}if(!a(this).hasClass("initialized")){a(this).addClass("initialized");var c,d,e=!1,f=!0,g=275,h=200,i=a(this),j=a("<div></div>").addClass("material-placeholder");i.wrap(j),i.on("click",function(){var h=i.parent(".material-placeholder"),j=window.innerWidth,k=window.innerHeight,l=i.width(),m=i.height();if(f===!1)return b(),!1;if(e&&f===!0)return b(),!1;f=!1,i.addClass("active"),e=!0,h.css({width:h[0].getBoundingClientRect().width,height:h[0].getBoundingClientRect().height,position:"relative",top:0,left:0}),c=void 0,d=h[0].parentNode;for(;null!==d&&!a(d).is(document);){var n=a(d);"visible"!==n.css("overflow")&&(n.css("overflow","visible"),c=void 0===c?n:c.add(n)),d=d.parentNode}i.css({position:"absolute","z-index":1e3}).data("width",l).data("height",m);var o=a('<div id="materialbox-overlay"></div>').css({opacity:0}).click(function(){f===!0&&b()});if(i.before(o),o.velocity({opacity:1},{duration:g,queue:!1,easing:"easeOutQuad"}),""!==i.data("caption")){var p=a('<div class="materialbox-caption"></div>');p.text(i.data("caption")),a("body").append(p),p.css({display:"inline"}),p.velocity({opacity:1},{duration:g,queue:!1,easing:"easeOutQuad"})}var q=0,r=l/j,s=m/k,t=0,u=0;r>s?(q=m/l,t=.9*j,u=.9*j*q):(q=l/m,t=.9*k*q,u=.9*k),i.hasClass("responsive-img")?i.velocity({"max-width":t,width:l},{duration:0,queue:!1,complete:function(){i.css({left:0,top:0}).velocity({height:u,width:t,left:a(document).scrollLeft()+j/2-i.parent(".material-placeholder").offset().left-t/2,top:a(document).scrollTop()+k/2-i.parent(".material-placeholder").offset().top-u/2},{duration:g,queue:!1,easing:"easeOutQuad",complete:function(){f=!0}})}}):i.css("left",0).css("top",0).velocity({height:u,width:t,left:a(document).scrollLeft()+j/2-i.parent(".material-placeholder").offset().left-t/2,top:a(document).scrollTop()+k/2-i.parent(".material-placeholder").offset().top-u/2},{duration:g,queue:!1,easing:"easeOutQuad",complete:function(){f=!0}})}),a(window).scroll(function(){e&&b()}),a(document).keyup(function(a){27===a.keyCode&&f===!0&&e&&b()})}})},a(document).ready(function(){a(".materialboxed").materialbox()})}(jQuery),function(a){a.fn.parallax=function(){var b=a(window).width();return this.each(function(c){function d(c){var d;d=601>b?e.height()>0?e.height():e.children("img").height():e.height()>0?e.height():500;var f=e.children("img").first(),g=f.height(),h=g-d,i=e.offset().top+d,j=e.offset().top,k=a(window).scrollTop(),l=window.innerHeight,m=k+l,n=(m-j)/(d+l),o=Math.round(h*n);c&&f.css("display","block"),i>k&&k+l>j&&f.css("transform","translate3D(-50%,"+o+"px, 0)")}var e=a(this);e.addClass("parallax"),e.children("img").one("load",function(){d(!0)}).each(function(){this.complete&&a(this).trigger("load")}),a(window).scroll(function(){b=a(window).width(),d(!1)}),a(window).resize(function(){b=a(window).width(),d(!1)})})}}(jQuery),function(a){var b={init:function(b){var c={onShow:null};return b=a.extend(c,b),this.each(function(){var c,d,e=a(this),f=(a(window).width(),e.find("li.tab a")),g=e.width(),h=Math.max(g,e[0].scrollWidth)/f.length,i=0,j=function(a){return g-a.position().left-a.outerWidth()-e.scrollLeft()},k=function(a){return a.position().left+e.scrollLeft()};c=a(f.filter('[href="'+location.hash+'"]')),0===c.length&&(c=a(this).find("li.tab a.active").first()),0===c.length&&(c=a(this).find("li.tab a").first()),c.addClass("active"),i=f.index(c),0>i&&(i=0),void 0!==c[0]&&(d=a(c[0].hash)),e.append('<div class="indicator"></div>');var l=e.find(".indicator");e.is(":visible")&&setTimeout(function(){l.css({right:j(c)}),l.css({left:k(c)})},0),a(window).resize(function(){g=e.width(),h=Math.max(g,e[0].scrollWidth)/f.length,0>i&&(i=0),0!==h&&0!==g&&(l.css({right:j(c)}),l.css({left:k(c)}))}),f.not(c).each(function(){a(Materialize.escapeHash(this.hash)).hide()}),e.on("click","a",function(m){if(a(this).parent().hasClass("disabled"))return void m.preventDefault();if(!a(this).attr("target")){g=e.width(),h=Math.max(g,e[0].scrollWidth)/f.length,c.removeClass("active"),void 0!==d&&d.hide(),c=a(this),d=a(Materialize.escapeHash(this.hash)),f=e.find("li.tab a");c.position();c.addClass("active");var n=i;i=f.index(a(this)),0>i&&(i=0),void 0!==d&&(d.show(),"function"==typeof b.onShow&&b.onShow.call(this,d)),i-n>=0?(l.velocity({right:j(c)},{duration:300,queue:!1,easing:"easeOutQuad"}),l.velocity({left:k(c)},{duration:300,queue:!1,easing:"easeOutQuad",delay:90})):(l.velocity({left:k(c)},{duration:300,queue:!1,easing:"easeOutQuad"}),l.velocity({right:j(c)},{duration:300,queue:!1,easing:"easeOutQuad",delay:90})),m.preventDefault()}})})},select_tab:function(a){this.find('a[href="#'+a+'"]').trigger("click")}};a.fn.tabs=function(c){return b[c]?b[c].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof c&&c?void a.error("Method "+c+" does not exist on jQuery.tabs"):b.init.apply(this,arguments)},a(document).ready(function(){a("ul.tabs").tabs()})}(jQuery),function(a){a.fn.tooltip=function(c){var d=5,e={delay:350,tooltip:"",position:"bottom",html:!1};return"remove"===c?(this.each(function(){a("#"+a(this).attr("data-tooltip-id")).remove(),a(this).off("mouseenter.tooltip mouseleave.tooltip")}),!1):(c=a.extend(e,c),this.each(function(){var e=Materialize.guid(),f=a(this);f.attr("data-tooltip-id")&&a("#"+f.attr("data-tooltip-id")).remove(),f.attr("data-tooltip-id",e);var g,h,i,j,k,l,m=function(){g=f.attr("data-html")?"true"===f.attr("data-html"):c.html,h=f.attr("data-delay"),h=void 0===h||""===h?c.delay:h,i=f.attr("data-position"),i=void 0===i||""===i?c.position:i,j=f.attr("data-tooltip"),j=void 0===j||""===j?c.tooltip:j};m();var n=function(){var b=a('<div class="material-tooltip"></div>');return j=g?a("<span></span>").html(j):a("<span></span>").text(j),b.append(j).appendTo(a("body")).attr("id",e),l=a('<div class="backdrop"></div>'),l.appendTo(b),b};k=n(),f.off("mouseenter.tooltip mouseleave.tooltip");var o,p=!1;f.on({"mouseenter.tooltip":function(a){var c=function(){m(),p=!0,k.velocity("stop"),l.velocity("stop"),k.css({display:"block",left:"0px",top:"0px"});var a,c,e,g=f.outerWidth(),h=f.outerHeight(),j=k.outerHeight(),n=k.outerWidth(),o="0px",q="0px",r=8,s=8;"top"===i?(a=f.offset().top-j-d,c=f.offset().left+g/2-n/2,e=b(c,a,n,j),o="-10px",l.css({bottom:0,left:0,borderRadius:"14px 14px 0 0",transformOrigin:"50% 100%",marginTop:j,marginLeft:n/2-l.width()/2})):"left"===i?(a=f.offset().top+h/2-j/2,c=f.offset().left-n-d,e=b(c,a,n,j),q="-10px",l.css({top:"-7px",right:0,width:"14px",height:"14px",borderRadius:"14px 0 0 14px",transformOrigin:"95% 50%",marginTop:j/2,marginLeft:n})):"right"===i?(a=f.offset().top+h/2-j/2,c=f.offset().left+g+d,e=b(c,a,n,j),q="+10px",l.css({top:"-7px",left:0,width:"14px",height:"14px",borderRadius:"0 14px 14px 0",transformOrigin:"5% 50%",marginTop:j/2,marginLeft:"0px"})):(a=f.offset().top+f.outerHeight()+d,c=f.offset().left+g/2-n/2,e=b(c,a,n,j),o="+10px",l.css({top:0,left:0,marginLeft:n/2-l.width()/2})),k.css({top:e.y,left:e.x}),r=Math.SQRT2*n/parseInt(l.css("width")),s=Math.SQRT2*j/parseInt(l.css("height")),k.velocity({marginTop:o,marginLeft:q},{duration:350,queue:!1}).velocity({opacity:1},{duration:300,delay:50,queue:!1}),l.css({display:"block"}).velocity({opacity:1},{duration:55,delay:0,queue:!1}).velocity({scaleX:r,scaleY:s},{duration:300,delay:0,queue:!1,easing:"easeInOutQuad"})};o=setTimeout(c,h)},"mouseleave.tooltip":function(){p=!1,clearTimeout(o),setTimeout(function(){p!==!0&&(k.velocity({opacity:0,marginTop:0,marginLeft:0},{duration:225,queue:!1}),l.velocity({opacity:0,scaleX:1,scaleY:1},{duration:225,queue:!1,complete:function(){l.css("display","none"),k.css("display","none"),p=!1}}))},225)}})}))};var b=function(b,c,d,e){var f=b,g=c;return 0>f?f=4:f+d>window.innerWidth&&(f-=f+d-window.innerWidth),0>g?g=4:g+e>window.innerHeight+a(window).scrollTop&&(g-=g+e-window.innerHeight),{x:f,y:g}};a(document).ready(function(){a(".tooltipped").tooltip()})}(jQuery),function(a){"use strict";function b(a){return null!==a&&a===a.window}function c(a){return b(a)?a:9===a.nodeType&&a.defaultView}function d(a){var b,d,e={top:0,left:0},f=a&&a.ownerDocument;return b=f.documentElement,"undefined"!=typeof a.getBoundingClientRect&&(e=a.getBoundingClientRect()),d=c(f),{top:e.top+d.pageYOffset-b.clientTop,left:e.left+d.pageXOffset-b.clientLeft}}function e(a){var b="";for(var c in a)a.hasOwnProperty(c)&&(b+=c+":"+a[c]+";");return b}function f(a){if(k.allowEvent(a)===!1)return null;for(var b=null,c=a.target||a.srcElement;null!==c.parentElement;){if(!(c instanceof SVGElement||-1===c.className.indexOf("waves-effect"))){b=c;break}if(c.classList.contains("waves-effect")){b=c;break}c=c.parentElement}return b}function g(b){var c=f(b);null!==c&&(j.show(b,c),"ontouchstart"in a&&(c.addEventListener("touchend",j.hide,!1),c.addEventListener("touchcancel",j.hide,!1)),c.addEventListener("mouseup",j.hide,!1),c.addEventListener("mouseleave",j.hide,!1))}var h=h||{},i=document.querySelectorAll.bind(document),j={duration:750,show:function(a,b){if(2===a.button)return!1;var c=b||this,f=document.createElement("div");f.className="waves-ripple",c.appendChild(f);var g=d(c),h=a.pageY-g.top,i=a.pageX-g.left,k="scale("+c.clientWidth/100*10+")";"touches"in a&&(h=a.touches[0].pageY-g.top,i=a.touches[0].pageX-g.left),f.setAttribute("data-hold",Date.now()),f.setAttribute("data-scale",k),f.setAttribute("data-x",i),f.setAttribute("data-y",h);var l={top:h+"px",left:i+"px"};f.className=f.className+" waves-notransition",f.setAttribute("style",e(l)),f.className=f.className.replace("waves-notransition",""),l["-webkit-transform"]=k,l["-moz-transform"]=k,l["-ms-transform"]=k,l["-o-transform"]=k,l.transform=k,l.opacity="1",l["-webkit-transition-duration"]=j.duration+"ms",l["-moz-transition-duration"]=j.duration+"ms",l["-o-transition-duration"]=j.duration+"ms",l["transition-duration"]=j.duration+"ms",l["-webkit-transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",l["-moz-transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",l["-o-transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",l["transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",f.setAttribute("style",e(l))},hide:function(a){k.touchup(a);var b=this,c=(1.4*b.clientWidth,null),d=b.getElementsByClassName("waves-ripple");if(!(d.length>0))return!1;c=d[d.length-1];var f=c.getAttribute("data-x"),g=c.getAttribute("data-y"),h=c.getAttribute("data-scale"),i=Date.now()-Number(c.getAttribute("data-hold")),l=350-i;0>l&&(l=0),setTimeout(function(){var a={top:g+"px",left:f+"px",opacity:"0","-webkit-transition-duration":j.duration+"ms","-moz-transition-duration":j.duration+"ms","-o-transition-duration":j.duration+"ms","transition-duration":j.duration+"ms","-webkit-transform":h,"-moz-transform":h,"-ms-transform":h,"-o-transform":h,transform:h};c.setAttribute("style",e(a)),setTimeout(function(){try{b.removeChild(c)}catch(a){return!1}},j.duration)},l)},wrapInput:function(a){for(var b=0;b<a.length;b++){var c=a[b];if("input"===c.tagName.toLowerCase()){var d=c.parentNode;if("i"===d.tagName.toLowerCase()&&-1!==d.className.indexOf("waves-effect"))continue;var e=document.createElement("i");e.className=c.className+" waves-input-wrapper";var f=c.getAttribute("style");f||(f=""),e.setAttribute("style",f),c.className="waves-button-input",c.removeAttribute("style"),d.replaceChild(e,c),e.appendChild(c)}}}},k={touches:0,allowEvent:function(a){var b=!0;return"touchstart"===a.type?k.touches+=1:"touchend"===a.type||"touchcancel"===a.type?setTimeout(function(){k.touches>0&&(k.touches-=1)},500):"mousedown"===a.type&&k.touches>0&&(b=!1),b},touchup:function(a){k.allowEvent(a)}};h.displayEffect=function(b){b=b||{},"duration"in b&&(j.duration=b.duration),j.wrapInput(i(".waves-effect")),"ontouchstart"in a&&document.body.addEventListener("touchstart",g,!1),document.body.addEventListener("mousedown",g,!1)},h.attach=function(b){"input"===b.tagName.toLowerCase()&&(j.wrapInput([b]),b=b.parentElement),"ontouchstart"in a&&b.addEventListener("touchstart",g,!1),b.addEventListener("mousedown",g,!1)},a.Waves=h,document.addEventListener("DOMContentLoaded",function(){h.displayEffect()},!1)}(window),Materialize.toast=function(a,b,c,d){function e(a){var b=document.createElement("div");if(b.classList.add("toast"),c)for(var e=c.split(" "),f=0,g=e.length;g>f;f++)b.classList.add(e[f]);("object"==typeof HTMLElement?a instanceof HTMLElement:a&&"object"==typeof a&&null!==a&&1===a.nodeType&&"string"==typeof a.nodeName)?b.appendChild(a):a instanceof jQuery?b.appendChild(a[0]):b.innerHTML=a;var h=new Hammer(b,{prevent_default:!1});return h.on("pan",function(a){var c=a.deltaX,d=80;b.classList.contains("panning")||b.classList.add("panning");var e=1-Math.abs(c/d);0>e&&(e=0),Vel(b,{left:c,opacity:e},{duration:50,queue:!1,easing:"easeOutQuad"})}),h.on("panend",function(a){var c=a.deltaX,e=80;Math.abs(c)>e?Vel(b,{marginTop:"-40px"},{duration:375,easing:"easeOutExpo",queue:!1,complete:function(){"function"==typeof d&&d(),b.parentNode.removeChild(b)}}):(b.classList.remove("panning"),Vel(b,{left:0,opacity:1},{duration:300,easing:"easeOutExpo",queue:!1}))}),b}c=c||"";var f=document.getElementById("toast-container");null===f&&(f=document.createElement("div"),f.id="toast-container",document.body.appendChild(f));var g=e(a);a&&f.appendChild(g),g.style.top="35px",g.style.opacity=0,Vel(g,{top:"0px",opacity:1},{duration:300,easing:"easeOutCubic",queue:!1});var h,i=b;null!=i&&(h=setInterval(function(){null===g.parentNode&&window.clearInterval(h),g.classList.contains("panning")||(i-=20),0>=i&&(Vel(g,{opacity:0,marginTop:"-40px"},{duration:375,easing:"easeOutExpo",queue:!1,complete:function(){"function"==typeof d&&d(),this[0].parentNode.removeChild(this[0])}}),window.clearInterval(h))},20))},function(a){var b={init:function(b){var c={menuWidth:300,edge:"left",closeOnClick:!1,draggable:!0};b=a.extend(c,b),a(this).each(function(){var c=a(this),d=a("#"+c.attr("data-activates"));300!=b.menuWidth&&d.css("width",b.menuWidth);var e;b.draggable?(e=a('<div class="drag-target"></div>').attr("data-sidenav",c.attr("data-activates")),a("body").append(e)):e=a(),"left"==b.edge?(d.css("transform","translateX(-100%)"),e.css({left:0})):(d.addClass("right-aligned").css("transform","translateX(100%)"),e.css({right:0})),d.hasClass("fixed")&&window.innerWidth>992&&d.css("transform","translateX(0)"),d.hasClass("fixed")&&a(window).resize(function(){window.innerWidth>992?0!==a("#sidenav-overlay").length&&h?f(!0):d.css("transform","translateX(0%)"):h===!1&&("left"===b.edge?d.css("transform","translateX(-100%)"):d.css("transform","translateX(100%)"))}),b.closeOnClick===!0&&d.on("click.itemclick","a:not(.collapsible-header)",function(){f()});var f=function(c){g=!1,h=!1,a("body").css({overflow:"",width:""}),a("#sidenav-overlay").velocity({opacity:0},{duration:200,queue:!1,easing:"easeOutQuad",complete:function(){a(this).remove()}}),"left"===b.edge?(e.css({width:"",right:"",left:"0"}),d.velocity({translateX:"-100%"},{duration:200,queue:!1,easing:"easeOutCubic",complete:function(){c===!0&&(d.removeAttr("style"),d.css("width",b.menuWidth))}})):(e.css({width:"",right:"0",left:""}),d.velocity({translateX:"100%"},{duration:200,queue:!1,easing:"easeOutCubic",complete:function(){c===!0&&(d.removeAttr("style"),d.css("width",b.menuWidth))}}))},g=!1,h=!1;b.draggable&&(e.on("click",function(){h&&f()}),e.hammer({prevent_default:!1}).bind("pan",function(c){if("touch"==c.gesture.pointerType){var e=(c.gesture.direction,c.gesture.center.x),g=(c.gesture.center.y,c.gesture.velocityX,a("body")),i=a("#sidenav-overlay"),j=g.innerWidth();if(g.css("overflow","hidden"),g.width(j),0===i.length&&(i=a('<div id="sidenav-overlay"></div>'),i.css("opacity",0).click(function(){f()}),a("body").append(i)),"left"===b.edge&&(e>b.menuWidth?e=b.menuWidth:0>e&&(e=0)),"left"===b.edge)e<b.menuWidth/2?h=!1:e>=b.menuWidth/2&&(h=!0),d.css("transform","translateX("+(e-b.menuWidth)+"px)");else{e<window.innerWidth-b.menuWidth/2?h=!0:e>=window.innerWidth-b.menuWidth/2&&(h=!1);var k=e-b.menuWidth/2;0>k&&(k=0),d.css("transform","translateX("+k+"px)")}var l;"left"===b.edge?(l=e/b.menuWidth,i.velocity({opacity:l},{duration:10,queue:!1,easing:"easeOutQuad"})):(l=Math.abs((e-window.innerWidth)/b.menuWidth),i.velocity({opacity:l},{duration:10,queue:!1,easing:"easeOutQuad"}))}}).bind("panend",function(c){if("touch"==c.gesture.pointerType){var f=a('<div id="sidenav-overlay"></div>'),i=c.gesture.velocityX,j=c.gesture.center.x,k=j-b.menuWidth,l=j-b.menuWidth/2;k>0&&(k=0),0>l&&(l=0),g=!1,"left"===b.edge?h&&.3>=i||-.5>i?(0!==k&&d.velocity({translateX:[0,k]},{duration:300,queue:!1,easing:"easeOutQuad"}),f.velocity({opacity:1},{duration:50,queue:!1,easing:"easeOutQuad"}),e.css({width:"50%",right:0,left:""}),h=!0):(!h||i>.3)&&(a("body").css({overflow:"",width:""}),d.velocity({translateX:[-1*b.menuWidth-10,k]},{duration:200,queue:!1,easing:"easeOutQuad"}),f.velocity({opacity:0},{duration:200,queue:!1,easing:"easeOutQuad",complete:function(){a(this).remove()}}),e.css({width:"10px",right:"",left:0})):h&&i>=-.3||i>.5?(0!==l&&d.velocity({translateX:[0,l]},{duration:300,queue:!1,easing:"easeOutQuad"}),f.velocity({opacity:1},{duration:50,queue:!1,easing:"easeOutQuad"}),e.css({width:"50%",right:"",left:0}),h=!0):(!h||-.3>i)&&(a("body").css({overflow:"",width:""}),d.velocity({translateX:[b.menuWidth+10,l]},{duration:200,queue:!1,easing:"easeOutQuad"}),f.velocity({opacity:0},{duration:200,queue:!1,easing:"easeOutQuad",complete:function(){a(this).remove()}}),e.css({width:"10px",right:0,left:""}))}})),c.click(function(){if(h===!0)h=!1,g=!1,f();else{var c=a("body"),i=a('<div id="sidenav-overlay"></div>'),j=c.innerWidth();c.css("overflow","hidden"),c.width(j),a("body").append(e),"left"===b.edge?(e.css({width:"50%",right:0,left:""}),d.velocity({translateX:[0,-1*b.menuWidth]},{duration:300,queue:!1,easing:"easeOutQuad"})):(e.css({width:"50%",right:"",left:0}),d.velocity({translateX:[0,b.menuWidth]},{duration:300,queue:!1,easing:"easeOutQuad"})),i.css("opacity",0).click(function(){h=!1,g=!1,f(),i.velocity({opacity:0},{duration:300,queue:!1,easing:"easeOutQuad",complete:function(){a(this).remove()}})}),a("body").append(i),i.velocity({opacity:1},{duration:300,queue:!1,easing:"easeOutQuad",complete:function(){h=!0,g=!1}})}return!1})})},destroy:function(){var b=a("#sidenav-overlay"),c=a('.drag-target[data-sidenav="'+a(this).attr("data-activates")+'"]');b.trigger("click"),c.remove(),a(this).off("click"),b.remove()},show:function(){this.trigger("click")},hide:function(){a("#sidenav-overlay").trigger("click")}};a.fn.sideNav=function(c){return b[c]?b[c].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof c&&c?void a.error("Method "+c+" does not exist on jQuery.sideNav"):b.init.apply(this,arguments)}}(jQuery),function(a){function b(b,c,d,e){var f=a();return a.each(g,function(a,g){if(g.height()>0){var h=g.offset().top,i=g.offset().left,j=i+g.width(),k=h+g.height(),l=!(i>c||e>j||h>d||b>k);l&&f.push(g)}}),f}function c(c){++j;var d=f.scrollTop(),e=f.scrollLeft(),g=e+f.width(),i=d+f.height(),l=b(d+k.top+c||200,g+k.right,i+k.bottom,e+k.left);a.each(l,function(a,b){var c=b.data("scrollSpy:ticks");"number"!=typeof c&&b.triggerHandler("scrollSpy:enter"),b.data("scrollSpy:ticks",j)}),a.each(h,function(a,b){var c=b.data("scrollSpy:ticks");"number"==typeof c&&c!==j&&(b.triggerHandler("scrollSpy:exit"),b.data("scrollSpy:ticks",null))}),h=l}function d(){f.trigger("scrollSpy:winSize")}function e(a,b,c){var d,e,f,g=null,h=0;c||(c={});var i=function(){h=c.leading===!1?0:l(),g=null,f=a.apply(d,e),d=e=null};return function(){var j=l();h||c.leading!==!1||(h=j);var k=b-(j-h);return d=this,e=arguments,0>=k?(clearTimeout(g),g=null,h=j,f=a.apply(d,e),d=e=null):g||c.trailing===!1||(g=setTimeout(i,k)),f}}var f=a(window),g=[],h=[],i=!1,j=0,k={top:0,right:0,bottom:0,left:0},l=Date.now||function(){return(new Date).getTime()};a.scrollSpy=function(b,d){var h={throttle:100,scrollOffset:200};d=a.extend(h,d);var j=[];b=a(b),b.each(function(b,c){g.push(a(c)),a(c).data("scrollSpy:id",b),a('a[href="#'+a(c).attr("id")+'"]').click(function(b){b.preventDefault();var c=a(Materialize.escapeHash(this.hash)).offset().top+1;a("html, body").animate({scrollTop:c-d.scrollOffset},{duration:400,queue:!1,easing:"easeOutCubic"})})}),k.top=d.offsetTop||0,k.right=d.offsetRight||0,k.bottom=d.offsetBottom||0,k.left=d.offsetLeft||0;var l=e(function(){c(d.scrollOffset)},d.throttle||100),m=function(){a(document).ready(l)};return i||(f.on("scroll",m),f.on("resize",m),i=!0),setTimeout(m,0),b.on("scrollSpy:enter",function(){j=a.grep(j,function(a){return 0!=a.height()});var b=a(this);j[0]?(a('a[href="#'+j[0].attr("id")+'"]').removeClass("active"),b.data("scrollSpy:id")<j[0].data("scrollSpy:id")?j.unshift(a(this)):j.push(a(this))):j.push(a(this)),a('a[href="#'+j[0].attr("id")+'"]').addClass("active")}),b.on("scrollSpy:exit",function(){if(j=a.grep(j,function(a){return 0!=a.height()}),j[0]){a('a[href="#'+j[0].attr("id")+'"]').removeClass("active");var b=a(this);j=a.grep(j,function(a){return a.attr("id")!=b.attr("id")}),j[0]&&a('a[href="#'+j[0].attr("id")+'"]').addClass("active")}}),b},a.winSizeSpy=function(b){return a.winSizeSpy=function(){return f},b=b||{throttle:100},f.on("resize",e(d,b.throttle||100))},a.fn.scrollSpy=function(b){return a.scrollSpy(a(this),b)}}(jQuery),function(a){a(document).ready(function(){function b(b){var c=b.css("font-family"),d=b.css("font-size"),f=b.css("line-height");d&&e.css("font-size",d),c&&e.css("font-family",c),f&&e.css("line-height",f),"off"===b.attr("wrap")&&e.css("overflow-wrap","normal").css("white-space","pre"),e.text(b.val()+"\n");var g=e.html().replace(/\n/g,"<br>");e.html(g),b.is(":visible")?e.css("width",b.width()):e.css("width",a(window).width()/2),b.css("height",e.height())}Materialize.updateTextFields=function(){var b="input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea";a(b).each(function(b,c){a(c).val().length>0||c.autofocus||void 0!==a(this).attr("placeholder")||a(c)[0].validity.badInput===!0?a(this).siblings("label").addClass("active"):a(this).siblings("label").removeClass("active")})};var c="input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea";a(document).on("change",c,function(){(0!==a(this).val().length||void 0!==a(this).attr("placeholder"))&&a(this).siblings("label").addClass("active"),validate_field(a(this))}),a(document).ready(function(){Materialize.updateTextFields()}),a(document).on("reset",function(b){var d=a(b.target);d.is("form")&&(d.find(c).removeClass("valid").removeClass("invalid"),d.find(c).each(function(){""===a(this).attr("value")&&a(this).siblings("label").removeClass("active")}),d.find("select.initialized").each(function(){var a=d.find("option[selected]").text();d.siblings("input.select-dropdown").val(a)}))}),a(document).on("focus",c,function(){a(this).siblings("label, .prefix").addClass("active")}),a(document).on("blur",c,function(){var b=a(this),c=".prefix";0===b.val().length&&b[0].validity.badInput!==!0&&void 0===b.attr("placeholder")&&(c+=", label"),b.siblings(c).removeClass("active"),validate_field(b)}),window.validate_field=function(a){var b=void 0!==a.attr("length"),c=parseInt(a.attr("length")),d=a.val().length;0===a.val().length&&a[0].validity.badInput===!1?a.hasClass("validate")&&(a.removeClass("valid"),a.removeClass("invalid")):a.hasClass("validate")&&(a.is(":valid")&&b&&c>=d||a.is(":valid")&&!b?(a.removeClass("invalid"),a.addClass("valid")):(a.removeClass("valid"),a.addClass("invalid")))};var d="input[type=radio], input[type=checkbox]";a(document).on("keyup.radio",d,function(b){if(9===b.which){a(this).addClass("tabbed");var c=a(this);return void c.one("blur",function(b){a(this).removeClass("tabbed")})}});var e=a(".hiddendiv").first();e.length||(e=a('<div class="hiddendiv common"></div>'),a("body").append(e));var f=".materialize-textarea";a(f).each(function(){var c=a(this);c.val().length&&b(c)}),a("body").on("keyup keydown autoresize",f,function(){b(a(this))}),a(document).on("change",'.file-field input[type="file"]',function(){for(var b=a(this).closest(".file-field"),c=b.find("input.file-path"),d=a(this)[0].files,e=[],f=0;f<d.length;f++)e.push(d[f].name);c.val(e.join(", ")),c.trigger("change")});var g,h="input[type=range]",i=!1;a(h).each(function(){var b=a('<span class="thumb"><span class="value"></span></span>');a(this).after(b)});var j=".range-field";a(document).on("change",h,function(b){var c=a(this).siblings(".thumb");c.find(".value").html(a(this).val())}),a(document).on("input mousedown touchstart",h,function(b){var c=a(this).siblings(".thumb"),d=a(this).outerWidth();c.length<=0&&(c=a('<span class="thumb"><span class="value"></span></span>'),a(this).after(c)),c.find(".value").html(a(this).val()),i=!0,a(this).addClass("active"),c.hasClass("active")||c.velocity({height:"30px",width:"30px",top:"-20px",marginLeft:"-15px"},{duration:300,easing:"easeOutExpo"}),"input"!==b.type&&(g=void 0===b.pageX||null===b.pageX?b.originalEvent.touches[0].pageX-a(this).offset().left:b.pageX-a(this).offset().left,0>g?g=0:g>d&&(g=d),c.addClass("active").css("left",g)),c.find(".value").html(a(this).val())}),a(document).on("mouseup touchend",j,function(){i=!1,a(this).removeClass("active")}),a(document).on("mousemove touchmove",j,function(b){var c,d=a(this).children(".thumb");if(i){d.hasClass("active")||d.velocity({height:"30px",width:"30px",top:"-20px",marginLeft:"-15px"},{duration:300,easing:"easeOutExpo"}),c=void 0===b.pageX||null===b.pageX?b.originalEvent.touches[0].pageX-a(this).offset().left:b.pageX-a(this).offset().left;var e=a(this).outerWidth();0>c?c=0:c>e&&(c=e),d.addClass("active").css("left",c),d.find(".value").html(d.siblings(h).val())}}),a(document).on("mouseout touchleave",j,function(){if(!i){var b=a(this).children(".thumb");b.hasClass("active")&&b.velocity({height:"0",width:"0",top:"10px",marginLeft:"-6px"},{duration:100}),b.removeClass("active")}}),a.fn.autocomplete=function(b){var c={data:{}};return b=a.extend(c,b),this.each(function(){var c=a(this),d=b.data,e=c.closest(".input-field");if(!a.isEmptyObject(d)){var f=a('<ul class="autocomplete-content dropdown-content"></ul>');e.length?e.append(f):c.after(f);var g=function(a,b){var c=b.find("img"),d=b.text().toLowerCase().indexOf(""+a.toLowerCase()),e=d+a.length-1,f=b.text().slice(0,d),g=b.text().slice(d,e+1),h=b.text().slice(e+1);b.html("<span>"+f+"<span class='highlight'>"+g+"</span>"+h+"</span>"),c.length&&b.prepend(c)};c.on("keyup",function(b){if(13===b.which)return void f.find("li").first().click();var e=c.val().toLowerCase();if(f.empty(),""!==e)for(var h in d)if(d.hasOwnProperty(h)&&-1!==h.toLowerCase().indexOf(e)&&h.toLowerCase()!==e){var i=a("<li></li>");d[h]?i.append('<img src="'+d[h]+'" class="right circle"><span>'+h+"</span>"):i.append("<span>"+h+"</span>"),f.append(i),g(e,i)}}),f.on("click","li",function(){c.val(a(this).text().trim()),c.trigger("change"),f.empty()})}})}}),a.fn.material_select=function(b){function c(a,b,c){var e=a.indexOf(b),f=-1===e;return f?a.push(b):a.splice(e,1),c.siblings("ul.dropdown-content").find("li").eq(b).toggleClass("active"),c.find("option").eq(b).prop("selected",f),d(a,c),f}function d(a,b){for(var c="",d=0,e=a.length;e>d;d++){var f=b.find("option").eq(a[d]).text();c+=0===d?f:", "+f}""===c&&(c=b.find("option:disabled").eq(0).text()),b.siblings("input.select-dropdown").val(c)}a(this).each(function(){var d=a(this);if(!d.hasClass("browser-default")){var e=d.attr("multiple")?!0:!1,f=d.data("select-id");if(f&&(d.parent().find("span.caret").remove(),d.parent().find("input").remove(),d.unwrap(),a("ul#select-options-"+f).remove()),"destroy"===b)return void d.data("select-id",null).removeClass("initialized");var g=Materialize.guid();d.data("select-id",g);var h=a('<div class="select-wrapper"></div>');h.addClass(d.attr("class"));var i=a('<ul id="select-options-'+g+'" class="dropdown-content select-dropdown '+(e?"multiple-select-dropdown":"")+'"></ul>'),j=d.children("option, optgroup"),k=[],l=!1,m=d.find("option:selected").html()||d.find("option:first").html()||"",n=function(b,c,d){var e=c.is(":disabled")?"disabled ":"",f="optgroup-option"===d?"optgroup-option ":"",g=c.data("icon"),h=c.attr("class");if(g){var j="";return h&&(j=' class="'+h+'"'),"multiple"===d?i.append(a('<li class="'+e+'"><img alt="" src="'+g+'"'+j+'><span><input type="checkbox"'+e+"/><label></label>"+c.html()+"</span></li>")):i.append(a('<li class="'+e+f+'"><img alt="" src="'+g+'"'+j+"><span>"+c.html()+"</span></li>")),!0}"multiple"===d?i.append(a('<li class="'+e+'"><span><input type="checkbox"'+e+"/><label></label>"+c.html()+"</span></li>")):i.append(a('<li class="'+e+f+'"><span>'+c.html()+"</span></li>"))};j.length&&j.each(function(){if(a(this).is("option"))e?n(d,a(this),"multiple"):n(d,a(this));else if(a(this).is("optgroup")){var b=a(this).children("option");i.append(a('<li class="optgroup"><span>'+a(this).attr("label")+"</span></li>")),b.each(function(){n(d,a(this),"optgroup-option")})}}),i.find("li:not(.optgroup)").each(function(f){a(this).click(function(g){if(!a(this).hasClass("disabled")&&!a(this).hasClass("optgroup")){
9
+ var h=!0;e?(a('input[type="checkbox"]',this).prop("checked",function(a,b){return!b}),h=c(k,a(this).index(),d),q.trigger("focus")):(i.find("li").removeClass("active"),a(this).toggleClass("active"),q.val(a(this).text())),r(i,a(this)),d.find("option").eq(f).prop("selected",h),d.trigger("change"),"undefined"!=typeof b&&b()}g.stopPropagation()})}),d.wrap(h);var o=a('<span class="caret">&#9660;</span>');d.is(":disabled")&&o.addClass("disabled");var p=m.replace(/"/g,"&quot;"),q=a('<input type="text" class="select-dropdown" readonly="true" '+(d.is(":disabled")?"disabled":"")+' data-activates="select-options-'+g+'" value="'+p+'"/>');d.before(q),q.before(o),q.after(i),d.is(":disabled")||q.dropdown({hover:!1,closeOnClick:!1}),d.attr("tabindex")&&a(q[0]).attr("tabindex",d.attr("tabindex")),d.addClass("initialized"),q.on({focus:function(){if(a("ul.select-dropdown").not(i[0]).is(":visible")&&a("input.select-dropdown").trigger("close"),!i.is(":visible")){a(this).trigger("open",["focus"]);var b=a(this).val(),c=i.find("li").filter(function(){return a(this).text().toLowerCase()===b.toLowerCase()})[0];r(i,c)}},click:function(a){a.stopPropagation()}}),q.on("blur",function(){e||a(this).trigger("close"),i.find("li.selected").removeClass("selected")}),i.hover(function(){l=!0},function(){l=!1}),a(window).on({click:function(){e&&(l||q.trigger("close"))}}),e&&d.find("option:selected:not(:disabled)").each(function(){var b=a(this).index();c(k,b,d),i.find("li").eq(b).find(":checkbox").prop("checked",!0)});var r=function(b,c){if(c){b.find("li.selected").removeClass("selected");var d=a(c);d.addClass("selected"),i.scrollTo(d)}},s=[],t=function(b){if(9==b.which)return void q.trigger("close");if(40==b.which&&!i.is(":visible"))return void q.trigger("open");if(13!=b.which||i.is(":visible")){b.preventDefault();var c=String.fromCharCode(b.which).toLowerCase(),d=[9,13,27,38,40];if(c&&-1===d.indexOf(b.which)){s.push(c);var f=s.join(""),g=i.find("li").filter(function(){return 0===a(this).text().toLowerCase().indexOf(f)})[0];g&&r(i,g)}if(13==b.which){var h=i.find("li.selected:not(.disabled)")[0];h&&(a(h).trigger("click"),e||q.trigger("close"))}40==b.which&&(g=i.find("li.selected").length?i.find("li.selected").next("li:not(.disabled)")[0]:i.find("li:not(.disabled)")[0],r(i,g)),27==b.which&&q.trigger("close"),38==b.which&&(g=i.find("li.selected").prev("li:not(.disabled)")[0],g&&r(i,g)),setTimeout(function(){s=[]},1e3)}};q.on("keydown",t)}})}}(jQuery),function(a){var b={init:function(b){var c={indicators:!0,height:400,transition:500,interval:6e3};return b=a.extend(c,b),this.each(function(){function c(a,b){a.hasClass("center-align")?a.velocity({opacity:0,translateY:-100},{duration:b,queue:!1}):a.hasClass("right-align")?a.velocity({opacity:0,translateX:100},{duration:b,queue:!1}):a.hasClass("left-align")&&a.velocity({opacity:0,translateX:-100},{duration:b,queue:!1})}function d(a){a>=j.length?a=0:0>a&&(a=j.length-1),k=i.find(".active").index(),k!=a&&(e=j.eq(k),$caption=e.find(".caption"),e.removeClass("active"),e.velocity({opacity:0},{duration:b.transition,queue:!1,easing:"easeOutQuad",complete:function(){j.not(".active").velocity({opacity:0,translateX:0,translateY:0},{duration:0,queue:!1})}}),c($caption,b.transition),b.indicators&&f.eq(k).removeClass("active"),j.eq(a).velocity({opacity:1},{duration:b.transition,queue:!1,easing:"easeOutQuad"}),j.eq(a).find(".caption").velocity({opacity:1,translateX:0,translateY:0},{duration:b.transition,delay:b.transition,queue:!1,easing:"easeOutQuad"}),j.eq(a).addClass("active"),b.indicators&&f.eq(a).addClass("active"))}var e,f,g,h=a(this),i=h.find("ul.slides").first(),j=i.find("> li"),k=i.find(".active").index();-1!=k&&(e=j.eq(k)),h.hasClass("fullscreen")||(b.indicators?h.height(b.height+40):h.height(b.height),i.height(b.height)),j.find(".caption").each(function(){c(a(this),0)}),j.find("img").each(function(){var b="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";a(this).attr("src")!==b&&(a(this).css("background-image","url("+a(this).attr("src")+")"),a(this).attr("src",b))}),b.indicators&&(f=a('<ul class="indicators"></ul>'),j.each(function(c){var e=a('<li class="indicator-item"></li>');e.click(function(){var c=i.parent(),e=c.find(a(this)).index();d(e),clearInterval(g),g=setInterval(function(){k=i.find(".active").index(),j.length==k+1?k=0:k+=1,d(k)},b.transition+b.interval)}),f.append(e)}),h.append(f),f=h.find("ul.indicators").find("li.indicator-item")),e?e.show():(j.first().addClass("active").velocity({opacity:1},{duration:b.transition,queue:!1,easing:"easeOutQuad"}),k=0,e=j.eq(k),b.indicators&&f.eq(k).addClass("active")),e.find("img").each(function(){e.find(".caption").velocity({opacity:1,translateX:0,translateY:0},{duration:b.transition,queue:!1,easing:"easeOutQuad"})}),g=setInterval(function(){k=i.find(".active").index(),d(k+1)},b.transition+b.interval);var l=!1,m=!1,n=!1;h.hammer({prevent_default:!1}).bind("pan",function(a){if("touch"===a.gesture.pointerType){clearInterval(g);var b=a.gesture.direction,c=a.gesture.deltaX,d=a.gesture.velocityX;$curr_slide=i.find(".active"),$curr_slide.velocity({translateX:c},{duration:50,queue:!1,easing:"easeOutQuad"}),4===b&&(c>h.innerWidth()/2||-.65>d)?n=!0:2===b&&(c<-1*h.innerWidth()/2||d>.65)&&(m=!0);var e;m&&(e=$curr_slide.next(),0===e.length&&(e=j.first()),e.velocity({opacity:1},{duration:300,queue:!1,easing:"easeOutQuad"})),n&&(e=$curr_slide.prev(),0===e.length&&(e=j.last()),e.velocity({opacity:1},{duration:300,queue:!1,easing:"easeOutQuad"}))}}).bind("panend",function(a){"touch"===a.gesture.pointerType&&($curr_slide=i.find(".active"),l=!1,curr_index=i.find(".active").index(),!n&&!m||j.length<=1?$curr_slide.velocity({translateX:0},{duration:300,queue:!1,easing:"easeOutQuad"}):m?(d(curr_index+1),$curr_slide.velocity({translateX:-1*h.innerWidth()},{duration:300,queue:!1,easing:"easeOutQuad",complete:function(){$curr_slide.velocity({opacity:0,translateX:0},{duration:0,queue:!1})}})):n&&(d(curr_index-1),$curr_slide.velocity({translateX:h.innerWidth()},{duration:300,queue:!1,easing:"easeOutQuad",complete:function(){$curr_slide.velocity({opacity:0,translateX:0},{duration:0,queue:!1})}})),m=!1,n=!1,clearInterval(g),g=setInterval(function(){k=i.find(".active").index(),j.length==k+1?k=0:k+=1,d(k)},b.transition+b.interval))}),h.on("sliderPause",function(){clearInterval(g)}),h.on("sliderStart",function(){clearInterval(g),g=setInterval(function(){k=i.find(".active").index(),j.length==k+1?k=0:k+=1,d(k)},b.transition+b.interval)}),h.on("sliderNext",function(){k=i.find(".active").index(),d(k+1)}),h.on("sliderPrev",function(){k=i.find(".active").index(),d(k-1)})})},pause:function(){a(this).trigger("sliderPause")},start:function(){a(this).trigger("sliderStart")},next:function(){a(this).trigger("sliderNext")},prev:function(){a(this).trigger("sliderPrev")}};a.fn.slider=function(c){return b[c]?b[c].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof c&&c?void a.error("Method "+c+" does not exist on jQuery.tooltip"):b.init.apply(this,arguments)}}(jQuery),function(a){a(document).ready(function(){a(document).on("click.card",".card",function(b){a(this).find("> .card-reveal").length&&(a(b.target).is(a(".card-reveal .card-title"))||a(b.target).is(a(".card-reveal .card-title i"))?a(this).find(".card-reveal").velocity({translateY:0},{duration:225,queue:!1,easing:"easeInOutQuad",complete:function(){a(this).css({display:"none"})}}):(a(b.target).is(a(".card .activator"))||a(b.target).is(a(".card .activator i")))&&(a(b.target).closest(".card").css("overflow","hidden"),a(this).find(".card-reveal").css({display:"block"}).velocity("stop",!1).velocity({translateY:"-100%"},{duration:300,queue:!1,easing:"easeInOutQuad"})))})})}(jQuery),function(a){var b=!1,c={data:[],placeholder:"",secondaryPlaceholder:""};a(document).ready(function(){a(document).on("click",".chip .close",function(b){var c=a(this).closest(".chips");c.attr("data-initialized")||a(this).closest(".chip").remove()})}),a.fn.material_chip=function(d){var e=this;if(this.$el=a(this),this.$document=a(document),this.SELS={CHIPS:".chips",CHIP:".chip",INPUT:"input",DELETE:".material-icons",SELECTED_CHIP:".selected"},"data"===d)return this.$el.data("chips");var f=a.extend({},c,d);this.init=function(){var b=0;e.$el.each(function(){var c=a(this),d=Materialize.guid();f.data&&f.data instanceof Array||(f.data=[]),c.data("chips",f.data),c.attr("data-index",b),c.attr("data-initialized",!0),c.hasClass(e.SELS.CHIPS)||c.addClass("chips"),e.chips(c,d),b++})},this.handleEvents=function(){var b=e.SELS;e.$document.off("click.chips-focus",b.CHIPS).on("click.chips-focus",b.CHIPS,function(c){a(c.target).find(b.INPUT).focus()}),e.$document.off("click.chips-select",b.CHIP).on("click.chips-select",b.CHIP,function(c){a(b.CHIP).removeClass("selected"),a(this).toggleClass("selected")}),e.$document.off("keydown.chips").on("keydown.chips",function(c){if(!a(c.target).is("input, textarea")){var d,f=e.$document.find(b.CHIP+b.SELECTED_CHIP),g=f.closest(b.CHIPS),h=f.siblings(b.CHIP).length;if(f.length)if(8===c.which||46===c.which){c.preventDefault(),d=f.index(),e.deleteChip(d,g);var i=null;h>d+1?i=d:(d===h||d+1===h)&&(i=h-1),0>i&&(i=null),null!==i&&e.selectChip(i,g),h||g.find("input").focus()}else if(37===c.which){if(d=f.index()-1,0>d)return;a(b.CHIP).removeClass("selected"),e.selectChip(d,g)}else if(39===c.which){if(d=f.index()+1,a(b.CHIP).removeClass("selected"),d>h)return void g.find("input").focus();e.selectChip(d,g)}}}),e.$document.off("focusin.chips",b.CHIPS+" "+b.INPUT).on("focusin.chips",b.CHIPS+" "+b.INPUT,function(c){var d=a(c.target).closest(b.CHIPS);d.addClass("focus"),d.siblings("label, .prefix").addClass("active"),a(b.CHIP).removeClass("selected")}),e.$document.off("focusout.chips",b.CHIPS+" "+b.INPUT).on("focusout.chips",b.CHIPS+" "+b.INPUT,function(c){var d=a(c.target).closest(b.CHIPS);d.removeClass("focus"),d.data("chips").length||d.siblings("label").removeClass("active"),d.siblings(".prefix").removeClass("active")}),e.$document.off("keydown.chips-add",b.CHIPS+" "+b.INPUT).on("keydown.chips-add",b.CHIPS+" "+b.INPUT,function(c){var d=a(c.target),f=d.closest(b.CHIPS),g=f.children(b.CHIP).length;return 13===c.which?(c.preventDefault(),e.addChip({tag:d.val()},f),void d.val("")):8!==c.keyCode&&37!==c.keyCode||""!==d.val()||!g?void 0:(e.selectChip(g-1,f),void d.blur())}),e.$document.off("click.chips-delete",b.CHIPS+" "+b.DELETE).on("click.chips-delete",b.CHIPS+" "+b.DELETE,function(c){var d=a(c.target),f=d.closest(b.CHIPS),g=d.closest(b.CHIP);c.stopPropagation(),e.deleteChip(g.index(),f),f.find("input").focus()})},this.chips=function(a,b){var c="";a.data("chips").forEach(function(a){c+=e.renderChip(a)}),c+='<input id="'+b+'" class="input" placeholder="">',a.html(c),e.setPlaceholder(a);var d=a.next("label");d.length&&(d.attr("for",b),a.data("chips").length&&d.addClass("active"))},this.renderChip=function(a){if(a.tag){var b='<div class="chip">'+a.tag;return a.image&&(b+=' <img src="'+a.image+'"> '),b+='<i class="material-icons close">close</i>',b+="</div>"}},this.setPlaceholder=function(a){a.data("chips").length&&f.placeholder?a.find("input").prop("placeholder",f.placeholder):!a.data("chips").length&&f.secondaryPlaceholder&&a.find("input").prop("placeholder",f.secondaryPlaceholder)},this.isValid=function(a,b){for(var c=a.data("chips"),d=!1,e=0;e<c.length;e++)if(c[e].tag===b.tag)return void(d=!0);return""!==b.tag&&!d},this.addChip=function(b,c){if(e.isValid(c,b)){for(var d=e.renderChip(b),f=[],g=c.data("chips"),h=0;h<g.length;h++)f.push(g[h]);f.push(b),c.data("chips",f),a(d).insertBefore(c.find("input")),c.trigger("chip.add",b),e.setPlaceholder(c)}},this.deleteChip=function(a,b){var c=b.data("chips")[a];b.find(".chip").eq(a).remove();for(var d=[],f=b.data("chips"),g=0;g<f.length;g++)g!==a&&d.push(f[g]);b.data("chips",d),b.trigger("chip.delete",c),e.setPlaceholder(b)},this.selectChip=function(a,b){var c=b.find(".chip").eq(a);c&&!1===c.hasClass("selected")&&(c.addClass("selected"),b.trigger("chip.select",b.data("chips")[a]))},this.getChipsElement=function(a,b){return b.eq(a)},this.init(),b||(this.handleEvents(),b=!0)}}(jQuery),function(a){a.fn.pushpin=function(b){var c={top:0,bottom:1/0,offset:0};return"remove"===b?(this.each(function(){(id=a(this).data("pushpin-id"))&&(a(window).off("scroll."+id),a(this).removeData("pushpin-id").removeClass("pin-top pinned pin-bottom").removeAttr("style"))}),!1):(b=a.extend(c,b),$index=0,this.each(function(){function c(a){a.removeClass("pin-top"),a.removeClass("pinned"),a.removeClass("pin-bottom")}function d(d,e){d.each(function(){b.top<=e&&b.bottom>=e&&!a(this).hasClass("pinned")&&(c(a(this)),a(this).css("top",b.offset),a(this).addClass("pinned")),e<b.top&&!a(this).hasClass("pin-top")&&(c(a(this)),a(this).css("top",0),a(this).addClass("pin-top")),e>b.bottom&&!a(this).hasClass("pin-bottom")&&(c(a(this)),a(this).addClass("pin-bottom"),a(this).css("top",b.bottom-g))})}var e=Materialize.guid(),f=a(this),g=a(this).offset().top;a(this).data("pushpin-id",e),d(f,a(window).scrollTop()),a(window).on("scroll."+e,function(){var c=a(window).scrollTop()+b.offset;d(f,c)})}))}}(jQuery),function(a){a(document).ready(function(){a.fn.reverse=[].reverse,a(document).on("mouseenter.fixedActionBtn",".fixed-action-btn:not(.click-to-toggle):not(.toolbar)",function(c){var d=a(this);b(d)}),a(document).on("mouseleave.fixedActionBtn",".fixed-action-btn:not(.click-to-toggle):not(.toolbar)",function(b){var d=a(this);c(d)}),a(document).on("click.fabClickToggle",".fixed-action-btn.click-to-toggle > a",function(d){var e=a(this),f=e.parent();f.hasClass("active")?c(f):b(f)}),a(document).on("click.fabToolbar",".fixed-action-btn.toolbar > a",function(b){var c=a(this),e=c.parent();d(e)})}),a.fn.extend({openFAB:function(){b(a(this))},closeFAB:function(){c(a(this))},openToolbar:function(){d(a(this))},closeToolbar:function(){e(a(this))}});var b=function(b){var c=b;if(c.hasClass("active")===!1){var d,e,f=c.hasClass("horizontal");f===!0?e=40:d=40,c.addClass("active"),c.find("ul .btn-floating").velocity({scaleY:".4",scaleX:".4",translateY:d+"px",translateX:e+"px"},{duration:0});var g=0;c.find("ul .btn-floating").reverse().each(function(){a(this).velocity({opacity:"1",scaleX:"1",scaleY:"1",translateY:"0",translateX:"0"},{duration:80,delay:g}),g+=40})}},c=function(a){var b,c,d=a,e=d.hasClass("horizontal");e===!0?c=40:b=40,d.removeClass("active");d.find("ul .btn-floating").velocity("stop",!0),d.find("ul .btn-floating").velocity({opacity:"0",scaleX:".4",scaleY:".4",translateY:b+"px",translateX:c+"px"},{duration:80})},d=function(b){if("true"!==b.attr("data-open")){var c,d,f,g=window.innerWidth,h=window.innerHeight,i=b[0].getBoundingClientRect(),j=b.find("> a").first(),k=b.find("> ul").first(),l=a('<div class="fab-backdrop"></div>'),m=j.css("background-color");j.append(l),c=i.left-g/2+i.width/2,d=h-i.bottom,f=g/l.width(),b.attr("data-origin-bottom",i.bottom),b.attr("data-origin-left",i.left),b.attr("data-origin-width",i.width),b.addClass("active"),b.attr("data-open",!0),b.css({"text-align":"center",width:"100%",bottom:0,left:0,transform:"translateX("+c+"px)",transition:"none"}),j.css({transform:"translateY("+-d+"px)",transition:"none"}),l.css({"background-color":m}),setTimeout(function(){b.css({transform:"",transition:"transform .2s cubic-bezier(0.550, 0.085, 0.680, 0.530), background-color 0s linear .2s"}),j.css({overflow:"visible",transform:"",transition:"transform .2s"}),setTimeout(function(){b.css({overflow:"hidden","background-color":m}),l.css({transform:"scale("+f+")",transition:"transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)"}),k.find("> li > a").css({opacity:1}),a(window).on("scroll.fabToolbarClose",function(){e(b),a(window).off("scroll.fabToolbarClose"),a(document).off("click.fabToolbarClose")}),a(document).on("click.fabToolbarClose",function(c){a(c.target).closest(k).length||(e(b),a(window).off("scroll.fabToolbarClose"),a(document).off("click.fabToolbarClose"))})},100)},0)}},e=function(a){if("true"===a.attr("data-open")){var b,c,d,e=window.innerWidth,f=window.innerHeight,g=a.attr("data-origin-width"),h=a.attr("data-origin-bottom"),i=a.attr("data-origin-left"),j=a.find("> .btn-floating").first(),k=a.find("> ul").first(),l=a.find(".fab-backdrop"),m=j.css("background-color");b=i-e/2+g/2,c=f-h,d=e/l.width(),a.removeClass("active"),a.attr("data-open",!1),a.css({"background-color":"transparent",transition:"none"}),j.css({transition:"none"}),l.css({transform:"scale(0)","background-color":m}),k.find("> li > a").css({opacity:""}),setTimeout(function(){l.remove(),a.css({"text-align":"",width:"",bottom:"",left:"",overflow:"","background-color":"",transform:"translate3d("+-b+"px,0,0)"}),j.css({overflow:"",transform:"translate3d(0,"+c+"px,0)"}),setTimeout(function(){a.css({transform:"translate3d(0,0,0)",transition:"transform .2s"}),j.css({transform:"translate3d(0,0,0)",transition:"transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)"})},20)},200)}}}(jQuery),function(a){Materialize.fadeInImage=function(b){var c;if("string"==typeof b)c=a(b);else{if("object"!=typeof b)return;c=b}c.css({opacity:0}),a(c).velocity({opacity:1},{duration:650,queue:!1,easing:"easeOutSine"}),a(c).velocity({opacity:1},{duration:1300,queue:!1,easing:"swing",step:function(b,c){c.start=100;var d=b/100,e=150-(100-b)/1.75;100>e&&(e=100),b>=0&&a(this).css({"-webkit-filter":"grayscale("+d+")brightness("+e+"%)",filter:"grayscale("+d+")brightness("+e+"%)"})}})},Materialize.showStaggeredList=function(b){var c;if("string"==typeof b)c=a(b);else{if("object"!=typeof b)return;c=b}var d=0;c.find("li").velocity({translateX:"-100px"},{duration:0}),c.find("li").each(function(){a(this).velocity({opacity:"1",translateX:"0"},{duration:800,delay:d,easing:[60,10]}),d+=120})},a(document).ready(function(){var b=!1,c=!1;a(".dismissable").each(function(){a(this).hammer({prevent_default:!1}).bind("pan",function(d){if("touch"===d.gesture.pointerType){var e=a(this),f=d.gesture.direction,g=d.gesture.deltaX,h=d.gesture.velocityX;e.velocity({translateX:g},{duration:50,queue:!1,easing:"easeOutQuad"}),4===f&&(g>e.innerWidth()/2||-.75>h)&&(b=!0),2===f&&(g<-1*e.innerWidth()/2||h>.75)&&(c=!0)}}).bind("panend",function(d){if(Math.abs(d.gesture.deltaX)<a(this).innerWidth()/2&&(c=!1,b=!1),"touch"===d.gesture.pointerType){var e=a(this);if(b||c){var f;f=b?e.innerWidth():-1*e.innerWidth(),e.velocity({translateX:f},{duration:100,queue:!1,easing:"easeOutQuad",complete:function(){e.css("border","none"),e.velocity({height:0,padding:0},{duration:200,queue:!1,easing:"easeOutQuad",complete:function(){e.remove()}})}})}else e.velocity({translateX:0},{duration:100,queue:!1,easing:"easeOutQuad"});b=!1,c=!1}})})})}(jQuery),function(a){Materialize.scrollFire=function(a){var b=!1;window.addEventListener("scroll",function(){b=!0}),setInterval(function(){if(b){b=!1;for(var c=window.pageYOffset+window.innerHeight,d=0;d<a.length;d++){var e=a[d],f=e.selector,g=e.offset,h=e.callback,i=document.querySelector(f);if(null!==i){var j=i.getBoundingClientRect().top+window.pageYOffset;if(c>j+g&&e.done!==!0){if("function"==typeof h)h.call(this,i);else if("string"==typeof h){var k=new Function(h);k(i)}e.done=!0}}}}},100)}}(jQuery),function(a){"function"==typeof define&&define.amd?define("picker",["jquery"],a):"object"==typeof exports?module.exports=a(require("jquery")):this.Picker=a(jQuery)}(function(a){function b(f,g,i,l){function m(){return b._.node("div",b._.node("div",b._.node("div",b._.node("div",y.component.nodes(t.open),v.box),v.wrap),v.frame),v.holder)}function n(){w.data(g,y).addClass(v.input).attr("tabindex",-1).val(w.data("value")?y.get("select",u.format):f.value),u.editable||w.on("focus."+t.id+" click."+t.id,function(a){a.preventDefault(),y.$root.eq(0).focus()}).on("keydown."+t.id,q),e(f,{haspopup:!0,expanded:!1,readonly:!1,owns:f.id+"_root"})}function o(){y.$root.on({keydown:q,focusin:function(a){y.$root.removeClass(v.focused),a.stopPropagation()},"mousedown click":function(b){var c=b.target;c!=y.$root.children()[0]&&(b.stopPropagation(),"mousedown"!=b.type||a(c).is("input, select, textarea, button, option")||(b.preventDefault(),y.$root.eq(0).focus()))}}).on({focus:function(){w.addClass(v.target)},blur:function(){w.removeClass(v.target)}}).on("focus.toOpen",r).on("click","[data-pick], [data-nav], [data-clear], [data-close]",function(){var b=a(this),c=b.data(),d=b.hasClass(v.navDisabled)||b.hasClass(v.disabled),e=h();e=e&&(e.type||e.href),(d||e&&!a.contains(y.$root[0],e))&&y.$root.eq(0).focus(),!d&&c.nav?y.set("highlight",y.component.item.highlight,{nav:c.nav}):!d&&"pick"in c?y.set("select",c.pick):c.clear?y.clear().close(!0):c.close&&y.close(!0)}),e(y.$root[0],"hidden",!0)}function p(){var b;u.hiddenName===!0?(b=f.name,f.name=""):(b=["string"==typeof u.hiddenPrefix?u.hiddenPrefix:"","string"==typeof u.hiddenSuffix?u.hiddenSuffix:"_submit"],b=b[0]+f.name+b[1]),y._hidden=a('<input type=hidden name="'+b+'"'+(w.data("value")||f.value?' value="'+y.get("select",u.formatSubmit)+'"':"")+">")[0],w.on("change."+t.id,function(){y._hidden.value=f.value?y.get("select",u.formatSubmit):""}),u.container?a(u.container).append(y._hidden):w.after(y._hidden)}function q(a){var b=a.keyCode,c=/^(8|46)$/.test(b);return 27==b?(y.close(),!1):void((32==b||c||!t.open&&y.component.key[b])&&(a.preventDefault(),a.stopPropagation(),c?y.clear().close():y.open()))}function r(a){a.stopPropagation(),"focus"==a.type&&y.$root.addClass(v.focused),y.open()}if(!f)return b;var s=!1,t={id:f.id||"P"+Math.abs(~~(Math.random()*new Date))},u=i?a.extend(!0,{},i.defaults,l):l||{},v=a.extend({},b.klasses(),u.klass),w=a(f),x=function(){return this.start()},y=x.prototype={constructor:x,$node:w,start:function(){return t&&t.start?y:(t.methods={},t.start=!0,t.open=!1,t.type=f.type,f.autofocus=f==h(),f.readOnly=!u.editable,f.id=f.id||t.id,"text"!=f.type&&(f.type="text"),y.component=new i(y,u),y.$root=a(b._.node("div",m(),v.picker,'id="'+f.id+'_root" tabindex="0"')),o(),u.formatSubmit&&p(),n(),u.container?a(u.container).append(y.$root):w.after(y.$root),y.on({start:y.component.onStart,render:y.component.onRender,stop:y.component.onStop,open:y.component.onOpen,close:y.component.onClose,set:y.component.onSet}).on({start:u.onStart,render:u.onRender,stop:u.onStop,open:u.onOpen,close:u.onClose,set:u.onSet}),s=c(y.$root.children()[0]),f.autofocus&&y.open(),y.trigger("start").trigger("render"))},render:function(a){return a?y.$root.html(m()):y.$root.find("."+v.box).html(y.component.nodes(t.open)),y.trigger("render")},stop:function(){return t.start?(y.close(),y._hidden&&y._hidden.parentNode.removeChild(y._hidden),y.$root.remove(),w.removeClass(v.input).removeData(g),setTimeout(function(){w.off("."+t.id)},0),f.type=t.type,f.readOnly=!1,y.trigger("stop"),t.methods={},t.start=!1,y):y},open:function(c){return t.open?y:(w.addClass(v.active),e(f,"expanded",!0),setTimeout(function(){y.$root.addClass(v.opened),e(y.$root[0],"hidden",!1)},0),c!==!1&&(t.open=!0,s&&k.css("overflow","hidden").css("padding-right","+="+d()),y.$root.eq(0).focus(),j.on("click."+t.id+" focusin."+t.id,function(a){var b=a.target;b!=f&&b!=document&&3!=a.which&&y.close(b===y.$root.children()[0])}).on("keydown."+t.id,function(c){var d=c.keyCode,e=y.component.key[d],f=c.target;27==d?y.close(!0):f!=y.$root[0]||!e&&13!=d?a.contains(y.$root[0],f)&&13==d&&(c.preventDefault(),f.click()):(c.preventDefault(),e?b._.trigger(y.component.key.go,y,[b._.trigger(e)]):y.$root.find("."+v.highlighted).hasClass(v.disabled)||y.set("select",y.component.item.highlight).close())})),y.trigger("open"))},close:function(a){return a&&(y.$root.off("focus.toOpen").eq(0).focus(),setTimeout(function(){y.$root.on("focus.toOpen",r)},0)),w.removeClass(v.active),e(f,"expanded",!1),setTimeout(function(){y.$root.removeClass(v.opened+" "+v.focused),e(y.$root[0],"hidden",!0)},0),t.open?(t.open=!1,s&&k.css("overflow","").css("padding-right","-="+d()),j.off("."+t.id),y.trigger("close")):y},clear:function(a){return y.set("clear",null,a)},set:function(b,c,d){var e,f,g=a.isPlainObject(b),h=g?b:{};if(d=g&&a.isPlainObject(c)?c:d||{},b){g||(h[b]=c);for(e in h)f=h[e],e in y.component.item&&(void 0===f&&(f=null),y.component.set(e,f,d)),("select"==e||"clear"==e)&&w.val("clear"==e?"":y.get(e,u.format)).trigger("change");y.render()}return d.muted?y:y.trigger("set",h)},get:function(a,c){if(a=a||"value",null!=t[a])return t[a];if("valueSubmit"==a){if(y._hidden)return y._hidden.value;a="value"}if("value"==a)return f.value;if(a in y.component.item){if("string"==typeof c){var d=y.component.get(a);return d?b._.trigger(y.component.formats.toString,y.component,[c,d]):""}return y.component.get(a)}},on:function(b,c,d){var e,f,g=a.isPlainObject(b),h=g?b:{};if(b){g||(h[b]=c);for(e in h)f=h[e],d&&(e="_"+e),t.methods[e]=t.methods[e]||[],t.methods[e].push(f)}return y},off:function(){var a,b,c=arguments;for(a=0,namesCount=c.length;a<namesCount;a+=1)b=c[a],b in t.methods&&delete t.methods[b];return y},trigger:function(a,c){var d=function(a){var d=t.methods[a];d&&d.map(function(a){b._.trigger(a,y,[c])})};return d("_"+a),d(a),y}};return new x}function c(a){var b,c="position";return a.currentStyle?b=a.currentStyle[c]:window.getComputedStyle&&(b=getComputedStyle(a)[c]),"fixed"==b}function d(){if(k.height()<=i.height())return 0;var b=a('<div style="visibility:hidden;width:100px" />').appendTo("body"),c=b[0].offsetWidth;b.css("overflow","scroll");var d=a('<div style="width:100%" />').appendTo(b),e=d[0].offsetWidth;return b.remove(),c-e}function e(b,c,d){if(a.isPlainObject(c))for(var e in c)f(b,e,c[e]);else f(b,c,d)}function f(a,b,c){a.setAttribute(("role"==b?"":"aria-")+b,c)}function g(b,c){a.isPlainObject(b)||(b={attribute:c}),c="";for(var d in b){var e=("role"==d?"":"aria-")+d,f=b[d];c+=null==f?"":e+'="'+b[d]+'"'}return c}function h(){try{return document.activeElement}catch(a){}}var i=a(window),j=a(document),k=a(document.documentElement);return b.klasses=function(a){return a=a||"picker",{picker:a,opened:a+"--opened",focused:a+"--focused",input:a+"__input",active:a+"__input--active",target:a+"__input--target",holder:a+"__holder",frame:a+"__frame",wrap:a+"__wrap",box:a+"__box"}},b._={group:function(a){for(var c,d="",e=b._.trigger(a.min,a);e<=b._.trigger(a.max,a,[e]);e+=a.i)c=b._.trigger(a.item,a,[e]),d+=b._.node(a.node,c[0],c[1],c[2]);return d},node:function(b,c,d,e){return c?(c=a.isArray(c)?c.join(""):c,d=d?' class="'+d+'"':"",e=e?" "+e:"","<"+b+d+e+">"+c+"</"+b+">"):""},lead:function(a){return(10>a?"0":"")+a},trigger:function(a,b,c){return"function"==typeof a?a.apply(b,c||[]):a},digits:function(a){return/\d/.test(a[1])?2:1},isDate:function(a){return{}.toString.call(a).indexOf("Date")>-1&&this.isInteger(a.getDate())},isInteger:function(a){return{}.toString.call(a).indexOf("Number")>-1&&a%1===0},ariaAttr:g},b.extend=function(c,d){a.fn[c]=function(e,f){var g=this.data(c);return"picker"==e?g:g&&"string"==typeof e?b._.trigger(g[e],g,[f]):this.each(function(){var f=a(this);f.data(c)||new b(this,c,d,e)})},a.fn[c].defaults=d.defaults},b}),function(a){"function"==typeof define&&define.amd?define(["picker","jquery"],a):"object"==typeof exports?module.exports=a(require("./picker.js"),require("jquery")):a(Picker,jQuery)}(function(a,b){function c(a,b){var c=this,d=a.$node[0],e=d.value,f=a.$node.data("value"),g=f||e,h=f?b.formatSubmit:b.format,i=function(){return d.currentStyle?"rtl"==d.currentStyle.direction:"rtl"==getComputedStyle(a.$root[0]).direction};c.settings=b,c.$node=a.$node,c.queue={min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse navigate create validate",view:"parse create validate viewset",disable:"deactivate",enable:"activate"},c.item={},c.item.clear=null,c.item.disable=(b.disable||[]).slice(0),c.item.enable=-function(a){return a[0]===!0?a.shift():-1}(c.item.disable),c.set("min",b.min).set("max",b.max).set("now"),g?c.set("select",g,{format:h}):c.set("select",null).set("highlight",c.item.now),c.key={40:7,38:-7,39:function(){return i()?-1:1},37:function(){return i()?1:-1},go:function(a){var b=c.item.highlight,d=new Date(b.year,b.month,b.date+a);c.set("highlight",d,{interval:a}),this.render()}},a.on("render",function(){a.$root.find("."+b.klass.selectMonth).on("change",function(){var c=this.value;c&&(a.set("highlight",[a.get("view").year,c,a.get("highlight").date]),a.$root.find("."+b.klass.selectMonth).trigger("focus"))}),a.$root.find("."+b.klass.selectYear).on("change",function(){var c=this.value;c&&(a.set("highlight",[c,a.get("view").month,a.get("highlight").date]),a.$root.find("."+b.klass.selectYear).trigger("focus"))})},1).on("open",function(){var d="";c.disabled(c.get("now"))&&(d=":not(."+b.klass.buttonToday+")"),a.$root.find("button"+d+", select").attr("disabled",!1)},1).on("close",function(){a.$root.find("button, select").attr("disabled",!0)},1)}var d=7,e=6,f=a._;c.prototype.set=function(a,b,c){var d=this,e=d.item;return null===b?("clear"==a&&(a="select"),e[a]=b,d):(e["enable"==a?"disable":"flip"==a?"enable":a]=d.queue[a].split(" ").map(function(e){return b=d[e](a,b,c)}).pop(),"select"==a?d.set("highlight",e.select,c):"highlight"==a?d.set("view",e.highlight,c):a.match(/^(flip|min|max|disable|enable)$/)&&(e.select&&d.disabled(e.select)&&d.set("select",e.select,c),e.highlight&&d.disabled(e.highlight)&&d.set("highlight",e.highlight,c)),d)},c.prototype.get=function(a){return this.item[a]},c.prototype.create=function(a,c,d){var e,g=this;return c=void 0===c?a:c,c==-(1/0)||c==1/0?e=c:b.isPlainObject(c)&&f.isInteger(c.pick)?c=c.obj:b.isArray(c)?(c=new Date(c[0],c[1],c[2]),c=f.isDate(c)?c:g.create().obj):c=f.isInteger(c)||f.isDate(c)?g.normalize(new Date(c),d):g.now(a,c,d),{year:e||c.getFullYear(),month:e||c.getMonth(),date:e||c.getDate(),day:e||c.getDay(),obj:e||c,pick:e||c.getTime()}},c.prototype.createRange=function(a,c){var d=this,e=function(a){return a===!0||b.isArray(a)||f.isDate(a)?d.create(a):a};return f.isInteger(a)||(a=e(a)),f.isInteger(c)||(c=e(c)),f.isInteger(a)&&b.isPlainObject(c)?a=[c.year,c.month,c.date+a]:f.isInteger(c)&&b.isPlainObject(a)&&(c=[a.year,a.month,a.date+c]),{from:e(a),to:e(c)}},c.prototype.withinRange=function(a,b){return a=this.createRange(a.from,a.to),b.pick>=a.from.pick&&b.pick<=a.to.pick},c.prototype.overlapRanges=function(a,b){var c=this;return a=c.createRange(a.from,a.to),b=c.createRange(b.from,b.to),c.withinRange(a,b.from)||c.withinRange(a,b.to)||c.withinRange(b,a.from)||c.withinRange(b,a.to)},c.prototype.now=function(a,b,c){return b=new Date,c&&c.rel&&b.setDate(b.getDate()+c.rel),this.normalize(b,c)},c.prototype.navigate=function(a,c,d){var e,f,g,h,i=b.isArray(c),j=b.isPlainObject(c),k=this.item.view;if(i||j){for(j?(f=c.year,g=c.month,h=c.date):(f=+c[0],g=+c[1],h=+c[2]),d&&d.nav&&k&&k.month!==g&&(f=k.year,g=k.month),e=new Date(f,g+(d&&d.nav?d.nav:0),1),f=e.getFullYear(),g=e.getMonth();new Date(f,g,h).getMonth()!==g;)h-=1;c=[f,g,h]}return c},c.prototype.normalize=function(a){return a.setHours(0,0,0,0),a},c.prototype.measure=function(a,b){var c=this;return b?"string"==typeof b?b=c.parse(a,b):f.isInteger(b)&&(b=c.now(a,b,{rel:b})):b="min"==a?-(1/0):1/0,b},c.prototype.viewset=function(a,b){return this.create([b.year,b.month,1])},c.prototype.validate=function(a,c,d){var e,g,h,i,j=this,k=c,l=d&&d.interval?d.interval:1,m=-1===j.item.enable,n=j.item.min,o=j.item.max,p=m&&j.item.disable.filter(function(a){if(b.isArray(a)){var d=j.create(a).pick;d<c.pick?e=!0:d>c.pick&&(g=!0)}return f.isInteger(a)}).length;if((!d||!d.nav)&&(!m&&j.disabled(c)||m&&j.disabled(c)&&(p||e||g)||!m&&(c.pick<=n.pick||c.pick>=o.pick)))for(m&&!p&&(!g&&l>0||!e&&0>l)&&(l*=-1);j.disabled(c)&&(Math.abs(l)>1&&(c.month<k.month||c.month>k.month)&&(c=k,l=l>0?1:-1),c.pick<=n.pick?(h=!0,l=1,c=j.create([n.year,n.month,n.date+(c.pick===n.pick?0:-1)])):c.pick>=o.pick&&(i=!0,l=-1,c=j.create([o.year,o.month,o.date+(c.pick===o.pick?0:1)])),!h||!i);)c=j.create([c.year,c.month,c.date+l]);return c},c.prototype.disabled=function(a){var c=this,d=c.item.disable.filter(function(d){return f.isInteger(d)?a.day===(c.settings.firstDay?d:d-1)%7:b.isArray(d)||f.isDate(d)?a.pick===c.create(d).pick:b.isPlainObject(d)?c.withinRange(d,a):void 0;
10
+ });return d=d.length&&!d.filter(function(a){return b.isArray(a)&&"inverted"==a[3]||b.isPlainObject(a)&&a.inverted}).length,-1===c.item.enable?!d:d||a.pick<c.item.min.pick||a.pick>c.item.max.pick},c.prototype.parse=function(a,b,c){var d=this,e={};return b&&"string"==typeof b?(c&&c.format||(c=c||{},c.format=d.settings.format),d.formats.toArray(c.format).map(function(a){var c=d.formats[a],g=c?f.trigger(c,d,[b,e]):a.replace(/^!/,"").length;c&&(e[a]=b.substr(0,g)),b=b.substr(g)}),[e.yyyy||e.yy,+(e.mm||e.m)-1,e.dd||e.d]):b},c.prototype.formats=function(){function a(a,b,c){var d=a.match(/\w+/)[0];return c.mm||c.m||(c.m=b.indexOf(d)+1),d.length}function b(a){return a.match(/\w+/)[0].length}return{d:function(a,b){return a?f.digits(a):b.date},dd:function(a,b){return a?2:f.lead(b.date)},ddd:function(a,c){return a?b(a):this.settings.weekdaysShort[c.day]},dddd:function(a,c){return a?b(a):this.settings.weekdaysFull[c.day]},m:function(a,b){return a?f.digits(a):b.month+1},mm:function(a,b){return a?2:f.lead(b.month+1)},mmm:function(b,c){var d=this.settings.monthsShort;return b?a(b,d,c):d[c.month]},mmmm:function(b,c){var d=this.settings.monthsFull;return b?a(b,d,c):d[c.month]},yy:function(a,b){return a?2:(""+b.year).slice(2)},yyyy:function(a,b){return a?4:b.year},toArray:function(a){return a.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g)},toString:function(a,b){var c=this;return c.formats.toArray(a).map(function(a){return f.trigger(c.formats[a],c,[0,b])||a.replace(/^!/,"")}).join("")}}}(),c.prototype.isDateExact=function(a,c){var d=this;return f.isInteger(a)&&f.isInteger(c)||"boolean"==typeof a&&"boolean"==typeof c?a===c:(f.isDate(a)||b.isArray(a))&&(f.isDate(c)||b.isArray(c))?d.create(a).pick===d.create(c).pick:b.isPlainObject(a)&&b.isPlainObject(c)?d.isDateExact(a.from,c.from)&&d.isDateExact(a.to,c.to):!1},c.prototype.isDateOverlap=function(a,c){var d=this,e=d.settings.firstDay?1:0;return f.isInteger(a)&&(f.isDate(c)||b.isArray(c))?(a=a%7+e,a===d.create(c).day+1):f.isInteger(c)&&(f.isDate(a)||b.isArray(a))?(c=c%7+e,c===d.create(a).day+1):b.isPlainObject(a)&&b.isPlainObject(c)?d.overlapRanges(a,c):!1},c.prototype.flipEnable=function(a){var b=this.item;b.enable=a||(-1==b.enable?1:-1)},c.prototype.deactivate=function(a,c){var d=this,e=d.item.disable.slice(0);return"flip"==c?d.flipEnable():c===!1?(d.flipEnable(1),e=[]):c===!0?(d.flipEnable(-1),e=[]):c.map(function(a){for(var c,g=0;g<e.length;g+=1)if(d.isDateExact(a,e[g])){c=!0;break}c||(f.isInteger(a)||f.isDate(a)||b.isArray(a)||b.isPlainObject(a)&&a.from&&a.to)&&e.push(a)}),e},c.prototype.activate=function(a,c){var d=this,e=d.item.disable,g=e.length;return"flip"==c?d.flipEnable():c===!0?(d.flipEnable(1),e=[]):c===!1?(d.flipEnable(-1),e=[]):c.map(function(a){var c,h,i,j;for(i=0;g>i;i+=1){if(h=e[i],d.isDateExact(h,a)){c=e[i]=null,j=!0;break}if(d.isDateOverlap(h,a)){b.isPlainObject(a)?(a.inverted=!0,c=a):b.isArray(a)?(c=a,c[3]||c.push("inverted")):f.isDate(a)&&(c=[a.getFullYear(),a.getMonth(),a.getDate(),"inverted"]);break}}if(c)for(i=0;g>i;i+=1)if(d.isDateExact(e[i],a)){e[i]=null;break}if(j)for(i=0;g>i;i+=1)if(d.isDateOverlap(e[i],a)){e[i]=null;break}c&&e.push(c)}),e.filter(function(a){return null!=a})},c.prototype.nodes=function(a){var b=this,c=b.settings,g=b.item,h=g.now,i=g.select,j=g.highlight,k=g.view,l=g.disable,m=g.min,n=g.max,o=function(a,b){return c.firstDay&&(a.push(a.shift()),b.push(b.shift())),f.node("thead",f.node("tr",f.group({min:0,max:d-1,i:1,node:"th",item:function(d){return[a[d],c.klass.weekdays,'scope=col title="'+b[d]+'"']}})))}((c.showWeekdaysFull?c.weekdaysFull:c.weekdaysLetter).slice(0),c.weekdaysFull.slice(0)),p=function(a){return f.node("div"," ",c.klass["nav"+(a?"Next":"Prev")]+(a&&k.year>=n.year&&k.month>=n.month||!a&&k.year<=m.year&&k.month<=m.month?" "+c.klass.navDisabled:""),"data-nav="+(a||-1)+" "+f.ariaAttr({role:"button",controls:b.$node[0].id+"_table"})+' title="'+(a?c.labelMonthNext:c.labelMonthPrev)+'"')},q=function(d){var e=c.showMonthsShort?c.monthsShort:c.monthsFull;return"short_months"==d&&(e=c.monthsShort),c.selectMonths&&void 0==d?f.node("select",f.group({min:0,max:11,i:1,node:"option",item:function(a){return[e[a],0,"value="+a+(k.month==a?" selected":"")+(k.year==m.year&&a<m.month||k.year==n.year&&a>n.month?" disabled":"")]}}),c.klass.selectMonth+" browser-default",(a?"":"disabled")+" "+f.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelMonthSelect+'"'):"short_months"==d?null!=i?f.node("div",e[i.month]):f.node("div",e[k.month]):f.node("div",e[k.month],c.klass.month)},r=function(d){var e=k.year,g=c.selectYears===!0?5:~~(c.selectYears/2);if(g){var h=m.year,i=n.year,j=e-g,l=e+g;if(h>j&&(l+=h-j,j=h),l>i){var o=j-h,p=l-i;j-=o>p?p:o,l=i}if(c.selectYears&&void 0==d)return f.node("select",f.group({min:j,max:l,i:1,node:"option",item:function(a){return[a,0,"value="+a+(e==a?" selected":"")]}}),c.klass.selectYear+" browser-default",(a?"":"disabled")+" "+f.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelYearSelect+'"')}return"raw"==d?f.node("div",e):f.node("div",e,c.klass.year)};return createDayLabel=function(){return null!=i?f.node("div",i.date):f.node("div",h.date)},createWeekdayLabel=function(){var a;a=null!=i?i.day:h.day;var b=c.weekdaysFull[a];return b},f.node("div",f.node("div",createWeekdayLabel(),"picker__weekday-display")+f.node("div",q("short_months"),c.klass.month_display)+f.node("div",createDayLabel(),c.klass.day_display)+f.node("div",r("raw"),c.klass.year_display),c.klass.date_display)+f.node("div",f.node("div",(c.selectYears?q()+r():q()+r())+p()+p(1),c.klass.header)+f.node("table",o+f.node("tbody",f.group({min:0,max:e-1,i:1,node:"tr",item:function(a){var e=c.firstDay&&0===b.create([k.year,k.month,1]).day?-7:0;return[f.group({min:d*a-k.day+e+1,max:function(){return this.min+d-1},i:1,node:"td",item:function(a){a=b.create([k.year,k.month,a+(c.firstDay?1:0)]);var d=i&&i.pick==a.pick,e=j&&j.pick==a.pick,g=l&&b.disabled(a)||a.pick<m.pick||a.pick>n.pick,o=f.trigger(b.formats.toString,b,[c.format,a]);return[f.node("div",a.date,function(b){return b.push(k.month==a.month?c.klass.infocus:c.klass.outfocus),h.pick==a.pick&&b.push(c.klass.now),d&&b.push(c.klass.selected),e&&b.push(c.klass.highlighted),g&&b.push(c.klass.disabled),b.join(" ")}([c.klass.day]),"data-pick="+a.pick+" "+f.ariaAttr({role:"gridcell",label:o,selected:d&&b.$node.val()===o?!0:null,activedescendant:e?!0:null,disabled:g?!0:null})),"",f.ariaAttr({role:"presentation"})]}})]}})),c.klass.table,'id="'+b.$node[0].id+'_table" '+f.ariaAttr({role:"grid",controls:b.$node[0].id,readonly:!0})),c.klass.calendar_container)+f.node("div",f.node("button",c.today,"btn-flat picker__today","type=button data-pick="+h.pick+(a&&!b.disabled(h)?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id}))+f.node("button",c.clear,"btn-flat picker__clear","type=button data-clear=1"+(a?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id}))+f.node("button",c.close,"btn-flat picker__close","type=button data-close=true "+(a?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id})),c.klass.footer)},c.defaults=function(a){return{labelMonthNext:"Next month",labelMonthPrev:"Previous month",labelMonthSelect:"Select a month",labelYearSelect:"Select a year",monthsFull:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdaysFull:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdaysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],weekdaysLetter:["S","M","T","W","T","F","S"],today:"Today",clear:"Clear",close:"Close",format:"d mmmm, yyyy",klass:{table:a+"table",header:a+"header",date_display:a+"date-display",day_display:a+"day-display",month_display:a+"month-display",year_display:a+"year-display",calendar_container:a+"calendar-container",navPrev:a+"nav--prev",navNext:a+"nav--next",navDisabled:a+"nav--disabled",month:a+"month",year:a+"year",selectMonth:a+"select--month",selectYear:a+"select--year",weekdays:a+"weekday",day:a+"day",disabled:a+"day--disabled",selected:a+"day--selected",highlighted:a+"day--highlighted",now:a+"day--today",infocus:a+"day--infocus",outfocus:a+"day--outfocus",footer:a+"footer",buttonClear:a+"button--clear",buttonToday:a+"button--today",buttonClose:a+"button--close"}}}(a.klasses().picker+"__"),a.extend("pickadate",c)}),function(a){function b(){var b=+a(this).attr("length"),c=+a(this).val().length,d=b>=c;a(this).parent().find('span[class="character-counter"]').html(c+"/"+b),e(d,a(this))}function c(b){var c=b.parent().find('span[class="character-counter"]');c.length||(c=a("<span/>").addClass("character-counter").css("float","right").css("font-size","12px").css("height",1),b.parent().append(c))}function d(){a(this).parent().find('span[class="character-counter"]').html("")}function e(a,b){var c=b.hasClass("invalid");a&&c?b.removeClass("invalid"):a||c||(b.removeClass("valid"),b.addClass("invalid"))}a.fn.characterCounter=function(){return this.each(function(){var e=a(this),f=e.parent().find('span[class="character-counter"]');if(!f.length){var g=void 0!==e.attr("length");g&&(e.on("input",b),e.on("focus",b),e.on("blur",d),c(e))}})},a(document).ready(function(){a("input, textarea").characterCounter()})}(jQuery),function(a){var b={init:function(b){var c={time_constant:200,dist:-100,shift:0,padding:0,full_width:!1,indicators:!1,no_wrap:!1};return b=a.extend(c,b),this.each(function(){function c(){"undefined"!=typeof window.ontouchstart&&(H[0].addEventListener("touchstart",l),H[0].addEventListener("touchmove",m),H[0].addEventListener("touchend",n)),H[0].addEventListener("mousedown",l),H[0].addEventListener("mousemove",m),H[0].addEventListener("mouseup",n),H[0].addEventListener("mouseleave",n),H[0].addEventListener("click",j)}function d(a){return a.targetTouches&&a.targetTouches.length>=1?a.targetTouches[0].clientX:a.clientX}function e(a){return a.targetTouches&&a.targetTouches.length>=1?a.targetTouches[0].clientY:a.clientY}function f(a){return a>=t?a%t:0>a?f(t+a%t):a}function g(a){var c,d,e,g,h,i,j;if(p="number"==typeof a?a:p,q=Math.floor((p+s/2)/s),e=p-q*s,g=0>e?1:-1,h=-g*e*2/s,d=t>>1,b.full_width?j="translateX(0)":(j="translateX("+(H[0].clientWidth-item_width)/2+"px) ",j+="translateY("+(H[0].clientHeight-item_width)/2+"px)"),I){var k=q%t,l=G.find(".indicator-item.active");l.index()!==k&&(l.removeClass("active"),G.find(".indicator-item").eq(k).addClass("active"))}for((!b.no_wrap||q>=0&&t>q)&&(i=o[f(q)],i.style[A]=j+" translateX("+-e/2+"px) translateX("+g*b.shift*h*c+"px) translateZ("+b.dist*h+"px)",i.style.zIndex=0,b.full_width?tweenedOpacity=1:tweenedOpacity=1-.2*h,i.style.opacity=tweenedOpacity,i.style.display="block"),c=1;d>=c;++c)b.full_width?(zTranslation=b.dist,tweenedOpacity=c===d&&0>e?1-h:1):(zTranslation=b.dist*(2*c+h*g),tweenedOpacity=1-.2*(2*c+h*g)),(!b.no_wrap||t>q+c)&&(i=o[f(q+c)],i.style[A]=j+" translateX("+(b.shift+(s*c-e)/2)+"px) translateZ("+zTranslation+"px)",i.style.zIndex=-c,i.style.opacity=tweenedOpacity,i.style.display="block"),b.full_width?(zTranslation=b.dist,tweenedOpacity=c===d&&e>0?1-h:1):(zTranslation=b.dist*(2*c-h*g),tweenedOpacity=1-.2*(2*c-h*g)),(!b.no_wrap||q-c>=0)&&(i=o[f(q-c)],i.style[A]=j+" translateX("+(-b.shift+(-s*c-e)/2)+"px) translateZ("+zTranslation+"px)",i.style.zIndex=-c,i.style.opacity=tweenedOpacity,i.style.display="block");(!b.no_wrap||q>=0&&t>q)&&(i=o[f(q)],i.style[A]=j+" translateX("+-e/2+"px) translateX("+g*b.shift*h+"px) translateZ("+b.dist*h+"px)",i.style.zIndex=0,b.full_width?tweenedOpacity=1:tweenedOpacity=1-.2*h,i.style.opacity=tweenedOpacity,i.style.display="block")}function h(){var a,b,c,d;a=Date.now(),b=a-C,C=a,c=p-B,B=p,d=1e3*c/(1+b),z=.8*d+.2*z}function i(){var a,c;w&&(a=Date.now()-C,c=w*Math.exp(-a/b.time_constant),c>2||-2>c?(g(x-c),requestAnimationFrame(i)):g(x))}function j(c){if(E)return c.preventDefault(),c.stopPropagation(),!1;if(!b.full_width){var d=a(c.target).closest(".carousel-item").index(),e=q%t-d;0!==e&&(c.preventDefault(),c.stopPropagation()),k(d)}}function k(a){var c=q%t-a;b.no_wrap||(0>c?Math.abs(c+t)<Math.abs(c)&&(c+=t):c>0&&Math.abs(c-t)<c&&(c-=t)),0>c?H.trigger("carouselNext",[Math.abs(c)]):c>0&&H.trigger("carouselPrev",[c])}function l(a){r=!0,E=!1,F=!1,u=d(a),v=e(a),z=w=0,B=p,C=Date.now(),clearInterval(D),D=setInterval(h,100)}function m(a){var b,c,f;if(r)if(b=d(a),y=e(a),c=u-b,f=Math.abs(v-y),30>f&&!F)(c>2||-2>c)&&(E=!0,u=b,g(p+c));else{if(E)return a.preventDefault(),a.stopPropagation(),!1;F=!0}return E?(a.preventDefault(),a.stopPropagation(),!1):void 0}function n(a){return r?(r=!1,clearInterval(D),x=p,(z>10||-10>z)&&(w=.9*z,x=p+w),x=Math.round(x/s)*s,b.no_wrap&&(x>=s*(t-1)?x=s*(t-1):0>x&&(x=0)),w=x-p,C=Date.now(),requestAnimationFrame(i),E&&(a.preventDefault(),a.stopPropagation()),!1):void 0}var o,p,q,r,s,t,u,v,w,x,z,A,B,C,D,E,F,G=a('<ul class="indicators"></ul>'),H=a(this),I=H.attr("data-indicators")||b.indicators;if(H.hasClass("initialized"))return a(this).trigger("carouselNext",[1e-6]),!0;if(b.full_width){b.dist=0;var J=H.find(".carousel-item img").first();J.length?imageHeight=J.on("load",function(){H.css("height",a(this).height())}):(imageHeight=H.find(".carousel-item").first().height(),H.css("height",imageHeight)),I&&H.find(".carousel-fixed-item").addClass("with-indicators")}H.addClass("initialized"),r=!1,p=x=0,o=[],item_width=H.find(".carousel-item").first().innerWidth(),s=2*item_width+b.padding,H.find(".carousel-item").each(function(b){if(o.push(a(this)[0]),I){var c=a('<li class="indicator-item"></li>');0===b&&c.addClass("active"),c.click(function(){var b=a(this).index();k(b)}),G.append(c)}}),I&&H.append(G),t=o.length,A="transform",["webkit","Moz","O","ms"].every(function(a){var b=a+"Transform";return"undefined"!=typeof document.body.style[b]?(A=b,!1):!0}),window.onresize=g,c(),g(p),a(this).on("carouselNext",function(a,b){void 0===b&&(b=1),x=p+s*b,p!==x&&(w=x-p,C=Date.now(),requestAnimationFrame(i))}),a(this).on("carouselPrev",function(a,b){void 0===b&&(b=1),x=p-s*b,p!==x&&(w=x-p,C=Date.now(),requestAnimationFrame(i))}),a(this).on("carouselSet",function(a,b){void 0===b&&(b=0),k(b)})})},next:function(b){a(this).trigger("carouselNext",[b])},prev:function(b){a(this).trigger("carouselPrev",[b])},set:function(b){a(this).trigger("carouselSet",[b])}};a.fn.carousel=function(c){return b[c]?b[c].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof c&&c?void a.error("Method "+c+" does not exist on jQuery.carousel"):b.init.apply(this,arguments)}}(jQuery);
admin/js/xcloner-admin.js ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function( $ ) {
2
+ 'use strict';
3
+
4
+ jQuery(document).ready(function(){
5
+
6
+ jQuery("span.shorten_string").click(function(){
7
+ jQuery(this).toggleClass("full");
8
+ doShortText(jQuery(this));
9
+ })
10
+
11
+ jQuery("span.shorten_string").each(function(){
12
+ doShortText(jQuery(this));
13
+ })
14
+
15
+ jQuery("#xcloner_regex_exclude").on("focus", function(){
16
+ jQuery("ul.xcloner_regex_exclude_limit li").fadeIn();
17
+ })
18
+
19
+ jQuery(".regex_pattern").click(function(){
20
+ jQuery(this).select();
21
+ })
22
+
23
+ jQuery(".btn.system_info_toggle").click(function(){
24
+ jQuery(".additional_system_info").toggle();
25
+ })
26
+
27
+ jQuery(".nav-tab-wrapper.content li").click(function(e){
28
+ jQuery(".nav-tab-wrapper li a").removeClass("nav-tab-active");
29
+ jQuery(this).find('a').addClass("nav-tab-active");
30
+ jQuery(".nav-tab-wrapper-content .tab-content").removeClass('active');
31
+ jQuery(".nav-tab-wrapper-content "+jQuery(this).find('a').attr('href')).addClass('active');
32
+
33
+ e.preventDefault();
34
+
35
+ location.hash = jQuery(this).find('a').attr('href')+"_hash";
36
+
37
+ })
38
+
39
+ var hash = window.location.hash;
40
+ if(hash){
41
+ next_tab(hash.replace("_hash",""));
42
+ }
43
+ })
44
+
45
+ /**
46
+ * All of the code for your admin-facing JavaScript source
47
+ * should reside in this file.
48
+ *
49
+ * Note: It has been assumed you will write jQuery code here, so the
50
+ * $ function reference has been prepared for usage within the scope
51
+ * of this function.
52
+ *
53
+ * This enables you to define handlers, for when the DOM is ready:
54
+ *
55
+ * $(function() {
56
+ *
57
+ * });
58
+ *
59
+ * When the window is loaded:
60
+ *
61
+ * $( window ).load(function() {
62
+ *
63
+ * });
64
+ *
65
+ * ...and/or other possibilities.
66
+ *
67
+ * Ideally, it is not considered best practise to attach more than a
68
+ * single DOM-ready or window-load handler for a particular page.
69
+ * Although scripts in the WordPress core, Plugins and Themes may be
70
+ * practising this, we should strive to set a better example in our own work.
71
+ */
72
+
73
+ })( jQuery );
74
+
75
+
76
+
77
+
78
+ jQuery( document ).ajaxError(function(err, request) {
79
+ //console.log( err );
80
+ //console.log( request );
81
+ //show_ajax_error("dd", "dd12", request)
82
+ });
83
+
84
+ function next_tab(hash){
85
+ jQuery(".nav-tab-wrapper").find("li a[href='"+hash+"']").trigger('click');
86
+ location.hash = hash;
87
+ }
88
+
89
+ function doShortText(elem)
90
+ {
91
+ if(elem.hasClass("full")){
92
+ elem.text(elem.attr("data-text"));
93
+ return;
94
+ }
95
+ var text = elem.text()
96
+ var text_lenght = text.length;
97
+ var first = text.substr(0, 10);
98
+ var last = text.substr(text_lenght-20, text_lenght);
99
+
100
+ elem.attr("data-text", text).text(first+"..."+last);
101
+ }
102
+
103
+ function show_ajax_error(title, msg, json){
104
+
105
+ //var json = jQuery.parseJSON( body )
106
+
107
+ if(xcloner_backup !== undefined)
108
+ xcloner_backup.cancel_backup();
109
+
110
+ if(json.responseText)
111
+ msg = msg+": "+json.responseText;
112
+
113
+ jQuery("#error_modal .title").text(title);
114
+ jQuery("#error_modal .msg").text(msg);
115
+
116
+ if(json.status)
117
+ jQuery("#error_modal .status").text(json.status+" "+json.statusText);
118
+
119
+ jQuery("#error_modal .body").text(JSON.stringify(json));
120
+ var error_modal = jQuery("#error_modal").modal();
121
+ error_modal.modal('open');
122
+ }
123
+
124
+ var ID = function () {
125
+ // Math.random should be unique because of its seeding algorithm.
126
+ // Convert it to base 36 (numbers + letters), and grab the first 9 characters
127
+ // after the decimal.
128
+ return '_' + Math.random().toString(36).substr(2, 9);
129
+ };
130
+
131
+
132
+
admin/js/xcloner-backup-class.js ADDED
@@ -0,0 +1,422 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class Xcloner_Backup{
2
+
3
+ constructor()
4
+ {
5
+ this.cancel = 0;
6
+ this.params;
7
+ this.generate_hash = false;
8
+ this.last_dumpfile = "";
9
+ this.last_backup_file = ""
10
+ this.backup_part = 0
11
+ this.backup_size_total = 0;
12
+ this.resume = new Object();
13
+ }
14
+
15
+ get_form_params()
16
+ {
17
+ var table_params = []
18
+ var files_params = []
19
+ var extra = []
20
+
21
+ jQuery.each(jQuery("#jstree_database_container").jstree("get_checked",true),function(){
22
+
23
+ var object = new Object();
24
+ object.id = this.id
25
+ object.parent = this.parent
26
+
27
+ var index = table_params.length;
28
+ table_params[index] = object
29
+ });
30
+
31
+ jQuery.each(jQuery("#jstree_files_container").jstree("get_checked",true),function(){
32
+ //console.log(this.id+"-"+this.parent);
33
+
34
+ var object = new Object();
35
+ object.id = this.id
36
+ object.parent = this.parent
37
+
38
+ var index = files_params.length;
39
+ files_params[index] = object
40
+ });
41
+
42
+ var $return = new Object();
43
+ $return.table_params = table_params;
44
+ $return.files_params = files_params;
45
+ $return.backup_params = jQuery('#generate_backup_form').serializeArray();
46
+
47
+ return $return;
48
+ }
49
+
50
+ do_backup_database_callback(elem, action, json )
51
+ {
52
+ if(json.extra)
53
+ this.params.extra = json.extra;
54
+
55
+ if(json.extra.stats)
56
+ {
57
+ if(json.extra.stats.tables_count !== undefined)
58
+ jQuery(elem).find(".table-counter").text(parseInt(json.extra.stats.tables_count));
59
+
60
+ if(json.extra.stats.database_count !== undefined)
61
+ jQuery(elem).find(".database-counter").text(parseInt(json.extra.stats.database_count));
62
+
63
+ if(json.extra.stats.total_records !== undefined)
64
+ jQuery(elem).find(".total-records").text(parseInt(json.extra.stats.total_records));
65
+ }
66
+
67
+ if(json.extra.tableName)
68
+ {
69
+ jQuery(elem).find(".last-logged-table").text(json.extra.databaseName+"."+json.extra.tableName+" ("+json.extra.processedRecords+" records)");
70
+ }
71
+
72
+ if(json.extra.processedRecords !== undefined && !json.extra.startAtRecord && !json.extra.endDump)
73
+ {
74
+ var records = parseInt(jQuery(elem).find(".total-records").attr('data-processed')) + parseInt(json.extra.processedRecords);
75
+
76
+ var percent = 100*parseInt(records)/parseInt(jQuery(elem).find(".total-records").text());
77
+ jQuery(elem).find('.progress .determinate').css('width', percent+'%');
78
+
79
+ jQuery(elem).find(".total-records").attr('data-processed', records);
80
+ jQuery(elem).find(".status-body ul.logged-tables").prepend(jQuery("<li>").text(json.extra.databaseName+"."+json.extra.tableName+" ("+json.extra.processedRecords+" records)"));
81
+ }
82
+
83
+ if(json.extra.dumpfile !== undefined){
84
+ var db_text = (json.extra.dumpfile+" ("+this.getSize(json.extra.dumpsize, 1024)+" KB)");
85
+
86
+ if(!jQuery(this.last_dumpfile).hasClass(json.extra.dumpfile)){
87
+ this.last_dumpfile = (jQuery("<li>").addClass(json.extra.dumpfile).html(db_text)).prependTo("ul.logged-databases");
88
+ }
89
+ else{
90
+ jQuery(this.last_dumpfile).html(db_text)
91
+ }
92
+
93
+ }
94
+
95
+ if(!json.finished /*&& !this.cancel*/){
96
+
97
+ this.do_ajax(elem, action);
98
+ return false;
99
+ }
100
+
101
+
102
+
103
+ jQuery(elem).find(".last-logged-table").text('done');
104
+ jQuery(elem).find('.progress .determinate').css('width', '100%');
105
+
106
+ this.do_backup_files();
107
+
108
+ }
109
+
110
+ do_backup_database()
111
+ {
112
+ if(!jQuery('#jstree_database_container').length){
113
+ this.do_backup_files();
114
+ return;
115
+ }
116
+
117
+ /*if(this.cancel)
118
+ return false;*/
119
+
120
+ var elem = "#generate_backup ul.backup-status li.database-backup";
121
+ jQuery(elem).show();
122
+ jQuery(elem+' .status-body').show();
123
+
124
+ jQuery(elem).find(".total-records").text(0);
125
+ jQuery(elem).find(".total-records").attr('data-processed', 0);
126
+ jQuery(elem).find(".table-counter").text(0);
127
+ jQuery(elem).find(".database-counter").text(0);
128
+ jQuery(elem).find(".logged-databases").html("");
129
+ jQuery(elem).find(".logged-tables").html("");
130
+
131
+ this.last_dumpfile = 0;
132
+
133
+ jQuery(elem).find('.progress .determinate').css('width', '0%');
134
+
135
+ this.do_ajax(elem, 'backup_database', 1);
136
+ }
137
+
138
+ do_scan_filesystem_callback(elem, action, json )
139
+ {
140
+
141
+ if(json.total_files_num)
142
+ jQuery(".file-system .file-counter").text(parseInt(json.total_files_num) + parseInt(jQuery(".file-system .file-counter").text()));
143
+
144
+ if(json.total_files_size) {
145
+ var size = parseFloat(json.total_files_size) + parseFloat(jQuery(".file-system .file-size-total").text())
146
+ jQuery(".file-system .file-size-total").text(size.toFixed(2));
147
+ }
148
+
149
+ if(json.last_logged_file)
150
+ jQuery(".file-system .last-logged-file").text(json.last_logged_file);
151
+
152
+ if(!json.finished /*&& !this.cancel*/){
153
+
154
+ this.do_ajax(elem, action);
155
+ return false;
156
+ }
157
+
158
+ //finished
159
+ jQuery(elem).find('.progress .indeterminate').removeClass('indeterminate').addClass('determinate').css('width', '100%');
160
+ jQuery(".file-system .last-logged-file").text('done');
161
+
162
+ //this.do_backup_database();
163
+ this.do_backup_database();
164
+
165
+ }
166
+ do_scan_filesystem()
167
+ {
168
+ /*if(this.cancel)
169
+ return false;*/
170
+
171
+ var elem = "#generate_backup ul.backup-status li.file-system";
172
+ jQuery(elem).show();
173
+ jQuery(elem+' .status-body').show();
174
+ jQuery(elem).find('.collapsible-header').trigger('click');
175
+
176
+ jQuery(".file-system .file-counter").text(0);
177
+ jQuery(".file-system .last-logged-file").text("");
178
+ jQuery(".file-system .file-size-total").text(0);
179
+ jQuery('.file-system .progress div').removeClass('determinate').addClass('indeterminate').css('width', '0%');
180
+
181
+
182
+ this.do_ajax(elem, 'scan_filesystem', 1);
183
+
184
+ }
185
+
186
+ do_backup_files_callback(elem, action, json)
187
+ {
188
+ /*if(this.cancel)
189
+ return false;*/
190
+
191
+ if(json.extra)
192
+ this.params.extra = json.extra;
193
+
194
+ if(json.extra)
195
+ {
196
+ if(json.extra.start_at_line !== undefined)
197
+ jQuery(elem).find(".file-counter").text(parseInt(json.extra.start_at_line));
198
+
199
+ if(json.extra.start_at_line !== undefined){
200
+ //var prev_backup_size = parseInt(jQuery(elem).find(".file-size-total").attr('data-processed'));
201
+ jQuery(elem).find(".file-size-total").text( this.getSize(this.backup_size_total+parseInt(json.extra.backup_size)));
202
+ //var backup_size = parseInt(json.extra.backup_size);
203
+ }
204
+
205
+ }
206
+
207
+ if(json.extra.processed_file)
208
+ {
209
+ if(json.extra.start_at_byte !== undefined && json.extra.start_at_byte)
210
+ var processed_size = json.extra.start_at_byte;
211
+ else
212
+ var processed_size = json.extra.processed_file_size;
213
+
214
+ jQuery(elem).find(".last-logged-file").text(json.extra.processed_file+" ("+this.getSize(processed_size, 1024)+" KB)");
215
+ }
216
+
217
+ if(json.extra.processed_file !== undefined){
218
+
219
+ var backup_text = json.extra.backup_archive_name_full+" ("+this.getSize(json.extra.backup_size)+") MB";
220
+
221
+ if(this.backup_part != json.extra.backup_part)
222
+ {
223
+ this.backup_part = json.extra.backup_part;
224
+ this.backup_size_total = this.backup_size_total+json.extra.backup_size;
225
+ }
226
+
227
+ if(!jQuery(this.last_backup_file).hasClass(json.extra.backup_archive_name)){
228
+ this.last_backup_file = (jQuery("<li>").addClass(json.extra.backup_archive_name).html(backup_text)).prependTo(jQuery(elem).find(".status-body .backup-name"));
229
+ }
230
+
231
+ jQuery(this.last_backup_file).html(backup_text)
232
+
233
+ }
234
+
235
+
236
+ if(json.extra.lines_total)
237
+ {
238
+ var percent = 100*parseInt(json.extra.start_at_line)/parseInt(json.extra.lines_total);
239
+ jQuery(elem).find('.progress .determinate').css('width', percent+'%');
240
+ }
241
+
242
+ if(!json.finished /*&& !this.cancel*/){
243
+
244
+ this.do_ajax(elem, action);
245
+ return false;
246
+ }
247
+
248
+ jQuery(elem).find(".last-logged-file").text('done');
249
+ jQuery(".backup-done .cloud-upload").attr("href", "#"+json.extra.backup_parent);
250
+ jQuery(".backup-done .download").attr("href", "#"+json.extra.backup_parent);
251
+ jQuery(".backup-done .list-backup-content").attr("href", "#"+json.extra.backup_parent);
252
+
253
+ //this.restart_backup();
254
+ this.do_backup_done()
255
+ }
256
+
257
+ do_backup_files()
258
+ {
259
+ if(this.cancel)
260
+ return false;
261
+
262
+ var elem = "#generate_backup ul.backup-status li.files-backup";
263
+ jQuery(elem).show();
264
+ jQuery(elem+' .status-body').show();
265
+ jQuery(elem).find('.collapsible-header').trigger('click');
266
+
267
+ jQuery(elem).find(".file-size-total").text(0);
268
+ jQuery(elem).find(".file-size-total").attr('data-processed', 0);
269
+ jQuery(elem).find(".file-counter").text(0);
270
+ jQuery(elem).find(".last-logged-file").text("");
271
+
272
+ jQuery(elem).find('.progress .determinate').css('width', '0%');
273
+
274
+ this.do_ajax(elem, 'backup_files', 1);
275
+ }
276
+
277
+ do_backup_done()
278
+ {
279
+ var elem = "#generate_backup ul.backup-status li.backup-done";
280
+ jQuery(elem).show();
281
+ jQuery(elem+' .status-body').show();
282
+ jQuery(elem).find('.collapsible-header').trigger('click');
283
+
284
+ this.set_cancel(false)
285
+ jQuery('#generate_backup .action-buttons a').hide();
286
+ jQuery('#generate_backup .action-buttons .start').css('display', 'inline-block');
287
+
288
+ }
289
+
290
+ do_save_schedule_callback(elem, action, json)
291
+ {
292
+ jQuery("#schedule_backup_success").show();
293
+ }
294
+
295
+ cancel_backup()
296
+ {
297
+ this.set_cancel(true)
298
+ jQuery('#generate_backup .action-buttons a').hide();
299
+ jQuery('#generate_backup .action-buttons .start').css('display', 'inline-block');
300
+ jQuery('#generate_backup .action-buttons .restart').css('display', 'inline-block');
301
+
302
+ //this.restart_backup();
303
+ }
304
+
305
+ restart_backup()
306
+ { this.set_cancel(false);
307
+
308
+ jQuery('#generate_backup .action-buttons a').hide();
309
+ jQuery('#generate_backup .action-buttons .cancel').css('display', 'inline-block');
310
+
311
+ if(this.resume.action)
312
+ {
313
+ //console.log(this.resume.action)
314
+ this.do_ajax(this.resume.elem, this.resume.action, this.resume.params);
315
+ this.resume = new Object();
316
+ return;
317
+ }
318
+
319
+ this.start_backup()
320
+ }
321
+
322
+ start_backup()
323
+ {
324
+
325
+ this.resume = new Object()
326
+ this.set_cancel(false);
327
+ jQuery('#generate_backup .action-buttons a').hide();
328
+ jQuery('#generate_backup .action-buttons .cancel').css('display', 'inline-block');
329
+
330
+
331
+ this.generate_hash = true;
332
+ //this.cancel = false;
333
+ this.backup_size_total = 0;
334
+ this.last_backup_file = "";
335
+ this.backup_part = 0;
336
+ jQuery('#generate_backup ul.backup-name li').remove();
337
+
338
+ jQuery('#generate_backup ul.backup-status > li').hide();
339
+ jQuery('#generate_backup .backup-status').show();
340
+
341
+ this.params = this.get_form_params();
342
+
343
+
344
+
345
+ this.do_scan_filesystem();
346
+
347
+ }
348
+
349
+ set_cancel(status)
350
+ {
351
+ if(status)
352
+ {
353
+ //document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0, class: 'determinate' }}));
354
+ //jQuery("#generate_backup .collapsible-header.active .progress > div").add
355
+ }
356
+ this.cancel = status
357
+ }
358
+
359
+ get_cancel(status)
360
+ {
361
+ return this.cancel
362
+ }
363
+
364
+ init_resume(elem, action, init)
365
+ {
366
+ this.resume.elem = elem
367
+ this.resume.action = action
368
+ this.resume.init = init
369
+ }
370
+
371
+ do_ajax(elem, action, init = 0)
372
+ {
373
+ var hash = '';
374
+ if(this.params.hash !==undefined)
375
+ hash = this.params.hash;
376
+ else if(this.generate_hash)
377
+ hash = 'generate_hash';
378
+
379
+
380
+ if(this.cancel == true)
381
+ {
382
+ this.init_resume(elem, action, init);
383
+ return;
384
+ }
385
+
386
+ var callback = 'do_'+action+'_callback';
387
+ var data = JSON.stringify(this.params);
388
+ var $this = this;
389
+
390
+ jQuery.ajax({
391
+ url: ajaxurl,
392
+ dataType: 'json',
393
+ type: 'POST',
394
+ data: {'action': action, 'data': data, 'init': init, 'hash': hash, 'API_ID': ID()},
395
+ error: function(err) {
396
+ show_ajax_error("Communication Error", "", err)
397
+ $this.init_resume(elem, action, init);
398
+ //console.log(err);
399
+ }
400
+ }).done(function(json) {
401
+ if(json.hash){
402
+ $this.params.hash = json.hash;
403
+ //console.log(json.hash);
404
+ }
405
+ if(json.error !== undefined){
406
+ show_ajax_error("Communication Error", "", json.error_message);
407
+ $this.init_resume(elem, action, init);
408
+ return;
409
+ }
410
+
411
+ $this.resume = new Object();
412
+
413
+ $this[callback](elem, action, json)
414
+
415
+ });
416
+ }
417
+
418
+ getSize(bytes, conv = 1024*1024)
419
+ {
420
+ return (bytes/conv).toFixed(2);
421
+ }
422
+ }
admin/js/xcloner-manage-backups-class.js ADDED
@@ -0,0 +1,257 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ class Xcloner_Manage_Backups{
3
+
4
+ constructor()
5
+ {
6
+ this.file_counter = 0
7
+ //this.edit_modal = jQuery('.modal').modal();
8
+ }
9
+
10
+ download_backup_by_name(id)
11
+ {
12
+ window.open(ajaxurl+"?action=download_backup_by_name&name="+id);
13
+ return false;
14
+ }
15
+
16
+ delete_backup_by_name(id, elem, dataTable)
17
+ {
18
+ var $this = this
19
+
20
+ if(id){
21
+ jQuery.ajax({
22
+ url: ajaxurl,
23
+ method: 'post',
24
+ data: { action : 'delete_backup_by_name', name: id},
25
+ success: function(response){
26
+ if(response.finished)
27
+ {
28
+ dataTable
29
+ .row( jQuery(elem).parents('tr') )
30
+ .remove()
31
+ .draw();
32
+ }
33
+ else{
34
+ alert("There was an error deleting the file");
35
+ }
36
+ },
37
+ dataType: 'json'
38
+ });
39
+ }
40
+ }
41
+
42
+ list_backup_content_callback(backup_file, start = 0, part= 0)
43
+ {
44
+ var $this = this;
45
+
46
+ if(backup_file)
47
+ {
48
+ jQuery.ajax({
49
+ url: ajaxurl,
50
+ method: 'post',
51
+ data: { action : 'list_backup_files', file: backup_file, start: start, part: part},
52
+ success: function(response){
53
+
54
+ if(response.error)
55
+ {
56
+ jQuery("#backup_cotent_modal .files-list").addClass("error").prepend(response.message)
57
+ jQuery("#backup_cotent_modal .progress > div").addClass("determinate").removeClass(".indeterminate").css('width', "100%")
58
+ return;
59
+ }
60
+
61
+ var files_text = [];
62
+
63
+ for(var i in response.files)
64
+ {
65
+
66
+ if(response.total_size !== undefined)
67
+ {
68
+ var percent = parseInt(response.start*100)/parseInt(response.total_size)
69
+ //jQuery("#backup_cotent_modal .progress .determinate").css('width', percent + "%")
70
+ }
71
+
72
+ $this.file_counter++
73
+
74
+ files_text[i] = "<li>"+($this.file_counter +". <span title='"+response.files[i].mtime+"'>"+response.files[i].path+"</span> ("+response.files[i].size+" bytes)")+"</li>";
75
+ }
76
+
77
+ jQuery("#backup_cotent_modal .modal-content .files-list").prepend(files_text.reverse().join("\n"));
78
+
79
+ if(!response.finished && jQuery('#backup_cotent_modal').is(':visible'))
80
+ $this.list_backup_content_callback(backup_file, response.start, response.part)
81
+ else
82
+ jQuery("#backup_cotent_modal .progress > div").addClass('determinate').removeClass(".indeterminate").css('width', "100%")
83
+
84
+ },
85
+ error: function(xhr, textStatus, error){
86
+ jQuery("#backup_cotent_modal .files-list").addClass("error").prepend(textStatus+error)
87
+ },
88
+ dataType: 'json'
89
+ });
90
+ }
91
+
92
+ }
93
+
94
+
95
+ list_backup_content(backup_file)
96
+ {
97
+ this.file_counter = 0
98
+ jQuery("#backup_cotent_modal .modal-content .files-list").text("").removeClass("error");
99
+ jQuery("#backup_cotent_modal .modal-content .backup-name").text(backup_file);
100
+ jQuery("#backup_cotent_modal").modal('open');
101
+ jQuery("#backup_cotent_modal .progress > div").removeClass('determinate').addClass("indeterminate");
102
+
103
+ this.list_backup_content_callback(backup_file)
104
+ }
105
+
106
+ cloud_upload(backup_file)
107
+ {
108
+ jQuery('#remote_storage_modal').find(".backup_name").text(backup_file)
109
+ jQuery('#remote_storage_modal').find("input.backup_name").val(backup_file)
110
+ Materialize.updateTextFields();
111
+ jQuery('select').material_select();
112
+ jQuery("#remote_storage_modal").modal('open')
113
+ jQuery("#remote_storage_modal .status").hide();
114
+
115
+ jQuery(".remote-storage-form").off("submit").on("submit",function(){
116
+ jQuery("#remote_storage_modal .status").show();
117
+ jQuery("#remote_storage_modal .status .progress .indeterminate").removeClass("determinate").css("width", "0%");
118
+ jQuery("#remote_storage_modal .status-text").removeClass("error").text("");
119
+
120
+ var storage_type = jQuery("#remote_storage_modal select").val();
121
+
122
+ if(backup_file)
123
+ {
124
+ jQuery.ajax({
125
+ url: ajaxurl,
126
+ method: 'post',
127
+ data: { action : 'upload_backup_to_remote', file: backup_file, storage_type: storage_type},
128
+ success: function(response){
129
+ if(response.error)
130
+ {
131
+ jQuery("#remote_storage_modal .status-text").addClass("error").text(response.message)
132
+ }else{
133
+ jQuery("#remote_storage_modal .status-text").removeClass("error").text("done")
134
+ }
135
+
136
+ jQuery("#remote_storage_modal .status .progress .indeterminate").addClass("determinate").css("width", "100%");
137
+ },
138
+ error: function(xhr, textStatus, error){
139
+ jQuery("#remote_storage_modal .status-text").addClass("error").text(textStatus+error)
140
+ },
141
+ dataType: 'json'
142
+ });
143
+ }
144
+
145
+ return false;
146
+ })
147
+ }
148
+
149
+ //end class
150
+ }
151
+
152
+ jQuery(document).ready(function(){
153
+
154
+ var xcloner_manage_backups = new Xcloner_Manage_Backups();
155
+
156
+ jQuery("a.expand-multipart").on("click", function(){
157
+ jQuery(this).parent().find("ul.multipart").toggle();
158
+ jQuery(this).parent().find("a.expand-multipart.remove").toggle();
159
+ jQuery(this).parent().find("a.expand-multipart.add").toggle();
160
+ })
161
+ var dataTable = jQuery('#manage_backups').DataTable( {
162
+ 'responsive': true,
163
+ 'bFilter': true,
164
+ "order": [[ 2, "desc" ]],
165
+ buttons: [
166
+ 'selectAll',
167
+ 'selectNone'
168
+ ],
169
+ "language": {
170
+ "emptyTable": "No backups available",
171
+ buttons: {
172
+ selectAll: "Select all items",
173
+ selectNone: "Select none"
174
+ }
175
+ },
176
+ columnDefs: [
177
+ { targets: 'no-sort', orderable: false }
178
+ ],
179
+ "columns": [
180
+ { "width": "1%" },
181
+ { "width": "25%" },
182
+ { "width": "5%" },
183
+ { "width": "5%" },
184
+ { "width": "5%" },
185
+ ],
186
+ "oLanguage": {
187
+ "sSearch": "",
188
+ "sSearchPlaceholder" : 'Search Backups',
189
+ } ,
190
+ "fnDrawCallback": function( oSettings ) {
191
+
192
+ jQuery(this).off("click", ".delete").on("click", ".delete", function(e){
193
+
194
+ var hash = jQuery(this).attr('href');
195
+ var id = hash.substr(1)
196
+ if(show_delete_alert && confirm('Are you sure you want to delete it?'))
197
+ var data = xcloner_manage_backups.delete_backup_by_name(id, (this), dataTable);
198
+ else
199
+ var data = xcloner_manage_backups.delete_backup_by_name(id, (this), dataTable);
200
+ e.preventDefault();
201
+ })
202
+
203
+ jQuery(this).off("click", ".download").on("click", ".download", function(e){
204
+ var hash = jQuery(this).attr('href');
205
+ var id = hash.substr(1)
206
+ var data = xcloner_manage_backups.download_backup_by_name(id);
207
+ e.preventDefault();
208
+ })
209
+
210
+ jQuery(this).off("click", ".cloud-upload").on("click", ".cloud-upload", function(e){
211
+ var hash = jQuery(this).attr('href');
212
+ var id = hash.substr(1)
213
+ var data = xcloner_manage_backups.cloud_upload(id);
214
+ e.preventDefault();
215
+ })
216
+
217
+ jQuery(this).off("click", ".list-backup-content").on("click", ".list-backup-content", function(e){
218
+ var hash = jQuery(this).attr('href');
219
+ var id = hash.substr(1)
220
+ var data = xcloner_manage_backups.list_backup_content(id);
221
+ e.preventDefault();
222
+ })
223
+ }
224
+ });
225
+
226
+ jQuery('#select_all').click(function () {
227
+ jQuery('input:checkbox').prop('checked', this.checked);
228
+ });
229
+
230
+ jQuery(".delete-all").click(function(){
231
+ if(confirm('Are you sure you want to delete selected items?'))
232
+ {
233
+ show_delete_alert = 0;
234
+ jQuery('input:checkbox').each(function(){
235
+ if(jQuery(this).is(":checked"))
236
+ {
237
+ jQuery(this).parent().parent().parent().find(".delete").trigger('click');
238
+ }
239
+ })
240
+ show_delete_alert = 1;
241
+ }
242
+ })
243
+
244
+ /*jQuery("#save_schedule").on("submit", function(){
245
+
246
+ xcloner_scheduler.save_schedule(jQuery(this), dataTable)
247
+
248
+ return false;
249
+ })*/
250
+
251
+ jQuery("#remote_storage_modal").modal();
252
+
253
+
254
+ var show_delete_alert=1;
255
+
256
+
257
+ });
admin/js/xcloner-remote-storage-class.js ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class Xcloner_Remote_Storage
2
+ {
3
+
4
+ constructor()
5
+ {
6
+
7
+ }
8
+
9
+ toggle_status(elem)
10
+ {
11
+ var field = jQuery(elem).attr("name")
12
+ var value = 0
13
+ if(jQuery(elem).is(":checked"))
14
+ value = 1;
15
+
16
+ if(field){
17
+ jQuery.ajax({
18
+ url: ajaxurl,
19
+ method: 'post',
20
+ data: { action : 'remote_storage_save_status', id: field, value: value},
21
+ success: function(response){
22
+ if(!response.finished)
23
+ alert('Error changing status')
24
+ },
25
+ dataType: 'json'
26
+
27
+ })
28
+ }
29
+
30
+ }
31
+ }
admin/js/xcloner-restore-class.js ADDED
@@ -0,0 +1,827 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class Xcloner_Restore{
2
+
3
+ constructor(hash)
4
+ {
5
+ this.steps = ['restore-script-upload-step','backup-upload-step','restore-remote-backup-step','restore-remote-database-step','restore-finish-step']
6
+ this.ajaxurl = ajaxurl;
7
+ this.cancel = false;
8
+ this.upload_file_event = new Event('upload_file_event');
9
+ this.resume = new Object();
10
+ this.hash = hash;
11
+
12
+ document.addEventListener("backup_upload_finish", function (e) {
13
+
14
+ jQuery(".xcloner-restore .backup-upload-step .toggler").removeClass("cancel");
15
+
16
+ }, false);
17
+
18
+ document.addEventListener("remote_restore_backup_finish", function (e) {
19
+
20
+ jQuery(".xcloner-restore .restore-remote-backup-step .toggler").removeClass("cancel");
21
+
22
+ }, false);
23
+
24
+ document.addEventListener("remote_restore_mysql_backup_finish", function (e) {
25
+
26
+ jQuery(".xcloner-restore .restore-remote-database-step .toggler").removeClass("cancel");
27
+
28
+ }, false);
29
+
30
+ document.addEventListener("restore_script_invalid", function (e) {
31
+
32
+ jQuery(".xcloner-restore #restore_script_url").addClass("invalid").removeClass('valid');
33
+ jQuery(".xcloner-restore #validate_url .material-icons").text("error");
34
+
35
+ }, false);
36
+
37
+ document.addEventListener("restore_script_valid", function (e) {
38
+
39
+ jQuery(".xcloner-restore #validate_url .material-icons").text("check_circle");
40
+ jQuery(".xcloner-restore #restore_script_url").removeClass("invalid").addClass('valid');
41
+
42
+ }, false);
43
+
44
+ document.addEventListener("xcloner_populate_remote_backup_files_list", function (e) {
45
+
46
+ var files = e.detail.files
47
+
48
+ jQuery('.xcloner-restore #remote_backup_file').find('option').not(':first').remove();
49
+
50
+
51
+ for( var key in files)
52
+ {
53
+ if(files[key].selected)
54
+ var selected = "selected";
55
+ else
56
+ var selected = "not-selected";
57
+
58
+ jQuery('.xcloner-restore #remote_backup_file').append("<option value='"+files[key].path+"' "+selected+">"+files[key].path+"("+e.detail.$this.getSize(files[key].size)+" MB)"+"</option>").addClass("file");
59
+ }
60
+
61
+ }, false);
62
+
63
+ document.addEventListener("xcloner_populate_remote_mysqldump_files_list", function (e) {
64
+
65
+ var files = e.detail.files
66
+
67
+ jQuery('.xcloner-restore #remote_database_file').find('option').not(':first').remove();
68
+
69
+ for( var key in files)
70
+ {
71
+ if(files[key].selected)
72
+ var selected = "selected";
73
+ else
74
+ var selected = "not-selected";
75
+
76
+ var option = jQuery('.xcloner-restore #remote_database_file').append("<option value='"+files[key].path+"' "+selected+">"+files[key].path+"("+e.detail.$this.getSize(files[key].size)+" MB) "+files[key].timestamp+"</option>").addClass("file");
77
+ }
78
+
79
+ }, false);
80
+
81
+ document.addEventListener("xcloner_restore_next_step", function (e) {
82
+
83
+ if(e.detail.$this !== undefined)
84
+ {
85
+ var $this = e.detail.$this
86
+ jQuery(".xcloner-restore li."+$this.steps[$this.set_current_step]).addClass('active').show().find(".collapsible-header").trigger('click');
87
+ }
88
+
89
+ }, false);
90
+
91
+ document.addEventListener("xcloner_restore_update_progress", function (e) {
92
+
93
+ if(e.detail.percent !== undefined)
94
+ {
95
+ jQuery(".xcloner-restore .steps.active .progress").show();
96
+
97
+ if(e.detail.class == "indeterminate")
98
+ jQuery(".xcloner-restore .steps.active .progress > div").addClass(e.detail.class).removeClass('determinate')
99
+ if(e.detail.class == "determinate")
100
+ jQuery(".xcloner-restore .steps.active .progress > div").addClass(e.detail.class).removeClass('indeterminate')
101
+
102
+ if(e.detail.percent == 100)
103
+ jQuery(".xcloner-restore .steps.active .progress > div").removeClass('indeterminate').addClass('determinate').css("width", e.detail.percent+"%")
104
+ else
105
+ jQuery(".xcloner-restore .steps.active .progress .determinate").css("width", e.detail.percent+"%")
106
+ }
107
+
108
+ }, false);
109
+
110
+
111
+ document.addEventListener("xcloner_restore_display_status_text", function (e) {
112
+
113
+ if(e.detail.status === undefined)
114
+ e.detail.status = "updated";
115
+
116
+ if(e.detail.message !== undefined)
117
+ {
118
+ jQuery(".xcloner-restore .steps.active .status").html("<div class='"+e.detail.status+"'>"+e.detail.message+"</div>");
119
+ }
120
+
121
+ }, false);
122
+
123
+ document.addEventListener("xcloner_populate_remote_restore_path", function (e) {
124
+
125
+ if(e.detail.dir !== undefined)
126
+ {
127
+ if(!jQuery(".xcloner-restore #remote_restore_path").val())
128
+ jQuery(".xcloner-restore #remote_restore_path").val(e.detail.dir);
129
+ }
130
+
131
+ if(e.detail.restore_script_url !== undefined)
132
+ {
133
+ if(!jQuery(".xcloner-restore #remote_restore_url").val())
134
+ jQuery(".xcloner-restore #remote_restore_url").val(e.detail.restore_script_url);
135
+
136
+ if(!jQuery(".xcloner-restore #remote_restore_site_url").val())
137
+ jQuery(".xcloner-restore #remote_restore_site_url").val(e.detail.restore_script_url);
138
+ }
139
+
140
+ }, false);
141
+
142
+ document.addEventListener("remote_restore_update_files_list", function (e) {
143
+
144
+ if(e.detail.files !== undefined && e.detail.files.length)
145
+ {
146
+ var files_text = [];
147
+ for(var i=0; i<e.detail.files.length;i++)
148
+ {
149
+ files_text[i] = "<li>"+(e.detail.files[i])+"</li>";
150
+ }
151
+ jQuery('.xcloner-restore .restore-remote-backup-step .files-list').prepend(files_text.reverse().join("\n"));
152
+ }else{
153
+ jQuery('.xcloner-restore .restore-remote-backup-step .files-list').html("");
154
+ }
155
+
156
+ }, false);
157
+
158
+ document.addEventListener("xcloner_restore_display_query_box", function (e) {
159
+
160
+ if(e.detail.query)
161
+ {
162
+ jQuery(".xcloner-restore .query-box").show();
163
+ jQuery(".xcloner-restore .query-list").val(e.detail.query)
164
+ }else{
165
+ jQuery(".xcloner-restore .query-box").hide();
166
+ jQuery(".xcloner-restore .query-list").val("")
167
+ }
168
+
169
+
170
+ }, false);
171
+
172
+ document.addEventListener("xcloner_restore_finish", function (e) {
173
+
174
+ jQuery(".xcloner-restore #xcloner_restore_finish").show();
175
+
176
+ }, false);
177
+
178
+
179
+ }
180
+
181
+ get_remote_backup_files_callback(response, status, params = new Object())
182
+ {
183
+ if(status)
184
+ {
185
+ var files = response.statusText.files;
186
+ document.dispatchEvent(new CustomEvent("xcloner_populate_remote_backup_files_list", {detail: {files: files, $this: this }}));
187
+ }
188
+ }
189
+
190
+ get_remote_backup_files()
191
+ {
192
+ this.ajaxurl = this.restore_script_url;
193
+ this.set_cancel(false);
194
+
195
+ var params = new Object()
196
+ params.local_backup_file = jQuery(".xcloner-restore .backup-upload-step #backup_file").val();
197
+
198
+ this.do_ajax('get_remote_backup_files_callback', 'list_backup_archives', params)
199
+
200
+ this.get_remote_restore_path_default()
201
+ }
202
+
203
+ get_remote_mysqldump_files_callback(response, status, params = new Object())
204
+ {
205
+
206
+ if(status)
207
+ {
208
+ var files = response.statusText.files;
209
+ document.dispatchEvent(new CustomEvent("xcloner_populate_remote_mysqldump_files_list", {detail: {files: files, $this: this }}));
210
+ }
211
+ }
212
+
213
+ get_remote_mysqldump_files()
214
+ {
215
+ this.ajaxurl = this.restore_script_url;
216
+ this.set_cancel(false);
217
+
218
+
219
+ if(this.resume.callback == "get_remote_mysqldump_files_callback")
220
+ {
221
+ console.log("do resume");
222
+ this.do_ajax(this.resume.callback, this.resume.action, this.resume.params);
223
+ this.resume = new Object();
224
+ return;
225
+ }
226
+
227
+
228
+ var params = new Object()
229
+ params.backup_file = this.get_backup_file()
230
+ params.remote_path = this.get_remote_path()
231
+
232
+ //console.log(params)
233
+
234
+ this.do_ajax('get_remote_mysqldump_files_callback', 'list_mysqldump_backups', params)
235
+
236
+ }
237
+
238
+ get_backup_file()
239
+ {
240
+ return jQuery(".xcloner-restore #remote_backup_file").val()
241
+ }
242
+
243
+ get_remote_path()
244
+ {
245
+ return jQuery(".xcloner-restore #remote_restore_path").val()
246
+ }
247
+
248
+ get_remote_restore_path_default_callback(response, status, params = new Object())
249
+ {
250
+ if(status)
251
+ {
252
+ document.dispatchEvent(new CustomEvent("xcloner_populate_remote_restore_path", {detail: {dir: response.statusText.dir, restore_script_url: response.statusText.restore_script_url, $this: this }}))
253
+ }
254
+ }
255
+
256
+ get_remote_restore_path_default()
257
+ {
258
+ this.ajaxurl = this.restore_script_url;
259
+ this.set_cancel(false);
260
+
261
+ var params = new Object()
262
+
263
+ params.restore_script_url = this.restore_script_url;
264
+
265
+ this.do_ajax('get_remote_restore_path_default_callback', 'get_current_directory', params)
266
+ }
267
+
268
+ remote_restore_backup_file_callback(response, status, params = new Object())
269
+ {
270
+
271
+ if(!status)
272
+ {
273
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: response.status+" "+response.statusText }}));
274
+ document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 100 }}));
275
+ document.dispatchEvent(new CustomEvent("remote_restore_backup_finish"));
276
+ return;
277
+ }
278
+
279
+ var processed = parseInt(response.statusText.start)+parseInt(response.statusText.processed)
280
+
281
+ if(response.statusText.extracted_files)
282
+ {
283
+ //console.log(response.statusText.extracted_files);
284
+ document.dispatchEvent(new CustomEvent("remote_restore_update_files_list", {detail: {files: response.statusText.extracted_files}}));
285
+ }
286
+
287
+ if(!response.statusText.finished)
288
+ {
289
+ params.start = response.statusText.start
290
+ params.part = response.statusText.part
291
+ params.processed = response.statusText.processed
292
+
293
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: 'Processing <strong>'+response.statusText.backup_file+'</strong>- wrote '+this.getSize(processed, 1024)+" KB to disk"}}));
294
+
295
+ this.do_ajax('remote_restore_backup_file_callback', 'restore_backup_to_path', params)
296
+ return
297
+ }
298
+
299
+ document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 100 }}));
300
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: "Done restoring <strong>"+ response.statusText.backup_file +"</strong>."}}));
301
+ document.dispatchEvent(new CustomEvent("remote_restore_backup_finish"));
302
+ this.cancel = false;
303
+ }
304
+
305
+ remote_restore_backup_file(backup_file, remote_path)
306
+ {
307
+ this.ajaxurl = this.restore_script_url;
308
+ this.set_cancel(false);
309
+
310
+ var params = new Object()
311
+ params.backup_file = backup_file
312
+ params.remote_path = remote_path
313
+
314
+ if(this.resume.callback == "remote_restore_backup_file_callback")
315
+ {
316
+ console.log("do resume");
317
+ this.do_ajax(this.resume.callback, this.resume.action, this.resume.params);
318
+ this.resume = new Object();
319
+ return;
320
+ }
321
+ document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0, class: 'indeterminate' }}));
322
+ document.dispatchEvent(new CustomEvent("remote_restore_update_files_list", {detail: {files: ""}}));
323
+
324
+ this.do_ajax('remote_restore_backup_file_callback', 'restore_backup_to_path', params)
325
+ }
326
+
327
+ remote_restore_mysql_backup_file_callback(response, status, params = new Object())
328
+ {
329
+ //var processed = parseInt(response.statusText.start)+parseInt(response.statusText.processed)
330
+
331
+ if(!status)
332
+ {
333
+ this.start = response.statusText.start;
334
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_query_box", {detail: { query: response.statusText.query }}));
335
+
336
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: response.status+" "+response.statusText.message }}));
337
+ //document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 100 }}));
338
+ document.dispatchEvent(new CustomEvent("remote_restore_mysql_backup_finish"));
339
+ return;
340
+ }
341
+
342
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_query_box", {detail: { query: "" }}));
343
+ params.query = "";
344
+
345
+ var processed = parseInt(response.statusText.start)+parseInt(response.statusText.processed)
346
+
347
+ if(response.statusText.extracted_files)
348
+ {
349
+ //console.log(response.statusText.extracted_files);
350
+ //document.dispatchEvent(new CustomEvent("remote_restore_update_files_list", {detail: {files: response.statusText.extracted_files}}));
351
+ }
352
+
353
+ if(!response.statusText.finished)
354
+ {
355
+ params.start = response.statusText.start
356
+ params.processed = response.statusText.processed
357
+
358
+ var percent = 0;
359
+
360
+ if(response.statusText.backup_size)
361
+ percent = (100*parseInt(response.statusText.start))/parseInt(response.statusText.backup_size);
362
+
363
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: 'Processing <strong>'+response.statusText.backup_file+'</strong>- wrote '+this.getSize(response.statusText.start, 1024)+" KB of data"}}));
364
+ document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: percent }}));
365
+
366
+ this.do_ajax('remote_restore_mysql_backup_file_callback', 'restore_mysql_backup', params)
367
+ return
368
+ }
369
+
370
+ document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 100 }}));
371
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: "Done restoring <strong>"+ response.statusText.backup_file +"</strong>."}}));
372
+ document.dispatchEvent(new CustomEvent("remote_restore_mysql_backup_finish"));
373
+ this.cancel = false;
374
+
375
+ }
376
+
377
+ remote_restore_mysql_backup_file(mysqldump_file)
378
+ {
379
+ this.ajaxurl = this.restore_script_url;
380
+ this.set_cancel(false);
381
+
382
+ var params = new Object()
383
+
384
+ params.remote_mysql_host = jQuery(".xcloner-restore #remote_mysql_host").val();
385
+ params.remote_mysql_db = jQuery(".xcloner-restore #remote_mysql_db").val();
386
+ params.remote_mysql_user = jQuery(".xcloner-restore #remote_mysql_user").val();
387
+ params.remote_mysql_pass = jQuery(".xcloner-restore #remote_mysql_pass").val();
388
+ params.remote_path = jQuery(".xcloner-restore #remote_restore_path").val();
389
+
390
+ params.wp_home_url = jQuery(".xcloner-restore #wp_home_url").val();
391
+ params.remote_restore_url = jQuery(".xcloner-restore #remote_restore_url").val();
392
+
393
+ if(jQuery(".xcloner-restore #wp_site_url").length)
394
+ {
395
+ params.wp_site_url = jQuery(".xcloner-restore #wp_site_url").val();
396
+ params.restore_site_url = jQuery(".xcloner-restore #remote_restore_site_url").val();
397
+ }
398
+
399
+ //console.log(params)
400
+
401
+ params.mysqldump_file = mysqldump_file
402
+ params.query = ""
403
+ params.start = 0
404
+
405
+ if(jQuery(".xcloner-restore .query-box .query-list").val())
406
+ {
407
+ params.query = jQuery(".xcloner-restore .query-box .query-list").val();
408
+ params.start = this.start
409
+ }
410
+
411
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_query_box", {detail: { query: "" }}));
412
+
413
+ if(this.resume.callback == "remote_restore_mysql_backup_file_callback")
414
+ {
415
+ console.log("do resume mysql backup restore");
416
+ this.do_ajax(this.resume.callback, this.resume.action, this.resume.params);
417
+ this.resume = new Object();
418
+ return;
419
+ }
420
+
421
+ this.do_ajax('remote_restore_mysql_backup_file_callback', 'restore_mysql_backup', params)
422
+ }
423
+
424
+ restore_finish_callback(response, status, params = new Object())
425
+ {
426
+ if(status)
427
+ {
428
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: response.statusText, $this: this }}))
429
+ }else{
430
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: "error", message: response.statusText, $this: this }}))
431
+ return false;
432
+ }
433
+
434
+ document.dispatchEvent(new CustomEvent("xcloner_restore_finish", {detail: {message: response.statusText, $this: this }}))
435
+ }
436
+
437
+ restore_finish()
438
+ {
439
+ this.ajaxurl = this.restore_script_url;
440
+ this.set_cancel(false);
441
+
442
+ var params = new Object()
443
+
444
+ params.remote_mysql_host = jQuery(".xcloner-restore #remote_mysql_host").val();
445
+ params.remote_mysql_db = jQuery(".xcloner-restore #remote_mysql_db").val();
446
+ params.remote_mysql_user = jQuery(".xcloner-restore #remote_mysql_user").val();
447
+ params.remote_mysql_pass = jQuery(".xcloner-restore #remote_mysql_pass").val();
448
+ params.remote_path = jQuery(".xcloner-restore #remote_restore_path").val();
449
+ params.remote_restore_url = jQuery(".xcloner-restore #remote_restore_url").val();
450
+
451
+ params.delete_backup_temporary_folder = 0;
452
+ params.delete_restore_script = 0;
453
+ params.update_remote_site_url = 0;
454
+
455
+ if(jQuery(".xcloner-restore #delete_backup_temporary_folder").is(":checked"))
456
+ params.delete_backup_temporary_folder = 1;
457
+ if(jQuery(".xcloner-restore #delete_restore_script").is(":checked"))
458
+ params.delete_restore_script = 1;
459
+ if(jQuery(".xcloner-restore #update_remote_site_url").is(":checked"))
460
+ params.update_remote_site_url = 1;
461
+
462
+ this.do_ajax('restore_finish_callback', 'restore_finish', params)
463
+
464
+ }
465
+
466
+ upload_backup_file(file)
467
+ {
468
+ this.ajaxurl = ajaxurl;
469
+ var params = new Object()
470
+ this.set_cancel(false);
471
+
472
+ if(this.resume.callback == "upload_backup_file_callback")
473
+ {
474
+ this.do_ajax(this.resume.callback, this.resume.action, this.resume.params);
475
+ this.resume = new Object();
476
+ return;
477
+ }
478
+
479
+ params.file = file;
480
+ params.start = 0;
481
+ params.target_url = this.restore_script_url
482
+
483
+ document.dispatchEvent(new CustomEvent("backup_upload_start"));
484
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: "Uploading backup 0%" }}));
485
+ document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0 }}));
486
+
487
+ this.do_ajax('upload_backup_file_callback', 'restore_upload_backup', params)
488
+ }
489
+
490
+
491
+ upload_backup_file_callback(response, status, params = new Object())
492
+ {
493
+ if(!status)
494
+ {
495
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: response.status+" "+response.statusText }}));
496
+ document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 100 }}));
497
+ return;
498
+ }
499
+
500
+ if(response && (response.start !== false || response.part<response.total_parts))
501
+ {
502
+ var percent = 0;
503
+ if(response.total_size)
504
+ {
505
+ if(!response.start)
506
+ response.start = 0;
507
+ var size = parseInt(response.start)+parseInt(response.uploaded_size)
508
+ percent = (100*parseInt(size))/parseInt(response.total_size)
509
+ }
510
+
511
+ var part_text = "";
512
+ if(response.part > 0)
513
+ part_text = "part "+response.part+" - ";
514
+
515
+ document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: percent }}));
516
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: "Uploading backup "+part_text+parseFloat(percent).toFixed(2)+"%" }}));
517
+
518
+ params.start = response.start;
519
+ params.part = response.part;
520
+ params.uploaded_size = response.uploaded_size;
521
+ this.do_ajax('upload_backup_file_callback', 'restore_upload_backup', params)
522
+ }
523
+ else
524
+ {
525
+ this.cancel = false
526
+ document.dispatchEvent(new CustomEvent("backup_upload_finish"));
527
+ document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 100 }}));
528
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: "Done." }}));
529
+ }
530
+ }
531
+
532
+ verify_restore_url(response, status, params = new Object())
533
+ {
534
+ this.ajaxurl = this.restore_script_url;
535
+
536
+ jQuery(".xcloner-restore #xcloner_restore_finish").hide();
537
+
538
+ if(!response)
539
+ {
540
+ this.cancel = false;
541
+ this.set_current_step = 0
542
+ this.do_ajax("verify_restore_url");
543
+ }else{
544
+
545
+ if(!status)
546
+ {
547
+ document.dispatchEvent(new CustomEvent("restore_script_invalid"));
548
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status:'error', message: response.status+" "+response.statusText }}));
549
+ //document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 100 }}));
550
+
551
+ }else{
552
+
553
+ document.dispatchEvent(new CustomEvent("restore_script_valid"));
554
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: "Validation ok." }}));
555
+
556
+ this.next_step();
557
+ }
558
+ }
559
+ }
560
+
561
+ next_step()
562
+ {
563
+ this.set_current_step = jQuery(".xcloner-restore li.active").attr("data-step");
564
+
565
+ document.dispatchEvent(new CustomEvent("xcloner_restore_next_step", {detail: {$this: this}}));
566
+
567
+ }
568
+
569
+ init_resume()
570
+ {
571
+ this.resume = new Object()
572
+ if(jQuery(".xcloner-restore .steps.active .progress").is(":visible"))
573
+ document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0 }}));
574
+ if(jQuery(".xcloner-restore .steps.active .status").html())
575
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {message: ""}}));
576
+ document.dispatchEvent(new CustomEvent("remote_restore_update_files_list", {detail: {files: ""}}));
577
+ }
578
+
579
+ do_ajax(callback, action="", params= new Object())
580
+ {
581
+ params.action = action
582
+ params.hash = this.hash
583
+ params.API_ID = ID()
584
+
585
+ if(this.cancel == true)
586
+ {
587
+ this.resume.callback = callback
588
+ this.resume.action = action
589
+ this.resume.params = params
590
+
591
+ //this.request.abort();
592
+
593
+ return;
594
+ }
595
+
596
+ if(!this.restore_script_url)
597
+ return false;
598
+
599
+ var $this = this;
600
+
601
+ jQuery(".xcloner-restore .steps.active").addClass("active_status");
602
+
603
+ this.request = jQuery.ajax({
604
+ url: this.ajaxurl,
605
+ dataType: 'json',
606
+ type: 'POST',
607
+ data: params,
608
+ error: function(xhr, status, error) {
609
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: xhr.status+" "+xhr.statusText}}));
610
+ $this[callback](xhr, false);
611
+ }
612
+ }).done(function(json) {
613
+
614
+ if(json.status != 200){
615
+ if(json.error)
616
+ {
617
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: json.message}}));
618
+ }
619
+ else
620
+ {
621
+ $this[callback](json, false, params);
622
+ }
623
+
624
+ return;
625
+ }
626
+ $this[callback](json, true, params);
627
+ });
628
+ }
629
+
630
+
631
+ set_restore_script_url(url)
632
+ {
633
+ this.restore_script_url = url;
634
+ }
635
+
636
+ set_current_step(id)
637
+ {
638
+ this.set_current_step = id;
639
+ }
640
+
641
+ set_cancel(status)
642
+ {
643
+ if(status)
644
+ {
645
+ //document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {append : true, message: "Cancelled" }}));
646
+ document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0, class: 'determinate' }}));
647
+
648
+ }
649
+
650
+ this.cancel = status
651
+ }
652
+
653
+ get_cancel(status)
654
+ {
655
+ return this.cancel
656
+ }
657
+
658
+ getSize(bytes, conv = 1024*1024)
659
+ {
660
+ return (bytes/conv).toFixed(2);
661
+ }
662
+
663
+
664
+ }
665
+
666
+ var xcloner_auth_key = "";
667
+
668
+ jQuery(document).ready(function(){
669
+
670
+ var xcloner_restore = new Xcloner_Restore(xcloner_auth_key);
671
+
672
+ xcloner_restore.set_current_step(0);
673
+
674
+ jQuery('select').material_select();
675
+
676
+ jQuery(".xcloner-restore .upload-backup.cancel").on("click", function(){
677
+ //jQuery(".xcloner-restore #upload_backup").show();
678
+ //jQuery(this).hide();
679
+ xcloner_restore.set_cancel(true);
680
+ })
681
+
682
+ jQuery(".xcloner-restore .upload-backup").on("click",function(){
683
+
684
+ if(jQuery(this).hasClass('cancel'))
685
+ xcloner_restore.set_cancel(true);
686
+ else
687
+ xcloner_restore.set_cancel(false);
688
+
689
+ var backup_file = jQuery(".xcloner-restore #backup_file").val();
690
+
691
+ if(backup_file)
692
+ {
693
+ jQuery(this).parent().toggleClass("cancel")
694
+
695
+ if(!xcloner_restore.get_cancel())
696
+ xcloner_restore.upload_backup_file(backup_file);
697
+ }else{
698
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: "Please select a backup file from the list above" }}));
699
+
700
+ }
701
+ })
702
+
703
+ jQuery(".xcloner-restore #validate_url").on("click", function(){
704
+
705
+ xcloner_restore.set_restore_script_url(jQuery(".xcloner-restore #restore_script_url").val());
706
+ xcloner_restore.verify_restore_url();
707
+
708
+ })
709
+
710
+ jQuery(".xcloner-restore #skip_upload_backup").on("click", function(){
711
+
712
+ xcloner_restore.set_cancel(true);
713
+ xcloner_restore.next_step();
714
+
715
+ })
716
+
717
+ jQuery(".xcloner-restore #skip_restore_remote_database_step").on("click", function(){
718
+
719
+ xcloner_restore.set_cancel(true);
720
+ xcloner_restore.next_step();
721
+
722
+ })
723
+
724
+ jQuery(".xcloner-restore li.steps").on("click", function(){
725
+ xcloner_restore.set_current_step = (jQuery(this).attr("data-step")-1)
726
+ })
727
+
728
+ jQuery(".xcloner-restore #skip_remote_backup_step").on("click", function(){
729
+ xcloner_restore.set_cancel(true);
730
+ xcloner_restore.next_step();
731
+ })
732
+
733
+ jQuery(".xcloner-restore .restore-remote-backup-step .collapsible-header").click(function(){
734
+ xcloner_restore.get_remote_backup_files();
735
+ })
736
+
737
+ jQuery(".xcloner-restore .restore-remote-database-step .collapsible-header").click(function(){
738
+ xcloner_restore.get_remote_mysqldump_files();
739
+ })
740
+
741
+ jQuery(".xcloner-restore #remote_backup_file").on("change", function(){
742
+ xcloner_restore.init_resume()
743
+ })
744
+
745
+ jQuery(".xcloner-restore #backup_file").on("change", function(){
746
+ xcloner_restore.init_resume()
747
+ })
748
+
749
+ jQuery(".xcloner-restore #restore_finish").click(function(){
750
+ xcloner_restore.restore_finish();
751
+ })
752
+
753
+ jQuery(".xcloner-restore #refresh_remote_backup_file").on("click", function(e){
754
+ document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0 }}));
755
+ xcloner_restore.resume = new Object();
756
+ xcloner_restore.get_remote_backup_files();
757
+ e.stopPropagation();
758
+ })
759
+
760
+ jQuery(".xcloner-restore #refresh_database_file").on("click", function(e){
761
+ document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0 }}));
762
+ xcloner_restore.resume = new Object();
763
+ xcloner_restore.get_remote_mysqldump_files();
764
+ e.stopPropagation();
765
+ })
766
+
767
+ jQuery(".xcloner-restore #toggle_file_restore_display").on("click", function(){
768
+ jQuery(".xcloner-restore .restore-remote-backup-step .files-list").toggle();
769
+ })
770
+
771
+ jQuery(".xcloner-restore .restore_remote_mysqldump").on("click", function(e){
772
+ if(jQuery(this).hasClass('cancel'))
773
+ xcloner_restore.set_cancel(true);
774
+ else
775
+ xcloner_restore.set_cancel(false);
776
+
777
+ this.remote_database_file = jQuery(".xcloner-restore #remote_database_file").val();
778
+
779
+ if(!this.remote_database_file)
780
+ {
781
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: "Please select a mysqld backup file from the list" }}));
782
+ return;
783
+ }
784
+
785
+ jQuery(this).parent().toggleClass("cancel")
786
+
787
+ if(!xcloner_restore.get_cancel())
788
+ {
789
+ document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0, class: 'determinate' }}));
790
+ xcloner_restore.remote_restore_mysql_backup_file(this.remote_database_file);
791
+ }
792
+
793
+ })
794
+
795
+ jQuery(".xcloner-restore .restore-remote-backup-step .restore_remote_backup").click(function(){
796
+ if(jQuery(this).hasClass('cancel'))
797
+ xcloner_restore.set_cancel(true);
798
+ else
799
+ xcloner_restore.set_cancel(false);
800
+
801
+ this.backup_file = jQuery(".xcloner-restore #remote_backup_file").val();
802
+
803
+ if(!this.backup_file)
804
+ {
805
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: "Please select a backup file from the list above" }}));
806
+ return;
807
+ }
808
+
809
+ this.remote_path = jQuery(".xcloner-restore #remote_restore_path").val();
810
+
811
+ if(!this.remote_path)
812
+ {
813
+ document.dispatchEvent(new CustomEvent("xcloner_restore_display_status_text", {detail: {status: 'error', message: "Please enter the remote restore path" }}));
814
+ return;
815
+ }
816
+
817
+ jQuery(this).parent().toggleClass("cancel")
818
+
819
+ if(!xcloner_restore.get_cancel())
820
+ {
821
+ document.dispatchEvent(new CustomEvent("xcloner_restore_update_progress", {detail: {percent: 0, class: 'indeterminate' }}));
822
+ xcloner_restore.remote_restore_backup_file(this.backup_file, this.remote_path);
823
+ }
824
+
825
+ })
826
+
827
+ })
admin/js/xcloner-scheduler-class.js ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function(){
2
+
3
+ class Xcloner_Scheduler{
4
+
5
+ constructor()
6
+ {
7
+ this.edit_modal = jQuery('.modal').modal();
8
+ }
9
+
10
+ get_form_params()
11
+ {
12
+
13
+ }
14
+
15
+ get_schedule_by_id(id)
16
+ {
17
+ var $this = this
18
+
19
+ if(id){
20
+ jQuery.ajax({
21
+ url: ajaxurl,
22
+ data: { action : 'get_schedule_by_id', id: id},
23
+ success: function(response){
24
+ if(response.id == id)
25
+ $this.create_modal(response)
26
+ },
27
+ dataType: 'json'
28
+ });
29
+ }
30
+ }
31
+
32
+ delete_schedule_by_id(id, elem, dataTable)
33
+ {
34
+ var $this = this
35
+
36
+ if(id){
37
+ jQuery.ajax({
38
+ url: ajaxurl,
39
+ data: { action : 'delete_schedule_by_id', id: id},
40
+ success: function(response){
41
+ //window.location = "";
42
+ //alert("Schedule deleted");
43
+ dataTable
44
+ .row( jQuery(elem).parents('tr') )
45
+ .remove()
46
+ .draw();
47
+ },
48
+ dataType: 'json'
49
+ });
50
+ }
51
+ }
52
+
53
+ create_modal(response)
54
+ {
55
+ this.edit_modal.find("#schedule_id").text(response.id)
56
+
57
+ if(response.status == 1)
58
+ this.edit_modal.find("#status").attr("checked", "checked");
59
+ else
60
+ this.edit_modal.find("#status").removeAttr("checked");
61
+
62
+ this.edit_modal.find("#schedule_id").text(response.id)
63
+ this.edit_modal.find("#schedule_id_hidden").val(response.id)
64
+ this.edit_modal.find("#schedule_name").val(response.name)
65
+ this.edit_modal.find("#backup_name").val(response.backup_params.backup_name)
66
+ this.edit_modal.find("#email_notification").val(response.backup_params.email_notification)
67
+ this.edit_modal.find('#schedule_frequency>option[value="' + response.recurrence + '"]').prop('selected', true);
68
+ this.edit_modal.find('#schedule_storage>option[value="' + response.remote_storage + '"]').prop('selected', true);
69
+ //var date = new Date(response.start_at);
70
+ this.edit_modal.find("#schedule_start_date").val(response.start_at)
71
+
72
+ var tables = jQuery.parseJSON(response.table_params)
73
+
74
+ var tables_list = "";
75
+
76
+ for(var db in tables)
77
+ {
78
+ for(var i in tables[db])
79
+ tables_list += db+"."+tables[db][i]+"\n";
80
+ }
81
+
82
+ this.edit_modal.find("#table_params").val(tables_list)
83
+
84
+ var files = jQuery.parseJSON(response.excluded_files)
85
+ var exclude_files_list = "";
86
+ for(var i in files)
87
+ {
88
+ exclude_files_list += files[i]+"\n";
89
+
90
+ }
91
+
92
+ this.edit_modal.find("#excluded_files").val(exclude_files_list)
93
+
94
+ jQuery('select').material_select();
95
+
96
+ Materialize.updateTextFields();
97
+
98
+ this.edit_modal.modal('open');
99
+ }
100
+
101
+ save_schedule(form, dataTable)
102
+ {
103
+ /*if(!this.IsJsonString(jQuery("#table_params").val()) )
104
+ {
105
+ //alert("Database field is not a valid json data!");
106
+ //return false;
107
+ }
108
+
109
+ if(!this.IsJsonString(jQuery("#excluded_files").val()) )
110
+ {
111
+ alert("Exclude files field is not a valid json data!");
112
+ return false;
113
+ }*/
114
+
115
+ var data = jQuery(form).serialize();
116
+ var $this = this
117
+
118
+ jQuery.ajax({
119
+ url: ajaxurl,
120
+ dataType: 'json',
121
+ type: 'POST',
122
+ data: data,
123
+ error: function(err) {
124
+ //show_ajax_error("Communication Error", "", err)
125
+ //console.log(err);
126
+ alert("Error saving schedule!");
127
+ }
128
+ }).done(function(json) {
129
+
130
+ if(json.error !== undefined){
131
+ alert("Error saving schedule!"+json.error);
132
+ return;
133
+ }
134
+
135
+ $this.edit_modal.modal('close');
136
+ //location.reload();
137
+ dataTable.ajax.reload();
138
+
139
+ });
140
+
141
+ }
142
+
143
+ IsJsonString(str) {
144
+ try {
145
+ JSON.parse(str);
146
+ } catch (e) {
147
+ return false;
148
+ }
149
+ return true;
150
+ }
151
+
152
+ //end class
153
+ }
154
+
155
+
156
+ var xcloner_scheduler = new Xcloner_Scheduler();
157
+
158
+ jQuery("select[required]").css({display: "block", height: 0, padding: 0, width: 0, position: 'absolute'});
159
+
160
+ dataTable = jQuery('#scheduled_backups').DataTable( {
161
+ 'responsive': true,
162
+ 'bFilter': false,
163
+ "order": [[ 3, "desc" ]],
164
+ buttons: [
165
+ 'selectAll',
166
+ 'selectNone'
167
+ ],
168
+ "language": {
169
+ "emptyTable": "No schedules available"
170
+ },
171
+ columnDefs: [
172
+ { targets: 'no-sort', orderable: false },
173
+ { className: "hide-on-med-and-down", "targets": [ 3, 5 ] }
174
+ ],
175
+ language: {
176
+ buttons: {
177
+ selectAll: "Select all items",
178
+ selectNone: "Select none"
179
+ }
180
+ },
181
+ "ajax": ajaxurl+"?action=get_scheduler_list",
182
+ "fnDrawCallback": function( oSettings ) {
183
+ //jQuery("#scheduled_backups").find(".edit").each(function(){
184
+ jQuery(this).off("click", ".edit").on("click", ".edit",function(){
185
+ var hash = jQuery(this).attr('href');
186
+ var id = hash.substr(1)
187
+ var data = xcloner_scheduler.get_schedule_by_id(id);
188
+ })
189
+ //})
190
+
191
+ //jQuery("#scheduled_backups").find(".delete").each(function(){
192
+ jQuery(this).off("click", ".delete").on("click", ".delete", function(){
193
+ var hash = jQuery(this).attr('href');
194
+ var id = hash.substr(1)
195
+ if(confirm('Are you sure you want to delete it?'))
196
+ var data = xcloner_scheduler.delete_schedule_by_id(id, (this), dataTable);
197
+ })
198
+ //})
199
+
200
+ jQuery("span.shorten_string").each(function(){
201
+ doShortText(jQuery(this));
202
+ })
203
+ jQuery("span.shorten_string").click(function(){
204
+ jQuery(this).toggleClass("full");
205
+ doShortText(jQuery(this));
206
+ })
207
+
208
+ }
209
+ });
210
+
211
+ jQuery("#save_schedule").on("submit", function(){
212
+
213
+ xcloner_scheduler.save_schedule(jQuery(this), dataTable)
214
+
215
+ return false;
216
+ })
217
+
218
+ jQuery('.timepicker').pickatime({
219
+ default: 'now',
220
+ min: [7,30],
221
+ twelvehour: false, // change to 12 hour AM/PM clock from 24 hour
222
+ donetext: 'OK',
223
+ autoclose: false,
224
+ vibrate: true // vibrate the device when dragging clock hand
225
+ });
226
+
227
+ var date_picker = jQuery('.datepicker').pickadate({
228
+ format: 'd mmmm yyyy',
229
+ selectMonths: true, // Creates a dropdown to control month
230
+ selectYears: 15, // Creates a dropdown of 15 years to control year
231
+ min: +0.1,
232
+ onSet: function() {
233
+ //this.close();
234
+ }
235
+ });
236
+
237
+ });
admin/partials/xcloner_console_page.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $xcloner_settings = new Xcloner_Settings();
4
+ $logger = new Xcloner_Logger();
5
+
6
+
7
+ $xcloner_scheduler = new Xcloner_Scheduler();
8
+ //$xcloner_scheduler->xcloner_scheduler_callback(90);
9
+
10
+ //$logger_content = $logger->getLastDebugLines();
11
+
12
+ $xcloner_file_transfer = new Xcloner_File_Transfer();
13
+
14
+ $xcloner_file_transfer->set_target("http://thinkovi.com/xcloner/xcloner_restore.php");
15
+ //$xcloner_file_transfer->set_target("http://localhost/xcloner/xcloner_restore.php");
16
+
17
+ $start = 0 ;
18
+ while( $start = $xcloner_file_transfer->transfer_file("backup_localhost-2017-02-07_13-29-sql-ac9b0.tgz", $start))
19
+ {
20
+ //echo $start."--";
21
+ }
22
+
23
+ echo "done";
24
+ ?>
25
+ <div class="col s12 ">
26
+ <div>
27
+ <h5 class="left-align">
28
+ <?php echo __('XCloner Debugger Dashboard', 'xcloner-backup-and-restore') ?>
29
+ </h5>
30
+
31
+ <?php if($xcloner_settings->get_xcloner_option('xcloner_enable_log')) :?>
32
+ <ul class="collapsible xcloner-debugger" data-collapsible="accordion">
33
+ <li class="active">
34
+ <div class="collapsible-header active"><i class="material-icons">bug_report</i>XCloner Debugger</div>
35
+ <div class="collapsible-body">
36
+ <div class="console" id="xcloner-console"><?php if(isset($logger_content)) echo implode("<br />\n", $logger_content); ?></div>
37
+ </div>
38
+ </li>
39
+ </ul>
40
+ <script>
41
+ jQuery(document).ready(function(){
42
+ var objDiv = document.getElementById("xcloner-console");
43
+ objDiv.scrollTop = objDiv.scrollHeight;
44
+ /*setInterval(function(){
45
+ getXclonerLog();
46
+ }, 2000);*/
47
+ })
48
+ </script>
49
+ <?php endif;?>
50
+ </div>
51
+ </div>
admin/partials/xcloner_generate_backups_page.php ADDED
@@ -0,0 +1,502 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $xcloner_settings = new Xcloner_Settings();
3
+ $xcloner_remote_storage = new Xcloner_Remote_Storage();
4
+ $available_storages = $xcloner_remote_storage->get_available_storages();
5
+ $tab = 1;
6
+ ?>
7
+
8
+ <script>var xcloner_backup = new Xcloner_Backup();</script>
9
+
10
+ <h1><?= esc_html(get_admin_page_title()); ?></h1>
11
+
12
+ <ul class="nav-tab-wrapper content row">
13
+ <li><a href="#backup_options" class="nav-tab col s12 m3 l2 nav-tab-active"><?php echo $tab.". ".__('Backup Options','xcloner-backup-and-restore')?></a></li>
14
+ <?php if($xcloner_settings->get_enable_mysql_backup()):?>
15
+ <li><a href="#database_options" class="nav-tab col s12 m3 l2 "><?php echo ++$tab.". ".__('Database Options','xcloner-backup-and-restore')?></a></li>
16
+ <?php endif?>
17
+ <li><a href="#files_options" class="nav-tab col s12 m3 l2 "><?php echo ++$tab.". ".__('Files Options','xcloner-backup-and-restore')?></a></li>
18
+ <li><a href="#generate_backup" class="nav-tab col s12 m3 l2 "><?php echo ++$tab.". ".__('Generate Backup','xcloner-backup-and-restore')?></a></li>
19
+ <li><a href="#schedule_backup" class="nav-tab col s12 m3 l2 "><?php echo ++$tab.". ".__('Schedule Backup','xcloner-backup-and-restore')?></a></li>
20
+ </ul>
21
+
22
+ <form action="" method="POST" id="generate_backup_form">
23
+ <div class="nav-tab-wrapper-content">
24
+ <!-- Backup Options Content Tab-->
25
+ <div id="backup_options" class="tab-content active">
26
+ <div class="row">
27
+ <div class="input-field inline col s12 m10 l6">
28
+ <i class="material-icons prefix">input</i>
29
+ <input name="backup_name" id="backup_name" type="text" value=<?php echo $xcloner_settings->get_default_backup_name() ?> >
30
+ <label for="backup_name"><?php echo __('Backup Name','xcloner-backup-and-restore')?></label>
31
+ </div>
32
+ <div class="hide-on-small-only m2">
33
+ <a class="btn-floating tooltipped btn-small" data-position="right" data-delay="50" data-tooltip="<?php echo __('The default backup name, supported tags [time], [hostname], [domain]','xcloner-backup-and-restore')?>" data-tooltip-id=""><i class="material-icons">help_outline</i></a>
34
+ </div>
35
+ </div>
36
+
37
+ <div class="row">
38
+ <div class="input-field inline col s12 m10 l6">
39
+ <i class="material-icons prefix">input</i>
40
+ <input name="email_notification" id="email_notification" type="text" value="<?php echo get_option('admin_email');?>" >
41
+ <label for="email_notification"><?php echo __('Send Email Notification To','xcloner-backup-and-restore')?></label>
42
+ </div>
43
+ <div class="hide-on-small-only m2">
44
+ <a class="btn-floating tooltipped btn-small" data-position="right" data-delay="50" data-tooltip="<?php echo __('If left blank, no notification will be sent','xcloner-backup-and-restore')?>" data-tooltip-id=""><i class="material-icons">help_outline</i></a>
45
+ </div>
46
+ </div>
47
+
48
+ <div class="row">
49
+ <div class="input-field col s12 m10 l6">
50
+ <i class="material-icons prefix">input</i>
51
+ <textarea name="backup_comments" id="backup_comments" class="materialize-textarea"></textarea>
52
+ <label for="backup_comments"><?php echo __('Backup Comments','xcloner-backup-and-restore')?></label>
53
+ </div>
54
+ <div class="hide-on-small-only m2">
55
+ <a class="btn-floating tooltipped btn-small" data-position="right" data-delay="50" data-tooltip="<?php echo __('Some default backup comments that will be stored inside the backup archive','xcloner-backup-and-restore')?>" data-tooltip-id=""><i class="material-icons">help_outline</i></a>
56
+ </div>
57
+ </div>
58
+
59
+ <div class="row">
60
+ <div class="input-field col s12 m10 l6 right-align">
61
+ <a class="waves-effect waves-light btn" onclick="next_tab('#database_options');"><i class="material-icons right">skip_next</i>Next</a>
62
+ </div>
63
+ </div>
64
+ </div>
65
+
66
+ <?php if($xcloner_settings->get_enable_mysql_backup()):?>
67
+ <div id="database_options" class="tab-content">
68
+ <h2><?php echo __('Select database data to include in the backup', 'xcloner-backup-and-restore')?>:
69
+ <a class="btn-floating tooltipped btn-small" data-position="right" data-delay="50" data-tooltip="<?php echo __('Enable the \'Backup only WP tables\' setting if you don\'t want to show all other databases and tables not related to this Wordpress install','xcloner-backup-and-restore');?>" data-tooltip-id=""><i class="material-icons">help_outline</i></a>
70
+ </h2>
71
+
72
+ <!-- database/tables tree -->
73
+ <div class="row">
74
+ <div class="col s12 l6">
75
+ <div id="jstree_database_container"></div>
76
+ </div>
77
+ </div>
78
+
79
+ <div class="row">
80
+ <div class="input-field col s12 m10 l6 right-align">
81
+ <a class="waves-effect waves-light btn" onclick="next_tab('#files_options');"><i class="material-icons right">skip_next</i>Next</a>
82
+ </div>
83
+ </div>
84
+
85
+ </div>
86
+ <?php endif ?>
87
+
88
+ <div id="files_options" class="tab-content">
89
+ <h2><?php echo __('Select from below the files/folders you want to exclude from your Backup Archive','xcloner-backup-and-restore')?>:
90
+ <a class="btn-floating tooltipped btn-small" data-position="bottom" data-delay="50" data-html="true" data-tooltip="<?php echo __('You can navigate below through all your site structure(Backup Start Location) to exclude any file/folder you need by clicking the checkbox near it. <br />If the checkobx is disabled, then it matches a Regex Exclude File option and it can\'t be unchecked','xcloner-backup-and-restore');?>" data-tooltip-id=""><i class="material-icons">help_outline</i></a>
91
+ </h2>
92
+
93
+ <!-- Files System Container -->
94
+ <div class="row">
95
+ <div class="col s12 l6">
96
+ <div id="jstree_files_container"></div>
97
+ </div>
98
+ </div>
99
+
100
+ <div class="row">
101
+ <div class="input-field col s12 m10 l6 right-align">
102
+ <a class="waves-effect waves-light btn" onclick="next_tab('#generate_backup');"><i class="material-icons right">skip_next</i>Next</a>
103
+ </div>
104
+ </div>
105
+
106
+ </div>
107
+ <div id="generate_backup" class="tab-content">
108
+ <div class="row ">
109
+ <div class="col s12 l10 center action-buttons">
110
+ <a class="waves-effect waves-light btn-large teal darken-1 start" onclick="xcloner_backup.start_backup()">Start Backup<i class="material-icons left">forward</i></a>
111
+ <a class="waves-effect waves-light btn-large teal darken-1 restart" onclick="xcloner_backup.restart_backup()">Restart Backup<i class="material-icons left">cached</i></a>
112
+ <a class="waves-effect waves-light btn-large red darken-1 cancel" onclick="xcloner_backup.cancel_backup()">Cancel Backup<i class="material-icons left">cancel</i></a>
113
+ </div>
114
+ <div class="col l10 s12">
115
+ <ul class="backup-status collapsible" data-collapsible="accordion">
116
+ <li class="file-system">
117
+ <div class="collapsible-header">
118
+ <i class="material-icons">folder</i><?php echo __('Scanning The File System...','xcloner-backup-and-restore')?>
119
+
120
+ <p class="right"><?php echo sprintf(__('Found %s files (%s)', 'xcloner-backup-and-restore'), '<span class="file-counter">0</span>', '<span class="file-size-total">0</span>MB')?></p>
121
+
122
+ <div>
123
+ <p class="right"><span class="last-logged-file"></span></p>
124
+ </div>
125
+
126
+ <div class="progress">
127
+ <div class="indeterminate"></div>
128
+ </div>
129
+ </div>
130
+ <div class="collapsible-body status-body"></div>
131
+ </li>
132
+ <?php if($xcloner_settings->get_enable_mysql_backup()):?>
133
+ <li class="database-backup">
134
+ <div class="collapsible-header">
135
+ <i class="material-icons">storage</i><?php echo __('Generating the Mysql Backup...','xcloner-backup-and-restore')?>
136
+
137
+ <p class="right"><?php echo sprintf(__('Found %s tables in %s databases (%s)', 'xcloner-backup-and-restore'), '<span class="table-counter">0</span>', '<span class="database-counter">0</span>', '<span data-processed="0" class="total-records">0</span> records','xcloner-backup-and-restore')?></p>
138
+
139
+ <div>
140
+ <p class="right"><span class="last-logged-table"></span></p>
141
+ </div>
142
+
143
+ <div class="progress">
144
+ <div class="determinate" style="width:0%"></div>
145
+ </div>
146
+ </div>
147
+ <div class="collapsible-body status-body">
148
+ <div class="row">
149
+ <div class="col l7 s12">
150
+ <ul class="logged-tables"></ul>
151
+ </div>
152
+ <div class="col l5 s12">
153
+ <ul class="logged-databases right"></ul>
154
+ </div>
155
+ </div>
156
+ </div>
157
+ </li>
158
+ <?php endif?>
159
+ <li class="files-backup">
160
+ <div class="collapsible-header">
161
+ <i class="material-icons">archive</i><?php echo __('Adding Files to Archive...','xcloner-backup-and-restore')?>
162
+
163
+ <p class="right"><?php echo sprintf(__('Adding %s files (%s)','xcloner-backup-and-restore'), '<span class="file-counter">0</span>', '<span data-processed="0" class="file-size-total">0</span>MB')?></p>
164
+
165
+ <div>
166
+ <p class="right"><span class="last-logged-file"></span></p>
167
+ </div>
168
+
169
+ <div class="progress">
170
+ <div class="determinate" style="width:0%"></div>
171
+ </div>
172
+ </div>
173
+ <div class="collapsible-body status-body">
174
+ <div class="row">
175
+ <div class="col l3 s12">
176
+ <h2><?php echo __("Backup Parts",'xcloner-backup-and-restore')?>: </h2>
177
+ </div>
178
+ <div class="col l9 s12">
179
+ <ul class="backup-name"></ul>
180
+ </div>
181
+ </div>
182
+ </div>
183
+ </li>
184
+ <li class="backup-done">
185
+ <div class="collapsible-header">
186
+ <i class="material-icons">done</i><?php echo __('Backup Done','xcloner-backup-and-restore')?>
187
+
188
+ <p class="right">
189
+ <?php if(sizeof($available_storages)):?>
190
+ <a href="#" class="cloud-upload" title="<?php echo __("Send Backup To Remote Storage",'xcloner-backup-and-restore')?>"><i class="material-icons">cloud_upload</i></a>
191
+ <?php endif?>
192
+ <a href="#" class="download" title="<?php echo __("Download Backup",'xcloner-backup-and-restore')?>"><i class="material-icons">file_download</i></a>
193
+ <a href="#" class="list-backup-content" title="<?php echo __("List Backup Content",'xcloner-backup-and-restore')?>"><i class="material-icons">folder_open</i></a>
194
+ </p>
195
+
196
+ <div class="progress">
197
+ <div class="determinate" style="width:100%"></div>
198
+ </div>
199
+
200
+ </div>
201
+ <div class="collapsible-body center-align">
202
+ <div class="row">
203
+ <h5><?php echo __("Thank you for using XCloner.",'xcloner-backup-and-restore')?></h5>
204
+ <h6><?php echo sprintf(__("We would love to hear about your experience in the %s.", 'xcloner-backup-and-restore'),'<a href="https://wordpress.org/support/plugin/xcloner-backup-and-restore/reviews/" target="_blank">Wordpress XCloner Reviews Section</a>') ?></h6>
205
+ <a class="twitter-follow-button" href="https://twitter.com/thinkovi" data-show-count="false">Follow @thinkovi</a>
206
+ <script src="//platform.twitter.com/widgets.js" async="" charset="utf-8"></script>
207
+ </div>
208
+ </div>
209
+ </li>
210
+ </ul>
211
+ </div>
212
+
213
+ </div>
214
+ </div>
215
+
216
+ <div id="schedule_backup" class="tab-content">
217
+
218
+ <div class="row">
219
+ <div id="schedule_backup_success" class="col s12 l6 updated settings-error notice is-dismissible">
220
+ <p><strong><?php echo __('Schedule Saved', 'xcloner-backup-and-restore')?></strong></p>
221
+ <button type="button" class="notice-dismiss"><span class="screen-reader-text"><?php echo __('(Dismiss this notice.','xcloner-backup-and-restore')?></span></button>
222
+ </div>
223
+ </div>
224
+
225
+ <!--<div class="row server-time">
226
+ <div class="col s12 m10 l6 teal lighten-1">
227
+ <h2><?php echo __('Current Server Time', 'xcloner-backup-and-restore')?>: <span class="right"><?php echo date("Y/m/d H:i")?></span></h2>
228
+ </div>
229
+ </div>
230
+ -->
231
+ <div class="row">
232
+ <div class="input-field inline col s12 m10 l6">
233
+ <input type="text" id="schedule_name" class="" name="schedule_name" required>
234
+ <label for="schedule_name"><?php echo __('Schedule Name', 'xcloner-backup-and-restore') ?></label>
235
+ </div>
236
+ </div>
237
+
238
+ <div class="row">
239
+ <div class="input-field inline col s12 m6 l4">
240
+ <input type="datetime-local" id="datepicker" class="datepicker" name="schedule_start_date" >
241
+ <label for="datepicker"><?php echo __('Schedule Backup To Start On:','xcloner-backup-and-restore')?></label>
242
+ </div>
243
+ <div class="input-field inline col s12 m4 l2">
244
+ <input id="timepicker_ampm_dark" class="timepicker" type="time" name="schedule_start_time">
245
+ <label for="timepicker_ampm_dark"><?php echo __('At:','xcloner-backup-and-restore')?></label>
246
+ </div>
247
+ </div>
248
+
249
+ <div class="row">
250
+ <div class="input-field col s12 m10 l6">
251
+ <select name="schedule_frequency" id="schedule_frequency" class="validate" required>
252
+ <option value="" disabled selected><?php echo __('please select', 'xcloner-backup-and-restore') ?></option>
253
+ <option value="single"><?php echo __("Don't Repeat",'xcloner-backup-and-restore')?></option>
254
+ <option value="hourly"><?php echo __("Hourly",'xcloner-backup-and-restore')?></option>
255
+ <option value="daily"><?php echo __("Daily",'xcloner-backup-and-restore')?></option>
256
+ <option value="weekly"><?php echo __("Weekly",'xcloner-backup-and-restore')?></option>
257
+ <option value="monthly"><?php echo __("Monthly",'xcloner-backup-and-restore')?></option>
258
+ </select>
259
+ <label><?php echo __('Please Select Frequency to run', 'xcloner-backup-and-restore') ?></label>
260
+ </div>
261
+ </div>
262
+
263
+ <?php if(sizeof($available_storages)):?>
264
+ <div class="row">
265
+ <div class="input-field col s12 m10 l6">
266
+ <select name="schedule_storage" id="schedule_storage" class="validate">
267
+ <option value="" selected><?php echo __('none', 'xcloner-backup-and-restore') ?></option>
268
+ <?php foreach($available_storages as $storage=>$text):?>
269
+ <option value="<?php echo $storage?>"><?php echo $text?></option>
270
+ <?php endforeach?>
271
+ </select>
272
+ <label><?php echo __('Send To Remote Storage', 'xcloner-backup-and-restore') ?></label>
273
+ </div>
274
+ </div>
275
+ <?php endif?>
276
+ <div class="row">
277
+ <div class="col s12 m10 l6">
278
+ <button class="right btn waves-effect waves-light submit_schedule" type="submit" name="action"><?php echo __("Submit" ,'xcloner-backup-and-restore')?>
279
+ <i class="material-icons right">send</i>
280
+ </button>
281
+ </div>
282
+ </div>
283
+ </div>
284
+ </div>
285
+ </form>
286
+
287
+ <!-- Error Modal Structure -->
288
+ <div id="error_modal" class="modal">
289
+ <a title="Online Help" href="https://wordpress.org/support/plugin/xcloner-backup-and-restore" target="_blank"><i class="material-icons medium right">help</i></a>
290
+ <div class="modal-content">
291
+ <h4 class="title_line"><span class="title"></span></h4>
292
+ <!--<h5 class="title_line"><?php echo __('Message')?>: <span class="msg.old"></span></h5>-->
293
+ <h5><?php echo __('Response Code', 'xcloner-backup-and-restore')?>: <span class="status"></span></h5>
294
+ <textarea class="body" rows="5"></textarea>
295
+ </div>
296
+ <div class="modal-footer">
297
+ <a class=" modal-action modal-close waves-effect waves-green btn-flat red darken-2"><?php echo __('Close','xcloner-backup-and-restore')?></a>
298
+ </div>
299
+ </div>
300
+
301
+ <!-- List Backup Content Modal-->
302
+
303
+ <div id="backup_cotent_modal" class="modal">
304
+ <div class="modal-content">
305
+ <h4><?php echo sprintf(__("Listing Backup Content ",'xcloner-backup-and-restore'), "")?></h4>
306
+ <h5 class="backup-name"></h5>
307
+
308
+ <div class="progress">
309
+ <div class="indeterminate"></div>
310
+ </div>
311
+ <ul class="files-list"></ul>
312
+ </div>
313
+ </div>
314
+
315
+ <!-- Remote Storage Modal Structure -->
316
+ <div id="remote_storage_modal" class="modal">
317
+ <form method="POST" class="remote-storage-form">
318
+ <input type="hidden" name="file" class="backup_name">
319
+ <div class="modal-content">
320
+ <h4><?php echo __("Remote Storage Transfer",'xcloner-backup-and-restore')?></h4>
321
+ <p>
322
+ <?php if(sizeof($available_storages)):?>
323
+ <div class="row">
324
+ <div class="col s12 label">
325
+ <label><?php echo __(sprintf('Send %s to remote storage', "<span class='backup_name'></span>"), 'xcloner-backup-and-restore') ?></label>
326
+ </div>
327
+ <div class="input-field col s8 m10">
328
+ <select name="transfer_storage" id="transfer_storage" class="validate" required >
329
+ <option value="" selected><?php echo __('please select...', 'xcloner-backup-and-restore') ?></option>
330
+ <?php foreach($available_storages as $storage=>$text):?>
331
+ <option value="<?php echo $storage?>"><?php echo $text?></option>
332
+ <?php endforeach?>
333
+ </select>
334
+
335
+ </div>
336
+ <div class="s4 m2 right">
337
+ <button type="submit" class="upload-submit btn-floating btn-large waves-effect waves-light teal"><i class="material-icons">file_upload</i></submit>
338
+ </div>
339
+ </div>
340
+ <div class="row status">
341
+ <?php echo __("Uploading backup to the selected remote storage...",'xcloner-backup-and-restore')?> <span class="status-text"></span>
342
+ <div class="progress">
343
+ <div class="indeterminate"></div>
344
+ </div>
345
+ </div>
346
+ <?php endif?>
347
+ </p>
348
+ </div>
349
+ </form>
350
+ </div>
351
+
352
+ <script>
353
+ jQuery(function () {
354
+
355
+ jQuery('select').material_select();
356
+ jQuery("select[required]").css({display: "block", height: 0, padding: 0, width: 0, position: 'absolute'});
357
+ jQuery(".backup-done .cloud-upload").on("click", function(e){
358
+ var xcloner_manage_backups = new Xcloner_Manage_Backups();
359
+ var hash = jQuery(this).attr('href');
360
+ var id = hash.substr(1)
361
+
362
+ e.preventDefault();
363
+ xcloner_manage_backups.cloud_upload(id)
364
+ })
365
+
366
+ jQuery("#generate_backup_form").on("submit", function(){
367
+
368
+ xcloner_backup.params = xcloner_backup.get_form_params();
369
+ var data = JSON.stringify(xcloner_backup.params);
370
+
371
+ xcloner_backup.set_cancel(false);
372
+
373
+ xcloner_backup.do_ajax(data, "save_schedule")
374
+ return false;
375
+ })
376
+
377
+ jQuery(".backup-done .download").on("click", function(e){
378
+ var xcloner_manage_backups = new Xcloner_Manage_Backups();
379
+ var hash = jQuery(this).attr('href');
380
+ var id = hash.substr(1)
381
+
382
+ e.preventDefault();
383
+ xcloner_manage_backups.download_backup_by_name(id)
384
+ })
385
+
386
+ jQuery(".backup-done .list-backup-content").on("click", function(e){
387
+ var xcloner_manage_backups = new Xcloner_Manage_Backups();
388
+ var hash = jQuery(this).attr('href');
389
+ var id = hash.substr(1)
390
+
391
+ e.preventDefault();
392
+ xcloner_manage_backups.list_backup_content(id)
393
+ })
394
+
395
+ jQuery('.timepicker').pickatime({
396
+ default: 'now',
397
+ min: [7,30],
398
+ twelvehour: false, // change to 12 hour AM/PM clock from 24 hour
399
+ donetext: 'OK',
400
+ autoclose: false,
401
+ vibrate: true // vibrate the device when dragging clock hand
402
+ });
403
+
404
+ var date_picker = jQuery('.datepicker').pickadate({
405
+ format: 'd mmmm yyyy',
406
+ selectMonths: true, // Creates a dropdown to control month
407
+ selectYears: 15, // Creates a dropdown of 15 years to control year
408
+ min: +0.1,
409
+ onSet: function() {
410
+ //this.close();
411
+ }
412
+ });
413
+
414
+ <?php if($xcloner_settings->get_enable_mysql_backup()):?>
415
+ jQuery('#jstree_database_container').jstree({
416
+ 'core' : {
417
+ 'check_callback' : true,
418
+ 'data' : {
419
+ 'method': 'POST',
420
+ 'dataType': 'json',
421
+ 'url' : ajaxurl,
422
+ 'data' : function (node) {
423
+ var data = {
424
+ 'action': 'get_database_tables_action',
425
+ 'id' : node.id
426
+ }
427
+ return data;
428
+ }
429
+ },
430
+
431
+ 'error' : function (err) {
432
+ //alert("We have encountered a communication error with the server, please review the javascript console.");
433
+ var json = jQuery.parseJSON( err.data )
434
+ show_ajax_error("Error Loading Database Structure ", err.reason, json.xhr);
435
+ },
436
+
437
+ 'strings' : { 'Loading ...' : 'Loading the database structure...' },
438
+ 'themes' : {
439
+ "variant" : "default"
440
+ },
441
+ },
442
+ 'checkbox': {
443
+ three_state: true
444
+ },
445
+ 'plugins' : [
446
+ "checkbox",
447
+ "massload",
448
+ "search",
449
+ //"sort",
450
+ //"state",
451
+ "types",
452
+ "unique",
453
+ "wholerow"
454
+ ]
455
+ });
456
+ <?php endif ?>
457
+
458
+ jQuery('#jstree_files_container').jstree({
459
+ 'core' : {
460
+ 'check_callback' : true,
461
+ 'data' : {
462
+ 'method': 'POST',
463
+ 'dataType': 'json',
464
+ 'url' : ajaxurl,
465
+ 'data' : function (node) {
466
+ var data = {
467
+ 'action': 'get_file_system_action',
468
+ 'id' : node.id
469
+ }
470
+ return data;
471
+ }
472
+ },
473
+
474
+ 'error' : function (err) {
475
+ //alert("We have encountered a communication error with the server, please review the javascript console.");
476
+ var json = jQuery.parseJSON( err.data )
477
+ show_ajax_error("Error Loading Files Structure ", err.reason, json.xhr);
478
+ },
479
+
480
+ 'strings' : { 'Loading ...' : 'Loading the database structure...' },
481
+ 'themes' : {
482
+ "variant" : "default"
483
+ },
484
+ },
485
+ 'checkbox': {
486
+ three_state: true
487
+ },
488
+ 'plugins' : [
489
+ "checkbox",
490
+ "massload",
491
+ "search",
492
+ //"sort",
493
+ //"state",
494
+ "types",
495
+ "unique",
496
+ "wholerow"
497
+ ]
498
+ });
499
+ });
500
+
501
+
502
+ </script>
admin/partials/xcloner_init_page.php ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Provide a admin area view for the plugin
5
+ *
6
+ * This file is used to markup the admin-facing aspects of the plugin.
7
+ *
8
+ * @link http://www.thinkovi.com
9
+ * @since 1.0.0
10
+ *
11
+ * @package Xcloner
12
+ * @subpackage Xcloner/admin/partials
13
+ */
14
+
15
+ $requirements = new XCloner_Requirements();
16
+ $xcloner_settings = new Xcloner_Settings();
17
+ $xcloner_file_system = new Xcloner_File_System();
18
+ $logger = new Xcloner_Logger();
19
+ $xcloner_scheduler = new Xcloner_Scheduler();
20
+
21
+ $logger_content = $logger->getLastDebugLines();
22
+
23
+ $date_format = get_option( 'date_format' );
24
+ $time_format = get_option( 'time_format' );
25
+
26
+ if($requirements->check_backup_ready_status())
27
+ {
28
+ $latest_backup = $xcloner_file_system->get_latest_backup();
29
+ $xcloner_file_system->backup_storage_cleanup();
30
+ }
31
+ ?>
32
+
33
+ <div class="row">
34
+ <div class="col s12">
35
+ <h5 class="left-align">
36
+ <?php echo __('Backup Dashboard', 'xcloner-backup-and-restore') ?>
37
+ </h5>
38
+ </div>
39
+ </div>
40
+
41
+ <?php if(isset($latest_backup['timestamp']) and $latest_backup['timestamp'] < strtotime("-1 day")): ?>
42
+ <div id="setting-error-" class="error settings-error notice is-dismissible">
43
+ <p><strong>
44
+ <?php echo __('Your latest backup is older than 24 hours, please create a new backup to keep your site protected.', 'xcloner-backup-and-restore') ?>
45
+ </strong>
46
+ </p><button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span></button>
47
+ </div>
48
+ <?php endif?>
49
+
50
+ <?php if(!isset($latest_backup['timestamp']) ): ?>
51
+ <div id="setting-error-" class="error settings-error notice is-dismissible">
52
+ <p><strong>
53
+ <?php echo __('You have no backup that I could find, please generate a new backup to keep your site protected.', 'xcloner-backup-and-restore') ?>
54
+ </strong>
55
+ </p><button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span></button>
56
+ </div>
57
+ <?php endif?>
58
+
59
+ <?php if(!$requirements->check_backup_ready_status()):?>
60
+ <div id="setting-error-" class="error settings-error notice is-dismissible">
61
+ <p><strong>
62
+ <?php echo __('Backup system not ready, please check and fix the issues marked in red', 'xcloner-backup-and-restore') ?>
63
+ </strong>
64
+ </p><button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span></button>
65
+ </div>
66
+
67
+ <?php endif ?>
68
+
69
+
70
+
71
+ <!-- This file should primarily consist of HTML with a little bit of PHP. -->
72
+ <div class="row dashboard">
73
+ <div class="col s12 m12 l7">
74
+
75
+ <div class="row">
76
+
77
+ <ul class="collapsible xcloner-debugger" data-collapsible="accordion">
78
+
79
+ <li class="active">
80
+ <div class="collapsible-header active"><i class="material-icons">info</i>Backup Status</div>
81
+ <div class="collapsible-body">
82
+ <div class="" id="backup-status">
83
+ <div class="row">
84
+ <h5><?php echo __("Latest Backup", 'xcloner-backup-and-restore')?></h5>
85
+ <blockquote>
86
+ <?php if($latest_backup):?>
87
+ <div class="item">
88
+ <div class="title"><?php echo __("Backup Name", 'xcloner-backup-and-restore')?>:</div>
89
+ <?php echo $latest_backup['basename']?>
90
+ </div>
91
+ <div class="item">
92
+ <div class="title">
93
+ <?php echo __("Backup Size", 'xcloner-backup-and-restore')?>:
94
+ </div>
95
+ <?php echo size_format($latest_backup['size'])?>
96
+ </div>
97
+ <div class="item">
98
+ <div class="title"><?php echo __("Backup Date", 'xcloner-backup-and-restore')?>:</div>
99
+ <?php
100
+ echo date($date_format." ".$time_format, $latest_backup['timestamp'])
101
+ ?>
102
+ </div>
103
+ <?php else:?>
104
+ <div class="item">
105
+ <div class="title"><?php echo __("No Backup Yet", 'xcloner-backup-and-restore')?></div>
106
+ </div>
107
+ <?php endif?>
108
+ </blockquote>
109
+ <div>
110
+ <h5><?php echo __("Backup Storage Usage", 'xcloner-backup-and-restore')?></h5>
111
+ <blockquote>
112
+ <div class="item">
113
+ <div class="title"><?php echo __("Total Size", 'xcloner-backup-and-restore')?>:</div>
114
+ <?php echo size_format($xcloner_file_system->get_storage_usage());?>
115
+ </div>
116
+ </blockquote>
117
+ <h5><?php echo __("Next Scheduled Backup", 'xcloner-backup-and-restore')?></h5>
118
+ <blockquote>
119
+ <div class="item">
120
+ <?php
121
+ $list = ($xcloner_scheduler->get_next_run_schedule());
122
+
123
+ if(is_array($list))
124
+ {
125
+ $xcloner_file_system->sort_by($list, "next_run_time","desc");
126
+ }
127
+
128
+ if(isset($list[0]))
129
+ $latest_schedule = $list[0];
130
+ ?>
131
+ <?php if(isset($latest_schedule->name)):?>
132
+ <div class="title"><?php echo __("Schedule Name", 'xcloner-backup-and-restore')?>:</div>
133
+ <?php echo $latest_schedule->name;?>
134
+ <?php endif;?>
135
+ </div>
136
+ <div class="item">
137
+ <div class="title"><?php echo __("Next Call", 'xcloner-backup-and-restore')?>:</div>
138
+ <?php if(isset($latest_schedule->next_run_time))
139
+ echo date($date_format." ".$time_format, $latest_schedule->next_run_time);
140
+ else
141
+ echo __("Unscheduled",'xcloner-backup-and-restore');
142
+ ?>
143
+ </div>
144
+ </blockquote>
145
+ </div>
146
+ </div>
147
+ </li>
148
+
149
+ <?php if($xcloner_settings->get_xcloner_option('xcloner_enable_log')) :?>
150
+ <li class="active">
151
+ <div class="collapsible-header active">
152
+ <i class="material-icons">bug_report</i><?php echo __('XCloner Debugger', 'xcloner-backup-and-restore')?>
153
+ <span class="right"><?php echo basename($logger->get_main_logger_url())?></span>
154
+ </div>
155
+ <div class="collapsible-body">
156
+ <div class="console" id="xcloner-console"><?php if($logger_content) echo implode("<br />\n", array_reverse($logger_content)); ?></div>
157
+ </div>
158
+ </li>
159
+ <script>
160
+ jQuery(document).ready(function(){
161
+ var objDiv = document.getElementById("xcloner-console");
162
+ objDiv.scrollTop = objDiv.scrollHeight;
163
+ /*setInterval(function(){
164
+ getXclonerLog();
165
+ }, 2000);*/
166
+ })
167
+ </script>
168
+ <?php endif;?>
169
+
170
+ </ul>
171
+
172
+ </div>
173
+
174
+
175
+ </div>
176
+ <div class="col s12 m12 l5">
177
+
178
+ <div class="card blue-grey darken-1 z-depth-4 backup-ready">
179
+ <div class="card-content white-text">
180
+ <span class="card-title"><?php echo __("System Check",'xcloner-backup-and-restore')?></span>
181
+ <ul>
182
+ <li class="card-panel <?php echo ($requirements->check_xcloner_start_path(1)?"teal":"red")?> lighten-2" >
183
+ <?php echo __('Backup Start Location','xcloner-backup-and-restore')?>: <span class="shorten_string "><?php echo $requirements->check_xcloner_start_path();?></span>
184
+ </li>
185
+ <li class="card-panel <?php echo ($requirements->check_xcloner_store_path(1)?"teal":"red")?> lighten-2" >
186
+ <?php echo __('Backup Storage Location','xcloner-backup-and-restore')?>: <span class="shorten_string"><?php echo $requirements->check_xcloner_store_path();?></span>
187
+ </li>
188
+ <li class="card-panel <?php echo ($requirements->check_xcloner_tmp_path(1)?"teal":"red")?> lighten-2" >
189
+ <?php echo __('Temporary Location','xcloner-backup-and-restore')?>: <span class="shorten_string"><?php echo $requirements->check_xcloner_tmp_path();?></span>
190
+ </li>
191
+
192
+ <li class="card-panel <?php echo ($requirements->check_min_php_version(1)?"teal":"red")?> lighten-2" >
193
+ <?php echo __('PHP Version Check','xcloner-backup-and-restore')?>: <?php echo $requirements->check_min_php_version();?>
194
+ ( >= <?php echo $requirements->get_constant('min_php_version')?>)
195
+ </li>
196
+ <li class="card-panel <?php echo ($requirements->check_safe_mode(1)?"teal":"orange")?> lighten-2" >
197
+ <?php echo __('PHP Safe Mode','xcloner-backup-and-restore')?>: <?php echo $requirements->check_safe_mode();?>
198
+ ( <?php echo $requirements->get_constant('safe_mode')?>)
199
+ </li>
200
+ <li class="card-panel <?php echo ($requirements->check_backup_ready_status()?"teal":"red")?> lighten-2">
201
+ <?php echo ($requirements->check_backup_ready_status()?__('BACKUP READY','xcloner-backup-and-restore'):__('Backup not ready, please check above requirements','xcloner-backup-and-restore'))?>
202
+ <i class="material-icons right tiny"><?php echo ($requirements->check_backup_ready_status()?'thumb_up':'thumb_down')?></i>
203
+ </li>
204
+ </ul>
205
+ <ul class="additional_system_info">
206
+ <li class="card-panel grey darken-1" >
207
+ <?php echo __('PHP max_execution_time','xcloner-backup-and-restore')?>: <?php echo $requirements->get_max_execution_time();?>
208
+ </li>
209
+ <li class="card-panel grey darken-1" >
210
+ <?php echo __('PHP memory_limit','xcloner-backup-and-restore')?>: <?php echo $requirements->get_memory_limit();?>
211
+ </li>
212
+ <li class="card-panel grey darken-1" >
213
+ <?php echo __('PHP open_basedir','xcloner-backup-and-restore')?>: <?php echo $requirements->get_open_basedir();?>
214
+ </li>
215
+ <?php
216
+ $data = array();
217
+ if($requirements->check_backup_ready_status())
218
+ $data = $xcloner_file_system->estimate_read_write_time();
219
+ ?>
220
+ <li class="card-panel grey darken-1" >
221
+ <?php echo __('Reading Time 1MB Block','xcloner-backup-and-restore')?>: <?php echo (isset($data['reading_time'])?$data['reading_time']:__("unknown"));?>
222
+ </li>
223
+ <li class="card-panel grey darken-1" >
224
+ <?php echo __('Writing Time 1MB Block','xcloner-backup-and-restore')?>: <?php echo (isset($data['writing_time'])?$data['writing_time']:__("unknown"));?>
225
+ </li>
226
+ <li class="card-panel grey darken-1" >
227
+ <?php echo __('Free Disk Space','xcloner-backup-and-restore')?>: <?php echo $requirements->get_free_disk_space();;?>
228
+ </li>
229
+ </ul>
230
+ </div>
231
+ <div class="card-action">
232
+ <a class="waves-effect waves-light btn system_info_toggle blue darken-1"><i class="material-icons left">list</i><?php echo __('Toggle Additional System Info','xcloner-backup-and-restore')?></a>
233
+ </div>
234
+ </div>
235
+
236
+ </div>
237
+ </div>
admin/partials/xcloner_manage_backups_page.php ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $xcloner_file_system = new Xcloner_File_System();
4
+
5
+ $backup_list = $xcloner_file_system->get_backup_archives_list();
6
+
7
+ $xcloner_remote_storage = new Xcloner_Remote_Storage();
8
+ $available_storages = $xcloner_remote_storage->get_available_storages();
9
+ ?>
10
+
11
+ <h1><?= esc_html(get_admin_page_title()); ?></h1>
12
+
13
+ <table id="manage_backups">
14
+ <thead>
15
+ <tr class="grey lighten-2">
16
+ <th class="no-sort">
17
+ <p>
18
+ <input name="select_all" class="" id="select_all" value="1" type="checkbox">
19
+ <label for="select_all">&nbsp;</label>
20
+ </p>
21
+ </th>
22
+ <th data-field="id"><?php echo __("Backup Name",'xcloner-backup-and-restore')?></th>
23
+ <th data-field="name"><?php echo __("Created Time",'xcloner-backup-and-restore')?></th>
24
+ <th data-field="name"><?php echo __("Size",'xcloner-backup-and-restore')?></th>
25
+ <th class="no-sort" data-field="price"><?php echo __("Action",'xcloner-backup-and-restore')?></th>
26
+
27
+ </tr>
28
+ </thead>
29
+
30
+ <tbody>
31
+
32
+
33
+ <?php
34
+ $i = 0;
35
+ foreach($backup_list as $file_info):?>
36
+ <?php if(!isset($file_info['parent'])):?>
37
+
38
+ <tr>
39
+ <td class="checkbox">
40
+ <p>
41
+ <input name="backup[]" value="<?php echo $file_info['path']?>" type="checkbox" id="checkbox_<?php echo ++$i?>">
42
+ <label for="checkbox_<?php echo $i?>">&nbsp;</label>
43
+ </p>
44
+ </td>
45
+ <td>
46
+ <?php echo $file_info['path']?>
47
+ <?php
48
+ if(isset($file_info['childs']) and is_array($file_info['childs'])):
49
+ ?>
50
+ <a href="#" title="expand" class="expand-multipart add"><i class="material-icons">add</i></a>
51
+ <a href="#" title="collapse" class="expand-multipart remove"><i class="material-icons">remove</i></a>
52
+ <ul class="multipart">
53
+ <?php foreach($file_info['childs'] as $child):?>
54
+ <?php #$download_file .= "|".$child[0];?>
55
+ <li>
56
+ <?php echo $child[0]?> (<?php echo size_format($child[2])?>)
57
+ <a href="#<?php echo $child[0];?>" class="download" title="Download Backup"><i class="material-icons">file_download</i></a>
58
+ <a href="#<?php echo $child[0]?>" class="list-backup-content" title="<?php echo __('List Backup Content','xcloner-backup-and-restore')?>"><i class="material-icons">folder_open</i></a>
59
+ </li>
60
+ <?php endforeach;?>
61
+ </ul>
62
+ <?php endif;?>
63
+ </td>
64
+ <td><?php echo date("d M, Y H:i", $file_info['timestamp'])?></td>
65
+ <td><?php echo size_format($file_info['size'])?></td>
66
+ <td>
67
+ <a href="#<?php echo $file_info['path'];?>" class="download" title="<?php echo __('Download Backup','xcloner-backup-and-restore')?>"><i class="material-icons">file_download</i></a>
68
+ <?php if(sizeof($available_storages)):?>
69
+ <a href="#<?php echo $file_info['path']?>" class="cloud-upload" title="<?php echo __('Send Backup To Remote Storage','xcloner-backup-and-restore')?>"><i class="material-icons">cloud_upload</i></a>
70
+ <?php endif?>
71
+ <a href="#<?php echo $file_info['path']?>" class="list-backup-content" title="<?php echo __('List Backup Content','xcloner-backup-and-restore')?>"><i class="material-icons">folder_open</i></a>
72
+ <a href="#<?php echo $file_info['path']?>" class="delete" title="<?php echo __('Delete Backup','xcloner-backup-and-restore')?>"><i class="material-icons">delete</i></a>
73
+ </td>
74
+
75
+ </tr>
76
+
77
+ <?php endif?>
78
+ <?php endforeach?>
79
+
80
+ </tbody>
81
+ </table>
82
+
83
+ <a class="waves-effect waves-light btn delete-all"><i class="material-icons left">delete</i><?php echo __("Delete",'xcloner-backup-and-restore')?></a>
84
+
85
+ <!-- List Backup Content Modal-->
86
+
87
+ <div id="backup_cotent_modal" class="modal">
88
+ <div class="modal-content">
89
+ <h4><?php echo sprintf(__("Listing Backup Content ",'xcloner-backup-and-restore'), "")?></h4>
90
+ <h5 class="backup-name"></h5>
91
+
92
+ <div class="progress">
93
+ <div class="indeterminate"></div>
94
+ </div>
95
+ <ul class="files-list"></ul>
96
+ </div>
97
+ </div>
98
+
99
+ <!-- Remote Storage Modal Structure -->
100
+ <div id="remote_storage_modal" class="modal">
101
+ <form method="POST" class="remote-storage-form">
102
+ <input type="hidden" name="file" class="backup_name">
103
+ <div class="modal-content">
104
+ <h4><?php echo __("Remote Storage Transfer",'xcloner-backup-and-restore')?></h4>
105
+ <p>
106
+ <?php if(sizeof($available_storages)):?>
107
+ <div class="row">
108
+ <div class="col s12 label">
109
+ <label><?php echo sprintf(__('Send %s to remote storage','xcloner-backup-and-restore'), "<span class='backup_name'></span>") ?></label>
110
+ </div>
111
+ <div class="input-field col s8 m10">
112
+ <select name="transfer_storage" id="transfer_storage" class="validate" required >
113
+ <option value="" selected><?php echo __('please select...', 'xcloner-backup-and-restore') ?></option>
114
+ <?php foreach($available_storages as $storage=>$text):?>
115
+ <option value="<?php echo $storage?>"><?php echo $text?></option>
116
+ <?php endforeach?>
117
+ </select>
118
+
119
+ </div>
120
+ <div class="s4 m2 right">
121
+ <button type="submit" class="upload-submit btn-floating btn-large waves-effect waves-light teal"><i class="material-icons">file_upload</i></submit>
122
+ </div>
123
+ </div>
124
+ <div class="row status">
125
+ <?php echo __("Uploading backup to the selected remote storage...",'xcloner-backup-and-restore')?> <span class="status-text"></span>
126
+ <div class="progress">
127
+ <div class="indeterminate"></div>
128
+ </div>
129
+ </div>
130
+ <?php endif?>
131
+ </p>
132
+ </div>
133
+ </form>
134
+ </div>
135
+
admin/partials/xcloner_remote_storage_page.php ADDED
@@ -0,0 +1,593 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <h1><?= esc_html(get_admin_page_title()); ?></h1>
2
+
3
+ <form class="remote-storage-form" method="POST">
4
+
5
+ <input type="hidden" id="connection_check" name="connection_check" value="">
6
+
7
+ <div class="row remote-storage">
8
+ <div class="col s12 m12 l10">
9
+ <ul class="collapsible popout" data-collapsible="accordion">
10
+ <!-- FTP STORAGE-->
11
+ <li id="ftp">
12
+ <div class="collapsible-header">
13
+ <i class="material-icons">computer</i><?php echo __("Ftp Storage",'xcloner-backup-and-restore')?>
14
+ <div class="right">
15
+ <div class="switch">
16
+ <label>
17
+ Off
18
+ <input type="checkbox" name="xcloner_ftp_enable" class="status" value="1" <?php if(get_option("xcloner_ftp_enable")) echo "checked"?> \>
19
+ <span class="lever"></span>
20
+ On
21
+ </label>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ <div class="collapsible-body">
26
+ <div class="row">
27
+ <div class="col s12 m3 label">
28
+ <label for="ftp_host"><?php echo __("Ftp Hostname",'xcloner-backup-and-restore')?></label>
29
+ </div>
30
+ <div class="col s12 m6">
31
+ <input placeholder="<?php echo __("Ftp Hostname",'xcloner-backup-and-restore')?>" id="ftp_host" type="text" name="xcloner_ftp_hostname" class="validate" value="<?php echo get_option("xcloner_ftp_hostname")?>">
32
+ </div>
33
+ <div class=" col s12 m2">
34
+ <input placeholder="<?php echo __("Ftp Port",'xcloner-backup-and-restore')?>" id="ftp_port" type="text" name="xcloner_ftp_port" class="validate" value="<?php echo get_option("xcloner_ftp_port", 21)?>">
35
+ </div>
36
+ </div>
37
+
38
+ <div class="row">
39
+ <div class="col s12 m3 label">
40
+ <label for="ftp_username"><?php echo __("Ftp Username",'xcloner-backup-and-restore')?></label>
41
+ </div>
42
+ <div class=" col s12 m6">
43
+ <input placeholder="<?php echo __("Ftp Username",'xcloner-backup-and-restore')?>" id="ftp_username" type="text" name="xcloner_ftp_username" class="validate" value="<?php echo get_option("xcloner_ftp_username")?>" autocomplete="off" >
44
+ </div>
45
+ </div>
46
+
47
+
48
+ <div class="row">
49
+ <div class="col s12 m3 label">
50
+ <label for="ftp_password"><?php echo __("Ftp Password",'xcloner-backup-and-restore')?></label>
51
+ </div>
52
+ <div class=" col s12 m6">
53
+ <input placeholder="<?php echo __("Ftp Password",'xcloner-backup-and-restore')?>" id="ftp_password" type="password" name="xcloner_ftp_password" class="validate" value="<?php echo get_option("xcloner_ftp_password")?>" autocomplete="off" >
54
+ </div>
55
+ </div>
56
+
57
+ <div class="row">
58
+ <div class="col s12 m3 label">
59
+ <label for="ftp_root"><?php echo __("Ftp Storage Folder",'xcloner-backup-and-restore')?></label>
60
+ </div>
61
+ <div class=" col s12 m6">
62
+ <input placeholder="<?php echo __("Ftp Storage Folder",'xcloner-backup-and-restore')?>" id="ftp_root" type="text" name="xcloner_ftp_path" class="validate" value="<?php echo get_option("xcloner_ftp_path")?>">
63
+ </div>
64
+ </div>
65
+
66
+ <div class="row">
67
+ <div class="col s12 m3 label">
68
+ <label for="ftp_root"><?php echo __("Ftp Transfer Mode",'xcloner-backup-and-restore')?></label>
69
+ </div>
70
+ <div class=" col s12 m6 input-field inline">
71
+ <input name="xcloner_ftp_transfer_mode" type="radio" id="passive" value="1" <?php if(get_option("xcloner_ftp_transfer_mode", 1)) echo "checked"?> />
72
+ <label for="passive"><?php echo __("Passive",'xcloner-backup-and-restore')?></label>
73
+
74
+ <input name="xcloner_ftp_transfer_mode" type="radio" id="active" value="0" <?php if(!get_option("xcloner_ftp_transfer_mode", 1)) echo "checked"?> />
75
+ <label for="active"><?php echo __("Active",'xcloner-backup-and-restore')?></label>
76
+ </div>
77
+ </div>
78
+
79
+ <div class="row">
80
+ <div class="col s12 m3 label">
81
+ <label for="ftp_ssl_mode"><?php echo __("Ftp Secure Connection",'xcloner-backup-and-restore')?></label>
82
+ </div>
83
+ <div class=" col s12 m6 input-field inline">
84
+ <input name="xcloner_ftp_ssl_mode" type="radio" id="ftp_ssl_mode_inactive" value="0" <?php if(!get_option("xcloner_ftp_ssl_mode")) echo "checked"?> />
85
+ <label for="ftp_ssl_mode_inactive"><?php echo __("Disable",'xcloner-backup-and-restore')?></label>
86
+
87
+ <input name="xcloner_ftp_ssl_mode" type="radio" id="ftp_ssl_mode_active" value="1" <?php if(get_option("xcloner_ftp_ssl_mode")) echo "checked"?> />
88
+ <label for="ftp_ssl_mode_active"><?php echo __("Enable",'xcloner-backup-and-restore')?></label>
89
+ </div>
90
+ </div>
91
+
92
+ <div class="row">
93
+ <div class="col s12 m3 label">
94
+ <label for="ftp_timeout"><?php echo __("Ftp Timeout",'xcloner-backup-and-restore')?></label>
95
+ </div>
96
+ <div class=" col s12 m2">
97
+ <input placeholder="<?php echo __("Ftp Timeout",'xcloner-backup-and-restore')?>" id="ftp_timeout" type="text" name="xcloner_ftp_timeout" class="validate" value="<?php echo get_option("xcloner_ftp_timeout", 30)?>">
98
+ </div>
99
+ </div>
100
+
101
+ <div class="row">
102
+ <div class="col s12 m3 label">
103
+ <label for="ftp_cleanup_days"><?php echo __("Ftp Cleanup (days)",'xcloner-backup-and-restore')?></label>
104
+ </div>
105
+ <div class=" col s12 m6">
106
+ <input placeholder="<?php echo __("how many days to keep the backups for",'xcloner-backup-and-restore')?>" id="ftp_cleanup_days" type="text" name="xcloner_ftp_cleanup_days" class="validate" value="<?php echo get_option("xcloner_ftp_cleanup_days")?>">
107
+ </div>
108
+ </div>
109
+
110
+ <div class="row">
111
+ <div class="col s6 m4">
112
+ <button class="btn waves-effect waves-light" type="submit" name="action" id="action" value="ftp"><?php echo __("Save Settings",'xcloner-backup-and-restore')?>
113
+ <i class="material-icons right">save</i>
114
+ </button>
115
+ </div>
116
+ <div class="col s6 m4">
117
+ <button class="btn waves-effect waves-light orange" type="submit" name="action" id="action" value="ftp" onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify",'xcloner-backup-and-restore')?>
118
+ <i class="material-icons right">import_export</i>
119
+ </button>
120
+ </div>
121
+ </div>
122
+
123
+ </div>
124
+ </li>
125
+ <!-- SFTP STORAGE-->
126
+ <li id="sftp">
127
+ <div class="collapsible-header">
128
+ <i class="material-icons">computer</i><?php echo __("SFTP Storage",'xcloner-backup-and-restore')?>
129
+ <div class="right">
130
+ <div class="switch">
131
+ <label>
132
+ Off
133
+ <input type="checkbox" name="xcloner_sftp_enable" class="status" value="1" <?php if(get_option("xcloner_sftp_enable")) echo "checked"?> \>
134
+ <span class="lever"></span>
135
+ On
136
+ </label>
137
+ </div>
138
+ </div>
139
+ </div>
140
+ <div class="collapsible-body">
141
+ <div class="row">
142
+ <div class="col s12 m3 label">
143
+ <label for="sftp_host"><?php echo __("SFTP Hostname",'xcloner-backup-and-restore')?></label>
144
+ </div>
145
+ <div class="col s12 m6">
146
+ <input placeholder="<?php echo __("SFTP Hostname",'xcloner-backup-and-restore')?>" id="sftp_host" type="text" name="xcloner_sftp_hostname" class="validate" value="<?php echo get_option("xcloner_sftp_hostname")?>">
147
+ </div>
148
+ <div class=" col s12 m2">
149
+ <input placeholder="<?php echo __("SFTP Port",'xcloner-backup-and-restore')?>" id="sftp_port" type="text" name="xcloner_sftp_port" class="validate" value="<?php echo get_option("xcloner_sftp_port", 22)?>">
150
+ </div>
151
+ </div>
152
+
153
+ <div class="row">
154
+ <div class="col s12 m3 label">
155
+ <label for="sftp_username"><?php echo __("SFTP Username",'xcloner-backup-and-restore')?></label>
156
+ </div>
157
+ <div class=" col s12 m6">
158
+ <input placeholder="<?php echo __("SFTP Username",'xcloner-backup-and-restore')?>" id="sftp_username" type="text" name="xcloner_sftp_username" class="validate" value="<?php echo get_option("xcloner_sftp_username")?>" autocomplete="off" >
159
+ </div>
160
+ </div>
161
+
162
+
163
+ <div class="row">
164
+ <div class="col s12 m3 label">
165
+ <label for="sftp_password"><?php echo __("SFTP Password",'xcloner-backup-and-restore')?></label>
166
+ </div>
167
+ <div class=" col s12 m6">
168
+ <input placeholder="<?php echo __("SFTP Password",'xcloner-backup-and-restore')?>" id="ftp_spassword" type="password" name="xcloner_sftp_password" class="validate" value="<?php echo get_option("xcloner_sftp_password")?>" autocomplete="off" >
169
+ </div>
170
+ </div>
171
+
172
+ <div class="row">
173
+ <div class="col s12 m3 label">
174
+ <label for="sftp_private_key"><?php echo __("SFTP Private Key",'xcloner-backup-and-restore')?></label>
175
+ </div>
176
+ <div class=" col s12 m6">
177
+ <input placeholder="<?php echo __("SFTP Private Key",'xcloner-backup-and-restore')?>" id="sftp_private_key" type="text" name="xcloner_sftp_private_key" class="validate" value="<?php echo get_option("xcloner_sftp_private_key")?>">
178
+ </div>
179
+ </div>
180
+
181
+ <div class="row">
182
+ <div class="col s12 m3 label">
183
+ <label for="sftp_root"><?php echo __("SFTP Storage Folder",'xcloner-backup-and-restore')?></label>
184
+ </div>
185
+ <div class=" col s12 m6">
186
+ <input placeholder="<?php echo __("SFTP Storage Folder",'xcloner-backup-and-restore')?>" id="sftp_root" type="text" name="xcloner_sftp_path" class="validate" value="<?php echo get_option("xcloner_sftp_path")?>">
187
+ </div>
188
+ </div>
189
+
190
+ <div class="row">
191
+ <div class="col s12 m3 label">
192
+ <label for="sftp_timeout"><?php echo __("SFTP Timeout",'xcloner-backup-and-restore')?></label>
193
+ </div>
194
+ <div class=" col s12 m2">
195
+ <input placeholder="<?php echo __("SFTP Timeout",'xcloner-backup-and-restore')?>" id="sftp_timeout" type="text" name="xcloner_sftp_timeout" class="validate" value="<?php echo get_option("xcloner_sftp_timeout", 30)?>">
196
+ </div>
197
+ </div>
198
+
199
+ <div class="row">
200
+ <div class="col s12 m3 label">
201
+ <label for="sftp_cleanup_days"><?php echo __("SFTP Cleanup (days)",'xcloner-backup-and-restore')?></label>
202
+ </div>
203
+ <div class=" col s12 m6">
204
+ <input placeholder="<?php echo __("how many days to keep the backups for",'xcloner-backup-and-restore')?>" id="sftp_cleanup_days" type="text" name="xcloner_sftp_cleanup_days" class="validate" value="<?php echo get_option("xcloner_sftp_cleanup_days")?>">
205
+ </div>
206
+ </div>
207
+
208
+ <div class="row">
209
+ <div class="col s6 m4">
210
+ <button class="btn waves-effect waves-light" type="submit" name="action" id="action" value="sftp"><?php echo __("Save Settings",'xcloner-backup-and-restore')?>
211
+ <i class="material-icons right">save</i>
212
+ </button>
213
+ </div>
214
+ <div class="col s6 m4">
215
+ <button class="btn waves-effect waves-light orange" type="submit" name="action" id="action" value="sftp" onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify",'xcloner-backup-and-restore')?>
216
+ <i class="material-icons right">import_export</i>
217
+ </button>
218
+ </div>
219
+ </div>
220
+
221
+ </div>
222
+ </li>
223
+
224
+ <!-- AWS STORAGE-->
225
+ <li id="aws">
226
+ <div class="collapsible-header">
227
+ <i class="material-icons">computer</i><?php echo __("AWS Storage",'xcloner-backup-and-restore')?>
228
+ <div class="right">
229
+ <div class="switch">
230
+ <label>
231
+ Off
232
+ <input type="checkbox" name="xcloner_aws_enable" class="status" value="1" <?php if(get_option("xcloner_aws_enable")) echo "checked"?> \>
233
+ <span class="lever"></span>
234
+ On
235
+ </label>
236
+ </div>
237
+ </div>
238
+ </div>
239
+ <div class="collapsible-body">
240
+
241
+ <div class="row">
242
+ <div class="col s12 m3 label">
243
+ &nbsp;
244
+ </div>
245
+ <div class=" col s12 m6">
246
+ <p>
247
+ <?php echo sprintf(__('Visit %s and get your "Key" and "Secret".'), "<a href='https://aws.amazon.com/s3/' target='_blank'>https://aws.amazon.com/s3/</a>")?>
248
+ </p>
249
+ </div>
250
+ </div>
251
+
252
+ <div class="row">
253
+ <div class="col s12 m3 label">
254
+ <label for="aws_key"><?php echo __("AWS Key",'xcloner-backup-and-restore')?></label>
255
+ </div>
256
+ <div class=" col s12 m6">
257
+ <input placeholder="<?php echo __("AWS Key",'xcloner-backup-and-restore')?>" id="aws_key" type="text" name="xcloner_aws_key" class="validate" value="<?php echo get_option("xcloner_aws_key")?>" autocomplete="off" >
258
+ </div>
259
+ </div>
260
+
261
+ <div class="row">
262
+ <div class="col s12 m3 label">
263
+ <label for="aws_secret"><?php echo __("AWS Secret",'xcloner-backup-and-restore')?></label>
264
+ </div>
265
+ <div class=" col s12 m6">
266
+ <input placeholder="<?php echo __("AWS Secret",'xcloner-backup-and-restore')?>" id="aws_secret" type="text" name="xcloner_aws_secret" class="validate" value="<?php echo get_option("xcloner_aws_secret")?>" autocomplete="off" >
267
+ </div>
268
+ </div>
269
+
270
+ <div class="row">
271
+ <div class="col s12 m3 label">
272
+ <label for="aws_region"><?php echo __("AWS Region",'xcloner-backup-and-restore')?></label>
273
+ </div>
274
+ <div class=" col s12 m6">
275
+ <input placeholder="<?php echo __("AWS Region",'xcloner-backup-and-restore')?>" id="aws_region" type="text" name="xcloner_aws_region" class="validate" value="<?php echo get_option("xcloner_aws_region")?>" autocomplete="off" >
276
+ </div>
277
+ </div>
278
+
279
+ <div class="row">
280
+ <div class="col s12 m3 label">
281
+ <label for="aws_bucket_name"><?php echo __("AWS Bucket Name",'xcloner-backup-and-restore')?></label>
282
+ </div>
283
+ <div class=" col s12 m6">
284
+ <input placeholder="<?php echo __("AWS Bucket Name",'xcloner-backup-and-restore')?>" id="aws_bucket_name" type="text" name="xcloner_aws_bucket_name" class="validate" value="<?php echo get_option("xcloner_aws_bucket_name")?>" autocomplete="off" >
285
+ </div>
286
+ </div>
287
+
288
+ <div class="row">
289
+ <div class="col s12 m3 label">
290
+ <label for="aws_cleanup_days"><?php echo __("AWS Cleanup (days)",'xcloner-backup-and-restore')?></label>
291
+ </div>
292
+ <div class=" col s12 m6">
293
+ <input placeholder="<?php echo __("how many days to keep the backups for",'xcloner-backup-and-restore')?>" id="aws_cleanup_days" type="text" name="xcloner_aws_cleanup_days" class="validate" value="<?php echo get_option("xcloner_aws_cleanup_days")?>">
294
+ </div>
295
+ </div>
296
+
297
+ <div class="row">
298
+ <div class="col s6 m4">
299
+ <button class="btn waves-effect waves-light" type="submit" name="action" id="action" value="aws"><?php echo __("Save Settings",'xcloner-backup-and-restore')?>
300
+ <i class="material-icons right">save</i>
301
+ </button>
302
+ </div>
303
+ <div class="col s6 m4">
304
+ <button class="btn waves-effect waves-light orange" type="submit" name="action" id="action" value="aws" onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify",'xcloner-backup-and-restore')?>
305
+ <i class="material-icons right">import_export</i>
306
+ </button>
307
+ </div>
308
+ </div>
309
+
310
+ </div>
311
+ </li>
312
+
313
+ <!-- DROPBOX STORAGE-->
314
+ <li id="dropbox">
315
+ <div class="collapsible-header">
316
+ <i class="material-icons">computer</i><?php echo __("Dropbox Storage",'xcloner-backup-and-restore')?>
317
+ <div class="right">
318
+ <div class="switch">
319
+ <label>
320
+ Off
321
+ <input type="checkbox" name="xcloner_dropbox_enable" class="status" value="1" <?php if(get_option("xcloner_dropbox_enable")) echo "checked"?> \>
322
+ <span class="lever"></span>
323
+ On
324
+ </label>
325
+ </div>
326
+ </div>
327
+ </div>
328
+ <div class="collapsible-body">
329
+
330
+ <div class="row">
331
+ <div class="col s12 m3 label">
332
+ &nbsp;
333
+ </div>
334
+ <div class=" col s12 m6">
335
+ <p>
336
+ <?php echo sprintf(__('Visit %s and get your "App secret".'), "<a href='https://www.dropbox.com/developers/apps' target='_blank'>https://www.dropbox.com/developers/apps</a>")?>
337
+ </p>
338
+ </div>
339
+ </div>
340
+
341
+ <div class="row">
342
+ <div class="col s12 m3 label">
343
+ <label for="dropbox_access_token"><?php echo __("Dropbox Access Token",'xcloner-backup-and-restore')?></label>
344
+ </div>
345
+ <div class=" col s12 m6">
346
+ <input placeholder="<?php echo __("Dropbox Access Token",'xcloner-backup-and-restore')?>" id="dropbox_access_token" type="text" name="xcloner_dropbox_access_token" class="validate" value="<?php echo get_option("xcloner_dropbox_access_token")?>" autocomplete="off" >
347
+ </div>
348
+ </div>
349
+
350
+
351
+ <div class="row">
352
+ <div class="col s12 m3 label">
353
+ <label for="dropbox_app_secret"><?php echo __("Dropbox App Secret",'xcloner-backup-and-restore')?></label>
354
+ </div>
355
+ <div class=" col s12 m6">
356
+ <input placeholder="<?php echo __("Dropbox App Secret",'xcloner-backup-and-restore')?>" id="dropbox_app_secret" type="text" name="xcloner_dropbox_app_secret" class="validate" value="<?php echo get_option("xcloner_dropbox_app_secret")?>" autocomplete="off" >
357
+ </div>
358
+ </div>
359
+
360
+ <div class="row">
361
+ <div class="col s12 m3 label">
362
+ <label for="dropbox_prefix"><?php echo __("Dropbox Prefix",'xcloner-backup-and-restore')?></label>
363
+ </div>
364
+ <div class=" col s12 m6">
365
+ <input placeholder="<?php echo __("Dropbox Prefix",'xcloner-backup-and-restore')?>" id="dropbox_prefix" type="text" name="xcloner_dropbox_prefix" class="validate" value="<?php echo get_option("xcloner_dropbox_prefix")?>">
366
+ </div>
367
+ </div>
368
+
369
+ <div class="row">
370
+ <div class="col s12 m3 label">
371
+ <label for="dropbox_cleanup_days"><?php echo __("Dropbox Cleanup (days)",'xcloner-backup-and-restore')?></label>
372
+ </div>
373
+ <div class=" col s12 m6">
374
+ <input placeholder="<?php echo __("how many days to keep the backups for",'xcloner-backup-and-restore')?>" id="dropbox_cleanup_days" type="text" name="xcloner_dropbox_cleanup_days" class="validate" value="<?php echo get_option("xcloner_dropbox_cleanup_days")?>">
375
+ </div>
376
+ </div>
377
+
378
+ <div class="row">
379
+ <div class="col s6 m4">
380
+ <button class="btn waves-effect waves-light" type="submit" name="action" id="action" value="dropbox"><?php echo __("Save Settings",'xcloner-backup-and-restore')?>
381
+ <i class="material-icons right">save</i>
382
+ </button>
383
+ </div>
384
+ <div class="col s6 m4">
385
+ <button class="btn waves-effect waves-light orange" type="submit" name="action" id="action" value="dropbox" onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify",'xcloner-backup-and-restore')?>
386
+ <i class="material-icons right">import_export</i>
387
+ </button>
388
+ </div>
389
+ </div>
390
+
391
+ </div>
392
+ </li>
393
+
394
+ <!-- AZURE STORAGE-->
395
+ <li id="azure">
396
+ <div class="collapsible-header">
397
+ <i class="material-icons">computer</i><?php echo __("Azure Blog Storage",'xcloner-backup-and-restore')?>
398
+ <div class="right">
399
+ <div class="switch">
400
+ <label>
401
+ Off
402
+ <input type="checkbox" name="xcloner_azure_enable" class="status" value="1" <?php if(get_option("xcloner_azure_enable")) echo "checked"?> \>
403
+ <span class="lever"></span>
404
+ On
405
+ </label>
406
+ </div>
407
+ </div>
408
+ </div>
409
+ <div class="collapsible-body">
410
+
411
+ <div class="row">
412
+ <div class="col s12 m3 label">
413
+ &nbsp;
414
+ </div>
415
+ <div class=" col s12 m6">
416
+ <p>
417
+ <?php echo sprintf(__('Visit %s and get your "Api Key".','xcloner-backup-and-restore'), '<a href="https://azure.microsoft.com/en-us/services/storage/blobs/" target="_blank">https://azure.microsoft.com/en-us/services/storage/blobs/</a>')?>
418
+ </p>
419
+ </div>
420
+ </div>
421
+
422
+ <div class="row">
423
+ <div class="col s12 m3 label">
424
+ <label for="azure_account_name"><?php echo __("Azure Account Name",'xcloner-backup-and-restore')?></label>
425
+ </div>
426
+ <div class=" col s12 m6">
427
+ <input placeholder="<?php echo __("Azure Account Name",'xcloner-backup-and-restore')?>" id="azure_account_name" type="text" name="xcloner_azure_account_name" class="validate" value="<?php echo get_option("xcloner_azure_account_name")?>" autocomplete="off" >
428
+ </div>
429
+ </div>
430
+
431
+
432
+ <div class="row">
433
+ <div class="col s12 m3 label">
434
+ <label for="azure_api_key"><?php echo __("Azure Api Key",'xcloner-backup-and-restore')?></label>
435
+ </div>
436
+ <div class=" col s12 m6">
437
+ <input placeholder="<?php echo __("Azure Api Key",'xcloner-backup-and-restore')?>" id="azure_api_key" type="text" name="xcloner_azure_api_key" class="validate" value="<?php echo get_option("xcloner_azure_api_key")?>" autocomplete="off" >
438
+ </div>
439
+ </div>
440
+
441
+ <div class="row">
442
+ <div class="col s12 m3 label">
443
+ <label for="azure_container"><?php echo __("Azure Container",'xcloner-backup-and-restore')?></label>
444
+ </div>
445
+ <div class=" col s12 m6">
446
+ <input placeholder="<?php echo __("Azure Container",'xcloner-backup-and-restore')?>" id="azure_container" type="text" name="xcloner_azure_container" class="validate" value="<?php echo get_option("xcloner_azure_container")?>">
447
+ </div>
448
+ </div>
449
+
450
+ <div class="row">
451
+ <div class="col s12 m3 label">
452
+ <label for="azure_cleanup_days"><?php echo __("Azure Cleanup (days)",'xcloner-backup-and-restore')?></label>
453
+ </div>
454
+ <div class=" col s12 m6">
455
+ <input placeholder="<?php echo __("how many days to keep the backups for",'xcloner-backup-and-restore')?>" id="azure_cleanup_days" type="text" name="xcloner_azure_cleanup_days" class="validate" value="<?php echo get_option("xcloner_azure_cleanup_days")?>">
456
+ </div>
457
+ </div>
458
+
459
+ <div class="row">
460
+ <div class="col s6 m4">
461
+ <button class="btn waves-effect waves-light" type="submit" name="action" id="action" value="azure"><?php echo __("Save Settings",'xcloner-backup-and-restore')?>
462
+ <i class="material-icons right">save</i>
463
+ </button>
464
+ </div>
465
+ <div class="col s6 m4">
466
+ <button class="btn waves-effect waves-light orange" type="submit" name="action" id="action" value="azure" onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify",'xcloner-backup-and-restore')?>
467
+ <i class="material-icons right">import_export</i>
468
+ </button>
469
+ </div>
470
+ </div>
471
+
472
+ </div>
473
+ </li>
474
+
475
+ <!-- BACKBLAZE STORAGE-->
476
+ <li id="backblaze">
477
+ <div class="collapsible-header">
478
+ <i class="material-icons">computer</i><?php echo __("BackBlaze Storage",'xcloner-backup-and-restore')?>
479
+ <div class="right">
480
+ <div class="switch">
481
+ <label>
482
+ Off
483
+ <input type="checkbox" name="xcloner_backblaze_enable" class="status" value="1" <?php if(get_option("xcloner_backblaze_enable")) echo "checked"?> \>
484
+ <span class="lever"></span>
485
+ On
486
+ </label>
487
+ </div>
488
+ </div>
489
+ </div>
490
+ <div class="collapsible-body">
491
+
492
+ <div class="row">
493
+ <div class="col s12 m3 label">
494
+ &nbsp;
495
+ </div>
496
+ <div class=" col s12 m6">
497
+ <p>
498
+ <?php echo sprintf(__('Visit %s and get your Account Id and Application Key.','xcloner-backup-and-restore'), '<a href="https://secure.backblaze.com/b2_buckets.htm" target="_blank">https://secure.backblaze.com/b2_buckets.htm</a>')?>
499
+ </p>
500
+ </div>
501
+ </div>
502
+
503
+ <div class="row">
504
+ <div class="col s12 m3 label">
505
+ <label for="backblaze_account_id"><?php echo __("BackBlaze Account Id",'xcloner-backup-and-restore')?></label>
506
+ </div>
507
+ <div class=" col s12 m6">
508
+ <input placeholder="<?php echo __("BackBlaze Account Id",'xcloner-backup-and-restore')?>" id="backblaze_account_id" type="text" name="xcloner_backblaze_account_id" class="validate" value="<?php echo get_option("xcloner_backblaze_account_id")?>" autocomplete="off" >
509
+ </div>
510
+ </div>
511
+
512
+
513
+ <div class="row">
514
+ <div class="col s12 m3 label">
515
+ <label for="backblaze_application_key"><?php echo __("BackBlaze Application Key",'xcloner-backup-and-restore')?></label>
516
+ </div>
517
+ <div class=" col s12 m6">
518
+ <input placeholder="<?php echo __("BackBlaze Application Key",'xcloner-backup-and-restore')?>" id="backblaze_application_key" type="text" name="xcloner_backblaze_application_key" class="validate" value="<?php echo get_option("xcloner_backblaze_application_key")?>" autocomplete="off" >
519
+ </div>
520
+ </div>
521
+
522
+ <div class="row">
523
+ <div class="col s12 m3 label">
524
+ <label for="backblaze_bucket_name"><?php echo __("BackBlaze Bucket Name",'xcloner-backup-and-restore')?></label>
525
+ </div>
526
+ <div class=" col s12 m6">
527
+ <input placeholder="<?php echo __("BackBlaze Bucket Name",'xcloner-backup-and-restore')?>" id="backblaze_bucket_name" type="text" name="xcloner_backblaze_bucket_name" class="validate" value="<?php echo get_option("xcloner_backblaze_bucket_name")?>" autocomplete="off" >
528
+ </div>
529
+ </div>
530
+
531
+ <div class="row">
532
+ <div class="col s12 m3 label">
533
+ <label for="backblaze_cleanup_days"><?php echo __("BackBlaze Cleanup (days)",'xcloner-backup-and-restore')?></label>
534
+ </div>
535
+ <div class=" col s12 m6">
536
+ <input placeholder="<?php echo __("how many days to keep the backups for",'xcloner-backup-and-restore')?>" id="backblaze_cleanup_days" type="text" name="xcloner_backblaze_cleanup_days" class="validate" value="<?php echo get_option("xcloner_backblaze_cleanup_days")?>">
537
+ </div>
538
+ </div>
539
+
540
+ <div class="row">
541
+ <div class="col s6 m4">
542
+ <button class="btn waves-effect waves-light" type="submit" name="action" id="action" value="backblaze"><?php echo __("Save Settings",'xcloner-backup-and-restore')?>
543
+ <i class="material-icons right">save</i>
544
+ </button>
545
+ </div>
546
+ <div class="col s6 m4">
547
+ <button class="btn waves-effect waves-light orange" type="submit" name="action" id="action" value="backblaze" onclick="jQuery('#connection_check').val('1')"><?php echo __("Verify",'xcloner-backup-and-restore')?>
548
+ <i class="material-icons right">import_export</i>
549
+ </button>
550
+ </div>
551
+ </div>
552
+
553
+ </div>
554
+ </li>
555
+
556
+ <!--<li>
557
+ <div class="collapsible-header"><i class="material-icons">cloud</i>Amazon S3 Storage</div>
558
+ <div class="collapsible-body"><span>Lorem ipsum dolor sit amet.</span></div>
559
+ </li>
560
+ <li>
561
+ <div class="collapsible-header"><i class="material-icons">cloud</i>Dropbox Storage</div>
562
+ <div class="collapsible-body"><span>Lorem ipsum dolor sit amet.</span></div>
563
+ </li>
564
+ -->
565
+ </ul>
566
+ </div>
567
+ </div>
568
+
569
+ </form>
570
+
571
+ <script>
572
+ jQuery(document).ready(function(){
573
+
574
+ var remote_storage = new Xcloner_Remote_Storage();
575
+
576
+ jQuery(".remote-storage .status").on("change", function(){
577
+ remote_storage.toggle_status(this);
578
+ })
579
+
580
+ jQuery(".remote-storage-form #action").on("click", function(){
581
+ var tag = jQuery(this).val()
582
+ window.location.hash = "#"+tag;
583
+ })
584
+
585
+ if(location.hash)
586
+ jQuery(location.hash+" div.collapsible-header").addClass("active");
587
+
588
+ jQuery('.collapsible').collapsible();
589
+
590
+ Materialize.updateTextFields();
591
+ });
592
+
593
+ </script>
admin/partials/xcloner_restore_page.php ADDED
@@ -0,0 +1,331 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $xcloner_settings = new Xcloner_Settings();
4
+ $logger = new Xcloner_Logger();
5
+ $xcloner_file_system = new Xcloner_File_System();
6
+ $xcloner_file_transfer = new Xcloner_File_Transfer();
7
+
8
+ $start = 0 ;
9
+
10
+ $backup_list = $xcloner_file_system->get_latest_backups();
11
+
12
+ ?>
13
+
14
+ <h1><?= esc_html(get_admin_page_title()); ?></h1>
15
+
16
+ <script>
17
+ var xcloner_auth_key = '<?php echo md5(AUTH_KEY)?>';
18
+ </script>
19
+
20
+ <div class="row xcloner-restore">
21
+ <div class="col s12">
22
+ <ul class="collapsible xcloner-restore " data-collapsible="accordion">
23
+ <li data-step="1" class="restore-script-upload-step steps active show">
24
+ <div class="collapsible-header active"><i class="material-icons">settings_remote</i><?php echo __("Restore Script Upload",'xcloner-backup-and-restore')?></div>
25
+ <div class="collapsible-body row">
26
+
27
+ <ul class="text-steps">
28
+ <li><?php echo __("Please download the restore script from",'xcloner-backup-and-restore')?> <a href='#' onclick="window.location=ajaxurl+'?action=download_restore_script&phar=true'"><strong><?php echo __("here",'xcloner-backup-and-restore')?></strong></a>
29
+ </li>
30
+ <li>
31
+ <?php echo __("Extract the files on your new host",'xcloner-backup-and-restore')?>
32
+ </li>
33
+ <li>
34
+ <?php echo __("Provide url below to the <u>xcloner_restore.php</u> restore script, like http://my_restore_site.com/xcloner_restore.php",'xcloner-backup-and-restore')?>
35
+ </li>
36
+ <li>
37
+ <?php echo __("If your server is not web accessible, like a localhost computer, you can use a DynDNS service or install a blank copy of Wordpress with XCloner in the same environment and start the restore from there.",'xcloner-backup-and-restore')?>
38
+ </li>
39
+ <?php if(is_ssl()):?>
40
+ <li>
41
+ <?php echo __("We have detected your connection to the site as being secure, so your restore script address must start with https://.")?>
42
+ </li>
43
+ <?php endif ?>
44
+
45
+ </ul>
46
+
47
+ <div class="input-field col l9 s12">
48
+ <input value="<?php echo (is_ssl())?"https://":"http://"?>" id="restore_script_url" type="text" class="validate" placeholder="Url to XCloner Restore Script, example http://myddns.com/xcloner/xcloner_restore.php" >
49
+ <label for="restore_script_url"></label>
50
+ <div id="url_validation_status" class="status"></div>
51
+ </div>
52
+ <div class="col l3 s12 right-align">
53
+ <button class="btn waves-effect waves-light" type="submit" id="validate_url" name="action"><?php echo __("Check",'xcloner-backup-and-restore')?>
54
+ <i class="material-icons right">send</i>
55
+ </button>
56
+ </div>
57
+ </div>
58
+ </li>
59
+
60
+ <li data-step="2" class="backup-upload-step steps">
61
+ <div class="collapsible-header active"><i class="material-icons">file_upload</i><?php echo __("Upload Local Backup Archive To Remote Host",'xcloner-backup-and-restore')?>
62
+ </div>
63
+ <div class="collapsible-body row">
64
+ <p><?php echo __("You can skip this step if you want to transfer the archive in some other way, make sure you upload it in the same directory as the restore script from the previous step.",'xcloner-backup-and-restore')?></p>
65
+ <div class="input-field col s12 l7">
66
+ <select id="backup_file" name="backup_file" class="browser-default">
67
+ <option value="" disabled selected><?php echo __("Please select a local backup archive to upload to remote host",'xcloner-backup-and-restore')?></option>
68
+ <?php if(is_array($backup_list)):?>
69
+ <?php foreach($backup_list as $file):?>
70
+ <option value="<?php echo $file['basename']?>">
71
+ <?php echo $file['basename']?> (<?php echo size_format($file['size'])?>)
72
+ </option>
73
+ <?php endforeach?>
74
+ <?php endif ?>
75
+ </select>
76
+
77
+ <label> </label>
78
+ <div class="progress">
79
+ <div class="determinate" style="width: 0%"></div>
80
+ </div>
81
+ <div class="status"></div>
82
+ </div>
83
+ <div class="col s12 l5 right-align">
84
+ <div class="toggler">
85
+ <button class="btn waves-effect waves-light upload-backup normal" type="submit" id="" name="action"><?php echo __("Upload",'xcloner-backup-and-restore')?>
86
+ <i class="material-icons right">send</i>
87
+ </button>
88
+ <button class="btn waves-effect waves-light red upload-backup cancel" type="submit" id="" name="action"><?php echo __("Cancel",'xcloner-backup-and-restore')?>
89
+ <i class="material-icons right">close</i>
90
+ </button>
91
+ </div>
92
+ <button class="btn waves-effect waves-light grey" type="submit" title="<?php echo __("Skip Next",'xcloner-backup-and-restore')?>" id="skip_upload_backup" name="action"><?php echo __("Next",'xcloner-backup-and-restore')?>
93
+ <i class="material-icons right">navigate_next</i>
94
+ </button>
95
+ </div>
96
+ </div>
97
+ </li>
98
+
99
+ <li data-step="3" class="restore-remote-backup-step steps active">
100
+ <div class="collapsible-header"><i class="material-icons">folder_open</i><?php echo __("Restore Files Backup Available On Remote Host",'xcloner-backup-and-restore')?>
101
+ <i class="material-icons right" title="Refresh Remote Backup Files List" id="refresh_remote_backup_file">cached</i>
102
+
103
+ <div class="switch right">
104
+ <label>
105
+ <?php echo __('Verbose Output', 'xcloner-backup-and-restore')?>
106
+ <input type="checkbox" id="toggle_file_restore_display" name="toggle_file_restore_display" checked value="1">
107
+ <span class="lever"></span>
108
+
109
+ </label>
110
+ </div>
111
+ </div>
112
+ <div class="collapsible-body row">
113
+
114
+ <div class=" col s12 l7">
115
+ <div class="input-field row">
116
+ <input type="text" name="remote_restore_path" id="remote_restore_path" class="validate" placeholder="Restore Target Path">
117
+ <label><?php echo __("Remote Restore Target Path",'xcloner-backup-and-restore')?></label>
118
+ </div>
119
+
120
+ <div class="input-field row">
121
+ <select id="remote_backup_file" name="remote_backup_file" class="browser-default">
122
+ <option value="" disabled selected><?php echo __("Please select the remote backup file to restore",'xcloner-backup-and-restore')?></option>
123
+ </select>
124
+ <label></label>
125
+ </div>
126
+
127
+ <div class="progress">
128
+ <div class="indeterminate" style="width: 0%"></div>
129
+ </div>
130
+
131
+ <div class="status"></div>
132
+ <ul class="files-list"></ul>
133
+ </div>
134
+
135
+ <div class="col s12 l5 right-align">
136
+ <div class="toggler">
137
+ <button class="btn waves-effect waves-light restore_remote_backup normal " type="submit" id="" name="action"><?php echo __("Restore",'xcloner-backup-and-restore')?>
138
+ <i class="material-icons right">send</i>
139
+ </button>
140
+ <button class="btn waves-effect waves-light red restore_remote_backup cancel" type="submit" id="" name="action"><?php echo __("Cancel",'xcloner-backup-and-restore')?>
141
+ <i class="material-icons right">close</i>
142
+ </button>
143
+ </div>
144
+ <button class="btn waves-effect waves-light grey" type="submit" title="<?php echo __("Skip Next",'xcloner-backup-and-restore')?>" id="skip_remote_backup_step" name="action"><?php echo __("Next",'xcloner-backup-and-restore')?>
145
+ <i class="material-icons right">navigate_next</i>
146
+ </button>
147
+ </div>
148
+ </div>
149
+ </li>
150
+
151
+ <li data-step="4" class="restore-remote-database-step steps active">
152
+ <div class="collapsible-header"><i class="material-icons">list</i><?php echo __("Restore Remote Database - Search and Replace",'xcloner-backup-and-restore')?>
153
+ <i class="material-icons right" title="Refresh Database Backup Files List" id="refresh_database_file">cached</i>
154
+ </div>
155
+ <div class="collapsible-body row">
156
+
157
+ <div class="col s12">
158
+ <a class="btn-floating tooltipped btn-small right" data-position="left" data-delay="50" data-tooltip="<?php echo __('Please provide below the mysql connection details for the remote host database.','xcloner-backup-and-restore')?>" data-tooltip-id="92c95730-94e9-7b59-bd52-14adc30d5e3e"><i class="material-icons">help_outline</i></a>
159
+ <h5><?php echo __('Remote Mysql Details','xcloner-backup-and-restore')?></h5>
160
+ </div>
161
+ <div class=" col s12">
162
+ <div class="input-field col s12 m6">
163
+ <input type="text" name="remote_mysql_host" id="remote_mysql_host" class="validate" placeholder="Remote Mysql Hostname" value="localhost">
164
+ <label><?php echo __("Remote Mysql Hostname",'xcloner-backup-and-restore')?></label>
165
+ </div>
166
+
167
+ <div class="input-field col s12 m6">
168
+ <input type="text" name="remote_mysql_db" id="remote_mysql_db" class="validate" placeholder="Remote Mysql Database">
169
+ <label><?php echo __("Remote Mysql Database",'xcloner-backup-and-restore')?></label>
170
+ </div>
171
+
172
+ <div class="input-field col s12 m6">
173
+ <input type="text" name="remote_mysql_user" id="remote_mysql_user" class="validate" placeholder="Remote Mysql Username">
174
+ <label><?php echo __("Remote Mysql Username",'xcloner-backup-and-restore')?></label>
175
+ </div>
176
+
177
+
178
+ <div class="input-field col s12 m6">
179
+ <input type="text" name="remote_mysql_pass" id="remote_mysql_pass" class="validate" placeholder="Remote Mysql Password">
180
+ <label><?php echo __("Remote Mysql Password",'xcloner-backup-and-restore')?></label>
181
+ </div>
182
+
183
+ </div>
184
+ <div class="col s12">
185
+ <a class="btn-floating tooltipped btn-small right" data-position="left" data-delay="50" data-html="true" data-tooltip="<?php echo __('I will attempt to replace all mysql backup records matching the provided Source Url with the provided Target Url. <br />Leave blank the Target Url if you would like to skip this option. <br />As a bonus, I will also replace all matching serialized data and fix it\'s parsing.','xcloner-backup-and-restore')?>" data-tooltip-id="92c95730-94e9-7b59-bd52-14adc30d5e3e"><i class="material-icons">help_outline</i></a>
186
+ <h5><?php echo __('Remote Mysql Search and Replace','xcloner-backup-and-restore')?></h5>
187
+ </div>
188
+ <div class="col s12">
189
+ <div class="input-field col s12 m6 ">
190
+ <input type="text" name="wp_home_url" id="wp_home_url" class="validate" placeholder="WP Home Url" value="<?php echo home_url();?>">
191
+ <label><?php echo __("Source Home Url",'xcloner-backup-and-restore')?></label>
192
+ </div>
193
+
194
+ <div class="input-field col s12 m6 ">
195
+ <input type="text" name="remote_restore_url" id="remote_restore_url" class="validate" placeholder="Restore Target Url">
196
+ <label><?php echo __("With Target Home Url",'xcloner-backup-and-restore')?></label>
197
+ </div>
198
+
199
+ <?php if( site_url() != home_url()) : ?>
200
+ <div class="input-field col s12 m6 ">
201
+ <input type="text" name="wp_site_url" id="wp_site_url" class="validate" placeholder="WP Site Url" value="<?php echo site_url();?>">
202
+ <label><?php echo __("Source Site Url",'xcloner-backup-and-restore')?></label>
203
+ </div>
204
+
205
+ <div class="input-field col s12 m6 ">
206
+ <input type="text" name="remote_restore_site_url" id="remote_restore_site_url" class="validate" placeholder="Restore Target Url">
207
+ <label><?php echo __("With Target Site Url",'xcloner-backup-and-restore')?></label>
208
+ </div>
209
+
210
+ <?php endif;?>
211
+ </div>
212
+
213
+ <div class=" col s12 l7">
214
+ <div class="input-field row">
215
+ <select id="remote_database_file" name="remote_database_file" class="browser-default">
216
+ <option value="" disabled selected><?php echo __("Please select the remote database backup file to restore",'xcloner-backup-and-restore')?></option>
217
+ </select>
218
+
219
+ <label></label>
220
+ </div>
221
+
222
+ <div class="progress">
223
+ <div class="determinate" style="width: 0%"></div>
224
+ </div>
225
+
226
+ <div class="status"></div>
227
+ <div class="query-box">
228
+ <h6><?php echo __('Use the field below to fix your mysql query and Retry again the Restore', 'xcloner-backup-and-restore')?></h6>
229
+ <textarea class="query-list" cols="5"></textarea>
230
+ </div>
231
+ </div>
232
+
233
+ <div class="col s12 l5 right-align">
234
+ <div class="toggler">
235
+ <button class="btn waves-effect waves-light restore_remote_mysqldump normal " type="submit" id="" name="action"><?php echo __("Restore",'xcloner-backup-and-restore')?>
236
+ <i class="material-icons right">send</i>
237
+ </button>
238
+ <button class="btn waves-effect waves-light red restore_remote_mysqldump cancel" type="submit" id="" name="action"><?php echo __("Cancel",'xcloner-backup-and-restore')?>
239
+ <i class="material-icons right">close</i>
240
+ </button>
241
+ </div>
242
+
243
+ <button class="btn waves-effect waves-light grey" type="submit" title="<?php echo __("Skip Next",'xcloner-backup-and-restore')?>" id="skip_restore_remote_database_step" name="action"><?php echo __("Next",'xcloner-backup-and-restore')?>
244
+ <i class="material-icons right">navigate_next</i>
245
+ </button>
246
+
247
+ </div>
248
+
249
+ </div>
250
+ </li>
251
+
252
+ <li data-step="5" class="restore-finish-step steps active">
253
+ <div class="collapsible-header"><i class="material-icons">folder_open</i><?php echo __("Finishing up...",'xcloner-backup-and-restore')?>
254
+ </div>
255
+ <div class="collapsible-body row">
256
+
257
+ <div class="row">
258
+ <div class="col s4">
259
+ <label><?php echo __("Update wp-config.php mysql details and update the restored site Url",'xcloner-backup-and-restore')?></label>
260
+ </div>
261
+
262
+ <div class="col s8">
263
+ <div class="switch">
264
+ <label>
265
+ Off
266
+ <input type="checkbox" id="update_remote_site_url" name="update_remote_site_url" checked value="1">
267
+ <span class="lever"></span>
268
+ On
269
+ </label>
270
+ </div>
271
+ </div>
272
+ </div>
273
+
274
+ <div class="row">
275
+ <div class="col s4">
276
+ <label><?php echo __("Delete Restored Backup Temporary Folder",'xcloner-backup-and-restore')?></label>
277
+ </div>
278
+ <div class="col s8">
279
+ <div class="switch">
280
+ <label>
281
+ Off
282
+ <input type="checkbox" id="delete_backup_temporary_folder" name="delete_backup_temporary_folder" checked value="1">
283
+ <span class="lever"></span>
284
+ On
285
+ </label>
286
+ </div>
287
+ </div>
288
+ </div>
289
+
290
+ <div class="row">
291
+ <div class="col s4">
292
+ <label><?php echo __("Delete Restore Script",'xcloner-backup-and-restore')?></label>
293
+ </div>
294
+ <div class="col s8">
295
+ <div class="switch">
296
+ <label>
297
+ Off
298
+ <input type="checkbox" id="delete_restore_script" name="delete_restore_script" checked value="1">
299
+ <span class="lever"></span>
300
+ On
301
+ </label>
302
+ </div>
303
+ </div>
304
+ </div>
305
+
306
+ <div class=" row col s12">
307
+ <div class="status"></div>
308
+ </div>
309
+
310
+ <div class=" row col s12 center-align" id="xcloner_restore_finish">
311
+ <h5><?php echo __("Thank you for using XCloner.",'xcloner-backup-and-restore')?></h5>
312
+ <h6><?php echo sprintf(__("We would love to hear about your experience in the %s.", 'xcloner-backup-and-restore'),'<a href="https://wordpress.org/support/plugin/xcloner-backup-and-restore" target="_blank">Wordpress XCloner forums</a>') ?></h6>
313
+ <a class="twitter-follow-button" href="https://twitter.com/thinkovi" data-show-count="false">Follow @thinkovi</a>
314
+ <script src="//platform.twitter.com/widgets.js" async="" charset="utf-8"></script>
315
+ </div>
316
+
317
+ <div class="col s12 center-align">
318
+
319
+ <button class="btn waves-effect waves-light teal" type="submit" id="restore_finish" name="action"><?php echo __("Finish",'xcloner-backup-and-restore')?>
320
+ <i class="material-icons right">navigate_next</i>
321
+ </button>
322
+ </div>
323
+ </div>
324
+ </li>
325
+
326
+ </ul>
327
+ </div>
328
+ </div>
329
+
330
+
331
+
admin/partials/xcloner_scheduled_backups_page.php ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $xcloner_scheduler = new Xcloner_Scheduler();
3
+ $xcloner_remote_storage = new Xcloner_Remote_Storage();
4
+ $available_storages = $xcloner_remote_storage->get_available_storages();
5
+ ?>
6
+ <?php if(!defined("DISABLE_WP_CRON") or !DISABLE_WP_CRON): ?>
7
+ <div id="setting-error-" class="error settings-error notice is-dismissible">
8
+ <p><strong>
9
+ <?php echo sprintf(__('We have noticed that DISABLE_WP_CRON is disabled, we recommend enabling that and setting up wp-cron.php to run manually through your hosting account scheduler as explained <a href="%s" target="_blank">here</a>', 'xcloner-backup-and-restore'), "http://www.inmotionhosting.com/support/website/wordpress/disabling-the-wp-cronphp-in-wordpress") ?>
10
+ </strong>
11
+ </p><button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span></button>
12
+ </div>
13
+ <?php endif?>
14
+
15
+ <h1><?= esc_html(get_admin_page_title()); ?></h1>
16
+
17
+ <div class="row">
18
+ <table id="scheduled_backups" class="col s12" cellspacing="0" width="100%">
19
+ <thead>
20
+ <tr class="grey lighten-2">
21
+ <th><?php echo __('ID', 'xcloner-backup-and-restore')?></th>
22
+ <th><?php echo __('Schedule Name', 'xcloner-backup-and-restore')?></th>
23
+ <th><?php echo __('Recurrence', 'xcloner-backup-and-restore')?></th>
24
+ <th class="hide-on-med-and-down"><?php echo __('Next Execution', 'xcloner-backup-and-restore')?></th>
25
+ <th><?php echo __('Remote Storage', 'xcloner-backup-and-restore')?></th>
26
+ <th class="hide-on-med-and-down"><?php echo __('Last Backup', 'xcloner-backup-and-restore')?></th>
27
+ <th><?php echo __('Status', 'xcloner-backup-and-restore')?></th>
28
+ <th class="no-sort"><?php echo __('Action', 'xcloner-backup-and-restore')?></th>
29
+ </tr>
30
+ </thead>
31
+ <tfoot>
32
+ <tr>
33
+ <th><?php echo __('ID', 'xcloner-backup-and-restore')?></th>
34
+ <th><?php echo __('Schedule Name', 'xcloner-backup-and-restore')?></th>
35
+ <th><?php echo __('Recurrence', 'xcloner-backup-and-restore')?></th>
36
+ <th class="hide-on-med-and-down"><?php echo __('Next Execution', 'xcloner-backup-and-restore')?></th>
37
+ <th><?php echo __('Remote Storage', 'xcloner-backup-and-restore')?></th>
38
+ <th class="hide-on-med-and-down"><?php echo __('Last Backup', 'xcloner-backup-and-restore')?></th>
39
+ <th><?php echo __('Status', 'xcloner-backup-and-restore')?></th>
40
+ <th><?php echo __('Action', 'xcloner-backup-and-restore')?></th>
41
+ </tr>
42
+ </tfoot>
43
+ <tbody>
44
+ </tbody>
45
+ </table>
46
+ </div>
47
+
48
+ <div class="row">
49
+ <div class="col s12 m6 offset-m6 teal lighten-1" id="server_time">
50
+ <h2><?php echo __('Current Server Time', 'xcloner-backup-and-restore')?>: <span class="right"><?php echo date("Y/m/d H:i")?></span></h2>
51
+ </div>
52
+ </div>
53
+
54
+
55
+ <!-- Modal Structure -->
56
+ <div id="edit_schedule" class="modal">
57
+ <form method="POST" action="" id="save_schedule">
58
+ <input type="hidden" name="id" id="schedule_id_hidden">
59
+ <input type="hidden" name="action" value="save_schedule">
60
+ <div class="modal-content">
61
+
62
+ <div class="row">
63
+ <div class="col s12 m6">
64
+ <h4><?php echo __('Edit Schedule', 'xcloner-backup-and-restore') ?> #<span id="schedule_id"></span></h4>
65
+ </div>
66
+
67
+ <div class="col s12 m6 right-align">
68
+ <div class="switch">
69
+ <label>
70
+ <?php echo __('Off', 'xcloner-backup-and-restore') ?>
71
+ <input type="checkbox" id="status" name="status" value="1">
72
+ <span class="lever"></span>
73
+ <?php echo __('On', 'xcloner-backup-and-restore') ?>
74
+ </label>
75
+ </div>
76
+ </div>
77
+ </div>
78
+
79
+ <p>
80
+
81
+ <ul class="nav-tab-wrapper content row">
82
+ <li> <a href="#scheduler_settings" class="nav-tab col s12 m6 nav-tab-active"><?php echo __('Scheduler Settings', 'xcloner-backup-and-restore') ?></a></li>
83
+ <li> <a href="#advanced_scheduler_settings" class="nav-tab col s12 m6"><?php echo __('Advanced', 'xcloner-backup-and-restore') ?></a></li>
84
+ </ul>
85
+
86
+ <div class="nav-tab-wrapper-content">
87
+ <div id="scheduler_settings" class="tab-content active">
88
+
89
+ <div class="row">
90
+ <div class="input-field col s12 l12">
91
+ <input placeholder="" name="schedule_name" id="schedule_name" type="text" required value="">
92
+ <label for="schedule_name"><?php echo __('Schedule Name', 'xcloner-backup-and-restore') ?></label>
93
+ </div>
94
+ </div>
95
+
96
+ <div class="row">
97
+ <div class="input-field col s12 l6">
98
+ <input placeholder="" name="schedule_start_date" id="schedule_start_date" type="datetime" value="">
99
+ <label for="schedule_start_date" class="active"><?php echo __('Schedule Start At', 'xcloner-backup-and-restore') ?>:</label>
100
+ </div>
101
+
102
+ <div class="input-field col s12 l6">
103
+ <select name="schedule_frequency" id="schedule_frequency" class="validate" required>
104
+ <option value="" disabled selected><?php echo __('Schedule Recurrence', 'xcloner-backup-and-restore') ?></option>
105
+ <option value="single"><?php echo __("Don't Repeat",'xcloner-backup-and-restore')?></option>
106
+ <option value="hourly"><?php echo __("Hourly",'xcloner-backup-and-restore')?></option>
107
+ <option value="daily"><?php echo __("Daily",'xcloner-backup-and-restore')?></option>
108
+ <option value="weekly"><?php echo __("Weekly",'xcloner-backup-and-restore')?></option>
109
+ <option value="monthly"><?php echo __("Monthly",'xcloner-backup-and-restore')?></option>
110
+ </select>
111
+ </div>
112
+ </div>
113
+
114
+ <?php if(sizeof($available_storages)):?>
115
+ <div class="row">
116
+ <div class="input-field col s12 l6">
117
+ <select name="schedule_storage" id="schedule_storage" class="validate" >
118
+ <option value="" selected><?php echo __('none', 'xcloner-backup-and-restore') ?></option>
119
+ <?php foreach($available_storages as $storage=>$text):?>
120
+ <option value="<?php echo $storage?>"><?php echo $text?></option>
121
+ <?php endforeach?>
122
+ </select>
123
+ <label><?php echo __('Send To Remote Storage ', 'xcloner-backup-and-restore') ?></label>
124
+ </div>
125
+ </div>
126
+ <?php endif?>
127
+
128
+ <div class="row">
129
+ <div class="input-field col s12 l12">
130
+ <input placeholder="" name="email_notification" id="email_notification" type="text" value="">
131
+ <label for="email_notification"><?php echo __('Email Notification Address', 'xcloner-backup-and-restore') ?></label>
132
+ </div>
133
+ </div>
134
+
135
+ </div>
136
+
137
+ <div id="advanced_scheduler_settings" class="tab-content">
138
+ <div class="row">
139
+ <div class="input-field col s12 l12">
140
+ <input placeholder="" name="backup_name" id="backup_name" type="text" required value="">
141
+ <label for="backup_name"><?php echo __('Backup Name', 'xcloner-backup-and-restore') ?></label>
142
+ </div>
143
+ </div>
144
+
145
+ <div class="row">
146
+ <div class="input-field col s12 l12">
147
+ <textarea id="table_params" name="table_params" class="materialize-textarea" rows="15"></textarea>
148
+ <label for="table_params" class="active"><?php echo __('Included Database Data', 'xcloner-backup-and-restore') ?></label>
149
+ </div>
150
+ </div>
151
+
152
+ <div class="row">
153
+ <div class="input-field col s12 l12">
154
+ <textarea id="excluded_files" name="excluded_files" class="materialize-textarea" rows="15"></textarea>
155
+ <label for="excluded_files" class="active"><?php echo __('Excluded Files', 'xcloner-backup-and-restore') ?></label>
156
+ </div>
157
+ </div>
158
+ </div>
159
+ </div>
160
+
161
+ <div class="row">
162
+
163
+ <div class="input-field col s12">
164
+ <button class="right btn waves-effect waves-light" type="submit" name="action"><?php echo __('Save', 'xcloner-backup-and-restore') ?>
165
+ <i class="material-icons right">send</i>
166
+ </button>
167
+ </div>
168
+ </div>
169
+ </p>
170
+ </div>
171
+ </form>
172
+ </div>
173
+
administrator/.htaccess DELETED
@@ -1,2 +0,0 @@
1
- order deny,allow
2
- deny from all
 
 
administrator/backups/.htaccess DELETED
@@ -1,2 +0,0 @@
1
- order deny,allow
2
- deny from all
 
 
administrator/backups/index.html DELETED
File without changes
administrator/index.html DELETED
File without changes
browser/file.gif DELETED
Binary file
browser/filebrowser.css DELETED
@@ -1,34 +0,0 @@
1
- body{
2
- font-family:Arial, Helvetica, sans-serif;
3
- font-size: 76%;
4
- }
5
- #browser{
6
- width: 90%;
7
- border: 1px solid #ddd;
8
- padding: 0.2em 1em;
9
- margin:1em;
10
- }
11
- .searching{
12
- background: #efefef url(components/com_cloner/browser/timer.gif) no-repeat 46% 46%;
13
- }
14
- #header {
15
- color: #FFFFFF;
16
- background-color: #3571CA;
17
- padding: 0.2em;
18
- }
19
- #content {
20
- padding: 0.2em;
21
- border: 1px solid #999999;
22
- }
23
- li.file {
24
- white-space: nowrap;
25
- }
26
- li.folder {
27
- white-space: nowrap;
28
- }
29
- li.folder a{
30
- font-size: 16px;
31
- color: #000000;
32
- background: #efefef;
33
-
34
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
browser/files_inpage.php DELETED
@@ -1,23 +0,0 @@
1
- <?php
2
- defined( '_VALID_MOS' ) or die( 'Restricted access' );
3
-
4
- $thisApp=$_SERVER['PHP_SELF'] . "?browse=true";
5
-
6
- $fp = @fopen($_CONFIG['exfile'], "w");
7
- if($fp){
8
- @fwrite($fp, $_CONFIG['cron_exclude']);
9
- @fclose($fp);
10
- }
11
-
12
- if(isset($_GET['browse'])){
13
- $dir = isset($_GET['dir']) ? $_GET['dir'] : '/files';
14
- if(strpos($dir, "../")===true){
15
- exit;
16
- }
17
- }else{
18
-
19
- echo "Please wait... we are loading the folder structure";
20
-
21
- }
22
-
23
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
browser/files_xml.php DELETED
@@ -1,266 +0,0 @@
1
- <?php
2
- /**
3
- * XCloner
4
- * Oficial website: http://www.xcloner.com/
5
- * -------------------------------------------
6
- * Creator: Liuta Romulus Ovidiu
7
- * License: GNU/GPL
8
- * Email: admin@xcloner.com
9
- * Revision: 1.0
10
- * Date: November 2010
11
- **/
12
-
13
- defined( '_VALID_MOS' ) or die( 'Restricted access' );
14
-
15
- header("Cache-Control: no-cache");
16
- header("Pragma: nocache");
17
- header("Content-Type: text/xml; charset=utf-8");
18
-
19
- error_reporting(2);
20
-
21
- include(realpath(dirname(__FILE__))."/../cloner.config.php");
22
- include(realpath(dirname(__FILE__)) ."/../common.php");
23
-
24
- $request_dir = str_replace(array(".."), array(""), $_REQUEST['dir']);
25
- $dir = realpath(realpath($_CONFIG['backup_path']) . DIRECTORY_SEPARATOR. $request_dir);
26
-
27
- if(!stristr($dir, realpath($_CONFIG['backup_path'])))
28
- return false;
29
-
30
- $parent_dir = dirname($dir);
31
-
32
- if(strlen($parent_dir) < strlen($_CONFIG['backup_path']))
33
- $parent_dir = "/";
34
-
35
- $parent_dir = str_replace(realpath($_CONFIG['backup_path']),"",$parent_dir);
36
- $request_dir = str_replace(realpath($_CONFIG['backup_path']),"",$dir);
37
-
38
- $fulldir = $dir;
39
- $f_arr = array();
40
- $d_arr =array();
41
- $exclude = array();
42
- $_COOKIES = array();
43
- $exfile = realpath($_CONFIG['backup_path']."/administrator/backups")."/.excl";
44
-
45
- if(isset($_REQUEST['path']) and $_REQUEST['path'])
46
- $path = realpath($dir.DIRECTORY_SEPARATOR.$_REQUEST['path']);
47
-
48
- $loc = $_REQUEST['dir'];
49
-
50
- if(!is_dir($_CONFIG['backup_path'])){
51
-
52
- echo "<directory location=\"Error: Directory $_CONFIG[backup_path] does not exist!\"></directory>";
53
- exit;
54
-
55
- }elseif(!is_readable($_CONFIG['backup_path'])){
56
-
57
- echo "<directory location=\"Error: Directory $_CONFIG[backup_path] is not readable!\"></directory>";
58
- exit;
59
-
60
- }
61
-
62
-
63
- if($_REQUEST['act'] == "checkall"){
64
-
65
- check($dir, $exfile, 1);
66
-
67
- }
68
- elseif($_REQUEST['act'] == "uncheckall"){
69
-
70
- check($dir, $exfile, 0);
71
-
72
- }
73
-
74
- if($loc == "")
75
- $loc = "/";
76
-
77
-
78
- $data = "";
79
-
80
- if($fp = @fopen($exfile,"r")){
81
-
82
- while(!feof($fp)){
83
- $data .= fread($fp, 1024);
84
- }
85
- fclose($fp);
86
- }
87
- $_COOKIES = explode("\r\n", $data);
88
-
89
-
90
- $exc = 0;
91
-
92
- if($fp = @fopen($exfile,"w")){
93
-
94
- if(is_array($_COOKIES))
95
-
96
- foreach($_COOKIES as $key=>$value)
97
-
98
- if(trim($value!="")){
99
-
100
- if($value!=$path){
101
-
102
- fwrite($fp, $value."\r\n");
103
-
104
- }else{
105
-
106
- $exc = 1;
107
- }
108
- }
109
-
110
- if((!$exc)&&(trim($path)!=''))
111
-
112
- fwrite($fp, $path."\r\n");
113
-
114
- fclose($fp);
115
- }
116
-
117
-
118
- $data = "";
119
-
120
- if($fp = @fopen($exfile,"r")){
121
-
122
- while(!feof($fp)){
123
-
124
- $data .= fread($fp, 1024);
125
-
126
- }
127
-
128
- fclose($fp);
129
-
130
- }
131
- else{
132
-
133
- echo "<directory location=\"Error: Unable to write to file $exfile\"></directory>";
134
- exit;
135
-
136
- }
137
-
138
- $_COOKIES = explode("\r\n", $data);
139
-
140
-
141
- if(is_array($_COOKIES))
142
- foreach($_COOKIES as $key=>$value)
143
- if($value!='')
144
- {
145
-
146
- $exclude[] = $value;
147
-
148
-
149
- }
150
-
151
- sort($exclude);
152
-
153
- if (@is_dir($fulldir)){
154
-
155
- if ($root=@opendir($fulldir)){
156
- while ($file=@readdir($root)){
157
- if(@is_dir($fulldir.DIRECTORY_SEPARATOR.$file)){
158
- //is folder
159
- if($file=="." || $file==".."){continue;}
160
- else{
161
- $d_arr[] = $file;
162
- }
163
- }else{
164
- //is file
165
- $type=substr($file, strrpos($file, '.'));
166
- $f_arr[] = $file;
167
- }
168
- }
169
- }
170
-
171
- sort($f_arr);
172
-
173
- sort($d_arr);
174
-
175
-
176
- echo "<directory current_dir=\"".htmlspecialchars($request_dir.DIRECTORY_SEPARATOR)."\" location=\"".htmlspecialchars($dir)."\" parent_location=\"".htmlspecialchars($parent_dir)."\" >";
177
-
178
- foreach($d_arr as $file){
179
- if(in_array($dir.DIRECTORY_SEPARATOR.$file, $_COOKIES))
180
- $check = 'checked';
181
- else
182
- $check = '';
183
- echo "<folder check='$check'>".htmlspecialchars($file)."</folder>";
184
-
185
- }
186
-
187
- foreach($f_arr as $file){
188
- if(in_array($dir.DIRECTORY_SEPARATOR.$file, $_COOKIES))
189
- $check = 'checked';
190
- else
191
- $check = '';
192
-
193
- echo "<file check='$check' link=\"#\">".htmlspecialchars($file)."</file>";
194
-
195
- }
196
-
197
- foreach($exclude as $file)
198
- echo "<message>".str_replace("","",htmlspecialchars($file))."</message>";
199
-
200
- echo "</directory>";
201
-
202
-
203
- }
204
-
205
- function check($loc, $exfile, $act ){
206
- global $_CONFIG;
207
-
208
- $fulldir = $loc;
209
- $flist = array();
210
- $_COOKIES = array();
211
- if (@is_dir($fulldir)){
212
-
213
- if ($root=@opendir($fulldir)){
214
-
215
- while ($file=readdir($root))
216
- if(($file!='.')&&($file != '..'))
217
- {
218
-
219
- $flist[] = $loc .DIRECTORY_SEPARATOR. $file;
220
-
221
- }
222
- }
223
- }
224
-
225
- if($fp = @fopen($exfile,"r")){
226
-
227
- while(!feof($fp)){
228
- $data .= fread($fp, 1024);
229
- }
230
- fclose($fp);
231
- }
232
-
233
- $_COOKIES = explode("\r\n", $data);
234
-
235
-
236
-
237
- if($act == 1){
238
-
239
- $flist = @array_merge($_COOKIES, $flist);
240
-
241
- }
242
- else{
243
-
244
- $flist = @array_diff($_COOKIES, $flist);
245
-
246
- }
247
-
248
- $flist = @array_unique($flist);
249
-
250
- if($fp = @fopen($exfile,"w")){
251
-
252
- foreach($flist as $file){
253
-
254
- fwrite($fp, $file."\r\n");
255
-
256
- }
257
-
258
- fclose($fp);
259
- }
260
-
261
-
262
-
263
-
264
- }
265
-
266
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
browser/folder.gif DELETED
Binary file
browser/timer.gif DELETED
Binary file
browser/xmlhttp.js DELETED
@@ -1,156 +0,0 @@
1
- var request;
2
- var targetDiv;
3
- function loadXMLDoc(url) {
4
- // for Mozilla and othes who support XMLHttpRequest
5
- if (window.XMLHttpRequest) {
6
- request = new XMLHttpRequest();
7
- request.onreadystatechange = processXMLRequest;
8
- request.open("GET", url, true);
9
- request.send(null);
10
- // for Interweb Explorer
11
- } else if (window.ActiveXObject) {
12
- request = new ActiveXObject("Microsoft.XMLHTTP");
13
- if(request){
14
- request.onreadystatechange = processXMLRequest;
15
- request.open("GET", url, true);
16
- request.send();
17
- }
18
- } else{
19
- return false;
20
- }
21
- }
22
-
23
- function processXMLRequest() {
24
- // only if data is loaded
25
- if (request.readyState == 4) {
26
- // only if result of HTTP request was an OK
27
- if (request.status == 200 || request.readyState ==304) {
28
- useXML(request.responseXML);
29
- } else{
30
- targetDiv=document.getElementById("browser");
31
- targetDiv.innerHTML="Unable to load XML";
32
- }
33
- }
34
- }
35
-
36
- function do_browser(){
37
- targetDiv=document.getElementById("browser");
38
-
39
- if(loadXMLDoc("admin-ajax.php?action=files_xml")){
40
- targetDiv.className="searching";
41
- targetDiv.innerHTML="";
42
- }
43
- }
44
-
45
- function createCookie(name,value,days)
46
- {
47
- if (days)
48
- {
49
- var date = new Date();
50
- date.setTime(date.getTime()+(days*24*60*60*1000));
51
- var expires = "; expires="+date.toGMTString();
52
- }
53
- else var expires = "";
54
- document.cookie = name+"="+value+expires+"; path=/";
55
- }
56
-
57
- function readCookie(name)
58
- {
59
- var nameEQ = name + "=";
60
- var ca = document.cookie.split(';');
61
-
62
- for(var i=0;i < ca.length;i++)
63
- {
64
- var c = ca[i];
65
- while (c.charAt(0)==' ') c = c.substring(1,c.length);
66
- if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
67
- }
68
- return null;
69
- }
70
-
71
- function eraseCookie(name)
72
- {
73
- createCookie(name,"",-1);
74
- }
75
-
76
- function checkp(value, loc){
77
- if(readCookie('path_'+value)){
78
- eraseCookie('path_'+value);
79
- }
80
- else{
81
- createCookie('path_'+value,value,'1');
82
- }
83
-
84
-
85
-
86
-
87
- }
88
- function checkc(value){
89
- if(readCookie(value)){
90
- check = 'checked';
91
- }
92
- else{
93
- check = '';
94
- }
95
- return check;
96
- }
97
-
98
-
99
-
100
-
101
-
102
- function useXML(xmlInfo){
103
- targetDiv.className="";
104
- message = "";
105
-
106
- var infoTags=xmlInfo.getElementsByTagName("directory");
107
- var loc=infoTags[0].getAttribute("location");
108
- var parent_location=infoTags[0].getAttribute("parent_location");
109
- var current_dir=infoTags[0].getAttribute("current_dir");
110
- if(loc == "")
111
- loc1 = 'Path Root';
112
- else
113
- loc1 = loc;
114
-
115
- var newloc1="admin-ajax.php?action=files_xml&dir=" + current_dir ;
116
-
117
- var stringHTML="<p><b>" + loc1 +"</b> <br /><br /></p>";
118
-
119
- if(loc.indexOf("/")!=-1){
120
- var newfile="admin-ajax.php?action=files_xml&dir=" + parent_location.slice(0, loc.lastIndexOf("/"));
121
- stringHTML=stringHTML+"<p><a href=\"#\" onclick=\"loadXMLDoc('" + newfile +"')\">[Up a level]</a> <a href='#' onclick=\"loadXMLDoc('" + newloc1 +"&amp;act=checkall')\" >[check all]</a> <a href='#' onclick=\"loadXMLDoc('" + newloc1 +"&amp;act=uncheckall')\" >[uncheck all]</a></p><br />"
122
- }
123
- if(infoTags[0].hasChildNodes){
124
- stringHTML=stringHTML+"<ul>";
125
- for(node=infoTags[0].firstChild; node!=null; node=node.nextSibling){
126
-
127
- var newloc="admin-ajax.php?action=files_xml&dir=" + current_dir ;
128
- path = node.firstChild.nodeValue;
129
-
130
- if(node.nodeName=="file"){
131
-
132
- stringHTML=stringHTML+"<li class=\"file\"><img src='../wp-content/plugins/xcloner-backup-and-restore/browser/file.gif' border='0'><input type=checkbox "+node.getAttribute('check')+" onclick=\"loadXMLDoc('" + newloc +"&amp;path="+path+"')\" name=cid[] value='"+path+"'><a href=\"" +node.getAttribute('link')+ "\">"+node.firstChild.nodeValue+"</a></li>";
133
-
134
- }
135
- if(node.nodeName=="message"){
136
-
137
-
138
- message = message + "<a href='#' onclick=\"loadXMLDoc('" + newloc+"&amp;path="+node.firstChild.nodeValue+"')\">"+node.firstChild.nodeValue+"</a><br />";
139
-
140
- }
141
- if(node.nodeName=="folder"){
142
-
143
-
144
- var newfile="admin-ajax.php?action=files_xml&dir=" + current_dir+node.firstChild.nodeValue;
145
- stringHTML=stringHTML+"<li class=\"folder\"><img src='../wp-content/plugins/xcloner-backup-and-restore/browser/folder.gif' border='0'><input type=checkbox "+node.getAttribute('check')+" onclick=\"loadXMLDoc('"+ newloc +"&amp;path="+path+"')\" name=cid[] value='"+path+"'><a href='#' class=\"folder\" onclick=\"loadXMLDoc('" + newfile+"')\">"+node.firstChild.nodeValue+"</a></li>";
146
- }
147
- }
148
- stringHTML=stringHTML+"</ul>";
149
- }
150
- else{
151
- stringHTML=stringHTML+"<p>No files in this directory</p>";
152
- }
153
-
154
- //stringHTML = stringHTML+ "</form>";
155
- targetDiv.innerHTML= "<table align='right' width='450'><tr><td align='right'><b>" + "Excluded items list:" + "</b><br />"+ message+"</td></tr></table>" + stringHTML ;
156
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/.htaccess DELETED
@@ -1,2 +0,0 @@
1
- order deny,allow
2
- deny from all
 
 
classes/DropboxClient.php DELETED
@@ -1,672 +0,0 @@
1
- <?php
2
- /**
3
- * DropPHP - A simple Dropbox client that works without cURL.
4
- *
5
- * http://fabi.me/en/php-projects/dropphp-dropbox-api-client/
6
- *
7
- *
8
- * @author Fabian Schlieper <fabian@fabi.me>
9
- * @copyright Fabian Schlieper 2014
10
- * @version 1.7.1
11
- * @license See LICENSE
12
- *
13
- */
14
-
15
- require_once(dirname(__FILE__)."/OAuthSimple.php");
16
-
17
- class DropboxClient {
18
-
19
- const API_URL = "https://api.dropbox.com/1/";
20
- const API_CONTENT_URL = "https://api-content.dropbox.com/1/";
21
-
22
- const BUFFER_SIZE = 4096;
23
-
24
- const MAX_UPLOAD_CHUNK_SIZE = 150000000; // 150MB
25
-
26
- const UPLOAD_CHUNK_SIZE = 4000000; // 4MB
27
-
28
- private $appParams;
29
- private $consumerToken;
30
-
31
- private $requestToken;
32
- private $accessToken;
33
-
34
- private $locale;
35
- private $rootPath;
36
-
37
- private $useCurl;
38
-
39
- function __construct ($app_params, $locale = "en"){
40
- $this->appParams = $app_params;
41
- if(empty($app_params['app_key']))
42
- throw new DropboxException("App Key is empty!");
43
-
44
- $this->consumerToken = array('t' => $this->appParams['app_key'], 's' => $this->appParams['app_secret']);
45
- $this->locale = $locale;
46
- $this->rootPath = empty($app_params['app_full_access']) ? "sandbox" : "dropbox";
47
-
48
- $this->requestToken = null;
49
- $this->accessToken = null;
50
-
51
- $this->useCurl = function_exists('curl_init');
52
- }
53
-
54
- function __wakeup() {
55
- $this->useCurl = $this->useCurl && function_exists('curl_init');
56
- }
57
- /**
58
- * Sets whether to use cURL if its available or PHP HTTP wrappers otherwise
59
- *
60
- * @access public
61
- * @return boolean Whether to actually use cURL (always false if not installed)
62
- */
63
- public function SetUseCUrl($use_it)
64
- {
65
- return ($this->useCurl = ($use_it && function_exists('curl_init')));
66
- }
67
-
68
- // ##################################################
69
- // Authorization
70
-
71
- /**
72
- * Step 1 of authentication process. Retrieves a request token or returns a previously retrieved one.
73
- *
74
- * @access public
75
- * @param boolean $get_new_token Optional (default false). Wether to retrieve a new request token.
76
- * @return array Request Token array.
77
- */
78
- public function GetRequestToken($get_new_token=false)
79
- {
80
- if(!empty($this->requestToken) && !$get_new_token)
81
- return $this->requestToken;
82
-
83
- $rt = $this->authCall("oauth/request_token");
84
- if(empty($rt) || empty($rt['oauth_token']))
85
- throw new DropboxException('Could not get request token!');
86
-
87
- return ($this->requestToken = array('t'=>$rt['oauth_token'], 's'=>$rt['oauth_token_secret']));
88
- }
89
-
90
- /**
91
- * Step 2. Returns a URL the user must be redirected to in order to connect the app to their Dropbox account
92
- *
93
- * @access public
94
- * @param string $return_url URL users are redirected after authorization
95
- * @return string URL
96
- */
97
- public function BuildAuthorizeUrl($return_url)
98
- {
99
- $rt = $this->GetRequestToken();
100
- if(empty($rt) || empty($rt['t'])) throw new DropboxException('Request Token Invalid ('.print_r($rt,true).').');
101
- return "https://www.dropbox.com/1/oauth/authorize?oauth_token=".$rt['t']."&oauth_callback=".urlencode($return_url);
102
- }
103
-
104
- /**
105
- * Step 3. Acquires an access token. This is the final step of authentication.
106
- *
107
- * @access public
108
- * @param array $request_token Optional. The previously retrieved request token. This parameter can only be skipped if the DropboxClient object has been (de)serialized.
109
- * @return array Access Token array.
110
- */
111
- public function GetAccessToken($request_token = null)
112
- {
113
- if(!empty($this->accessToken)) return $this->accessToken;
114
-
115
- if(empty($request_token)) $request_token = $this->requestToken;
116
- if(empty($request_token)) throw new DropboxException('Request token required!');
117
-
118
- $at = $this->authCall("oauth/access_token", $request_token);
119
- if(empty($at))
120
- throw new DropboxException(sprintf('Could not get access token! (request token: %s)', $request_token['t']));
121
-
122
- return ($this->accessToken = array('t'=>$at['oauth_token'], 's'=>$at['oauth_token_secret']));
123
- }
124
-
125
- /**
126
- * Sets a previously retrieved (and stored) access token.
127
- *
128
- * @access public
129
- * @param string|object $token The Access Token
130
- * @return none
131
- */
132
- public function SetAccessToken($token)
133
- {
134
- if(empty($token['t']) || empty($token['s'])) throw new DropboxException('Passed invalid access token.');
135
- $this->accessToken = $token;
136
- }
137
-
138
- /**
139
- * Checks if an access token has been set.
140
- *
141
- * @access public
142
- * @return boolean Authorized or not
143
- */
144
- public function IsAuthorized()
145
- {
146
- if(empty($this->accessToken)) return false;
147
- return true;
148
- }
149
-
150
-
151
- // ##################################################
152
- // API Functions
153
-
154
-
155
- /**
156
- * Retrieves information about the user's account.
157
- *
158
- * @access public
159
- * @return object Account info object. See https://www.dropbox.com/developers/reference/api#account-info
160
- */
161
- public function GetAccountInfo()
162
- {
163
- return $this->apiCall("account/info", "GET");
164
- }
165
-
166
-
167
- /**
168
- * Get file list of a dropbox folder.
169
- *
170
- * @access public
171
- * @param string|object $dropbox_path Dropbox path of the folder
172
- * @return array An array with metadata of files/folders keyed by paths
173
- */
174
- public function GetFiles($dropbox_path='', $recursive=false, $include_deleted=false)
175
- {
176
- if(is_object($dropbox_path) && !empty($dropbox_path->path)) $dropbox_path = $dropbox_path->path;
177
- return $this->getFileTree($dropbox_path, $include_deleted, $recursive ? 1000 : 0);
178
- }
179
-
180
- /**
181
- * Get file or folder metadata
182
- *
183
- * @access public
184
- * @param $dropbox_path string Dropbox path of the file or folder
185
- */
186
- public function GetMetadata($dropbox_path, $include_deleted=false, $rev=null)
187
- {
188
- if(is_object($dropbox_path) && !empty($dropbox_path->path)) $dropbox_path = $dropbox_path->path;
189
- return $this->apiCall("metadata/$this->rootPath/$dropbox_path", "GET", compact('include_deleted','rev'));
190
- }
191
-
192
- /**
193
- * Download a file to the webserver
194
- *
195
- * @access public
196
- * @param string|object $dropbox_file Dropbox path or metadata object of the file to download.
197
- * @param string $dest_path Local path for destination
198
- * @param string $rev Optional. The revision of the file to retrieve. This defaults to the most recent revision.
199
- * @param callback $progress_changed_callback Optional. Callback that will be called during download with 2 args: 1. bytes loaded, 2. file size
200
- * @return object Dropbox file metadata
201
- */
202
- public function DownloadFile($dropbox_file, $dest_path='', $rev=null, $progress_changed_callback = null)
203
- {
204
- if(is_object($dropbox_file) && !empty($dropbox_file->path))
205
- $dropbox_file = $dropbox_file->path;
206
-
207
- if(empty($dest_path)) $dest_path = basename($dropbox_file);
208
-
209
- $url = $this->cleanUrl(self::API_CONTENT_URL."/files/$this->rootPath/$dropbox_file")
210
- . (!empty($rev) ? ('?'.http_build_query(array('rev' => $rev),'','&')) : '');
211
- $context = $this->createRequestContext($url, "GET");
212
-
213
- $fh = @fopen($dest_path, 'wb'); // write binary
214
- if($fh === false) {
215
- @fclose($rh);
216
- throw new DropboxException("Could not create file $dest_path !");
217
- }
218
-
219
- if($this->useCurl) {
220
- curl_setopt($context, CURLOPT_BINARYTRANSFER, true);
221
- curl_setopt($context, CURLOPT_RETURNTRANSFER, true);
222
- curl_setopt($context, CURLOPT_FILE, $fh);
223
- $response_headers = array();
224
- self::execCurlAndClose($context, $response_headers);
225
- fclose($fh);
226
- $meta = self::getMetaFromHeaders($response_headers, true);
227
- $bytes_loaded = filesize($dest_path);
228
- } else {
229
- $rh = @fopen($url, 'rb', false, $context); // read binary
230
- if($rh === false)
231
- throw new DropboxException("HTTP request to $url failed!");
232
-
233
-
234
- // get file meta from HTTP header
235
- $s_meta = stream_get_meta_data($rh);
236
- $meta = self::getMetaFromHeaders($s_meta['wrapper_data'], true);
237
- $bytes_loaded = 0;
238
- while (!feof($rh)) {
239
- if(($s=fwrite($fh, fread($rh, self::BUFFER_SIZE))) === false) {
240
- @fclose($rh);
241
- @fclose($fh);
242
- throw new DropboxException("Writing to file $dest_path failed!'");
243
- }
244
- $bytes_loaded += $s;
245
- if(!empty($progress_changed_callback)) {
246
- call_user_func($progress_changed_callback, $bytes_loaded, $meta->bytes);
247
- }
248
- }
249
-
250
- fclose($rh);
251
- fclose($fh);
252
- }
253
-
254
- if($meta->bytes != $bytes_loaded)
255
- throw new DropboxException("Download size mismatch! (header:{$meta->bytes} vs actual:{$bytes_loaded}; curl:{$this->useCurl})");
256
-
257
- return $meta;
258
- }
259
-
260
- /**
261
- * Upload a file to dropbox
262
- *
263
- * @access public
264
- * @param $src_file string Local file to upload
265
- * @param $dropbox_path string Dropbox path for destination
266
- * @return object Dropbox file metadata
267
- */
268
- public function UploadFile($src_file, $dropbox_path='', $overwrite=true, $parent_rev=null)
269
- {
270
- if(empty($dropbox_path)) $dropbox_path = basename($src_file);
271
- elseif(is_object($dropbox_path) && !empty($dropbox_path->path)) $dropbox_path = $dropbox_path->path;
272
-
273
- // make sure the dropbox_path is not a dir. if it is, append baseneme of $src_file
274
- $dropbox_bn = basename($dropbox_path);
275
- if(strpos($dropbox_bn,'.') === false) { // check if ext. is missing -> could be a directory!
276
- try {
277
- $meta = $this->GetMetadata($dropbox_path);
278
- if($meta && $meta->is_dir)
279
- $dropbox_path = $dropbox_path . '/'. basename($src_file);
280
- } catch(Exception $e) {}
281
- }
282
-
283
- $file_size = filesize($src_file);
284
-
285
- if($file_size > self::MAX_UPLOAD_CHUNK_SIZE)
286
- {
287
- $fh = fopen($src_file,'rb');
288
- if($fh === false)
289
- throw new DropboxException();
290
-
291
- $upload_id = null;
292
- $offset = 0;
293
-
294
-
295
- while(!feof($fh)) {
296
- $url = $this->cleanUrl(self::API_CONTENT_URL."/chunked_upload").'?'.http_build_query(compact('upload_id', 'offset'),'','&');
297
- $content = fread($fh, self::UPLOAD_CHUNK_SIZE);
298
- $context = $this->createRequestContext($url, "PUT", $content);
299
-
300
- if($this->useCurl) {
301
- curl_setopt($context, CURLOPT_BINARYTRANSFER, true);
302
- $response = json_decode(self::execCurlAndClose($context));
303
- } else {
304
- $response = json_decode(file_get_contents($url, false, $context));
305
- }
306
- $offset += strlen($content);
307
- unset($content);
308
- unset($context);
309
-
310
- self::checkForError($response);
311
-
312
- if(empty($upload_id)) {
313
- $upload_id = $response->upload_id;
314
- if(empty($upload_id)) throw new DropboxException("Upload ID empty!");
315
- }
316
- if($offset >= $file_size)
317
- break;
318
- }
319
-
320
- @fclose($fh);
321
-
322
- return $this->apiCall("commit_chunked_upload/$this->rootPath/$dropbox_path", "POST", compact('overwrite','parent_rev','upload_id'), true);
323
- }
324
-
325
- $query = http_build_query(array_merge(compact('overwrite', 'parent_rev'), array('locale' => $this->locale)),'','&');
326
- $url = $this->cleanUrl(self::API_CONTENT_URL."/files_put/$this->rootPath/$dropbox_path")."?$query";
327
-
328
- if($this->useCurl) {
329
- $context = $this->createRequestContext($url, "PUT");
330
- curl_setopt($context, CURLOPT_BINARYTRANSFER, true);
331
- $fh = fopen($src_file, 'rb');
332
- curl_setopt($context, CURLOPT_PUT, 1);
333
- curl_setopt($context, CURLOPT_INFILE, $fh); // file pointer
334
- curl_setopt($context, CURLOPT_INFILESIZE, filesize($src_file));
335
- $meta = json_decode(self::execCurlAndClose($context));
336
- fclose($fh);
337
- return self::checkForError($meta);
338
- } else {
339
- $content = file_get_contents($src_file);
340
- if(strlen($content) == 0)
341
- throw new DropboxException("Could not read file $src_file or file is empty!");
342
-
343
- $context = $this->createRequestContext($url, "PUT", $content);
344
-
345
- return self::checkForError(json_decode(file_get_contents($url, false, $context)));
346
- }
347
- }
348
-
349
- /**
350
- * Get thumbnail for a specified image
351
- *
352
- * @access public
353
- * @param $dropbox_file string Path to the image
354
- * @param $format string Image format of the thumbnail (jpeg or png)
355
- * @param $size string Thumbnail size (xs, s, m, l, xl)
356
- * @return mime/* Returns the thumbnail as binary image data
357
- */
358
- public function GetThumbnail($dropbox_file, $size = 's', $format = 'jpeg', $echo = false)
359
- {
360
- if(is_object($dropbox_file) && !empty($dropbox_file->path)) $dropbox_file = $dropbox_file->path;
361
- $url = $this->cleanUrl(self::API_CONTENT_URL."thumbnails/$this->rootPath/$dropbox_file")
362
- . '?' . http_build_query(array('format' => $format, 'size' => $size),'','&');
363
- $context = $this->createRequestContext($url, "GET");
364
-
365
- if($this->useCurl) {
366
- curl_setopt($context, CURLOPT_BINARYTRANSFER, true);
367
- curl_setopt($context, CURLOPT_RETURNTRANSFER, true);
368
- }
369
-
370
- $thumb = $this->useCurl ? self::execCurlAndClose($context) : file_get_contents($url, NULL, $context);
371
-
372
- if($echo) {
373
- header('Content-type: image/'.$format);
374
- echo $thumb;
375
- unset($thumb);
376
- return;
377
- }
378
-
379
- return $thumb;
380
- }
381
-
382
-
383
- function GetLink($dropbox_file, $preview=true, $short=true, &$expires=null)
384
- {
385
- if(is_object($dropbox_file) && !empty($dropbox_file->path)) $dropbox_file = $dropbox_file->path;
386
- $url = $this->apiCall(($preview?"shares":"media")."/$this->rootPath/$dropbox_file", "POST", array('locale' => null, 'short_url'=> $preview ? $short : null));
387
- $expires = strtotime($url->expires);
388
- return $url->url;
389
- }
390
-
391
- function Delta($cursor)
392
- {
393
- return $this->apiCall("delta", "POST", compact('cursor'));
394
- }
395
-
396
- function GetRevisions($dropbox_file, $rev_limit=10)
397
- {
398
- if(is_object($dropbox_file) && !empty($dropbox_file->path)) $dropbox_file = $dropbox_file->path;
399
- return $this->apiCall("revisions/$this->rootPath/$dropbox_file", "GET", compact('rev_limit'));
400
- }
401
-
402
- function Restore($dropbox_file, $rev)
403
- {
404
- if(is_object($dropbox_file) && !empty($dropbox_file->path)) $dropbox_file = $dropbox_file->path;
405
- return $this->apiCall("restore/$this->rootPath/$dropbox_file", "POST", compact('rev'));
406
- }
407
-
408
- function Search($path, $query, $file_limit=1000, $include_deleted=false)
409
- {
410
- return $this->apiCall("search/$this->rootPath/$path", "POST", compact('query','file_limit','include_deleted'));
411
- }
412
-
413
- function GetCopyRef($dropbox_file, &$expires=null)
414
- {
415
- if(is_object($dropbox_file) && !empty($dropbox_file->path)) $dropbox_file = $dropbox_file->path;
416
- $ref = $this->apiCall("copy_ref/$this->rootPath/$dropbox_file", "GET", array('locale' => null));
417
- $expires = strtotime($ref->expires);
418
- return $ref->copy_ref;
419
- }
420
-
421
-
422
- function Copy($from_path, $to_path, $copy_ref=false)
423
- {
424
- if(is_object($from_path) && !empty($from_path->path)) $from_path = $from_path->path;
425
- return $this->apiCall("fileops/copy", "POST", array('root'=> $this->rootPath, ($copy_ref ? 'from_copy_ref' : 'from_path') => $from_path, 'to_path' => $to_path));
426
- }
427
-
428
- /**
429
- * Creates a new folder in the DropBox
430
- *
431
- * @access public
432
- * @param $path string The path to the new folder to create
433
- * @return object Dropbox folder metadata
434
- */
435
- function CreateFolder($path)
436
- {
437
- return $this->apiCall("fileops/create_folder", "POST", array('root'=> $this->rootPath, 'path' => $path));
438
- }
439
-
440
- /**
441
- * Delete file or folder
442
- *
443
- * @access public
444
- * @param $path mixed The path or metadata of the file/folder to be deleted.
445
- * @return object Dropbox metadata of deleted file or folder
446
- */
447
- function Delete($path)
448
- {
449
- if(is_object($path) && !empty($path->path)) $path = $path->path;
450
- return $this->apiCall("fileops/delete", "POST", array('locale' =>null, 'root'=> $this->rootPath, 'path' => $path));
451
- }
452
-
453
- function Move($from_path, $to_path)
454
- {
455
- if(is_object($from_path) && !empty($from_path->path)) $from_path = $from_path->path;
456
- return $this->apiCall("fileops/move", "POST", array('root'=> $this->rootPath, 'from_path' => $from_path, 'to_path' => $to_path));
457
- }
458
-
459
- function getFileTree($path="", $include_deleted = false, $max_depth = 0, $depth=0)
460
- {
461
- static $files;
462
- if($depth == 0) $files = array();
463
-
464
- $dir = $this->apiCall("metadata/$this->rootPath/$path", "GET", compact('include_deleted'));
465
-
466
- if(empty($dir) || !is_object($dir)) return false;
467
-
468
- if(!empty($dir->error)) throw new DropboxException($dir->error);
469
-
470
- foreach($dir->contents as $item)
471
- {
472
- $files[trim($item->path,'/')] = $item;
473
- if($item->is_dir && $depth < $max_depth)
474
- {
475
- $this->getFileTree($item->path, $include_deleted, $max_depth, $depth+1);
476
- }
477
- }
478
-
479
- return $files;
480
- }
481
-
482
- function createCurl($url, $http_context)
483
- {
484
- $ch = curl_init($url);
485
-
486
- $curl_opts = array(
487
- CURLOPT_HEADER => false, // exclude header from output
488
- //CURLOPT_MUTE => true, // no output!
489
- CURLOPT_RETURNTRANSFER => true, // but return!
490
- CURLOPT_SSL_VERIFYPEER => false,
491
- );
492
-
493
- $curl_opts[CURLOPT_CUSTOMREQUEST] = $http_context['method'];
494
-
495
- if(!empty($http_context['content'])) {
496
- $curl_opts[CURLOPT_POSTFIELDS] =& $http_context['content'];
497
- if(defined("CURLOPT_POSTFIELDSIZE"))
498
- $curl_opts[CURLOPT_POSTFIELDSIZE] = strlen($http_context['content']);
499
- }
500
-
501
- $curl_opts[CURLOPT_HTTPHEADER] = array_map('trim',explode("\n",$http_context['header']));
502
-
503
- curl_setopt_array($ch, $curl_opts);
504
- return $ch;
505
- }
506
-
507
- static private $_curlHeadersRef;
508
- static function _curlHeaderCallback($ch, $header)
509
- {
510
- self::$_curlHeadersRef[] = trim($header);
511
- return strlen($header);
512
- }
513
-
514
- static function &execCurlAndClose($ch, &$out_response_headers = null)
515
- {
516
- if(is_array($out_response_headers)) {
517
- self::$_curlHeadersRef =& $out_response_headers;
518
- curl_setopt($ch, CURLOPT_HEADERFUNCTION, array(__CLASS__, '_curlHeaderCallback'));
519
- }
520
- $res = curl_exec($ch);
521
- $err_no = curl_errno($ch);
522
- $err_str = curl_error($ch);
523
- curl_close($ch);
524
- if($err_no || $res === false) {
525
- throw new DropboxException("cURL-Error ($err_no): $err_str");
526
- }
527
-
528
- return $res;
529
- }
530
-
531
- private function createRequestContext($url, $method, &$content=null, $oauth_token=-1)
532
- {
533
- if($oauth_token === -1)
534
- $oauth_token = $this->accessToken;
535
-
536
- $method = strtoupper($method);
537
- $http_context = array('method'=>$method, 'header'=> '');
538
-
539
- $oauth = new OAuthSimple($this->consumerToken['t'],$this->consumerToken['s']);
540
-
541
- if(empty($oauth_token) && !empty($this->accessToken))
542
- $oauth_token = $this->accessToken;
543
-
544
- if(!empty($oauth_token)) {
545
- $oauth->setParameters(array('oauth_token' => $oauth_token['t']));
546
- $oauth->signatures(array('oauth_secret'=>$oauth_token['s']));
547
- }
548
-
549
- if(!empty($content)) {
550
- $post_vars = ($method != "PUT" && preg_match("/^[a-z][a-z0-9_]*=/i", substr($content, 0, 32)));
551
- $http_context['header'] .= "Content-Length: ".strlen($content)."\r\n";
552
- $http_context['header'] .= "Content-Type: application/".($post_vars?"x-www-form-urlencoded":"octet-stream")."\r\n";
553
- $http_context['content'] =& $content;
554
- if($method == "POST" && $post_vars)
555
- $oauth->setParameters($content);
556
- } elseif($method == "POST") {
557
- // make sure that content-length is always set when post request (otherwise some wrappers fail!)
558
- $http_context['content'] = "";
559
- $http_context['header'] .= "Content-Length: 0\r\n";
560
- }
561
-
562
-
563
- // check for query vars in url and add them to oauth parameters (and remove from path)
564
- $path = $url;
565
- $query = strrchr($url,'?');
566
- if(!empty($query)) {
567
- $oauth->setParameters(substr($query,1));
568
- $path = substr($url, 0, -strlen($query));
569
- }
570
-
571
-
572
- $signed = $oauth->sign(array(
573
- 'action' => $method,
574
- 'path'=> $path));
575
- //print_r($signed);
576
-
577
- $http_context['header'] .= "Authorization: ".$signed['header']."\r\n";
578
-
579
- return $this->useCurl ? $this->createCurl($url, $http_context) : stream_context_create(array('http'=>$http_context));
580
- }
581
-
582
- private function authCall($path, $request_token=null)
583
- {
584
- $url = $this->cleanUrl(self::API_URL.$path);
585
- $dummy = null;
586
- $context = $this->createRequestContext($url, "POST", $dummy, $request_token);
587
-
588
- $contents = $this->useCurl ? self::execCurlAndClose($context) : file_get_contents($url, false, $context);
589
- $data = array();
590
- parse_str($contents, $data);
591
- return $data;
592
- }
593
-
594
- private static function checkForError($resp)
595
- {
596
- if(!empty($resp->error))
597
- throw new DropboxException($resp->error);
598
- return $resp;
599
- }
600
-
601
-
602
- private function apiCall($path, $method, $params=array(), $content_call=false)
603
- {
604
- $url = $this->cleanUrl(($content_call ? self::API_CONTENT_URL : self::API_URL).$path);
605
- $content = http_build_query(array_merge(array('locale'=>$this->locale), $params),'','&');
606
-
607
- if($method == "GET") {
608
- $url .= "?".$content;
609
- $content = null;
610
- }
611
-
612
- $context = $this->createRequestContext($url, $method, $content);
613
- $json = $this->useCurl ? self::execCurlAndClose($context) : file_get_contents($url, false, $context);
614
- //if($json === false)
615
- // throw new DropboxException();
616
- $resp = json_decode($json);
617
- return self::checkForError($resp);
618
- }
619
-
620
-
621
- private static function getMetaFromHeaders(&$header_array, $throw_on_error=false)
622
- {
623
- $obj = json_decode(substr(@array_shift(array_filter($header_array, create_function('$s', 'return stripos($s, "x-dropbox-metadata:") === 0;'))), 20));
624
- if($throw_on_error && (empty($obj)||!is_object($obj)))
625
- throw new DropboxException("Could not retrieve meta data from header data: ".print_r($header_array,true));
626
- if($throw_on_error)
627
- self::checkForError ($obj);
628
- return $obj;
629
- }
630
-
631
-
632
- function cleanUrl($url) {
633
- $p = substr($url,0,8);
634
- $url = str_replace('//','/', str_replace('\\','/',substr($url,8)));
635
- $url = rawurlencode($url);
636
- $url = str_replace('%2F', '/', $url);
637
- return $p.$url;
638
- }
639
- }
640
-
641
- class DropboxException extends Exception {
642
-
643
- public function __construct($err = null, $isDebug = FALSE)
644
- {
645
- if(is_null($err)) {
646
- $el = error_get_last();
647
- $this->message = $el['message'];
648
- $this->file = $el['file'];
649
- $this->line = $el['line'];
650
- } else
651
- $this->message = $err;
652
- self::log_error($err);
653
- if ($isDebug)
654
- {
655
- self::display_error($err, TRUE);
656
- }
657
- }
658
-
659
- public static function log_error($err)
660
- {
661
- error_log($err, 0);
662
- }
663
-
664
- public static function display_error($err, $kill = FALSE)
665
- {
666
- print_r($err);
667
- if ($kill === FALSE)
668
- {
669
- die();
670
- }
671
- }
672
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/OAuthSimple.php DELETED
@@ -1,532 +0,0 @@
1
- <?php
2
- /**
3
- * OAuthSimple - A simpler version of OAuth
4
- *
5
- * https://github.com/jrconlin/oauthsimple
6
- *
7
- * @author jr conlin <src@jrconlin.com>
8
- * @copyright unitedHeroes.net 2011
9
- * @version 1.3
10
- * @license See OAuthSimple_license.txt
11
- *
12
- */
13
-
14
- class OAuthSimple {
15
- private $_secrets;
16
- private $_default_signature_method;
17
- private $_action;
18
- private $_nonce_chars;
19
-
20
- /**
21
- * Constructor
22
- *
23
- * @access public
24
- * @param api_key (String) The API Key (sometimes referred to as the consumer key) This value is usually supplied by the site you wish to use.
25
- * @param shared_secret (String) The shared secret. This value is also usually provided by the site you wish to use.
26
- * @return OAuthSimple (Object)
27
- */
28
- function __construct ($APIKey = "", $sharedSecret=""){
29
-
30
- if (!empty($APIKey))
31
- {
32
- $this->_secrets['consumer_key'] = $APIKey;
33
- }
34
-
35
- if (!empty($sharedSecret))
36
- {
37
- $this->_secrets['shared_secret'] = $sharedSecret;
38
- }
39
-
40
- $this->_default_signature_method = "HMAC-SHA1";
41
- $this->_action = "GET";
42
- $this->_nonce_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
43
-
44
- return $this;
45
- }
46
-
47
- /**
48
- * Reset the parameters and URL
49
- *
50
- * @access public
51
- * @return OAuthSimple (Object)
52
- */
53
- public function reset() {
54
- $this->_parameters = Array();
55
- $this->path = NULL;
56
- $this->sbs = NULL;
57
-
58
- return $this;
59
- }
60
-
61
- /**
62
- * Set the parameters either from a hash or a string
63
- *
64
- * @access public
65
- * @param(string, object) List of parameters for the call, this can either be a URI string (e.g. "foo=bar&gorp=banana" or an object/hash)
66
- * @return OAuthSimple (Object)
67
- */
68
- public function setParameters ($parameters=Array()) {
69
-
70
- if (is_string($parameters))
71
- {
72
- $parameters = $this->_parseParameterString($parameters);
73
- }
74
- if (empty($this->_parameters))
75
- {
76
- $this->_parameters = $parameters;
77
- }
78
- else if (!empty($parameters))
79
- {
80
- $this->_parameters = array_merge($this->_parameters,$parameters);
81
- }
82
- if (empty($this->_parameters['oauth_nonce']))
83
- {
84
- $this->_getNonce();
85
- }
86
- if (empty($this->_parameters['oauth_timestamp']))
87
- {
88
- $this->_getTimeStamp();
89
- }
90
- if (empty($this->_parameters['oauth_consumer_key']))
91
- {
92
- $this->_getApiKey();
93
- }
94
- if (empty($this->_parameters['oauth_token']))
95
- {
96
- $this->_getAccessToken();
97
- }
98
- if (empty($this->_parameters['oauth_signature_method']))
99
- {
100
- $this->setSignatureMethod();
101
- }
102
- if (empty($this->_parameters['oauth_version']))
103
- {
104
- $this->_parameters['oauth_version']="1.0";
105
- }
106
-
107
- return $this;
108
- }
109
-
110
- /**
111
- * Convenience method for setParameters
112
- *
113
- * @access public
114
- * @see setParameters
115
- */
116
- public function setQueryString ($parameters)
117
- {
118
- return $this->setParameters($parameters);
119
- }
120
-
121
- /**
122
- * Set the target URL (does not include the parameters)
123
- *
124
- * @param path (String) the fully qualified URI (excluding query arguments) (e.g "http://example.org/foo")
125
- * @return OAuthSimple (Object)
126
- */
127
- public function setURL ($path)
128
- {
129
- if (empty($path))
130
- {
131
- throw new OAuthSimpleException('No path specified for OAuthSimple.setURL');
132
- }
133
- $this->_path=$path;
134
-
135
- return $this;
136
- }
137
-
138
- /**
139
- * Convenience method for setURL
140
- *
141
- * @param path (String)
142
- * @see setURL
143
- */
144
- public function setPath ($path)
145
- {
146
- return $this->_path=$path;
147
- }
148
-
149
- /**
150
- * Set the "action" for the url, (e.g. GET,POST, DELETE, etc.)
151
- *
152
- * @param action (String) HTTP Action word.
153
- * @return OAuthSimple (Object)
154
- */
155
- public function setAction ($action)
156
- {
157
- if (empty($action))
158
- {
159
- $action = 'GET';
160
- }
161
- $action = strtoupper($action);
162
- if (preg_match('/[^A-Z]/',$action))
163
- {
164
- throw new OAuthSimpleException('Invalid action specified for OAuthSimple.setAction');
165
- }
166
- $this->_action = $action;
167
-
168
- return $this;
169
- }
170
-
171
- /**
172
- * Set the signatures (as well as validate the ones you have)
173
- *
174
- * @param signatures (object) object/hash of the token/signature pairs {api_key:, shared_secret:, oauth_token: oauth_secret:}
175
- * @return OAuthSimple (Object)
176
- */
177
- public function signatures ($signatures)
178
- {
179
- if (!empty($signatures) && !is_array($signatures))
180
- {
181
- throw new OAuthSimpleException('Must pass dictionary array to OAuthSimple.signatures');
182
- }
183
- if (!empty($signatures))
184
- {
185
- if (empty($this->_secrets))
186
- {
187
- $this->_secrets=Array();
188
- }
189
- $this->_secrets=array_merge($this->_secrets,$signatures);
190
- }
191
- if (isset($this->_secrets['api_key']))
192
- {
193
- $this->_secrets['consumer_key'] = $this->_secrets['api_key'];
194
- }
195
- if (isset($this->_secrets['access_token']))
196
- {
197
- $this->_secrets['oauth_token'] = $this->_secrets['access_token'];
198
- }
199
- if (isset($this->_secrets['access_secret']))
200
- {
201
- $this->_secrets['oauth_secret'] = $this->_secrets['access_secret'];
202
- }
203
- if (isset($this->_secrets['access_token_secret']))
204
- {
205
- $this->_secrets['oauth_secret'] = $this->_secrets['access_token_secret'];
206
- }
207
- if (empty($this->_secrets['consumer_key']))
208
- {
209
- throw new OAuthSimpleException('Missing required consumer_key in OAuthSimple.signatures');
210
- }
211
- if (empty($this->_secrets['shared_secret']))
212
- {
213
- throw new OAuthSimpleException('Missing requires shared_secret in OAuthSimple.signatures');
214
- }
215
- if (!empty($this->_secrets['oauth_token']) && empty($this->_secrets['oauth_secret']))
216
- {
217
- throw new OAuthSimpleException('Missing oauth_secret for supplied oauth_token in OAuthSimple.signatures');
218
- }
219
-
220
- return $this;
221
- }
222
-
223
- public function setTokensAndSecrets($signatures)
224
- {
225
- return $this->signatures($signatures);
226
- }
227
-
228
- /**
229
- * Set the signature method (currently only Plaintext or SHA-MAC1)
230
- *
231
- * @param method (String) Method of signing the transaction (only PLAINTEXT and SHA-MAC1 allowed for now)
232
- * @return OAuthSimple (Object)
233
- */
234
- public function setSignatureMethod ($method="")
235
- {
236
- if (empty($method))
237
- {
238
- $method = $this->_default_signature_method;
239
- }
240
- $method = strtoupper($method);
241
- switch($method)
242
- {
243
- case 'PLAINTEXT':
244
- case 'HMAC-SHA1':
245
- $this->_parameters['oauth_signature_method']=$method;
246
- break;
247
- default:
248
- throw new OAuthSimpleException ("Unknown signing method $method specified for OAuthSimple.setSignatureMethod");
249
- break;
250
- }
251
-
252
- return $this;
253
- }
254
-
255
- /** sign the request
256
- *
257
- * note: all arguments are optional, provided you've set them using the
258
- * other helper functions.
259
- *
260
- * @param args (Array) hash of arguments for the call {action, path, parameters (array), method, signatures (array)} all arguments are optional.
261
- * @return (Array) signed values
262
- */
263
- public function sign($args=array())
264
- {
265
- if (!empty($args['action']))
266
- {
267
- $this->setAction($args['action']);
268
- }
269
- if (!empty($args['path']))
270
- {
271
- $this->setPath($args['path']);
272
- }
273
- if (!empty($args['method']))
274
- {
275
- $this->setSignatureMethod($args['method']);
276
- }
277
- if (!empty($args['signatures']))
278
- {
279
- $this->signatures($args['signatures']);
280
- }
281
- if (empty($args['parameters']))
282
- {
283
- $args['parameters']=array();
284
- }
285
- $this->setParameters($args['parameters']);
286
- $normParams = $this->_normalizedParameters();
287
- $this->_parameters['oauth_signature'] = $this->_generateSignature($normParams);
288
-
289
- return Array (
290
- 'parameters' => $this->_parameters,
291
- 'signature' => self::_oauthEscape($this->_parameters['oauth_signature']),
292
- 'signed_url' => $this->_path . '?' . $this->_normalizedParameters(),
293
- 'header' => $this->getHeaderString(),
294
- 'sbs'=> $this->sbs
295
- );
296
- }
297
-
298
- /**
299
- * Return a formatted "header" string
300
- *
301
- * NOTE: This doesn't set the "Authorization: " prefix, which is required.
302
- * It's not set because various set header functions prefer different
303
- * ways to do that.
304
- *
305
- * @param args (Array)
306
- * @return $result (String)
307
- */
308
- public function getHeaderString ($args=array())
309
- {
310
- if (empty($this->_parameters['oauth_signature']))
311
- {
312
- $this->sign($args);
313
- }
314
- $result = 'OAuth ';
315
-
316
- foreach ($this->_parameters as $pName => $pValue)
317
- {
318
- if (strpos($pName,'oauth_') !== 0 || $pName == 'oauth_token_secret2')
319
- {
320
- continue;
321
- }
322
- if (is_array($pValue))
323
- {
324
- foreach ($pValue as $val)
325
- {
326
- $result .= $pName .'="' . self::_oauthEscape($val) . '", ';
327
- }
328
- }
329
- else
330
- {
331
- $result .= $pName . '="' . self::_oauthEscape($pValue) . '", ';
332
- }
333
- }
334
-
335
- return preg_replace('/, $/','',$result);
336
- }
337
-
338
- private function _parseParameterString ($paramString)
339
- {
340
- $elements = explode('&',$paramString);
341
- $result = array();
342
- foreach ($elements as $element)
343
- {
344
- list ($key,$token) = explode('=',$element);
345
- if ($token)
346
- {
347
- $token = urldecode($token);
348
- }
349
- if (!empty($result[$key]))
350
- {
351
- if (!is_array($result[$key]))
352
- {
353
- $result[$key] = array($result[$key],$token);
354
- }
355
- else
356
- {
357
- array_push($result[$key],$token);
358
- }
359
- }
360
- else
361
- $result[$key]=$token;
362
- }
363
- return $result;
364
- }
365
-
366
-
367
- private static function _oauthEscape($string)
368
- {
369
- if ($string === 0) { return 0; }
370
- if ($string == '0') { return '0'; }
371
- if (strlen($string) == 0) { return ''; }
372
- if (is_array($string)) {
373
- throw new OAuthSimpleException('Array passed to _oauthEscape');
374
- }
375
- $string = rawurlencode($string);
376
-
377
- $string = str_replace('+','%20',$string);
378
- $string = str_replace('!','%21',$string);
379
- $string = str_replace('*','%2A',$string);
380
- $string = str_replace('\'','%27',$string);
381
- $string = str_replace('(','%28',$string);
382
- $string = str_replace(')','%29',$string);
383
-
384
- return $string;
385
- }
386
-
387
- private function _getNonce($length=5)
388
- {
389
- $result = '';
390
- $cLength = strlen($this->_nonce_chars);
391
- for ($i=0; $i < $length; $i++)
392
- {
393
- $rnum = rand(0,$cLength);
394
- $result .= substr($this->_nonce_chars,$rnum,1);
395
- }
396
- $result = md5($result);
397
- $this->_parameters['oauth_nonce'] = $result;
398
-
399
- return $result;
400
- }
401
-
402
- private function _getApiKey()
403
- {
404
- if (empty($this->_secrets['consumer_key']))
405
- {
406
- throw new OAuthSimpleException('No consumer_key set for OAuthSimple');
407
- }
408
- $this->_parameters['oauth_consumer_key']=$this->_secrets['consumer_key'];
409
-
410
- return $this->_parameters['oauth_consumer_key'];
411
- }
412
-
413
- private function _getAccessToken()
414
- {
415
- if (!isset($this->_secrets['oauth_secret']))
416
- {
417
- return '';
418
- }
419
- if (!isset($this->_secrets['oauth_token']))
420
- {
421
- throw new OAuthSimpleException('No access token (oauth_token) set for OAuthSimple.');
422
- }
423
- $this->_parameters['oauth_token'] = $this->_secrets['oauth_token'];
424
-
425
- return $this->_parameters['oauth_token'];
426
- }
427
-
428
- private function _getTimeStamp()
429
- {
430
- return $this->_parameters['oauth_timestamp'] = time();
431
- }
432
-
433
- private function _normalizedParameters()
434
- {
435
- $normalized_keys = array();
436
- $return_array = array();
437
-
438
- foreach ( $this->_parameters as $paramName=>$paramValue) {
439
- if (!preg_match('/\w+_secret/',$paramName) OR (strpos($paramValue, '@') !== 0 && !file_exists(substr($paramValue, 1))) )
440
- {
441
- if (is_array($paramValue))
442
- {
443
- $normalized_keys[self::_oauthEscape($paramName)] = array();
444
- foreach($paramValue as $item)
445
- {
446
- array_push($normalized_keys[self::_oauthEscape($paramName)], self::_oauthEscape($item));
447
- }
448
- }
449
- else
450
- {
451
- $normalized_keys[self::_oauthEscape($paramName)] = self::_oauthEscape($paramValue);
452
- }
453
- }
454
- }
455
-
456
- ksort($normalized_keys);
457
-
458
- foreach($normalized_keys as $key=>$val)
459
- {
460
- if (is_array($val))
461
- {
462
- sort($val);
463
- foreach($val as $element)
464
- {
465
- array_push($return_array, $key . "=" . $element);
466
- }
467
- }
468
- else
469
- {
470
- array_push($return_array, $key .'='. $val);
471
- }
472
-
473
- }
474
-
475
- return join("&", $return_array);
476
- }
477
-
478
-
479
- private function _generateSignature ()
480
- {
481
- $secretKey = '';
482
- if(isset($this->_secrets['shared_secret']))
483
- {
484
- $secretKey = self::_oauthEscape($this->_secrets['shared_secret']);
485
- }
486
-
487
- $secretKey .= '&';
488
- if(isset($this->_secrets['oauth_secret']))
489
- {
490
- $secretKey .= self::_oauthEscape($this->_secrets['oauth_secret']);
491
- }
492
-
493
- switch($this->_parameters['oauth_signature_method'])
494
- {
495
- case 'PLAINTEXT':
496
- return urlencode($secretKey);;
497
- case 'HMAC-SHA1':
498
- $this->sbs = self::_oauthEscape($this->_action).'&'.self::_oauthEscape($this->_path).'&'.self::_oauthEscape($this->_normalizedParameters());
499
-
500
- return base64_encode(hash_hmac('sha1',$this->sbs,$secretKey,TRUE));
501
- default:
502
- throw new OAuthSimpleException('Unknown signature method for OAuthSimple');
503
- break;
504
- }
505
- }
506
- }
507
-
508
- class OAuthSimpleException extends Exception {
509
-
510
- public function __construct($err, $isDebug = FALSE)
511
- {
512
- self::log_error($err);
513
- if ($isDebug)
514
- {
515
- self::display_error($err, TRUE);
516
- }
517
- }
518
-
519
- public static function log_error($err)
520
- {
521
- error_log($err, 0);
522
- }
523
-
524
- public static function display_error($err, $kill = FALSE)
525
- {
526
- print_r($err);
527
- if ($kill === FALSE)
528
- {
529
- die();
530
- }
531
- }
532
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/S3.php DELETED
@@ -1,1368 +0,0 @@
1
- <?php
2
- /**
3
- * $Id: S3.php 47 2009-07-20 01:25:40Z don.schonknecht $
4
- *
5
- * Copyright (c) 2008, Donovan Schönknecht. All rights reserved.
6
- *
7
- * Redistribution and use in source and binary forms, with or without
8
- * modification, are permitted provided that the following conditions are met:
9
- *
10
- * - Redistributions of source code must retain the above copyright notice,
11
- * this list of conditions and the following disclaimer.
12
- * - Redistributions in binary form must reproduce the above copyright
13
- * notice, this list of conditions and the following disclaimer in the
14
- * documentation and/or other materials provided with the distribution.
15
- *
16
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
- * POSSIBILITY OF SUCH DAMAGE.
27
- *
28
- * Amazon S3 is a trademark of Amazon.com, Inc. or its affiliates.
29
- */
30
-
31
- /** ensure this file is being included by a parent file */
32
- defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
33
-
34
- /**
35
- * Amazon S3 PHP class
36
- *
37
- * @link http://undesigned.org.za/2007/10/22/amazon-s3-php-class
38
- * @version 0.4.0
39
- */
40
- class S3 {
41
- // ACL flags
42
- const ACL_PRIVATE = 'private';
43
- const ACL_PUBLIC_READ = 'public-read';
44
- const ACL_PUBLIC_READ_WRITE = 'public-read-write';
45
- const ACL_AUTHENTICATED_READ = 'authenticated-read';
46
-
47
- public static $useSSL = true;
48
-
49
- private static $__accessKey; // AWS Access key
50
- private static $__secretKey; // AWS Secret key
51
-
52
-
53
- /**
54
- * Constructor - if you're not using the class statically
55
- *
56
- * @param string $accessKey Access key
57
- * @param string $secretKey Secret key
58
- * @param boolean $useSSL Enable SSL
59
- * @return void
60
- */
61
- public function __construct($accessKey = null, $secretKey = null, $useSSL = true) {
62
- if ($accessKey !== null && $secretKey !== null)
63
- self::setAuth($accessKey, $secretKey);
64
- self::$useSSL = $useSSL;
65
- }
66
-
67
-
68
- /**
69
- * Set AWS access key and secret key
70
- *
71
- * @param string $accessKey Access key
72
- * @param string $secretKey Secret key
73
- * @return void
74
- */
75
- public static function setAuth($accessKey, $secretKey) {
76
- self::$__accessKey = $accessKey;
77
- self::$__secretKey = $secretKey;
78
- }
79
-
80
-
81
- /**
82
- * Get a list of buckets
83
- *
84
- * @param boolean $detailed Returns detailed bucket list when true
85
- * @return array | false
86
- */
87
- public static function listBuckets($detailed = false) {
88
- $rest = new S3Request('GET', '', '');
89
- $rest = $rest->getResponse();
90
- if ($rest->error === false && $rest->code !== 200)
91
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
92
- if ($rest->error !== false) {
93
- trigger_error(sprintf("S3::listBuckets(): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING);
94
- return false;
95
- }
96
- $results = array();
97
- if (!isset($rest->body->Buckets)) return $results;
98
-
99
- if ($detailed) {
100
- if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName))
101
- $results['owner'] = array(
102
- 'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->ID
103
- );
104
- $results['buckets'] = array();
105
- foreach ($rest->body->Buckets->Bucket as $b)
106
- $results['buckets'][] = array(
107
- 'name' => (string)$b->Name, 'time' => strtotime((string)$b->CreationDate)
108
- );
109
- } else
110
- foreach ($rest->body->Buckets->Bucket as $b) $results[] = (string)$b->Name;
111
-
112
- return $results;
113
- }
114
-
115
-
116
- /*
117
- * Get contents for a bucket
118
- *
119
- * If maxKeys is null this method will loop through truncated result sets
120
- *
121
- * @param string $bucket Bucket name
122
- * @param string $prefix Prefix
123
- * @param string $marker Marker (last file listed)
124
- * @param string $maxKeys Max keys (maximum number of keys to return)
125
- * @param string $delimiter Delimiter
126
- * @param boolean $returnCommonPrefixes Set to true to return CommonPrefixes
127
- * @return array | false
128
- */
129
- public static function getBucket($bucket, $prefix = null, $marker = null, $maxKeys = null, $delimiter = null, $returnCommonPrefixes = false) {
130
- $rest = new S3Request('GET', $bucket, '');
131
- if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix);
132
- if ($marker !== null && $marker !== '') $rest->setParameter('marker', $marker);
133
- if ($maxKeys !== null && $maxKeys !== '') $rest->setParameter('max-keys', $maxKeys);
134
- if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter);
135
- $response = $rest->getResponse();
136
- if ($response->error === false && $response->code !== 200)
137
- $response->error = array('code' => $response->code, 'message' => 'Unexpected HTTP status');
138
- if ($response->error !== false) {
139
- trigger_error(sprintf("S3::getBucket(): [%s] %s", $response->error['code'], $response->error['message']), E_USER_WARNING);
140
- return false;
141
- }
142
-
143
- $results = array();
144
-
145
- $nextMarker = null;
146
- if (isset($response->body, $response->body->Contents))
147
- foreach ($response->body->Contents as $c) {
148
- $results[(string)$c->Key] = array(
149
- 'name' => (string)$c->Key,
150
- 'time' => strtotime((string)$c->LastModified),
151
- 'size' => (int)$c->Size,
152
- 'hash' => substr((string)$c->ETag, 1, -1)
153
- );
154
- $nextMarker = (string)$c->Key;
155
- }
156
-
157
- if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes))
158
- foreach ($response->body->CommonPrefixes as $c)
159
- $results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix);
160
-
161
- if (isset($response->body, $response->body->IsTruncated) &&
162
- (string)$response->body->IsTruncated == 'false') return $results;
163
-
164
- if (isset($response->body, $response->body->NextMarker))
165
- $nextMarker = (string)$response->body->NextMarker;
166
-
167
- // Loop through truncated results if maxKeys isn't specified
168
- if ($maxKeys == null && $nextMarker !== null && (string)$response->body->IsTruncated == 'true')
169
- do {
170
- $rest = new S3Request('GET', $bucket, '');
171
- if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix);
172
- $rest->setParameter('marker', $nextMarker);
173
- if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter);
174
-
175
- if (($response = $rest->getResponse(true)) == false || $response->code !== 200) break;
176
-
177
- if (isset($response->body, $response->body->Contents))
178
- foreach ($response->body->Contents as $c) {
179
- $results[(string)$c->Key] = array(
180
- 'name' => (string)$c->Key,
181
- 'time' => strtotime((string)$c->LastModified),
182
- 'size' => (int)$c->Size,
183
- 'hash' => substr((string)$c->ETag, 1, -1)
184
- );
185
- $nextMarker = (string)$c->Key;
186
- }
187
-
188
- if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes))
189
- foreach ($response->body->CommonPrefixes as $c)
190
- $results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix);
191
-
192
- if (isset($response->body, $response->body->NextMarker))
193
- $nextMarker = (string)$response->body->NextMarker;
194
-
195
- } while ($response !== false && (string)$response->body->IsTruncated == 'true');
196
-
197
- return $results;
198
- }
199
-
200
-
201
- /**
202
- * Put a bucket
203
- *
204
- * @param string $bucket Bucket name
205
- * @param constant $acl ACL flag
206
- * @param string $location Set as "EU" to create buckets hosted in Europe
207
- * @return boolean
208
- */
209
- public static function putBucket($bucket, $acl = self::ACL_PRIVATE, $location = false) {
210
- $rest = new S3Request('PUT', $bucket, '');
211
- $rest->setAmzHeader('x-amz-acl', $acl);
212
-
213
- if ($location !== false) {
214
- $dom = new DOMDocument;
215
- $createBucketConfiguration = $dom->createElement('CreateBucketConfiguration');
216
- $locationConstraint = $dom->createElement('LocationConstraint', strtoupper($location));
217
- $createBucketConfiguration->appendChild($locationConstraint);
218
- $dom->appendChild($createBucketConfiguration);
219
- $rest->data = $dom->saveXML();
220
- $rest->size = strlen($rest->data);
221
- $rest->setHeader('Content-Type', 'application/xml');
222
- }
223
- $rest = $rest->getResponse();
224
-
225
- if ($rest->error === false && $rest->code !== 200)
226
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
227
- if ($rest->error !== false) {
228
- trigger_error(sprintf("S3::putBucket({$bucket}, {$acl}, {$location}): [%s] %s",
229
- $rest->error['code'], $rest->error['message']), E_USER_WARNING);
230
- return false;
231
- }
232
- return true;
233
- }
234
-
235
-
236
- /**
237
- * Delete an empty bucket
238
- *
239
- * @param string $bucket Bucket name
240
- * @return boolean
241
- */
242
- public static function deleteBucket($bucket) {
243
- $rest = new S3Request('DELETE', $bucket);
244
- $rest = $rest->getResponse();
245
- if ($rest->error === false && $rest->code !== 204)
246
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
247
- if ($rest->error !== false) {
248
- trigger_error(sprintf("S3::deleteBucket({$bucket}): [%s] %s",
249
- $rest->error['code'], $rest->error['message']), E_USER_WARNING);
250
- return false;
251
- }
252
- return true;
253
- }
254
-
255
-
256
- /**
257
- * Create input info array for putObject()
258
- *
259
- * @param string $file Input file
260
- * @param mixed $md5sum Use MD5 hash (supply a string if you want to use your own)
261
- * @return array | false
262
- */
263
- public static function inputFile($file, $md5sum = true) {
264
- if (!file_exists($file) || !is_file($file) || !is_readable($file)) {
265
- trigger_error('S3::inputFile(): Unable to open input file: '.$file, E_USER_WARNING);
266
- return false;
267
- }
268
- return array('file' => $file, 'size' => filesize($file),
269
- 'md5sum' => $md5sum !== false ? (is_string($md5sum) ? $md5sum :
270
- base64_encode(md5_file($file, true))) : '');
271
- }
272
-
273
-
274
- /**
275
- * Create input array info for putObject() with a resource
276
- *
277
- * @param string $resource Input resource to read from
278
- * @param integer $bufferSize Input byte size
279
- * @param string $md5sum MD5 hash to send (optional)
280
- * @return array | false
281
- */
282
- public static function inputResource(&$resource, $bufferSize, $md5sum = '') {
283
- if (!is_resource($resource) || $bufferSize < 0) {
284
- trigger_error('S3::inputResource(): Invalid resource or buffer size', E_USER_WARNING);
285
- return false;
286
- }
287
- $input = array('size' => $bufferSize, 'md5sum' => $md5sum);
288
- $input['fp'] =& $resource;
289
- return $input;
290
- }
291
-
292
-
293
- /**
294
- * Put an object
295
- *
296
- * @param mixed $input Input data
297
- * @param string $bucket Bucket name
298
- * @param string $uri Object URI
299
- * @param constant $acl ACL constant
300
- * @param array $metaHeaders Array of x-amz-meta-* headers
301
- * @param array $requestHeaders Array of request headers or content type as a string
302
- * @return boolean
303
- */
304
- public static function putObject($input, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array()) {
305
- if ($input === false) return false;
306
- $rest = new S3Request('PUT', $bucket, $uri);
307
-
308
- if (is_string($input)) $input = array(
309
- 'data' => $input, 'size' => strlen($input),
310
- 'md5sum' => base64_encode(md5($input, true))
311
- );
312
-
313
- // Data
314
- if (isset($input['fp']))
315
- $rest->fp =& $input['fp'];
316
- elseif (isset($input['file']))
317
- $rest->fp = @fopen($input['file'], 'rb');
318
- elseif (isset($input['data']))
319
- $rest->data = $input['data'];
320
-
321
- // Content-Length (required)
322
- if (isset($input['size']) && $input['size'] >= 0)
323
- $rest->size = $input['size'];
324
- else {
325
- if (isset($input['file']))
326
- $rest->size = filesize($input['file']);
327
- elseif (isset($input['data']))
328
- $rest->size = strlen($input['data']);
329
- }
330
-
331
- // Custom request headers (Content-Type, Content-Disposition, Content-Encoding)
332
- if (is_array($requestHeaders))
333
- foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
334
- elseif (is_string($requestHeaders)) // Support for legacy contentType parameter
335
- $input['type'] = $requestHeaders;
336
-
337
- // Content-Type
338
- if (!isset($input['type'])) {
339
- if (isset($requestHeaders['Content-Type']))
340
- $input['type'] =& $requestHeaders['Content-Type'];
341
- elseif (isset($input['file']))
342
- $input['type'] = self::__getMimeType($input['file']);
343
- else
344
- $input['type'] = 'application/octet-stream';
345
- }
346
-
347
- // We need to post with Content-Length and Content-Type, MD5 is optional
348
- if ($rest->size >= 0 && ($rest->fp !== false || $rest->data !== false)) {
349
- $rest->setHeader('Content-Type', $input['type']);
350
- if (isset($input['md5sum'])) $rest->setHeader('Content-MD5', $input['md5sum']);
351
-
352
- $rest->setAmzHeader('x-amz-acl', $acl);
353
- foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
354
- $rest->getResponse();
355
- } else
356
- $rest->response->error = array('code' => 0, 'message' => 'Missing input parameters');
357
-
358
- if ($rest->response->error === false && $rest->response->code !== 200)
359
- $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
360
- if ($rest->response->error !== false) {
361
- trigger_error(sprintf("S3::putObject(): [%s] %s", $rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING);
362
- return false;
363
- }
364
- return true;
365
- }
366
-
367
-
368
- /**
369
- * Put an object from a file (legacy function)
370
- *
371
- * @param string $file Input file path
372
- * @param string $bucket Bucket name
373
- * @param string $uri Object URI
374
- * @param constant $acl ACL constant
375
- * @param array $metaHeaders Array of x-amz-meta-* headers
376
- * @param string $contentType Content type
377
- * @return boolean
378
- */
379
- public static function putObjectFile($file, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = null) {
380
- return self::putObject(self::inputFile($file), $bucket, $uri, $acl, $metaHeaders, $contentType);
381
- }
382
-
383
-
384
- /**
385
- * Put an object from a string (legacy function)
386
- *
387
- * @param string $string Input data
388
- * @param string $bucket Bucket name
389
- * @param string $uri Object URI
390
- * @param constant $acl ACL constant
391
- * @param array $metaHeaders Array of x-amz-meta-* headers
392
- * @param string $contentType Content type
393
- * @return boolean
394
- */
395
- public static function putObjectString($string, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = 'text/plain') {
396
- return self::putObject($string, $bucket, $uri, $acl, $metaHeaders, $contentType);
397
- }
398
-
399
-
400
- /**
401
- * Get an object
402
- *
403
- * @param string $bucket Bucket name
404
- * @param string $uri Object URI
405
- * @param mixed $saveTo Filename or resource to write to
406
- * @return mixed
407
- */
408
- public static function getObject($bucket, $uri, $saveTo = false) {
409
- $rest = new S3Request('GET', $bucket, $uri);
410
- if ($saveTo !== false) {
411
- if (is_resource($saveTo))
412
- $rest->fp =& $saveTo;
413
- else
414
- if (($rest->fp = @fopen($saveTo, 'wb')) !== false)
415
- $rest->file = realpath($saveTo);
416
- else
417
- $rest->response->error = array('code' => 0, 'message' => 'Unable to open save file for writing: '.$saveTo);
418
- }
419
- if ($rest->response->error === false) $rest->getResponse();
420
-
421
- if ($rest->response->error === false && $rest->response->code !== 200)
422
- $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
423
- if ($rest->response->error !== false) {
424
- trigger_error(sprintf("S3::getObject({$bucket}, {$uri}): [%s] %s",
425
- $rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING);
426
- return false;
427
- }
428
- return $rest->response;
429
- }
430
-
431
-
432
- /**
433
- * Get object information
434
- *
435
- * @param string $bucket Bucket name
436
- * @param string $uri Object URI
437
- * @param boolean $returnInfo Return response information
438
- * @return mixed | false
439
- */
440
- public static function getObjectInfo($bucket, $uri, $returnInfo = true) {
441
- $rest = new S3Request('HEAD', $bucket, $uri);
442
- $rest = $rest->getResponse();
443
- if ($rest->error === false && ($rest->code !== 200 && $rest->code !== 404))
444
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
445
- if ($rest->error !== false) {
446
- trigger_error(sprintf("S3::getObjectInfo({$bucket}, {$uri}): [%s] %s",
447
- $rest->error['code'], $rest->error['message']), E_USER_WARNING);
448
- return false;
449
- }
450
- return $rest->code == 200 ? $returnInfo ? $rest->headers : true : false;
451
- }
452
-
453
-
454
- /**
455
- * Copy an object
456
- *
457
- * @param string $bucket Source bucket name
458
- * @param string $uri Source object URI
459
- * @param string $bucket Destination bucket name
460
- * @param string $uri Destination object URI
461
- * @param constant $acl ACL constant
462
- * @param array $metaHeaders Optional array of x-amz-meta-* headers
463
- * @param array $requestHeaders Optional array of request headers (content type, disposition, etc.)
464
- * @return mixed | false
465
- */
466
- public static function copyObject($srcBucket, $srcUri, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array()) {
467
- $rest = new S3Request('PUT', $bucket, $uri);
468
- $rest->setHeader('Content-Length', 0);
469
- foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
470
- foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
471
- $rest->setAmzHeader('x-amz-acl', $acl);
472
- $rest->setAmzHeader('x-amz-copy-source', sprintf('/%s/%s', $srcBucket, $srcUri));
473
- if (sizeof($requestHeaders) > 0 || sizeof($metaHeaders) > 0)
474
- $rest->setAmzHeader('x-amz-metadata-directive', 'REPLACE');
475
- $rest = $rest->getResponse();
476
- if ($rest->error === false && $rest->code !== 200)
477
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
478
- if ($rest->error !== false) {
479
- trigger_error(sprintf("S3::copyObject({$srcBucket}, {$srcUri}, {$bucket}, {$uri}): [%s] %s",
480
- $rest->error['code'], $rest->error['message']), E_USER_WARNING);
481
- return false;
482
- }
483
- return isset($rest->body->LastModified, $rest->body->ETag) ? array(
484
- 'time' => strtotime((string)$rest->body->LastModified),
485
- 'hash' => substr((string)$rest->body->ETag, 1, -1)
486
- ) : false;
487
- }
488
-
489
-
490
- /**
491
- * Set logging for a bucket
492
- *
493
- * @param string $bucket Bucket name
494
- * @param string $targetBucket Target bucket (where logs are stored)
495
- * @param string $targetPrefix Log prefix (e,g; domain.com-)
496
- * @return boolean
497
- */
498
- public static function setBucketLogging($bucket, $targetBucket, $targetPrefix = null) {
499
- // The S3 log delivery group has to be added to the target bucket's ACP
500
- if ($targetBucket !== null && ($acp = self::getAccessControlPolicy($targetBucket, '')) !== false) {
501
- // Only add permissions to the target bucket when they do not exist
502
- $aclWriteSet = false;
503
- $aclReadSet = false;
504
- foreach ($acp['acl'] as $acl)
505
- if ($acl['type'] == 'Group' && $acl['uri'] == 'http://acs.amazonaws.com/groups/s3/LogDelivery') {
506
- if ($acl['permission'] == 'WRITE') $aclWriteSet = true;
507
- elseif ($acl['permission'] == 'READ_ACP') $aclReadSet = true;
508
- }
509
- if (!$aclWriteSet) $acp['acl'][] = array(
510
- 'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'WRITE'
511
- );
512
- if (!$aclReadSet) $acp['acl'][] = array(
513
- 'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'READ_ACP'
514
- );
515
- if (!$aclReadSet || !$aclWriteSet) self::setAccessControlPolicy($targetBucket, '', $acp);
516
- }
517
-
518
- $dom = new DOMDocument;
519
- $bucketLoggingStatus = $dom->createElement('BucketLoggingStatus');
520
- $bucketLoggingStatus->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/');
521
- if ($targetBucket !== null) {
522
- if ($targetPrefix == null) $targetPrefix = $bucket . '-';
523
- $loggingEnabled = $dom->createElement('LoggingEnabled');
524
- $loggingEnabled->appendChild($dom->createElement('TargetBucket', $targetBucket));
525
- $loggingEnabled->appendChild($dom->createElement('TargetPrefix', $targetPrefix));
526
- // TODO: Add TargetGrants?
527
- $bucketLoggingStatus->appendChild($loggingEnabled);
528
- }
529
- $dom->appendChild($bucketLoggingStatus);
530
-
531
- $rest = new S3Request('PUT', $bucket, '');
532
- $rest->setParameter('logging', null);
533
- $rest->data = $dom->saveXML();
534
- $rest->size = strlen($rest->data);
535
- $rest->setHeader('Content-Type', 'application/xml');
536
- $rest = $rest->getResponse();
537
- if ($rest->error === false && $rest->code !== 200)
538
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
539
- if ($rest->error !== false) {
540
- trigger_error(sprintf("S3::setBucketLogging({$bucket}, {$uri}): [%s] %s",
541
- $rest->error['code'], $rest->error['message']), E_USER_WARNING);
542
- return false;
543
- }
544
- return true;
545
- }
546
-
547
-
548
- /**
549
- * Get logging status for a bucket
550
- *
551
- * This will return false if logging is not enabled.
552
- * Note: To enable logging, you also need to grant write access to the log group
553
- *
554
- * @param string $bucket Bucket name
555
- * @return array | false
556
- */
557
- public static function getBucketLogging($bucket) {
558
- $rest = new S3Request('GET', $bucket, '');
559
- $rest->setParameter('logging', null);
560
- $rest = $rest->getResponse();
561
- if ($rest->error === false && $rest->code !== 200)
562
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
563
- if ($rest->error !== false) {
564
- trigger_error(sprintf("S3::getBucketLogging({$bucket}): [%s] %s",
565
- $rest->error['code'], $rest->error['message']), E_USER_WARNING);
566
- return false;
567
- }
568
- if (!isset($rest->body->LoggingEnabled)) return false; // No logging
569
- return array(
570
- 'targetBucket' => (string)$rest->body->LoggingEnabled->TargetBucket,
571
- 'targetPrefix' => (string)$rest->body->LoggingEnabled->TargetPrefix,
572
- );
573
- }
574
-
575
-
576
- /**
577
- * Disable bucket logging
578
- *
579
- * @param string $bucket Bucket name
580
- * @return boolean
581
- */
582
- public static function disableBucketLogging($bucket) {
583
- return self::setBucketLogging($bucket, null);
584
- }
585
-
586
-
587
- /**
588
- * Get a bucket's location
589
- *
590
- * @param string $bucket Bucket name
591
- * @return string | false
592
- */
593
- public static function getBucketLocation($bucket) {
594
- $rest = new S3Request('GET', $bucket, '');
595
- $rest->setParameter('location', null);
596
- $rest = $rest->getResponse();
597
- if ($rest->error === false && $rest->code !== 200)
598
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
599
- if ($rest->error !== false) {
600
- trigger_error(sprintf("S3::getBucketLocation({$bucket}): [%s] %s",
601
- $rest->error['code'], $rest->error['message']), E_USER_WARNING);
602
- return false;
603
- }
604
- return (isset($rest->body[0]) && (string)$rest->body[0] !== '') ? (string)$rest->body[0] : 'US';
605
- }
606
-
607
-
608
- /**
609
- * Set object or bucket Access Control Policy
610
- *
611
- * @param string $bucket Bucket name
612
- * @param string $uri Object URI
613
- * @param array $acp Access Control Policy Data (same as the data returned from getAccessControlPolicy)
614
- * @return boolean
615
- */
616
- public static function setAccessControlPolicy($bucket, $uri = '', $acp = array()) {
617
- $dom = new DOMDocument;
618
- $dom->formatOutput = true;
619
- $accessControlPolicy = $dom->createElement('AccessControlPolicy');
620
- $accessControlList = $dom->createElement('AccessControlList');
621
-
622
- // It seems the owner has to be passed along too
623
- $owner = $dom->createElement('Owner');
624
- $owner->appendChild($dom->createElement('ID', $acp['owner']['id']));
625
- $owner->appendChild($dom->createElement('DisplayName', $acp['owner']['name']));
626
- $accessControlPolicy->appendChild($owner);
627
-
628
- foreach ($acp['acl'] as $g) {
629
- $grant = $dom->createElement('Grant');
630
- $grantee = $dom->createElement('Grantee');
631
- $grantee->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
632
- if (isset($g['id'])) { // CanonicalUser (DisplayName is omitted)
633
- $grantee->setAttribute('xsi:type', 'CanonicalUser');
634
- $grantee->appendChild($dom->createElement('ID', $g['id']));
635
- } elseif (isset($g['email'])) { // AmazonCustomerByEmail
636
- $grantee->setAttribute('xsi:type', 'AmazonCustomerByEmail');
637
- $grantee->appendChild($dom->createElement('EmailAddress', $g['email']));
638
- } elseif ($g['type'] == 'Group') { // Group
639
- $grantee->setAttribute('xsi:type', 'Group');
640
- $grantee->appendChild($dom->createElement('URI', $g['uri']));
641
- }
642
- $grant->appendChild($grantee);
643
- $grant->appendChild($dom->createElement('Permission', $g['permission']));
644
- $accessControlList->appendChild($grant);
645
- }
646
-
647
- $accessControlPolicy->appendChild($accessControlList);
648
- $dom->appendChild($accessControlPolicy);
649
-
650
- $rest = new S3Request('PUT', $bucket, $uri);
651
- $rest->setParameter('acl', null);
652
- $rest->data = $dom->saveXML();
653
- $rest->size = strlen($rest->data);
654
- $rest->setHeader('Content-Type', 'application/xml');
655
- $rest = $rest->getResponse();
656
- if ($rest->error === false && $rest->code !== 200)
657
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
658
- if ($rest->error !== false) {
659
- trigger_error(sprintf("S3::setAccessControlPolicy({$bucket}, {$uri}): [%s] %s",
660
- $rest->error['code'], $rest->error['message']), E_USER_WARNING);
661
- return false;
662
- }
663
- return true;
664
- }
665
-
666
-
667
- /**
668
- * Get object or bucket Access Control Policy
669
- *
670
- * @param string $bucket Bucket name
671
- * @param string $uri Object URI
672
- * @return mixed | false
673
- */
674
- public static function getAccessControlPolicy($bucket, $uri = '') {
675
- $rest = new S3Request('GET', $bucket, $uri);
676
- $rest->setParameter('acl', null);
677
- $rest = $rest->getResponse();
678
- if ($rest->error === false && $rest->code !== 200)
679
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
680
- if ($rest->error !== false) {
681
- trigger_error(sprintf("S3::getAccessControlPolicy({$bucket}, {$uri}): [%s] %s",
682
- $rest->error['code'], $rest->error['message']), E_USER_WARNING);
683
- return false;
684
- }
685
-
686
- $acp = array();
687
- if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName)) {
688
- $acp['owner'] = array(
689
- 'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->DisplayName
690
- );
691
- }
692
- if (isset($rest->body->AccessControlList)) {
693
- $acp['acl'] = array();
694
- foreach ($rest->body->AccessControlList->Grant as $grant) {
695
- foreach ($grant->Grantee as $grantee) {
696
- if (isset($grantee->ID, $grantee->DisplayName)) // CanonicalUser
697
- $acp['acl'][] = array(
698
- 'type' => 'CanonicalUser',
699
- 'id' => (string)$grantee->ID,
700
- 'name' => (string)$grantee->DisplayName,
701
- 'permission' => (string)$grant->Permission
702
- );
703
- elseif (isset($grantee->EmailAddress)) // AmazonCustomerByEmail
704
- $acp['acl'][] = array(
705
- 'type' => 'AmazonCustomerByEmail',
706
- 'email' => (string)$grantee->EmailAddress,
707
- 'permission' => (string)$grant->Permission
708
- );
709
- elseif (isset($grantee->URI)) // Group
710
- $acp['acl'][] = array(
711
- 'type' => 'Group',
712
- 'uri' => (string)$grantee->URI,
713
- 'permission' => (string)$grant->Permission
714
- );
715
- else continue;
716
- }
717
- }
718
- }
719
- return $acp;
720
- }
721
-
722
-
723
- /**
724
- * Delete an object
725
- *
726
- * @param string $bucket Bucket name
727
- * @param string $uri Object URI
728
- * @return boolean
729
- */
730
- public static function deleteObject($bucket, $uri) {
731
- $rest = new S3Request('DELETE', $bucket, $uri);
732
- $rest = $rest->getResponse();
733
- if ($rest->error === false && $rest->code !== 204)
734
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
735
- if ($rest->error !== false) {
736
- trigger_error(sprintf("S3::deleteObject(): [%s] %s",
737
- $rest->error['code'], $rest->error['message']), E_USER_WARNING);
738
- return false;
739
- }
740
- return true;
741
- }
742
-
743
-
744
- /**
745
- * Get a query string authenticated URL
746
- *
747
- * @param string $bucket Bucket name
748
- * @param string $uri Object URI
749
- * @param integer $lifetime Lifetime in seconds
750
- * @param boolean $hostBucket Use the bucket name as the hostname
751
- * @param boolean $https Use HTTPS ($hostBucket should be false for SSL verification)
752
- * @return string
753
- */
754
- public static function getAuthenticatedURL($bucket, $uri, $lifetime, $hostBucket = false, $https = false) {
755
- $expires = time() + $lifetime;
756
- $uri = str_replace('%2F', '/', rawurlencode($uri)); // URI should be encoded (thanks Sean O'Dea)
757
- return sprintf(($https ? 'https' : 'http').'://%s/%s?AWSAccessKeyId=%s&Expires=%u&Signature=%s',
758
- $hostBucket ? $bucket : $bucket.'.s3.amazonaws.com', $uri, self::$__accessKey, $expires,
759
- urlencode(self::__getHash("GET\n\n\n{$expires}\n/{$bucket}/{$uri}")));
760
- }
761
-
762
- /**
763
- * Get upload POST parameters for form uploads
764
- *
765
- * @param string $bucket Bucket name
766
- * @param string $uriPrefix Object URI prefix
767
- * @param constant $acl ACL constant
768
- * @param integer $lifetime Lifetime in seconds
769
- * @param integer $maxFileSize Maximum filesize in bytes (default 5MB)
770
- * @param string $successRedirect Redirect URL or 200 / 201 status code
771
- * @param array $amzHeaders Array of x-amz-meta-* headers
772
- * @param array $headers Array of request headers or content type as a string
773
- * @param boolean $flashVars Includes additional "Filename" variable posted by Flash
774
- * @return object
775
- */
776
- public static function getHttpUploadPostParams($bucket, $uriPrefix = '', $acl = self::ACL_PRIVATE, $lifetime = 3600, $maxFileSize = 5242880, $successRedirect = "201", $amzHeaders = array(), $headers = array(), $flashVars = false) {
777
- // Create policy object
778
- $policy = new stdClass;
779
- $policy->expiration = gmdate('Y-m-d\TH:i:s\Z', (time() + $lifetime));
780
- $policy->conditions = array();
781
- $obj = new stdClass; $obj->bucket = $bucket; array_push($policy->conditions, $obj);
782
- $obj = new stdClass; $obj->acl = $acl; array_push($policy->conditions, $obj);
783
-
784
- $obj = new stdClass; // 200 for non-redirect uploads
785
- if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
786
- $obj->success_action_status = (string)$successRedirect;
787
- else // URL
788
- $obj->success_action_redirect = $successRedirect;
789
- array_push($policy->conditions, $obj);
790
-
791
- array_push($policy->conditions, array('starts-with', '$key', $uriPrefix));
792
- if ($flashVars) array_push($policy->conditions, array('starts-with', '$Filename', ''));
793
- foreach (array_keys($headers) as $headerKey)
794
- array_push($policy->conditions, array('starts-with', '$'.$headerKey, ''));
795
- foreach ($amzHeaders as $headerKey => $headerVal) {
796
- $obj = new stdClass; $obj->{$headerKey} = (string)$headerVal; array_push($policy->conditions, $obj);
797
- }
798
- array_push($policy->conditions, array('content-length-range', 0, $maxFileSize));
799
- $policy = base64_encode(str_replace('\/', '/', json_encode($policy)));
800
-
801
- // Create parameters
802
- $params = new stdClass;
803
- $params->AWSAccessKeyId = self::$__accessKey;
804
- $params->key = $uriPrefix.'${filename}';
805
- $params->acl = $acl;
806
- $params->policy = $policy; unset($policy);
807
- $params->signature = self::__getHash($params->policy);
808
- if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
809
- $params->success_action_status = (string)$successRedirect;
810
- else
811
- $params->success_action_redirect = $successRedirect;
812
- foreach ($headers as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
813
- foreach ($amzHeaders as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
814
- return $params;
815
- }
816
-
817
- /**
818
- * Create a CloudFront distribution
819
- *
820
- * @param string $bucket Bucket name
821
- * @param boolean $enabled Enabled (true/false)
822
- * @param array $cnames Array containing CNAME aliases
823
- * @param string $comment Use the bucket name as the hostname
824
- * @return array | false
825
- */
826
- public static function createDistribution($bucket, $enabled = true, $cnames = array(), $comment = '') {
827
- self::$useSSL = true; // CloudFront requires SSL
828
- $rest = new S3Request('POST', '', '2008-06-30/distribution', 'cloudfront.amazonaws.com');
829
- $rest->data = self::__getCloudFrontDistributionConfigXML($bucket.'.s3.amazonaws.com', $enabled, $comment, (string)microtime(true), $cnames);
830
- $rest->size = strlen($rest->data);
831
- $rest->setHeader('Content-Type', 'application/xml');
832
- $rest = self::__getCloudFrontResponse($rest);
833
-
834
- if ($rest->error === false && $rest->code !== 201)
835
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
836
- if ($rest->error !== false) {
837
- trigger_error(sprintf("S3::createDistribution({$bucket}, ".(int)$enabled.", '$comment'): [%s] %s",
838
- $rest->error['code'], $rest->error['message']), E_USER_WARNING);
839
- return false;
840
- } elseif ($rest->body instanceof SimpleXMLElement)
841
- return self::__parseCloudFrontDistributionConfig($rest->body);
842
- return false;
843
- }
844
-
845
-
846
- /**
847
- * Get CloudFront distribution info
848
- *
849
- * @param string $distributionId Distribution ID from listDistributions()
850
- * @return array | false
851
- */
852
- public static function getDistribution($distributionId) {
853
- self::$useSSL = true; // CloudFront requires SSL
854
- $rest = new S3Request('GET', '', '2008-06-30/distribution/'.$distributionId, 'cloudfront.amazonaws.com');
855
- $rest = self::__getCloudFrontResponse($rest);
856
-
857
- if ($rest->error === false && $rest->code !== 200)
858
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
859
- if ($rest->error !== false) {
860
- trigger_error(sprintf("S3::getDistribution($distributionId): [%s] %s",
861
- $rest->error['code'], $rest->error['message']), E_USER_WARNING);
862
- return false;
863
- } elseif ($rest->body instanceof SimpleXMLElement) {
864
- $dist = self::__parseCloudFrontDistributionConfig($rest->body);
865
- $dist['hash'] = $rest->headers['hash'];
866
- return $dist;
867
- }
868
- return false;
869
- }
870
-
871
-
872
- /**
873
- * Update a CloudFront distribution
874
- *
875
- * @param array $dist Distribution array info identical to output of getDistribution()
876
- * @return array | false
877
- */
878
- public static function updateDistribution($dist) {
879
- self::$useSSL = true; // CloudFront requires SSL
880
- $rest = new S3Request('PUT', '', '2008-06-30/distribution/'.$dist['id'].'/config', 'cloudfront.amazonaws.com');
881
- $rest->data = self::__getCloudFrontDistributionConfigXML($dist['origin'], $dist['enabled'], $dist['comment'], $dist['callerReference'], $dist['cnames']);
882
- $rest->size = strlen($rest->data);
883
- $rest->setHeader('If-Match', $dist['hash']);
884
- $rest = self::__getCloudFrontResponse($rest);
885
-
886
- if ($rest->error === false && $rest->code !== 200)
887
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
888
- if ($rest->error !== false) {
889
- trigger_error(sprintf("S3::updateDistribution({$dist['id']}, ".(int)$enabled.", '$comment'): [%s] %s",
890
- $rest->error['code'], $rest->error['message']), E_USER_WARNING);
891
- return false;
892
- } else {
893
- $dist = self::__parseCloudFrontDistributionConfig($rest->body);
894
- $dist['hash'] = $rest->headers['hash'];
895
- return $dist;
896
- }
897
- return false;
898
- }
899
-
900
-
901
- /**
902
- * Delete a CloudFront distribution
903
- *
904
- * @param array $dist Distribution array info identical to output of getDistribution()
905
- * @return boolean
906
- */
907
- public static function deleteDistribution($dist) {
908
- self::$useSSL = true; // CloudFront requires SSL
909
- $rest = new S3Request('DELETE', '', '2008-06-30/distribution/'.$dist['id'], 'cloudfront.amazonaws.com');
910
- $rest->setHeader('If-Match', $dist['hash']);
911
- $rest = self::__getCloudFrontResponse($rest);
912
-
913
- if ($rest->error === false && $rest->code !== 204)
914
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
915
- if ($rest->error !== false) {
916
- trigger_error(sprintf("S3::deleteDistribution({$dist['id']}): [%s] %s",
917
- $rest->error['code'], $rest->error['message']), E_USER_WARNING);
918
- return false;
919
- }
920
- return true;
921
- }
922
-
923
-
924
- /**
925
- * Get a list of CloudFront distributions
926
- *
927
- * @return array
928
- */
929
- public static function listDistributions() {
930
- self::$useSSL = true; // CloudFront requires SSL
931
- $rest = new S3Request('GET', '', '2008-06-30/distribution', 'cloudfront.amazonaws.com');
932
- $rest = self::__getCloudFrontResponse($rest);
933
-
934
- if ($rest->error === false && $rest->code !== 200)
935
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
936
- if ($rest->error !== false) {
937
- trigger_error(sprintf("S3::listDistributions(): [%s] %s",
938
- $rest->error['code'], $rest->error['message']), E_USER_WARNING);
939
- return false;
940
- } elseif ($rest->body instanceof SimpleXMLElement && isset($rest->body->DistributionSummary)) {
941
- $list = array();
942
- if (isset($rest->body->Marker, $rest->body->MaxItems, $rest->body->IsTruncated)) {
943
- //$info['marker'] = (string)$rest->body->Marker;
944
- //$info['maxItems'] = (int)$rest->body->MaxItems;
945
- //$info['isTruncated'] = (string)$rest->body->IsTruncated == 'true' ? true : false;
946
- }
947
- foreach ($rest->body->DistributionSummary as $summary) {
948
- $list[(string)$summary->Id] = self::__parseCloudFrontDistributionConfig($summary);
949
- }
950
- return $list;
951
- }
952
- return array();
953
- }
954
-
955
-
956
- /**
957
- * Get a DistributionConfig DOMDocument
958
- *
959
- * @internal Used to create XML in createDistribution() and updateDistribution()
960
- * @param string $bucket Origin bucket
961
- * @param boolean $enabled Enabled (true/false)
962
- * @param string $comment Comment to append
963
- * @param string $callerReference Caller reference
964
- * @param array $cnames Array of CNAME aliases
965
- * @return string
966
- */
967
- private static function __getCloudFrontDistributionConfigXML($bucket, $enabled, $comment, $callerReference = '0', $cnames = array()) {
968
- $dom = new DOMDocument('1.0', 'UTF-8');
969
- $dom->formatOutput = true;
970
- $distributionConfig = $dom->createElement('DistributionConfig');
971
- $distributionConfig->setAttribute('xmlns', 'http://cloudfront.amazonaws.com/doc/2008-06-30/');
972
- $distributionConfig->appendChild($dom->createElement('Origin', $bucket));
973
- $distributionConfig->appendChild($dom->createElement('CallerReference', $callerReference));
974
- foreach ($cnames as $cname)
975
- $distributionConfig->appendChild($dom->createElement('CNAME', $cname));
976
- if ($comment !== '') $distributionConfig->appendChild($dom->createElement('Comment', $comment));
977
- $distributionConfig->appendChild($dom->createElement('Enabled', $enabled ? 'true' : 'false'));
978
- $dom->appendChild($distributionConfig);
979
- return $dom->saveXML();
980
- }
981
-
982
-
983
- /**
984
- * Parse a CloudFront distribution config
985
- *
986
- * @internal Used to parse the CloudFront DistributionConfig node to an array
987
- * @param object &$node DOMNode
988
- * @return array
989
- */
990
- private static function __parseCloudFrontDistributionConfig(&$node) {
991
- $dist = array();
992
- if (isset($node->Id, $node->Status, $node->LastModifiedTime, $node->DomainName)) {
993
- $dist['id'] = (string)$node->Id;
994
- $dist['status'] = (string)$node->Status;
995
- $dist['time'] = strtotime((string)$node->LastModifiedTime);
996
- $dist['domain'] = (string)$node->DomainName;
997
- }
998
- if (isset($node->CallerReference))
999
- $dist['callerReference'] = (string)$node->CallerReference;
1000
- if (isset($node->Comment))
1001
- $dist['comment'] = (string)$node->Comment;
1002
- if (isset($node->Enabled, $node->Origin)) {
1003
- $dist['origin'] = (string)$node->Origin;
1004
- $dist['enabled'] = (string)$node->Enabled == 'true' ? true : false;
1005
- } elseif (isset($node->DistributionConfig)) {
1006
- $dist = array_merge($dist, self::__parseCloudFrontDistributionConfig($node->DistributionConfig));
1007
- }
1008
- if (isset($node->CNAME)) {
1009
- $dist['cnames'] = array();
1010
- foreach ($node->CNAME as $cname) $dist['cnames'][(string)$cname] = (string)$cname;
1011
- }
1012
- return $dist;
1013
- }
1014
-
1015
-
1016
- /**
1017
- * Grab CloudFront response
1018
- *
1019
- * @internal Used to parse the CloudFront S3Request::getResponse() output
1020
- * @param object &$rest S3Request instance
1021
- * @return object
1022
- */
1023
- private static function __getCloudFrontResponse(&$rest) {
1024
- $rest->getResponse();
1025
- if ($rest->response->error === false && isset($rest->response->body) &&
1026
- is_string($rest->response->body) && substr($rest->response->body, 0, 5) == '<?xml') {
1027
- $rest->response->body = simplexml_load_string($rest->response->body);
1028
- // Grab CloudFront errors
1029
- if (isset($rest->response->body->Error, $rest->response->body->Error->Code,
1030
- $rest->response->body->Error->Message)) {
1031
- $rest->response->error = array(
1032
- 'code' => (string)$rest->response->body->Error->Code,
1033
- 'message' => (string)$rest->response->body->Error->Message
1034
- );
1035
- unset($rest->response->body);
1036
- }
1037
- }
1038
- return $rest->response;
1039
- }
1040
-
1041
-
1042
- /**
1043
- * Get MIME type for file
1044
- *
1045
- * @internal Used to get mime types
1046
- * @param string &$file File path
1047
- * @return string
1048
- */
1049
- public static function __getMimeType(&$file) {
1050
- $type = false;
1051
- // Fileinfo documentation says fileinfo_open() will use the
1052
- // MAGIC env var for the magic file
1053
- if (extension_loaded('fileinfo') && isset($_ENV['MAGIC']) &&
1054
- ($finfo = finfo_open(FILEINFO_MIME, $_ENV['MAGIC'])) !== false) {
1055
- if (($type = finfo_file($finfo, $file)) !== false) {
1056
- // Remove the charset and grab the last content-type
1057
- $type = explode(' ', str_replace('; charset=', ';charset=', $type));
1058
- $type = array_pop($type);
1059
- $type = explode(';', $type);
1060
- $type = trim(array_shift($type));
1061
- }
1062
- finfo_close($finfo);
1063
-
1064
- // If anyone is still using mime_content_type()
1065
- } elseif (function_exists('mime_content_type'))
1066
- $type = trim(mime_content_type($file));
1067
-
1068
- if ($type !== false && strlen($type) > 0) return $type;
1069
-
1070
- // Otherwise do it the old fashioned way
1071
- static $exts = array(
1072
- 'jpg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png',
1073
- 'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'ico' => 'image/x-icon',
1074
- 'swf' => 'application/x-shockwave-flash', 'pdf' => 'application/pdf',
1075
- 'zip' => 'application/zip', 'gz' => 'application/x-gzip',
1076
- 'tar' => 'application/x-tar', 'bz' => 'application/x-bzip',
1077
- 'bz2' => 'application/x-bzip2', 'txt' => 'text/plain',
1078
- 'asc' => 'text/plain', 'htm' => 'text/html', 'html' => 'text/html',
1079
- 'css' => 'text/css', 'js' => 'text/javascript',
1080
- 'xml' => 'text/xml', 'xsl' => 'application/xsl+xml',
1081
- 'ogg' => 'application/ogg', 'mp3' => 'audio/mpeg', 'wav' => 'audio/x-wav',
1082
- 'avi' => 'video/x-msvideo', 'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg',
1083
- 'mov' => 'video/quicktime', 'flv' => 'video/x-flv', 'php' => 'text/x-php'
1084
- );
1085
- $ext = strtolower(pathInfo($file, PATHINFO_EXTENSION));
1086
- return isset($exts[$ext]) ? $exts[$ext] : 'application/octet-stream';
1087
- }
1088
-
1089
-
1090
- /**
1091
- * Generate the auth string: "AWS AccessKey:Signature"
1092
- *
1093
- * @internal Used by S3Request::getResponse()
1094
- * @param string $string String to sign
1095
- * @return string
1096
- */
1097
- public static function __getSignature($string) {
1098
- return 'AWS '.self::$__accessKey.':'.self::__getHash($string);
1099
- }
1100
-
1101
-
1102
- /**
1103
- * Creates a HMAC-SHA1 hash
1104
- *
1105
- * This uses the hash extension if loaded
1106
- *
1107
- * @internal Used by __getSignature()
1108
- * @param string $string String to sign
1109
- * @return string
1110
- */
1111
- private static function __getHash($string) {
1112
- return base64_encode(extension_loaded('hash') ?
1113
- hash_hmac('sha1', $string, self::$__secretKey, true) : pack('H*', sha1(
1114
- (str_pad(self::$__secretKey, 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) .
1115
- pack('H*', sha1((str_pad(self::$__secretKey, 64, chr(0x00)) ^
1116
- (str_repeat(chr(0x36), 64))) . $string)))));
1117
- }
1118
-
1119
- }
1120
-
1121
- final class S3Request {
1122
- private $verb, $bucket, $uri, $resource = '', $parameters = array(),
1123
- $amzHeaders = array(), $headers = array(
1124
- 'Host' => '', 'Date' => '', 'Content-MD5' => '', 'Content-Type' => ''
1125
- );
1126
- public $fp = false, $size = 0, $data = false, $response;
1127
-
1128
-
1129
- /**
1130
- * Constructor
1131
- *
1132
- * @param string $verb Verb
1133
- * @param string $bucket Bucket name
1134
- * @param string $uri Object URI
1135
- * @return mixed
1136
- */
1137
- function __construct($verb, $bucket = '', $uri = '', $defaultHost = 's3.amazonaws.com') {
1138
- $this->verb = $verb;
1139
- $this->bucket = strtolower($bucket);
1140
- $this->uri = $uri !== '' ? '/'.str_replace('%2F', '/', rawurlencode($uri)) : '/';
1141
-
1142
- if ($this->bucket !== '') {
1143
- $this->headers['Host'] = $this->bucket.'.'.$defaultHost;
1144
- $this->resource = '/'.$this->bucket.$this->uri;
1145
- } else {
1146
- $this->headers['Host'] = $defaultHost;
1147
- //$this->resource = strlen($this->uri) > 1 ? '/'.$this->bucket.$this->uri : $this->uri;
1148
- $this->resource = $this->uri;
1149
- }
1150
- $this->headers['Date'] = gmdate('D, d M Y H:i:s T');
1151
-
1152
- $this->response = new STDClass;
1153
- $this->response->error = false;
1154
- }
1155
-
1156
-
1157
- /**
1158
- * Set request parameter
1159
- *
1160
- * @param string $key Key
1161
- * @param string $value Value
1162
- * @return void
1163
- */
1164
- public function setParameter($key, $value) {
1165
- $this->parameters[$key] = $value;
1166
- }
1167
-
1168
-
1169
- /**
1170
- * Set request header
1171
- *
1172
- * @param string $key Key
1173
- * @param string $value Value
1174
- * @return void
1175
- */
1176
- public function setHeader($key, $value) {
1177
- $this->headers[$key] = $value;
1178
- }
1179
-
1180
-
1181
- /**
1182
- * Set x-amz-meta-* header
1183
- *
1184
- * @param string $key Key
1185
- * @param string $value Value
1186
- * @return void
1187
- */
1188
- public function setAmzHeader($key, $value) {
1189
- $this->amzHeaders[$key] = $value;
1190
- }
1191
-
1192
-
1193
- /**
1194
- * Get the S3 response
1195
- *
1196
- * @return object | false
1197
- */
1198
- public function getResponse() {
1199
- $query = '';
1200
- if (sizeof($this->parameters) > 0) {
1201
- $query = substr($this->uri, -1) !== '?' ? '?' : '&';
1202
- foreach ($this->parameters as $var => $value)
1203
- if ($value == null || $value == '') $query .= $var.'&';
1204
- // Parameters should be encoded (thanks Sean O'Dea)
1205
- else $query .= $var.'='.rawurlencode($value).'&';
1206
- $query = substr($query, 0, -1);
1207
- $this->uri .= $query;
1208
-
1209
- if (array_key_exists('acl', $this->parameters) ||
1210
- array_key_exists('location', $this->parameters) ||
1211
- array_key_exists('torrent', $this->parameters) ||
1212
- array_key_exists('logging', $this->parameters))
1213
- $this->resource .= $query;
1214
- }
1215
- $url = ((S3::$useSSL && extension_loaded('openssl')) ?
1216
- 'https://':'http://').$this->headers['Host'].$this->uri;
1217
- //var_dump($this->bucket, $this->uri, $this->resource, $url);
1218
-
1219
- // Basic setup
1220
- $curl = curl_init();
1221
- curl_setopt($curl, CURLOPT_USERAGENT, 'S3/php');
1222
-
1223
- if (S3::$useSSL) {
1224
- curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
1225
- curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 1);
1226
- }
1227
-
1228
- curl_setopt($curl, CURLOPT_URL, $url);
1229
-
1230
- // Headers
1231
- $headers = array(); $amz = array();
1232
- foreach ($this->amzHeaders as $header => $value)
1233
- if (strlen($value) > 0) $headers[] = $header.': '.$value;
1234
- foreach ($this->headers as $header => $value)
1235
- if (strlen($value) > 0) $headers[] = $header.': '.$value;
1236
-
1237
- // Collect AMZ headers for signature
1238
- foreach ($this->amzHeaders as $header => $value)
1239
- if (strlen($value) > 0) $amz[] = strtolower($header).':'.$value;
1240
-
1241
- // AMZ headers must be sorted
1242
- if (sizeof($amz) > 0) {
1243
- sort($amz);
1244
- $amz = "\n".implode("\n", $amz);
1245
- } else $amz = '';
1246
-
1247
- // Authorization string (CloudFront stringToSign should only contain a date)
1248
- $headers[] = 'Authorization: ' . S3::__getSignature(
1249
- $this->headers['Host'] == 'cloudfront.amazonaws.com' ? $this->headers['Date'] :
1250
- $this->verb."\n".$this->headers['Content-MD5']."\n".
1251
- $this->headers['Content-Type']."\n".$this->headers['Date'].$amz."\n".$this->resource
1252
- );
1253
-
1254
- curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
1255
- curl_setopt($curl, CURLOPT_HEADER, false);
1256
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
1257
- curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback'));
1258
- curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, '__responseHeaderCallback'));
1259
- curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
1260
-
1261
- // Request types
1262
- switch ($this->verb) {
1263
- case 'GET': break;
1264
- case 'PUT': case 'POST': // POST only used for CloudFront
1265
- if ($this->fp !== false) {
1266
- curl_setopt($curl, CURLOPT_PUT, true);
1267
- curl_setopt($curl, CURLOPT_INFILE, $this->fp);
1268
- if ($this->size >= 0)
1269
- curl_setopt($curl, CURLOPT_INFILESIZE, $this->size);
1270
- } elseif ($this->data !== false) {
1271
- curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
1272
- curl_setopt($curl, CURLOPT_POSTFIELDS, $this->data);
1273
- if ($this->size >= 0)
1274
- curl_setopt($curl, CURLOPT_BUFFERSIZE, $this->size);
1275
- } else
1276
- curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
1277
- break;
1278
- case 'HEAD':
1279
- curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'HEAD');
1280
- curl_setopt($curl, CURLOPT_NOBODY, true);
1281
- break;
1282
- case 'DELETE':
1283
- curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
1284
- break;
1285
- default: break;
1286
- }
1287
-
1288
- // Execute, grab errors
1289
- if (curl_exec($curl))
1290
- $this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
1291
- else
1292
- $this->response->error = array(
1293
- 'code' => curl_errno($curl),
1294
- 'message' => curl_error($curl),
1295
- 'resource' => $this->resource
1296
- );
1297
-
1298
- @curl_close($curl);
1299
-
1300
- // Parse body into XML
1301
- if ($this->response->error === false && isset($this->response->headers['type']) &&
1302
- $this->response->headers['type'] == 'application/xml' && isset($this->response->body)) {
1303
- $this->response->body = simplexml_load_string($this->response->body);
1304
-
1305
- // Grab S3 errors
1306
- if (!in_array($this->response->code, array(200, 204)) &&
1307
- isset($this->response->body->Code, $this->response->body->Message)) {
1308
- $this->response->error = array(
1309
- 'code' => (string)$this->response->body->Code,
1310
- 'message' => (string)$this->response->body->Message
1311
- );
1312
- if (isset($this->response->body->Resource))
1313
- $this->response->error['resource'] = (string)$this->response->body->Resource;
1314
- unset($this->response->body);
1315
- }
1316
- }
1317
-
1318
- // Clean up file resources
1319
- if ($this->fp !== false && is_resource($this->fp)) fclose($this->fp);
1320
-
1321
- return $this->response;
1322
- }
1323
-
1324
-
1325
- /**
1326
- * CURL write callback
1327
- *
1328
- * @param resource &$curl CURL resource
1329
- * @param string &$data Data
1330
- * @return integer
1331
- */
1332
- private function __responseWriteCallback(&$curl, &$data) {
1333
- if ($this->response->code == 200 && $this->fp !== false)
1334
- return fwrite($this->fp, $data);
1335
- else
1336
- $this->response->body .= $data;
1337
- return strlen($data);
1338
- }
1339
-
1340
-
1341
- /**
1342
- * CURL header callback
1343
- *
1344
- * @param resource &$curl CURL resource
1345
- * @param string &$data Data
1346
- * @return integer
1347
- */
1348
- private function __responseHeaderCallback(&$curl, &$data) {
1349
- if (($strlen = strlen($data)) <= 2) return $strlen;
1350
- if (substr($data, 0, 4) == 'HTTP')
1351
- $this->response->code = (int)substr($data, 9, 3);
1352
- else {
1353
- list($header, $value) = explode(': ', trim($data), 2);
1354
- if ($header == 'Last-Modified')
1355
- $this->response->headers['time'] = strtotime($value);
1356
- elseif ($header == 'Content-Length')
1357
- $this->response->headers['size'] = (int)$value;
1358
- elseif ($header == 'Content-Type')
1359
- $this->response->headers['type'] = $value;
1360
- elseif ($header == 'ETag')
1361
- $this->response->headers['hash'] = $value{0} == '"' ? substr($value, 1, -1) : $value;
1362
- elseif (preg_match('/^x-amz-meta-.*$/', $header))
1363
- $this->response->headers[$header] = is_numeric($value) ? (int)$value : $value;
1364
- }
1365
- return $strlen;
1366
- }
1367
-
1368
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/error.class.php DELETED
File without changes
classes/fileRecursion.php DELETED
@@ -1,477 +0,0 @@
1
- <?php
2
- /*
3
- * fileRecursion.php
4
- *
5
- * Copyright 2011 Ovidiu Liuta <info@thinkovi.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program; if not, write to the Free Software
19
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
- * MA 02110-1301, USA.
21
- */
22
-
23
-
24
- class fileRecursion{
25
-
26
- public static $debug = 0;
27
-
28
- private static $fp;
29
- private static $fpd;
30
- private static $fpe;
31
- private static $d_arr;
32
- private static $f_arr;
33
- private static $BACKUP_EXTENSIONS = array("tar", "zip", "tgz", "tar.gz");
34
- private static $INCL_EXTENSIONS = array("sql", "txt");
35
-
36
- public static $excludeList = array();
37
- public static $count;
38
- public static $TEMP_PERM = ".excl";
39
- public static $TEMP_D_ARR = "tmp/.dir";
40
- public static $TEMP_EXCL = "tmp/.excl";
41
- public static $TEMP_DIR = "/opt/lampp/htdocs/joomla/administrator/backups"; //exclude other backups
42
- public static $START_DIR = "/"; # Backups Start Dir
43
- public static $EXCLUDE_FILES_SIZE = -1; //disabled
44
- public static $TEMP_OVERSIZED_FILE = "tmp/.oversized_files";
45
-
46
-
47
-
48
- public static function setData($data) {
49
-
50
- self::$TEMP_PERM = $data['TEMP_PERM'];
51
- self::$TEMP_EXCL = $data['TEMP_EXCL'];
52
- self::$TEMP_D_ARR = $data['TEMP_D_ARR'];
53
- self::$TEMP_DIR = $data['TEMP_DIR'];
54
- self::$START_DIR = $data['START_DIR'];
55
- self::$EXCLUDE_FILES_SIZE = $data['EXCLUDE_FILES_SIZE'];
56
- self::$TEMP_OVERSIZED_FILE = $data['TEMP_OVERSIZED_FILE'];
57
- }
58
-
59
- /*
60
- * Init the recursion system
61
- * name: init
62
- * @param string $startDir Initial directory
63
- * @return
64
- */
65
- public static function init($startDir = ""){
66
-
67
- ///if(self::$init)
68
- //@unlink(PERM);
69
-
70
- if($startDir != ""){
71
- self::debug("Starting fresh, deleting ". self::$TEMP_PERM);
72
- @unlink(self::$TEMP_PERM);
73
- self::$d_arr[] = $startDir;
74
- }
75
- else{
76
- self::debug("Starting a new queue ". self::$TEMP_D_ARR);
77
- self::debug("Opened directory $dir");
78
- self::$d_arr = array_filter(explode("\n", file_get_contents(self::$TEMP_D_ARR)));
79
- }
80
-
81
- self::$fp = fopen(self::$TEMP_PERM, "a");
82
- self::$fpd = fopen(self::$TEMP_D_ARR, "w");
83
- self::$fpe = fopen(self::$TEMP_OVERSIZED_FILE, "a");
84
-
85
- self::initEXCL();
86
-
87
- if($startDir != ""){
88
- $inclFiles = self::getInclFiles();
89
- self::writePermFiles($inclFiles, "F", 1);
90
- }
91
-
92
- }
93
-
94
- /*
95
- * We close the stuff left opened
96
- * name: close
97
- * @param
98
- * @return
99
- */
100
- public static function close(){
101
-
102
- @fclose(self::$fp );
103
- @fclose(self::$fpd );
104
- @fclose(self::$fpe );
105
-
106
- }
107
-
108
- /*
109
- * Count the number of files saved in TEMP_PERM
110
- * name: countPermFiles
111
- * @param
112
- * @return array $return($num, $size) (number of files saved, size of total files)
113
- */
114
- public static function countPermFiles(){
115
-
116
- $handle = fopen(self::$TEMP_PERM, "r");
117
- $return['count'] = 0;
118
- $return['size'] = 0;
119
-
120
- while (($buffer = fgets($handle, 4096)) !== false) {
121
-
122
- $return['count']++;
123
-
124
- $data = @explode("|", str_replace("\n", "", $buffer));
125
- //if($data[3] == 'F')
126
- $return['size'] = $return['size'] + $data[2];
127
- }
128
- fclose($handle);
129
-
130
- return $return;
131
-
132
- }
133
-
134
- /*
135
- * Return the backup files from TEMP_DIR
136
- * name: getBackupFiles
137
- * @param
138
- * @return array $backupFiles files list
139
- */
140
- public static function getBackupFiles(){
141
-
142
- $files = scandir(self::$TEMP_DIR);
143
- $backupFiles = array();
144
-
145
- foreach($files as $file){
146
- $info = pathinfo(self::$TEMP_DIR."/".$file);
147
-
148
- if(in_array($info['extension'], self::$BACKUP_EXTENSIONS)){
149
- //self::debug("Found previous files: ".$info['basename']);
150
- $backupFiles[sizeof($backupFiles)] = $info['dirname']."/".$info['basename'];
151
- }
152
- }
153
-
154
- self::debug("Found previous backup: ".implode(".",$backupFiles));
155
- return $backupFiles;
156
-
157
- }
158
-
159
- /*
160
- * Return the force include files from TEMP_DIR
161
- * name: getInclFiles
162
- * @param
163
- * @return array $backupFiles files list
164
- */
165
- public static function getInclFiles(){
166
-
167
- self::debug("Reading the ".self::$TEMP_DIR ." for inclusion files");
168
- if(self::isNotExcluded(self::$TEMP_DIR))
169
- return;
170
-
171
- $files = scandir(self::$TEMP_DIR);
172
- $backupFiles = array();
173
-
174
- foreach($files as $file){
175
- $info = pathinfo(self::$TEMP_DIR."/".$file);
176
-
177
- if(in_array($info['extension'], self::$INCL_EXTENSIONS)){
178
- self::debug("Found previous files: ".$info['basename']);
179
- $backupFiles[sizeof($backupFiles)] = $info['dirname']."/".$info['basename'];
180
- }
181
- }
182
-
183
- self::debug("Found previous backup: ".implode(".",$backupFiles));
184
- return $backupFiles;
185
-
186
- }
187
-
188
- /*
189
- * Initialize the excluded file list
190
- * name: initEXCL
191
- * @param
192
- * @return
193
- */
194
- public static function initEXCL(){
195
-
196
- //adding files from the TEMP_EXCL file
197
- if(file_exists(self::$TEMP_EXCL))
198
- self::$excludeList = array_filter(explode("\n", file_get_contents(self::$TEMP_EXCL)));
199
-
200
- //excluding existing backup archives
201
- $excludeBackupFiles = self::getBackupFiles();
202
- foreach($excludeBackupFiles as $file){
203
- self::$excludeList[sizeof(self::$excludeList)] = $file;
204
- }
205
- //self::debug(self::$TEMP_EXCL);
206
- self::debug("Excluded list:".implode("\n", self::$excludeList));
207
-
208
- }
209
-
210
- /*
211
- * Check if we processed the full directory
212
- * name: isQueueFinished
213
- * @param
214
- * @return
215
- */
216
- public static function isQueueFinished(){
217
-
218
- $return = true;
219
-
220
- if(sizeof(self::$d_arr) != 0){
221
- $return = false;
222
- }
223
-
224
- return $return;
225
-
226
- }
227
-
228
- /*
229
- * End recursion file system
230
- * name: end
231
- * @param
232
- * @return
233
- */
234
- public static function end(){
235
-
236
- fclose(self::$fp);
237
- fclose(self::$fpd);
238
-
239
- self::debug("All done, existing... ");
240
-
241
- }
242
-
243
- /*
244
- * Send debug messages
245
- *
246
- * name: debug
247
- * @param string $message
248
- * @return
249
- */
250
- public static function debug($message, $force=0){
251
-
252
- if((self::$debug) || ($force)){
253
- print($message."<br />\n");
254
- }
255
-
256
- return;
257
-
258
- }
259
-
260
- /*
261
- * Start the recursion
262
- *
263
- * name: start
264
- * @param
265
- * @return
266
- */
267
- public static function start(){
268
-
269
- self::debug("Start ");
270
- foreach(self::$d_arr as $key=>$startdir)
271
- if($startdir != ""){
272
-
273
- self::debug("Processing ". $startdir);
274
-
275
- unset(self::$d_arr[$key]);
276
-
277
- if(self::isNotExcluded($startdir)){
278
- self::writePermFile($startdir, "D");
279
- self::$count++;
280
- self::getDirectories($startdir);
281
- }else{
282
-
283
- self::debug("$startdir excluded");
284
- }
285
-
286
- }
287
-
288
- self::$d_arr = array_filter(self::$d_arr);
289
- if(sizeof(self::$d_arr) != 0){
290
-
291
- $data = implode("\n", self::$d_arr);
292
- fwrite(self::$fpd, $data);
293
- self::debug("Found $data");
294
- self::$count++;
295
- }
296
- else{
297
- self::debug("Queue finished");
298
- }
299
-
300
- }
301
-
302
- /*
303
- * Check if the file is not in the exclusion list
304
- *
305
- * name: isNotExcluded
306
- * @param string $file System File
307
- * @return
308
- */
309
- public static function isNotExcluded($file){
310
-
311
- $excluded = true;
312
-
313
- foreach(self::$excludeList as $exclFile){
314
- $mfile = str_replace(array("/","\\","\n","\r"), array("",""), trim($file));
315
- $mexclFile = str_replace(array("/","\\","\n","\r"), array("",""), ($exclFile));
316
-
317
- self::debug("exclude:".$mfile."--".$mexclFile);
318
- $string = stristr($mfile, $mexclFile);
319
- if($string != ""){
320
- $excluded = false;
321
- self::debug("$file excluded");
322
- return $excluded;
323
- }else
324
- self::debug("$file not excluded # $string");
325
- }
326
-
327
- return $excluded;
328
-
329
- }
330
-
331
-
332
- /*
333
- * Return the size of a file, tries to overcome the 4GB php filesize limitation
334
- *
335
- * name: getFileSize
336
- * @param string $file file path
337
- * @return string $sizeInBytes return the size in bytes of the file, PHP only returns values up to 4GB
338
- */
339
- public static function getFileSize($file){
340
-
341
- $sizeInBytes = sprintf("%u", filesize($file));
342
- if ((!$sizeInBytes) and (function_exists("exec"))){
343
- $command = "ls -l \"$file\" | cut -d \" \" -f 5";
344
- $sizeInBytes = @exec($command);
345
- }
346
-
347
- return $sizeInBytes;
348
-
349
- }
350
-
351
- public static function getOverLimitFiles(){
352
- @fclose(self::$fpe);
353
- $files = explode("\n", file_get_contents(self::$TEMP_OVERSIZED_FILE));
354
-
355
- return array_diff($files, array(""));
356
- }
357
-
358
- public static function writeExcludedFile($file, $fsize = 0){
359
-
360
- self::debug("Excluded $file from list as it is bigger than ". self::$EXCLUDE_FILES_SIZE." MB!!!");
361
-
362
- if(self::$fpe){
363
- fwrite(self::$fpe, $file."\t(".$fsize." bytes)\n");
364
- }
365
-
366
- }
367
-
368
- /*
369
- * Writing file details(path, permissions, size) to file
370
- *
371
- * name: writePermFile
372
- * @param file handler $fp file handler of where to write
373
- * @param string $file File to write
374
- * @return
375
- */
376
- public static function writePermFile($file, $append = "", $force = 0){
377
-
378
- $file = realpath($file);
379
-
380
- if((self::isNotExcluded($file)) or ($force)){
381
- // we check if file is not excluded
382
- $fperm = substr(sprintf('%o', @fileperms($file)), -4);
383
- $fsize = self::getFileSize($file);
384
- $sizeLimit = (self::$EXCLUDE_FILES_SIZE)*1024*1024; // we limit by MB
385
-
386
- if(intval(self::$EXCLUDE_FILES_SIZE) > -1){
387
- if(($fsize > $sizeLimit) and is_file($file)){
388
- //we check if file is larger than $EXCLUDE_FILES_SIZE
389
- self::writeExcludedFile($file, $fsize);
390
- return;
391
- }
392
- }
393
-
394
- $file = str_replace(self::$START_DIR, "", str_replace("\\","/", $file));
395
-
396
- fwrite(self::$fp, $file."|".$fperm."|".$fsize."|".$append."\n");
397
- self::debug($file ." added to list");
398
- }
399
- else{
400
- self::debug("$file excluded");
401
- }
402
- return;
403
- }
404
-
405
- /*
406
- * Handle an array of files
407
- *
408
- * name: writePermFiles
409
- * @param file handler $fp File handler of where to write
410
- * @param array $files The array of files
411
- * @return
412
- */
413
- public static function writePermFiles($files, $append = "", $force = 0){
414
-
415
- if(is_array($files)){
416
- foreach($files as $file){
417
- self::writePermFile($file, $append, $force);
418
- }
419
- }else{
420
- self::writePermFile($files, $append, $force);
421
- }
422
- return;
423
- }
424
-
425
- /*
426
- * Recurse the directory $dir and get all files in it
427
- *
428
- * name: getDirectories
429
- * @param string $dir Directory to scan
430
- * @param array &f_arr File list array
431
- * @param array &fd_arr Directory list array
432
- * @return
433
- */
434
- public static function getDirectories($dir){
435
- global $_CONFIG;
436
-
437
- self::debug("Processing $dir");
438
-
439
- if(!stristr(realpath($dir), realpath($_CONFIG['backup_path']))){
440
-
441
- return false;
442
- }
443
-
444
- if(is_dir($dir)) {
445
- self::debug("OK directory $dir");
446
- if($dh = opendir($dir)) {
447
-
448
- self::debug("Opened directory $dir");
449
-
450
- while(($file = readdir($dh)) !== false) {
451
- if($file != "." && $file != "..") {
452
-
453
- $cfile = $dir."/".$file;
454
-
455
- if(@is_dir($cfile))
456
- self::$d_arr[] = $cfile;
457
- else{
458
-
459
- self::writePermFile($cfile, "F");
460
- self::$count++;
461
- }
462
- }
463
- }
464
- @closedir($dh);
465
- }else{
466
- self::debug("Unable to open $dir");
467
- }
468
- }else{
469
- self::debug($dir." is not directory");
470
- }
471
-
472
-
473
- return;
474
-
475
- }
476
-
477
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/index.html DELETED
File without changes
classes/main.class.php DELETED
@@ -1,116 +0,0 @@
1
- <?php
2
- /*
3
- * main.class.php
4
- *
5
- * Copyright 2011 Ovidiu Liuta <info@thinkovi.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program; if not, write to the Free Software
19
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
- * MA 02110-1301, USA.
21
- */
22
-
23
- class Main{
24
-
25
- public static $_CONFIG;
26
-
27
-
28
- /*
29
- *
30
- * name: init
31
- * @param
32
- * @return
33
- */
34
- public static function init($_CONFIG){
35
- self::$_CONFIG = $_CONFIG;
36
- }
37
-
38
- /*
39
- *
40
- * name: unknown
41
- * @param
42
- * @return
43
- */
44
- public static function initBackup($backupName){
45
-
46
- self::generateBackupName($backupName);
47
-
48
- }
49
-
50
- /*
51
- * Will cleanup the temporary directory
52
- *
53
- * name: cleanUp
54
- * @param
55
- * @return
56
- */
57
- public static function cleanUp(){
58
-
59
- $dir = self::$_CONFIG['temp_dir'] ;
60
-
61
- if (@is_dir($dir)) {
62
- if ($dh = @opendir($dir)) {
63
- while (($file = @readdir($dh)) !== false) {
64
- if(($file!=".") and ($file!="..")){
65
- if(($file[0] == ".") and ($file[0] != ".htaccess"))
66
- //cleanup temp files
67
- @unlink($dir."/".$file);
68
- elseif(strstr( $file, "-sql.sql") != "")
69
- //cleanup sql files
70
- @unlink($dir."/".$file);
71
-
72
- }
73
- }
74
- closedir($dh);
75
- }
76
- }
77
-
78
- }
79
-
80
- public static function generateBackupName($backupName, $backupDatabase = 0, $dbbackup_drop = 0){
81
-
82
- $domainname = $_SERVER['HTTP_HOST'];
83
-
84
- if ((self::$_CONFIG['mem']) && ($_CONFIG['backup_refresh'])) {
85
- $f_ext = '.tar';
86
- $_CONFIG['tarcompress'] = '';
87
- } elseif (self::$_CONFIG['backup_compress']) {
88
- $f_ext = '.tgz';
89
- $_CONFIG['tarcompress'] = 'z';
90
- } else {
91
- $f_ext = '.tar';
92
- $_CONFIG['tarcompress'] = '';
93
- }
94
-
95
-
96
- if ($backupName == "") {
97
- if ($backupDatabase == 1) {
98
- if ($_REQUEST['dbbackup_drop']) {
99
- $filename = 'backup_' . date("Y-m-d_H-i") . '_' . $domainname . '-sql-drop' . $f_ext;
100
- } else {
101
- $filename = 'backup_' . date("Y-m-d_H-i") . '_' . $domainname . '-sql-nodrop' . $f_ext;
102
- }
103
- } else
104
- $filename = 'backup_' . date("Y-m-d_H-i") . '_' . $domainname . '-nosql' . $f_ext;
105
- } else {
106
- $filename = $_REQUEST['bname'] . $f_ext;
107
- }
108
-
109
- return $filename;
110
-
111
- }
112
-
113
- }
114
-
115
-
116
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/mysqlBackup.class.php DELETED
@@ -1,480 +0,0 @@
1
- <?php
2
- /*
3
- * mysqlBackup.class.php
4
- *
5
- * Copyright 2014 Ovidiu Liuta <info@thinkovi.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program; if not, write to the Free Software
19
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
- * MA 02110-1301, USA.
21
- */
22
-
23
-
24
- class DB{
25
-
26
- public static $dbHostname = "localhost";
27
- public static $dbUsername = "root";
28
- public static $dbPassword = "";
29
- public static $dbDatabase = "";
30
- public static $excludedTables = array();
31
-
32
- public static $debug = 0;
33
- public static $recordsPerSession = 10000;
34
- public static $dbCompatibility = "";
35
- public static $dbDropSyntax = 0;
36
- public static $countRecords = 0;
37
-
38
- private static $link;
39
- private static $db_selected;
40
-
41
- public static $TEMP_DBPROCESS_FILE = "tmp/.database";
42
- public static $TEMP_DUMP_FILE = "tmp/database-sql.sql";
43
-
44
- /*
45
- *Return any error
46
- *
47
- * name: error
48
- * @param string $message
49
- * @return
50
- */
51
- public function error($message, $force = ""){
52
-
53
- $return = "";
54
- $date = date("M j, Y @ H:i:s");
55
-
56
- if((self::$debug) && ($force)){
57
- //we have debug message as force is 1
58
- printf("Debug(%s) - %s \n", $date, $message);
59
- }
60
-
61
- if(!$force){
62
- //we have an error message
63
- printf("Error(%s) - %s \n", $date, $message);
64
- }
65
-
66
- return;
67
-
68
- }
69
-
70
- /*
71
- * Initialize the database connection
72
- *
73
- * name: init
74
- * @param array $data {'dbHostname', 'dbUsername', 'dbPassword', 'dbDatabase'}
75
- * @return
76
- */
77
- public function init($data, $start = 0){
78
-
79
- self::$dbHostname = $data['dbHostname'];
80
- self::$dbUsername = $data['dbUsername'];
81
- self::$dbPassword = $data['dbPassword'];
82
- self::$dbDatabase = $data['dbDatabase'];
83
- self::$excludedTables = $data['excludedTables'];
84
- self::$TEMP_DBPROCESS_FILE = $data['TEMP_DBPROCESS_FILE'];
85
- self::$TEMP_DUMP_FILE = $data['TEMP_DUMP_FILE'];
86
- self::$recordsPerSession = $data['recordsPerSession'];
87
- self::$dbCompatibility = $data['dbCompatibility'];
88
- self::$dbDropSyntax = $data['dbDropSyntax'];
89
-
90
- self::connect();
91
- self::headers();
92
-
93
- if($start){
94
- @unlink(self::$TEMP_DBPROCESS_FILE);
95
- }
96
-
97
- }
98
-
99
- /*
100
- * Connect to the database
101
- *
102
- * name: connect
103
- * @param
104
- * @return
105
- */
106
- public function connect(){
107
-
108
- self::$link = new mysqli(self::$dbHostname, self::$dbUsername, self::$dbPassword, self::$dbDatabase);
109
- if (mysqli_connect_errno()) {
110
- printf("Connect failed: %s\n", mysqli_connect_error());
111
- exit();
112
- }
113
-
114
- }
115
-
116
- /*
117
- * Disconnect from the database
118
- *
119
- * name: disconnect
120
- * @param
121
- * @return
122
- */
123
- public function disconnect(){
124
-
125
- //mysqli_close(self::$link);
126
-
127
- }
128
-
129
- /*
130
- * Send some special headers after the connection is initialized
131
- *
132
- * name: headers
133
- * @param
134
- * @return
135
- */
136
- private function headers(){
137
-
138
- self::query("SET SQL_QUOTE_SHOW_CREATE=1;");
139
- self::query("SET sql_mode = 0;");
140
- mysqli_set_charset(self::$link, 'utf8');
141
- if (self::$dbCompatibility)
142
- self::query("SET sql_mode=" . self::$dbCompatibility . ";");
143
-
144
- }
145
-
146
- /*
147
- * Run a mysql qeury
148
- *
149
- * name: query
150
- * @param string $query Query to run
151
- * @return $result or false
152
- */
153
- public function query($query){
154
-
155
- $result = mysqli_query(self::$link, $query.";");
156
- self::error($query, 1);
157
-
158
- if (!$result) {
159
- self::error('Invalid query: ' . mysqli_error(self::$link));
160
- return false;
161
- }
162
- else{
163
- return $result;
164
- }
165
-
166
- }
167
-
168
-
169
- /*
170
- * Returns an array of tables from a database and mark $2excluded ones
171
- *
172
- * name: lisTables
173
- * @param array $excluded array of tables to mark as excluded
174
- * @return array $tablesList
175
- */
176
- public function listTables($excluded){
177
-
178
- $tablesList = array("");
179
- $inc = 0;
180
-
181
- $result = self::query("SHOW TABLES in `".self::$dbDatabase."`");
182
-
183
- while ($row = mysqli_fetch_array( $result)){
184
- $tablesList[$inc]['table'] = $row[0];
185
-
186
- if(is_array($excluded))
187
- if( in_array($row[0], $excluded) )
188
- $tablesList[$inc]['excluded'] = 1;
189
- $inc++;
190
- }
191
-
192
- return $tablesList;
193
-
194
- }
195
-
196
- public function writeTempFile(){
197
-
198
- $tables = self::listTables(self::$excludedTables);
199
-
200
- $fp = fopen(self::$TEMP_DBPROCESS_FILE, "a");
201
-
202
- if($fp){
203
-
204
- fwrite($fp, sprintf("###newdump###\t%s\t%s\n", self::$dbDatabase, self::$TEMP_DUMP_FILE));
205
-
206
- // write this to the class and write to $TEMP_DBPROCESS_FILE file as database.table records
207
- foreach($tables as $key=>$table) if($table!= ""){
208
-
209
- $tables[$key]['records'] = 0;
210
-
211
- if(!$tables[$key]['excluded'])
212
- $tables[$key]['records'] = self::countRecords($tables[$key]['table']);
213
-
214
- $tmp = sprintf("`%s`.`%s`\t%s\t%s\n", self::$dbDatabase, $tables[$key]['table'], $tables[$key]['records'], $tables[$key]['excluded']);
215
- fwrite($fp, $tmp);
216
- }
217
-
218
- fwrite($fp, "###enddump###\n");
219
- fclose($fp);
220
- }
221
- else{
222
- self::error("Unable to open for writing file ".self::$TEMP_DBPROCESS_FILE);
223
- }
224
-
225
- }
226
-
227
- /*
228
- * Returns the number of records from a table
229
- *
230
- * name: countRecords
231
- * @param string $table - the source table
232
- * @return int $count
233
- */
234
- public function countRecords($table){
235
-
236
- $table = "`".self::$dbDatabase."`.`$table`";
237
-
238
- $result = self::query("SELECT count(*) FROM $table;");
239
-
240
- $count = mysqli_fetch_row($result);
241
-
242
- return intval($count[0]) ;// not max limit on 32 bit systems 2147483647; on 64 bit 9223372036854775807
243
-
244
- }
245
-
246
- /*
247
- * Processing the mysql backup incrementally
248
- *
249
- * name: processIncremental
250
- * @param
251
- * int $startAtLine - at which line from the perm.txt file to start reading
252
- * int startAtRecord - at which record to start from the table found at $startAtLine
253
- * string $dumpfie - where to save the data
254
- * string $dbCompatibility - MYSQL40, MYSQ32, none=default
255
- * int $dbDropSyntax - check if the DROP TABLE syntax should be added
256
- * @return array $return
257
- */
258
- public function processIncremental($startAtLine= 0, $startAtRecord = 0, $dumpfile = "", $dbCompatibility= "", $dbDropSyntax= ""){
259
-
260
- $count = 0;
261
- $return = array();
262
-
263
- self::error("Starting new process at line $startAtLine from record $startAtRecord", 1);
264
-
265
- $fp = fopen(self::$TEMP_DBPROCESS_FILE, "r");
266
- if($fp){
267
-
268
- while (($buffer = fgets($fp, 4096)) !== false){
269
-
270
- if($count == $startAtLine){
271
-
272
- $buffer = str_replace("\n", "", $buffer);
273
- $tableInfo =explode("\t", $buffer);
274
- //print_r($tableInfo);
275
- if($tableInfo[0] == "###newdump###"){
276
- // we create a new mysql dump file
277
- if($dumpfile != ""){
278
- // we finished a previous one and write the footers
279
- $return['dumpsize'] = self::dataFooters($dumpfile);
280
- }
281
-
282
- $dump = fopen($tableInfo[2], "w");
283
- fwrite($dump, self::dataHeaders($tableInfo[1]));
284
- $startAtLine++;
285
- fclose($dump);
286
- $dumpfile = $tableInfo[2];
287
-
288
- $return['newDump'] = 1;
289
- //break;
290
- }
291
- else{
292
- //we export the table
293
- if($tableInfo[0] == "###enddump###")
294
- $return['endDump'] = 1;
295
-
296
- $fd = fopen($dumpfile, "a");
297
-
298
- if($fd){
299
-
300
- $next = $startAtRecord + self::$recordsPerSession;
301
- // $tableInfo[1] number of records in the table
302
- $table = explode("`.`", $tableInfo[0]);
303
- $tableName = str_replace("`", "", $table[1]);
304
- $databaseName = str_replace("`", "", $table[0]);
305
-
306
- //return something to the browser
307
- $return['tableName'] = $tableName;
308
- $return['databaseName'] = $databaseName;
309
- $return['totalRecords'] = $tableInfo[1];
310
-
311
- //if(intval($return['totalRecords']) != 0)
312
- if(trim($tableName) !="" and !$tableInfo[2])
313
- self::exportTable($databaseName, $tableName, $startAtRecord, self::$recordsPerSession, $fd);
314
-
315
- fclose($fd);
316
-
317
- if($next > $tableInfo[1]) //we finished loading the records for next sessions, will go to the new record
318
- {
319
- $startAtLine ++;
320
- $startAtRecord = 0;
321
- }else{
322
- $startAtRecord = $startAtRecord + self::$recordsPerSession;
323
- }
324
-
325
- //$return['dbCompatibility'] = self::$dbCompatibility;
326
- //$return['dbDropSyntax'] = self::$dbDropSyntax;
327
- $return['startAtLine'] = $startAtLine;
328
- $return['startAtRecord'] = $startAtRecord;
329
- $return['dumpfile'] = $dumpfile;
330
-
331
- return $return;
332
- break;
333
-
334
- }else{
335
- self::error("Unable to open for writing file $dumpfile");
336
- }
337
- }
338
-
339
- }
340
-
341
- $count++;
342
-
343
-
344
- }
345
-
346
- //while is finished, lets go home...
347
- if($dumpfile != ""){
348
- // we finished a previous one and write the footers
349
- $return['dumpsize'] = self::dataFooters($dumpfile);
350
- }
351
- $return['finished'] = 1;
352
- $return['startAtLine'] = $startAtLine;
353
-
354
- return $return;
355
-
356
- }else{
357
- self::error("Unable to open for reading file ".self::$TEMP_DBPROCESS_FILE);
358
- }
359
-
360
-
361
- }
362
-
363
-
364
- /*
365
- * Exporting the table records
366
- *
367
- * name: exportTable
368
- * @param
369
- * string $databaseName - database name of the table
370
- * string tableName - table name
371
- * int $start - where to start from
372
- * int $limit - how many records
373
- * handler $fd - file handler where to write the records
374
- * @return
375
- */
376
- public function exportTable($databaseName, $tableName, $start, $limit, $fd){
377
-
378
- if($start == 0)
379
- self::dumpStructure($databaseName, $tableName, $fd);
380
-
381
- $start = intval($start);
382
- $limit = intval($limit);
383
- //exporting the table content now
384
-
385
- $result = self::query("SELECT * from `$databaseName`.`$tableName` Limit $start, $limit ;");
386
- if($result){
387
- while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)){
388
-
389
- fwrite($fd, "INSERT INTO `$tableName` VALUES (");
390
- $arr = $row;
391
- $buffer = "";
392
- self::$countRecords++;
393
-
394
- foreach ($arr as $key => $value) {
395
- $value = mysqli_real_escape_string(self::$link, $value);
396
- $buffer .= "'".$value."', ";
397
- }
398
- $buffer = rtrim($buffer, ', ') . ");\n";
399
- fwrite($fd, $buffer);
400
- unset($buffer);
401
-
402
- }
403
- }
404
-
405
- }
406
-
407
- public function dumpStructure($databaseName, $tableName ,$fd){
408
-
409
- fwrite($fd, "\n#\n# Table structure for table `$tableName`\n#\n\n");
410
-
411
- if (self::$dbDropSyntax)
412
- fwrite($fd, "\nDROP table IF EXISTS `$tableName`;\n");
413
-
414
- $result = self::query("SHOW CREATE table `$databaseName`.`$tableName`;");
415
- if($result){
416
- $row = mysqli_fetch_row( $result);
417
- fwrite($fd, $row[1].";\n");
418
- }
419
-
420
- fwrite($fd, "\n#\n# End Structure for table `$tableName`\n#\n\n");
421
- fwrite($fd, "#\n# Dumping data for table `$tableName`\n#\n\n");
422
- return;
423
-
424
- }
425
-
426
- public function dataFooters($dumpfile){
427
-
428
- // we finished the dump file, not return the size of it
429
- $ftemp = fopen($dumpfile, "a");
430
- if($ftemp){
431
- fwrite($ftemp, "\n#\n# Finished at: ".date("M j, Y \a\\t H:i")."\n#");
432
- fclose($ftemp);
433
- }else{
434
- self::error("Unable to open file $ftemp for writing");
435
- }
436
-
437
- return sprintf("%u", filesize($dumpfile));
438
-
439
- }
440
-
441
- public function resetcountRecords(){
442
- self::$countRecords = 0;
443
-
444
- return self::$countRecords;
445
- }
446
-
447
- public function getcountRecords(){
448
- return self::$countRecords;
449
- }
450
-
451
-
452
- public function dataHeaders($database){
453
-
454
- $return = "";
455
-
456
- $return .= "#\n";
457
- $return .= "# Powered by XCloner Site Backup\n";
458
- $return .= "# http://www.xcloner.com\n";
459
- $return .= "#\n";
460
- $return .= "# Host: " . $_SERVER['HTTP_HOST'] . "\n";
461
- $return .= "# Generation Time: " . date("M j, Y \a\\t H:i") . "\n";
462
- $return .= "# PHP Version: " . phpversion() . "\n";
463
- $return .= "# Mysql Compatibility: ". self::$dbCompatibility . "\n";
464
-
465
- $result = self::query("SHOW VARIABLES LIKE \"%version%\";");
466
- if($result){
467
- while($row = mysqli_fetch_array($result)){
468
-
469
- $return .= "# MYSQL ".$row[0].": ".$row[1]."\n";
470
-
471
- }
472
- }
473
-
474
- $return .= "#\n# Database : `" . $database . "`\n# --------------------------------------------------------\n\n";
475
- return $return;
476
-
477
- }
478
-
479
-
480
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpseclib/Crypt/AES.php DELETED
@@ -1,594 +0,0 @@
1
- <?php
2
- /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
-
4
- /**
5
- * Pure-PHP implementation of AES.
6
- *
7
- * Uses mcrypt, if available, and an internal implementation, otherwise.
8
- *
9
- * PHP versions 4 and 5
10
- *
11
- * If {@link Crypt_AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
12
- * {@link Crypt_AES::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
13
- * it'll be null-padded to 160-bits and 160 bits will be the key length until {@link Crypt_Rijndael::setKey() setKey()}
14
- * is called, again, at which point, it'll be recalculated.
15
- *
16
- * Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't
17
- * make a whole lot of sense. {@link Crypt_AES::setBlockLength() setBlockLength()}, for instance. Calling that function,
18
- * however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
19
- *
20
- * Here's a short example of how to use this library:
21
- * <code>
22
- * <?php
23
- * include('Crypt/AES.php');
24
- *
25
- * $aes = new Crypt_AES();
26
- *
27
- * $aes->setKey('abcdefghijklmnop');
28
- *
29
- * $size = 10 * 1024;
30
- * $plaintext = '';
31
- * for ($i = 0; $i < $size; $i++) {
32
- * $plaintext.= 'a';
33
- * }
34
- *
35
- * echo $aes->decrypt($aes->encrypt($plaintext));
36
- * ?>
37
- * </code>
38
- *
39
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
40
- * of this software and associated documentation files (the "Software"), to deal
41
- * in the Software without restriction, including without limitation the rights
42
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
43
- * copies of the Software, and to permit persons to whom the Software is
44
- * furnished to do so, subject to the following conditions:
45
- *
46
- * The above copyright notice and this permission notice shall be included in
47
- * all copies or substantial portions of the Software.
48
- *
49
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
52
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
54
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
55
- * THE SOFTWARE.
56
- *
57
- * @category Crypt
58
- * @package Crypt_AES
59
- * @author Jim Wigginton <terrafrost@php.net>
60
- * @copyright MMVIII Jim Wigginton
61
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
62
- * @version $Id: AES.php,v 1.7 2010/02/09 06:10:25 terrafrost Exp $
63
- * @link http://phpseclib.sourceforge.net
64
- */
65
-
66
- /**
67
- * Include Crypt_Rijndael
68
- */
69
- require_once 'Rijndael.php';
70
-
71
- /**#@+
72
- * @access public
73
- * @see Crypt_AES::encrypt()
74
- * @see Crypt_AES::decrypt()
75
- */
76
- /**
77
- * Encrypt / decrypt using the Counter mode.
78
- *
79
- * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
80
- *
81
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
82
- */
83
- define('CRYPT_AES_MODE_CTR', -1);
84
- /**
85
- * Encrypt / decrypt using the Electronic Code Book mode.
86
- *
87
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
88
- */
89
- define('CRYPT_AES_MODE_ECB', 1);
90
- /**
91
- * Encrypt / decrypt using the Code Book Chaining mode.
92
- *
93
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
94
- */
95
- define('CRYPT_AES_MODE_CBC', 2);
96
- /**
97
- * Encrypt / decrypt using the Cipher Feedback mode.
98
- *
99
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
100
- */
101
- define('CRYPT_AES_MODE_CFB', 3);
102
- /**
103
- * Encrypt / decrypt using the Cipher Feedback mode.
104
- *
105
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
106
- */
107
- define('CRYPT_AES_MODE_OFB', 4);
108
- /**#@-*/
109
-
110
- /**#@+
111
- * @access private
112
- * @see Crypt_AES::Crypt_AES()
113
- */
114
- /**
115
- * Toggles the internal implementation
116
- */
117
- define('CRYPT_AES_MODE_INTERNAL', 1);
118
- /**
119
- * Toggles the mcrypt implementation
120
- */
121
- define('CRYPT_AES_MODE_MCRYPT', 2);
122
- /**#@-*/
123
-
124
- /**
125
- * Pure-PHP implementation of AES.
126
- *
127
- * @author Jim Wigginton <terrafrost@php.net>
128
- * @version 0.1.0
129
- * @access public
130
- * @package Crypt_AES
131
- */
132
- class Crypt_AES extends Crypt_Rijndael {
133
- /**
134
- * mcrypt resource for encryption
135
- *
136
- * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
137
- * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
138
- *
139
- * @see Crypt_AES::encrypt()
140
- * @var String
141
- * @access private
142
- */
143
- var $enmcrypt;
144
-
145
- /**
146
- * mcrypt resource for decryption
147
- *
148
- * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
149
- * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
150
- *
151
- * @see Crypt_AES::decrypt()
152
- * @var String
153
- * @access private
154
- */
155
- var $demcrypt;
156
-
157
- /**
158
- * mcrypt resource for CFB mode
159
- *
160
- * @see Crypt_AES::encrypt()
161
- * @see Crypt_AES::decrypt()
162
- * @var String
163
- * @access private
164
- */
165
- var $ecb;
166
-
167
- /**
168
- * Default Constructor.
169
- *
170
- * Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
171
- * CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC. If not explictly set, CRYPT_AES_MODE_CBC will be used.
172
- *
173
- * @param optional Integer $mode
174
- * @return Crypt_AES
175
- * @access public
176
- */
177
- function Crypt_AES($mode = CRYPT_AES_MODE_CBC)
178
- {
179
- if ( !defined('CRYPT_AES_MODE') ) {
180
- switch (true) {
181
- case extension_loaded('mcrypt'):
182
- // i'd check to see if aes was supported, by doing in_array('des', mcrypt_list_algorithms('')),
183
- // but since that can be changed after the object has been created, there doesn't seem to be
184
- // a lot of point...
185
- define('CRYPT_AES_MODE', CRYPT_AES_MODE_MCRYPT);
186
- break;
187
- default:
188
- define('CRYPT_AES_MODE', CRYPT_AES_MODE_INTERNAL);
189
- }
190
- }
191
-
192
- switch ( CRYPT_AES_MODE ) {
193
- case CRYPT_AES_MODE_MCRYPT:
194
- switch ($mode) {
195
- case CRYPT_AES_MODE_ECB:
196
- $this->paddable = true;
197
- $this->mode = MCRYPT_MODE_ECB;
198
- break;
199
- case CRYPT_AES_MODE_CTR:
200
- // ctr doesn't have a constant associated with it even though it appears to be fairly widely
201
- // supported. in lieu of knowing just how widely supported it is, i've, for now, opted not to
202
- // include a compatibility layer. the layer has been implemented but, for now, is commented out.
203
- $this->mode = 'ctr';
204
- //$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_AES_MODE_CTR;
205
- break;
206
- case CRYPT_AES_MODE_CFB:
207
- $this->mode = 'ncfb';
208
- break;
209
- case CRYPT_AES_MODE_OFB:
210
- $this->mode = MCRYPT_MODE_NOFB;
211
- break;
212
- case CRYPT_AES_MODE_CBC:
213
- default:
214
- $this->paddable = true;
215
- $this->mode = MCRYPT_MODE_CBC;
216
- }
217
-
218
- $this->debuffer = $this->enbuffer = '';
219
-
220
- break;
221
- default:
222
- switch ($mode) {
223
- case CRYPT_AES_MODE_ECB:
224
- $this->paddable = true;
225
- $this->mode = CRYPT_RIJNDAEL_MODE_ECB;
226
- break;
227
- case CRYPT_AES_MODE_CTR:
228
- $this->mode = CRYPT_RIJNDAEL_MODE_CTR;
229
- break;
230
- case CRYPT_AES_MODE_CFB:
231
- $this->mode = CRYPT_RIJNDAEL_MODE_CFB;
232
- break;
233
- case CRYPT_AES_MODE_OFB:
234
- $this->mode = CRYPT_RIJNDAEL_MODE_OFB;
235
- break;
236
- case CRYPT_AES_MODE_CBC:
237
- default:
238
- $this->paddable = true;
239
- $this->mode = CRYPT_RIJNDAEL_MODE_CBC;
240
- }
241
- }
242
-
243
- if (CRYPT_AES_MODE == CRYPT_AES_MODE_INTERNAL) {
244
- parent::Crypt_Rijndael($this->mode);
245
- }
246
- }
247
-
248
- /**
249
- * Dummy function
250
- *
251
- * Since Crypt_AES extends Crypt_Rijndael, this function is, technically, available, but it doesn't do anything.
252
- *
253
- * @access public
254
- * @param Integer $length
255
- */
256
- function setBlockLength($length)
257
- {
258
- return;
259
- }
260
-
261
- /**
262
- * Encrypts a message.
263
- *
264
- * $plaintext will be padded with up to 16 additional bytes. Other AES implementations may or may not pad in the
265
- * same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
266
- * URL:
267
- *
268
- * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
269
- *
270
- * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
271
- * strlen($plaintext) will still need to be a multiple of 16, however, arbitrary values can be added to make it that
272
- * length.
273
- *
274
- * @see Crypt_AES::decrypt()
275
- * @access public
276
- * @param String $plaintext
277
- */
278
- function encrypt($plaintext)
279
- {
280
- if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
281
- $changed = $this->changed;
282
- $this->_mcryptSetup();
283
- /*
284
- if ($this->mode == CRYPT_AES_MODE_CTR) {
285
- $iv = $this->encryptIV;
286
- $xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($plaintext), $iv));
287
- $ciphertext = $plaintext ^ $xor;
288
- if ($this->continuousBuffer) {
289
- $this->encryptIV = $iv;
290
- }
291
- return $ciphertext;
292
- }
293
- */
294
- // re: http://phpseclib.sourceforge.net/cfb-demo.phps
295
- // using mcrypt's default handing of CFB the above would output two different things. using phpseclib's
296
- // rewritten CFB implementation the above outputs the same thing twice.
297
- if ($this->mode == 'ncfb') {
298
- if ($changed) {
299
- $this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
300
- mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
301
- }
302
-
303
- if (strlen($this->enbuffer)) {
304
- $ciphertext = $plaintext ^ substr($this->encryptIV, strlen($this->enbuffer));
305
- $this->enbuffer.= $ciphertext;
306
- if (strlen($this->enbuffer) == 16) {
307
- $this->encryptIV = $this->enbuffer;
308
- $this->enbuffer = '';
309
- mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
310
- }
311
- $plaintext = substr($plaintext, strlen($ciphertext));
312
- } else {
313
- $ciphertext = '';
314
- }
315
-
316
- $last_pos = strlen($plaintext) & 0xFFFFFFF0;
317
- $ciphertext.= $last_pos ? mcrypt_generic($this->enmcrypt, substr($plaintext, 0, $last_pos)) : '';
318
-
319
- if (strlen($plaintext) & 0xF) {
320
- if (strlen($ciphertext)) {
321
- $this->encryptIV = substr($ciphertext, -16);
322
- }
323
- $this->encryptIV = mcrypt_generic($this->ecb, $this->encryptIV);
324
- $this->enbuffer = substr($plaintext, $last_pos) ^ $this->encryptIV;
325
- $ciphertext.= $this->enbuffer;
326
- }
327
-
328
- return $ciphertext;
329
- }
330
-
331
- if ($this->paddable) {
332
- $plaintext = $this->_pad($plaintext);
333
- }
334
-
335
- $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
336
-
337
- if (!$this->continuousBuffer) {
338
- mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
339
- }
340
-
341
- return $ciphertext;
342
- }
343
-
344
- return parent::encrypt($plaintext);
345
- }
346
-
347
- /**
348
- * Decrypts a message.
349
- *
350
- * If strlen($ciphertext) is not a multiple of 16, null bytes will be added to the end of the string until it is.
351
- *
352
- * @see Crypt_AES::encrypt()
353
- * @access public
354
- * @param String $ciphertext
355
- */
356
- function decrypt($ciphertext)
357
- {
358
- if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
359
- $changed = $this->changed;
360
- $this->_mcryptSetup();
361
- /*
362
- if ($this->mode == CRYPT_AES_MODE_CTR) {
363
- $iv = $this->decryptIV;
364
- $xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($ciphertext), $iv));
365
- $plaintext = $ciphertext ^ $xor;
366
- if ($this->continuousBuffer) {
367
- $this->decryptIV = $iv;
368
- }
369
- return $plaintext;
370
- }
371
- */
372
- if ($this->mode == 'ncfb') {
373
- if ($changed) {
374
- $this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
375
- mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
376
- }
377
-
378
- if (strlen($this->debuffer)) {
379
- $plaintext = $ciphertext ^ substr($this->decryptIV, strlen($this->debuffer));
380
-
381
- $this->debuffer.= substr($ciphertext, 0, strlen($plaintext));
382
- if (strlen($this->debuffer) == 16) {
383
- $this->decryptIV = $this->debuffer;
384
- $this->debuffer = '';
385
- mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
386
- }
387
- $ciphertext = substr($ciphertext, strlen($plaintext));
388
- } else {
389
- $plaintext = '';
390
- }
391
-
392
- $last_pos = strlen($ciphertext) & 0xFFFFFFF0;
393
- $plaintext.= $last_pos ? mdecrypt_generic($this->demcrypt, substr($ciphertext, 0, $last_pos)) : '';
394
-
395
- if (strlen($ciphertext) & 0xF) {
396
- if (strlen($plaintext)) {
397
- $this->decryptIV = substr($ciphertext, $last_pos - 16, 16);
398
- }
399
- $this->decryptIV = mcrypt_generic($this->ecb, $this->decryptIV);
400
- $this->debuffer = substr($ciphertext, $last_pos);
401
- $plaintext.= $this->debuffer ^ $this->decryptIV;
402
- }
403
-
404
- return $plaintext;
405
- }
406
-
407
- if ($this->paddable) {
408
- // we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
409
- // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
410
- $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 15) & 0xFFFFFFF0, chr(0));
411
- }
412
-
413
- $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
414
-
415
- if (!$this->continuousBuffer) {
416
- mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
417
- }
418
-
419
- return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
420
- }
421
-
422
- return parent::decrypt($ciphertext);
423
- }
424
-
425
- /**
426
- * Setup mcrypt
427
- *
428
- * Validates all the variables.
429
- *
430
- * @access private
431
- */
432
- function _mcryptSetup()
433
- {
434
- if (!$this->changed) {
435
- return;
436
- }
437
-
438
- if (!$this->explicit_key_length) {
439
- // this just copied from Crypt_Rijndael::_setup()
440
- $length = strlen($this->key) >> 2;
441
- if ($length > 8) {
442
- $length = 8;
443
- } else if ($length < 4) {
444
- $length = 4;
445
- }
446
- $this->Nk = $length;
447
- $this->key_size = $length << 2;
448
- }
449
-
450
- switch ($this->Nk) {
451
- case 4: // 128
452
- $this->key_size = 16;
453
- break;
454
- case 5: // 160
455
- case 6: // 192
456
- $this->key_size = 24;
457
- break;
458
- case 7: // 224
459
- case 8: // 256
460
- $this->key_size = 32;
461
- }
462
-
463
- $this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, chr(0));
464
- $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($this->iv, 0, 16), 16, chr(0));
465
-
466
- if (!isset($this->enmcrypt)) {
467
- $mode = $this->mode;
468
- //$mode = $this->mode == CRYPT_AES_MODE_CTR ? MCRYPT_MODE_ECB : $this->mode;
469
-
470
- $this->demcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
471
- $this->enmcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
472
- } // else should mcrypt_generic_deinit be called?
473
-
474
- mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
475
- mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
476
-
477
- $this->changed = false;
478
- }
479
-
480
- /**
481
- * Encrypts a block
482
- *
483
- * Optimized over Crypt_Rijndael's implementation by means of loop unrolling.
484
- *
485
- * @see Crypt_Rijndael::_encryptBlock()
486
- * @access private
487
- * @param String $in
488
- * @return String
489
- */
490
- function _encryptBlock($in)
491
- {
492
- $state = unpack('N*word', $in);
493
-
494
- $Nr = $this->Nr;
495
- $w = $this->w;
496
- $t0 = $this->t0;
497
- $t1 = $this->t1;
498
- $t2 = $this->t2;
499
- $t3 = $this->t3;
500
-
501
- // addRoundKey and reindex $state
502
- $state = array(
503
- $state['word1'] ^ $w[0][0],
504
- $state['word2'] ^ $w[0][1],
505
- $state['word3'] ^ $w[0][2],
506
- $state['word4'] ^ $w[0][3]
507
- );
508
-
509
- // shiftRows + subWord + mixColumns + addRoundKey
510
- // we could loop unroll this and use if statements to do more rounds as necessary, but, in my tests, that yields
511
- // only a marginal improvement. since that also, imho, hinders the readability of the code, i've opted not to do it.
512
- for ($round = 1; $round < $this->Nr; $round++) {
513
- $state = array(
514
- $t0[$state[0] & 0xFF000000] ^ $t1[$state[1] & 0x00FF0000] ^ $t2[$state[2] & 0x0000FF00] ^ $t3[$state[3] & 0x000000FF] ^ $w[$round][0],
515
- $t0[$state[1] & 0xFF000000] ^ $t1[$state[2] & 0x00FF0000] ^ $t2[$state[3] & 0x0000FF00] ^ $t3[$state[0] & 0x000000FF] ^ $w[$round][1],
516
- $t0[$state[2] & 0xFF000000] ^ $t1[$state[3] & 0x00FF0000] ^ $t2[$state[0] & 0x0000FF00] ^ $t3[$state[1] & 0x000000FF] ^ $w[$round][2],
517
- $t0[$state[3] & 0xFF000000] ^ $t1[$state[0] & 0x00FF0000] ^ $t2[$state[1] & 0x0000FF00] ^ $t3[$state[2] & 0x000000FF] ^ $w[$round][3]
518
- );
519
-
520
- }
521
-
522
- // subWord
523
- $state = array(
524
- $this->_subWord($state[0]),
525
- $this->_subWord($state[1]),
526
- $this->_subWord($state[2]),
527
- $this->_subWord($state[3])
528
- );
529
-
530
- // shiftRows + addRoundKey
531
- $state = array(
532
- ($state[0] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[3] & 0x000000FF) ^ $this->w[$this->Nr][0],
533
- ($state[1] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[0] & 0x000000FF) ^ $this->w[$this->Nr][1],
534
- ($state[2] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[1] & 0x000000FF) ^ $this->w[$this->Nr][2],
535
- ($state[3] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[2] & 0x000000FF) ^ $this->w[$this->Nr][3]
536
- );
537
-
538
- return pack('N*', $state[0], $state[1], $state[2], $state[3]);
539
- }
540
-
541
- /**
542
- * Decrypts a block
543
- *
544
- * Optimized over Crypt_Rijndael's implementation by means of loop unrolling.
545
- *
546
- * @see Crypt_Rijndael::_decryptBlock()
547
- * @access private
548
- * @param String $in
549
- * @return String
550
- */
551
- function _decryptBlock($in)
552
- {
553
- $state = unpack('N*word', $in);
554
-
555
- $Nr = $this->Nr;
556
- $dw = $this->dw;
557
- $dt0 = $this->dt0;
558
- $dt1 = $this->dt1;
559
- $dt2 = $this->dt2;
560
- $dt3 = $this->dt3;
561
-
562
- // addRoundKey and reindex $state
563
- $state = array(
564
- $state['word1'] ^ $dw[$this->Nr][0],
565
- $state['word2'] ^ $dw[$this->Nr][1],
566
- $state['word3'] ^ $dw[$this->Nr][2],
567
- $state['word4'] ^ $dw[$this->Nr][3]
568
- );
569
-
570
-
571
- // invShiftRows + invSubBytes + invMixColumns + addRoundKey
572
- for ($round = $this->Nr - 1; $round > 0; $round--) {
573
- $state = array(
574
- $dt0[$state[0] & 0xFF000000] ^ $dt1[$state[3] & 0x00FF0000] ^ $dt2[$state[2] & 0x0000FF00] ^ $dt3[$state[1] & 0x000000FF] ^ $dw[$round][0],
575
- $dt0[$state[1] & 0xFF000000] ^ $dt1[$state[0] & 0x00FF0000] ^ $dt2[$state[3] & 0x0000FF00] ^ $dt3[$state[2] & 0x000000FF] ^ $dw[$round][1],
576
- $dt0[$state[2] & 0xFF000000] ^ $dt1[$state[1] & 0x00FF0000] ^ $dt2[$state[0] & 0x0000FF00] ^ $dt3[$state[3] & 0x000000FF] ^ $dw[$round][2],
577
- $dt0[$state[3] & 0xFF000000] ^ $dt1[$state[2] & 0x00FF0000] ^ $dt2[$state[1] & 0x0000FF00] ^ $dt3[$state[0] & 0x000000FF] ^ $dw[$round][3]
578
- );
579
- }
580
-
581
- // invShiftRows + invSubWord + addRoundKey
582
- $state = array(
583
- $this->_invSubWord(($state[0] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[1] & 0x000000FF)) ^ $dw[0][0],
584
- $this->_invSubWord(($state[1] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[2] & 0x000000FF)) ^ $dw[0][1],
585
- $this->_invSubWord(($state[2] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[3] & 0x000000FF)) ^ $dw[0][2],
586
- $this->_invSubWord(($state[3] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[0] & 0x000000FF)) ^ $dw[0][3]
587
- );
588
-
589
- return pack('N*', $state[0], $state[1], $state[2], $state[3]);
590
- }
591
- }
592
-
593
- // vim: ts=4:sw=4:et:
594
- // vim6: fdl=1:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpseclib/Crypt/DES.php DELETED
@@ -1,1245 +0,0 @@
1
- <?php
2
- /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
-
4
- /**
5
- * Pure-PHP implementation of DES.
6
- *
7
- * Uses mcrypt, if available, and an internal implementation, otherwise.
8
- *
9
- * PHP versions 4 and 5
10
- *
11
- * Useful resources are as follows:
12
- *
13
- * - {@link http://en.wikipedia.org/wiki/DES_supplementary_material Wikipedia: DES supplementary material}
14
- * - {@link http://www.itl.nist.gov/fipspubs/fip46-2.htm FIPS 46-2 - (DES), Data Encryption Standard}
15
- * - {@link http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-DES.html JavaScript DES Example}
16
- *
17
- * Here's a short example of how to use this library:
18
- * <code>
19
- * <?php
20
- * include('Crypt/DES.php');
21
- *
22
- * $des = new Crypt_DES();
23
- *
24
- * $des->setKey('abcdefgh');
25
- *
26
- * $size = 10 * 1024;
27
- * $plaintext = '';
28
- * for ($i = 0; $i < $size; $i++) {
29
- * $plaintext.= 'a';
30
- * }
31
- *
32
- * echo $des->decrypt($des->encrypt($plaintext));
33
- * ?>
34
- * </code>
35
- *
36
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
37
- * of this software and associated documentation files (the "Software"), to deal
38
- * in the Software without restriction, including without limitation the rights
39
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
40
- * copies of the Software, and to permit persons to whom the Software is
41
- * furnished to do so, subject to the following conditions:
42
- *
43
- * The above copyright notice and this permission notice shall be included in
44
- * all copies or substantial portions of the Software.
45
- *
46
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
48
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
49
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
50
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
51
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
52
- * THE SOFTWARE.
53
- *
54
- * @category Crypt
55
- * @package Crypt_DES
56
- * @author Jim Wigginton <terrafrost@php.net>
57
- * @copyright MMVII Jim Wigginton
58
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
59
- * @version $Id: DES.php,v 1.12 2010/02/09 06:10:26 terrafrost Exp $
60
- * @link http://phpseclib.sourceforge.net
61
- */
62
-
63
- /**#@+
64
- * @access private
65
- * @see Crypt_DES::_prepareKey()
66
- * @see Crypt_DES::_processBlock()
67
- */
68
- /**
69
- * Contains array_reverse($keys[CRYPT_DES_DECRYPT])
70
- */
71
- define('CRYPT_DES_ENCRYPT', 0);
72
- /**
73
- * Contains array_reverse($keys[CRYPT_DES_ENCRYPT])
74
- */
75
- define('CRYPT_DES_DECRYPT', 1);
76
- /**#@-*/
77
-
78
- /**#@+
79
- * @access public
80
- * @see Crypt_DES::encrypt()
81
- * @see Crypt_DES::decrypt()
82
- */
83
- /**
84
- * Encrypt / decrypt using the Counter mode.
85
- *
86
- * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
87
- *
88
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
89
- */
90
- define('CRYPT_DES_MODE_CTR', -1);
91
- /**
92
- * Encrypt / decrypt using the Electronic Code Book mode.
93
- *
94
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
95
- */
96
- define('CRYPT_DES_MODE_ECB', 1);
97
- /**
98
- * Encrypt / decrypt using the Code Book Chaining mode.
99
- *
100
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
101
- */
102
- define('CRYPT_DES_MODE_CBC', 2);
103
- /**
104
- * Encrypt / decrypt using the Cipher Feedback mode.
105
- *
106
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
107
- */
108
- define('CRYPT_DES_MODE_CFB', 3);
109
- /**
110
- * Encrypt / decrypt using the Cipher Feedback mode.
111
- *
112
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
113
- */
114
- define('CRYPT_DES_MODE_OFB', 4);
115
- /**#@-*/
116
-
117
- /**#@+
118
- * @access private
119
- * @see Crypt_DES::Crypt_DES()
120
- */
121
- /**
122
- * Toggles the internal implementation
123
- */
124
- define('CRYPT_DES_MODE_INTERNAL', 1);
125
- /**
126
- * Toggles the mcrypt implementation
127
- */
128
- define('CRYPT_DES_MODE_MCRYPT', 2);
129
- /**#@-*/
130
-
131
- /**
132
- * Pure-PHP implementation of DES.
133
- *
134
- * @author Jim Wigginton <terrafrost@php.net>
135
- * @version 0.1.0
136
- * @access public
137
- * @package Crypt_DES
138
- */
139
- class Crypt_DES {
140
- /**
141
- * The Key Schedule
142
- *
143
- * @see Crypt_DES::setKey()
144
- * @var Array
145
- * @access private
146
- */
147
- var $keys = "\0\0\0\0\0\0\0\0";
148
-
149
- /**
150
- * The Encryption Mode
151
- *
152
- * @see Crypt_DES::Crypt_DES()
153
- * @var Integer
154
- * @access private
155
- */
156
- var $mode;
157
-
158
- /**
159
- * Continuous Buffer status
160
- *
161
- * @see Crypt_DES::enableContinuousBuffer()
162
- * @var Boolean
163
- * @access private
164
- */
165
- var $continuousBuffer = false;
166
-
167
- /**
168
- * Padding status
169
- *
170
- * @see Crypt_DES::enablePadding()
171
- * @var Boolean
172
- * @access private
173
- */
174
- var $padding = true;
175
-
176
- /**
177
- * The Initialization Vector
178
- *
179
- * @see Crypt_DES::setIV()
180
- * @var String
181
- * @access private
182
- */
183
- var $iv = "\0\0\0\0\0\0\0\0";
184
-
185
- /**
186
- * A "sliding" Initialization Vector
187
- *
188
- * @see Crypt_DES::enableContinuousBuffer()
189
- * @var String
190
- * @access private
191
- */
192
- var $encryptIV = "\0\0\0\0\0\0\0\0";
193
-
194
- /**
195
- * A "sliding" Initialization Vector
196
- *
197
- * @see Crypt_DES::enableContinuousBuffer()
198
- * @var String
199
- * @access private
200
- */
201
- var $decryptIV = "\0\0\0\0\0\0\0\0";
202
-
203
- /**
204
- * mcrypt resource for encryption
205
- *
206
- * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
207
- * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
208
- *
209
- * @see Crypt_DES::encrypt()
210
- * @var String
211
- * @access private
212
- */
213
- var $enmcrypt;
214
-
215
- /**
216
- * mcrypt resource for decryption
217
- *
218
- * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
219
- * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
220
- *
221
- * @see Crypt_DES::decrypt()
222
- * @var String
223
- * @access private
224
- */
225
- var $demcrypt;
226
-
227
- /**
228
- * Does the enmcrypt resource need to be (re)initialized?
229
- *
230
- * @see Crypt_DES::setKey()
231
- * @see Crypt_DES::setIV()
232
- * @var Boolean
233
- * @access private
234
- */
235
- var $enchanged = true;
236
-
237
- /**
238
- * Does the demcrypt resource need to be (re)initialized?
239
- *
240
- * @see Crypt_DES::setKey()
241
- * @see Crypt_DES::setIV()
242
- * @var Boolean
243
- * @access private
244
- */
245
- var $dechanged = true;
246
-
247
- /**
248
- * Is the mode one that is paddable?
249
- *
250
- * @see Crypt_DES::Crypt_DES()
251
- * @var Boolean
252
- * @access private
253
- */
254
- var $paddable = false;
255
-
256
- /**
257
- * Encryption buffer for CTR, OFB and CFB modes
258
- *
259
- * @see Crypt_DES::encrypt()
260
- * @var String
261
- * @access private
262
- */
263
- var $enbuffer = '';
264
-
265
- /**
266
- * Decryption buffer for CTR, OFB and CFB modes
267
- *
268
- * @see Crypt_DES::decrypt()
269
- * @var String
270
- * @access private
271
- */
272
- var $debuffer = '';
273
-
274
- /**
275
- * mcrypt resource for CFB mode
276
- *
277
- * @see Crypt_DES::encrypt()
278
- * @see Crypt_DES::decrypt()
279
- * @var String
280
- * @access private
281
- */
282
- var $ecb;
283
-
284
- /**
285
- * Default Constructor.
286
- *
287
- * Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
288
- * CRYPT_DES_MODE_ECB or CRYPT_DES_MODE_CBC. If not explictly set, CRYPT_DES_MODE_CBC will be used.
289
- *
290
- * @param optional Integer $mode
291
- * @return Crypt_DES
292
- * @access public
293
- */
294
- function Crypt_DES($mode = CRYPT_MODE_DES_CBC)
295
- {
296
- if ( !defined('CRYPT_DES_MODE') ) {
297
- switch (true) {
298
- case extension_loaded('mcrypt'):
299
- // i'd check to see if des was supported, by doing in_array('des', mcrypt_list_algorithms('')),
300
- // but since that can be changed after the object has been created, there doesn't seem to be
301
- // a lot of point...
302
- define('CRYPT_DES_MODE', CRYPT_DES_MODE_MCRYPT);
303
- break;
304
- default:
305
- define('CRYPT_DES_MODE', CRYPT_DES_MODE_INTERNAL);
306
- }
307
- }
308
-
309
- switch ( CRYPT_DES_MODE ) {
310
- case CRYPT_DES_MODE_MCRYPT:
311
- switch ($mode) {
312
- case CRYPT_DES_MODE_ECB:
313
- $this->paddable = true;
314
- $this->mode = MCRYPT_MODE_ECB;
315
- break;
316
- case CRYPT_DES_MODE_CTR:
317
- $this->mode = 'ctr';
318
- //$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_DES_MODE_CTR;
319
- break;
320
- case CRYPT_DES_MODE_CFB:
321
- $this->mode = 'ncfb';
322
- break;
323
- case CRYPT_DES_MODE_OFB:
324
- $this->mode = MCRYPT_MODE_NOFB;
325
- break;
326
- case CRYPT_DES_MODE_CBC:
327
- default:
328
- $this->paddable = true;
329
- $this->mode = MCRYPT_MODE_CBC;
330
- }
331
-
332
- break;
333
- default:
334
- switch ($mode) {
335
- case CRYPT_DES_MODE_ECB:
336
- case CRYPT_DES_MODE_CBC:
337
- $this->paddable = true;
338
- $this->mode = $mode;
339
- break;
340
- case CRYPT_DES_MODE_CTR:
341
- case CRYPT_DES_MODE_CFB:
342
- case CRYPT_DES_MODE_OFB:
343
- $this->mode = $mode;
344
- break;
345
- default:
346
- $this->paddable = true;
347
- $this->mode = CRYPT_DES_MODE_CBC;
348
- }
349
- }
350
- }
351
-
352
- /**
353
- * Sets the key.
354
- *
355
- * Keys can be of any length. DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
356
- * only use the first eight, if $key has more then eight characters in it, and pad $key with the
357
- * null byte if it is less then eight characters long.
358
- *
359
- * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
360
- *
361
- * If the key is not explicitly set, it'll be assumed to be all zero's.
362
- *
363
- * @access public
364
- * @param String $key
365
- */
366
- function setKey($key)
367
- {
368
- $this->keys = ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) ? str_pad(substr($key, 0, 8), 8, chr(0)) : $this->_prepareKey($key);
369
- $this->changed = true;
370
- }
371
-
372
- /**
373
- * Sets the initialization vector. (optional)
374
- *
375
- * SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explictly set, it'll be assumed
376
- * to be all zero's.
377
- *
378
- * @access public
379
- * @param String $iv
380
- */
381
- function setIV($iv)
382
- {
383
- $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));
384
- $this->changed = true;
385
- }
386
-
387
- /**
388
- * Generate CTR XOR encryption key
389
- *
390
- * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
391
- * plaintext / ciphertext in CTR mode.
392
- *
393
- * @see Crypt_DES::decrypt()
394
- * @see Crypt_DES::encrypt()
395
- * @access public
396
- * @param Integer $length
397
- * @param String $iv
398
- */
399
- function _generate_xor($length, &$iv)
400
- {
401
- $xor = '';
402
- $num_blocks = ($length + 7) >> 3;
403
- for ($i = 0; $i < $num_blocks; $i++) {
404
- $xor.= $iv;
405
- for ($j = 4; $j <= 8; $j+=4) {
406
- $temp = substr($iv, -$j, 4);
407
- switch ($temp) {
408
- case "\xFF\xFF\xFF\xFF":
409
- $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
410
- break;
411
- case "\x7F\xFF\xFF\xFF":
412
- $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
413
- break 2;
414
- default:
415
- extract(unpack('Ncount', $temp));
416
- $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
417
- break 2;
418
- }
419
- }
420
- }
421
-
422
- return $xor;
423
- }
424
-
425
- /**
426
- * Encrypts a message.
427
- *
428
- * $plaintext will be padded with up to 8 additional bytes. Other DES implementations may or may not pad in the
429
- * same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
430
- * URL:
431
- *
432
- * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
433
- *
434
- * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
435
- * strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that
436
- * length.
437
- *
438
- * @see Crypt_DES::decrypt()
439
- * @access public
440
- * @param String $plaintext
441
- */
442
- function encrypt($plaintext)
443
- {
444
- if ($this->paddable) {
445
- $plaintext = $this->_pad($plaintext);
446
- }
447
-
448
- if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
449
- if ($this->enchanged) {
450
- if (!isset($this->enmcrypt)) {
451
- $this->enmcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
452
- }
453
- mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
454
- if ($this->mode != 'ncfb') {
455
- $this->enchanged = false;
456
- }
457
- }
458
-
459
- if ($this->mode != 'ncfb') {
460
- $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
461
- } else {
462
- if ($this->enchanged) {
463
- $this->ecb = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, '');
464
- mcrypt_generic_init($this->ecb, $this->keys, "\0\0\0\0\0\0\0\0");
465
- $this->enchanged = false;
466
- }
467
-
468
- if (strlen($this->enbuffer)) {
469
- $ciphertext = $plaintext ^ substr($this->encryptIV, strlen($this->enbuffer));
470
- $this->enbuffer.= $ciphertext;
471
- if (strlen($this->enbuffer) == 8) {
472
- $this->encryptIV = $this->enbuffer;
473
- $this->enbuffer = '';
474
- mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
475
- }
476
- $plaintext = substr($plaintext, strlen($ciphertext));
477
- } else {
478
- $ciphertext = '';
479
- }
480
-
481
- $last_pos = strlen($plaintext) & 0xFFFFFFF8;
482
- $ciphertext.= $last_pos ? mcrypt_generic($this->enmcrypt, substr($plaintext, 0, $last_pos)) : '';
483
-
484
- if (strlen($plaintext) & 0x7) {
485
- if (strlen($ciphertext)) {
486
- $this->encryptIV = substr($ciphertext, -8);
487
- }
488
- $this->encryptIV = mcrypt_generic($this->ecb, $this->encryptIV);
489
- $this->enbuffer = substr($plaintext, $last_pos) ^ $this->encryptIV;
490
- $ciphertext.= $this->enbuffer;
491
- }
492
- }
493
-
494
- if (!$this->continuousBuffer) {
495
- mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
496
- }
497
-
498
- return $ciphertext;
499
- }
500
-
501
- if (!is_array($this->keys)) {
502
- $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
503
- }
504
-
505
- $buffer = &$this->enbuffer;
506
- $continuousBuffer = $this->continuousBuffer;
507
- $ciphertext = '';
508
- switch ($this->mode) {
509
- case CRYPT_DES_MODE_ECB:
510
- for ($i = 0; $i < strlen($plaintext); $i+=8) {
511
- $ciphertext.= $this->_processBlock(substr($plaintext, $i, 8), CRYPT_DES_ENCRYPT);
512
- }
513
- break;
514
- case CRYPT_DES_MODE_CBC:
515
- $xor = $this->encryptIV;
516
- for ($i = 0; $i < strlen($plaintext); $i+=8) {
517
- $block = substr($plaintext, $i, 8);
518
- $block = $this->_processBlock($block ^ $xor, CRYPT_DES_ENCRYPT);
519
- $xor = $block;
520
- $ciphertext.= $block;
521
- }
522
- if ($this->continuousBuffer) {
523
- $this->encryptIV = $xor;
524
- }
525
- break;
526
- case CRYPT_DES_MODE_CTR:
527
- $xor = $this->encryptIV;
528
- if (strlen($buffer)) {
529
- for ($i = 0; $i < strlen($plaintext); $i+=8) {
530
- $block = substr($plaintext, $i, 8);
531
- $buffer.= $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
532
- $key = $this->_string_shift($buffer, 8);
533
- $ciphertext.= $block ^ $key;
534
- }
535
- } else {
536
- for ($i = 0; $i < strlen($plaintext); $i+=8) {
537
- $block = substr($plaintext, $i, 8);
538
- $key = $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
539
- $ciphertext.= $block ^ $key;
540
- }
541
- }
542
- if ($this->continuousBuffer) {
543
- $this->encryptIV = $xor;
544
- if ($start = strlen($plaintext) & 7) {
545
- $buffer = substr($key, $start) . $buffer;
546
- }
547
- }
548
- break;
549
- case CRYPT_DES_MODE_CFB:
550
- if (!empty($buffer['xor'])) {
551
- $ciphertext = $plaintext ^ $buffer['xor'];
552
- $iv = $buffer['encrypted'] . $ciphertext;
553
- $start = strlen($ciphertext);
554
- $buffer['encrypted'].= $ciphertext;
555
- $buffer['xor'] = substr($buffer['xor'], strlen($ciphertext));
556
- } else {
557
- $ciphertext = '';
558
- $iv = $this->encryptIV;
559
- $start = 0;
560
- }
561
-
562
- for ($i = $start; $i < strlen($plaintext); $i+=8) {
563
- $block = substr($plaintext, $i, 8);
564
- $xor = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);
565
- $iv = $block ^ $xor;
566
- if ($continuousBuffer && strlen($iv) != 8) {
567
- $buffer = array(
568
- 'encrypted' => $iv,
569
- 'xor' => substr($xor, strlen($iv))
570
- );
571
- }
572
- $ciphertext.= $iv;
573
- }
574
-
575
- if ($this->continuousBuffer) {
576
- $this->encryptIV = $iv;
577
- }
578
- break;
579
- case CRYPT_DES_MODE_OFB:
580
- $xor = $this->encryptIV;
581
- if (strlen($buffer)) {
582
- for ($i = 0; $i < strlen($plaintext); $i+=8) {
583
- $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
584
- $buffer.= $xor;
585
- $key = $this->_string_shift($buffer, 8);
586
- $ciphertext.= substr($plaintext, $i, 8) ^ $key;
587
- }
588
- } else {
589
- for ($i = 0; $i < strlen($plaintext); $i+=8) {
590
- $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
591
- $ciphertext.= substr($plaintext, $i, 8) ^ $xor;
592
- }
593
- $key = $xor;
594
- }
595
- if ($this->continuousBuffer) {
596
- $this->encryptIV = $xor;
597
- if ($start = strlen($plaintext) & 7) {
598
- $buffer = substr($key, $start) . $buffer;
599
- }
600
- }
601
- }
602
-
603
- return $ciphertext;
604
- }
605
-
606
- /**
607
- * Decrypts a message.
608
- *
609
- * If strlen($ciphertext) is not a multiple of 8, null bytes will be added to the end of the string until it is.
610
- *
611
- * @see Crypt_DES::encrypt()
612
- * @access public
613
- * @param String $ciphertext
614
- */
615
- function decrypt($ciphertext)
616
- {
617
- if ($this->paddable) {
618
- // we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
619
- // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
620
- $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));
621
- }
622
-
623
- if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
624
- if ($this->dechanged) {
625
- if (!isset($this->demcrypt)) {
626
- $this->demcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
627
- }
628
- mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
629
- if ($this->mode != 'ncfb') {
630
- $this->dechanged = false;
631
- }
632
- }
633
-
634
- if ($this->mode != 'ncfb') {
635
- $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
636
- } else {
637
- if ($this->dechanged) {
638
- $this->ecb = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, '');
639
- mcrypt_generic_init($this->ecb, $this->keys, "\0\0\0\0\0\0\0\0");
640
- $this->dechanged = false;
641
- }
642
-
643
- if (strlen($this->debuffer)) {
644
- $plaintext = $ciphertext ^ substr($this->decryptIV, strlen($this->debuffer));
645
-
646
- $this->debuffer.= substr($ciphertext, 0, strlen($plaintext));
647
- if (strlen($this->debuffer) == 8) {
648
- $this->decryptIV = $this->debuffer;
649
- $this->debuffer = '';
650
- mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
651
- }
652
- $ciphertext = substr($ciphertext, strlen($plaintext));
653
- } else {
654
- $plaintext = '';
655
- }
656
-
657
- $last_pos = strlen($ciphertext) & 0xFFFFFFF8;
658
- $plaintext.= $last_pos ? mdecrypt_generic($this->demcrypt, substr($ciphertext, 0, $last_pos)) : '';
659
-
660
- if (strlen($ciphertext) & 0x7) {
661
- if (strlen($plaintext)) {
662
- $this->decryptIV = substr($ciphertext, $last_pos - 8, 8);
663
- }
664
- $this->decryptIV = mcrypt_generic($this->ecb, $this->decryptIV);
665
- $this->debuffer = substr($ciphertext, $last_pos);
666
- $plaintext.= $this->debuffer ^ $this->decryptIV;
667
- }
668
-
669
- return $plaintext;
670
- }
671
-
672
- if (!$this->continuousBuffer) {
673
- mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
674
- }
675
-
676
- return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;
677
- }
678
-
679
- if (!is_array($this->keys)) {
680
- $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
681
- }
682
-
683
- $buffer = &$this->debuffer;
684
- $continuousBuffer = $this->continuousBuffer;
685
- $plaintext = '';
686
- switch ($this->mode) {
687
- case CRYPT_DES_MODE_ECB:
688
- for ($i = 0; $i < strlen($ciphertext); $i+=8) {
689
- $plaintext.= $this->_processBlock(substr($ciphertext, $i, 8), CRYPT_DES_DECRYPT);
690
- }
691
- break;
692
- case CRYPT_DES_MODE_CBC:
693
- $xor = $this->decryptIV;
694
- for ($i = 0; $i < strlen($ciphertext); $i+=8) {
695
- $block = substr($ciphertext, $i, 8);
696
- $plaintext.= $this->_processBlock($block, CRYPT_DES_DECRYPT) ^ $xor;
697
- $xor = $block;
698
- }
699
- if ($this->continuousBuffer) {
700
- $this->decryptIV = $xor;
701
- }
702
- break;
703
- case CRYPT_DES_MODE_CTR:
704
- $xor = $this->decryptIV;
705
- if (strlen($buffer)) {
706
- for ($i = 0; $i < strlen($ciphertext); $i+=8) {
707
- $block = substr($ciphertext, $i, 8);
708
- $buffer.= $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
709
- $key = $this->_string_shift($buffer, 8);
710
- $plaintext.= $block ^ $key;
711
- }
712
- } else {
713
- for ($i = 0; $i < strlen($ciphertext); $i+=8) {
714
- $block = substr($ciphertext, $i, 8);
715
- $key = $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
716
- $plaintext.= $block ^ $key;
717
- }
718
- }
719
- if ($this->continuousBuffer) {
720
- $this->decryptIV = $xor;
721
- if ($start = strlen($ciphertext) % 8) {
722
- $buffer = substr($key, $start) . $buffer;
723
- }
724
- }
725
- break;
726
- case CRYPT_DES_MODE_CFB:
727
- if (!empty($buffer['ciphertext'])) {
728
- $plaintext = $ciphertext ^ substr($this->decryptIV, strlen($buffer['ciphertext']));
729
- $buffer['ciphertext'].= substr($ciphertext, 0, strlen($plaintext));
730
- if (strlen($buffer['ciphertext']) == 8) {
731
- $xor = $this->_processBlock($buffer['ciphertext'], CRYPT_DES_ENCRYPT);
732
- $buffer['ciphertext'] = '';
733
- }
734
- $start = strlen($plaintext);
735
- $block = $this->decryptIV;
736
- } else {
737
- $plaintext = '';
738
- $xor = $this->_processBlock($this->decryptIV, CRYPT_DES_ENCRYPT);
739
- $start = 0;
740
- }
741
-
742
- for ($i = $start; $i < strlen($ciphertext); $i+=8) {
743
- $block = substr($ciphertext, $i, 8);
744
- $plaintext.= $block ^ $xor;
745
- if ($continuousBuffer && strlen($block) != 8) {
746
- $buffer['ciphertext'].= $block;
747
- $block = $xor;
748
- } else if (strlen($block) == 8) {
749
- $xor = $this->_processBlock($block, CRYPT_DES_ENCRYPT);
750
- }
751
- }
752
- if ($this->continuousBuffer) {
753
- $this->decryptIV = $block;
754
- }
755
- break;
756
- case CRYPT_DES_MODE_OFB:
757
- $xor = $this->decryptIV;
758
- if (strlen($buffer)) {
759
- for ($i = 0; $i < strlen($ciphertext); $i+=8) {
760
- $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
761
- $buffer.= $xor;
762
- $key = $this->_string_shift($buffer, 8);
763
- $plaintext.= substr($ciphertext, $i, 8) ^ $key;
764
- }
765
- } else {
766
- for ($i = 0; $i < strlen($ciphertext); $i+=8) {
767
- $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
768
- $plaintext.= substr($ciphertext, $i, 8) ^ $xor;
769
- }
770
- $key = $xor;
771
- }
772
- if ($this->continuousBuffer) {
773
- $this->decryptIV = $xor;
774
- if ($start = strlen($ciphertext) % 8) {
775
- $buffer = substr($key, $start) . $buffer;
776
- }
777
- }
778
- }
779
-
780
- return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
781
- }
782
-
783
- /**
784
- * Treat consecutive "packets" as if they are a continuous buffer.
785
- *
786
- * Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
787
- * will yield different outputs:
788
- *
789
- * <code>
790
- * echo $des->encrypt(substr($plaintext, 0, 8));
791
- * echo $des->encrypt(substr($plaintext, 8, 8));
792
- * </code>
793
- * <code>
794
- * echo $des->encrypt($plaintext);
795
- * </code>
796
- *
797
- * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
798
- * another, as demonstrated with the following:
799
- *
800
- * <code>
801
- * $des->encrypt(substr($plaintext, 0, 8));
802
- * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
803
- * </code>
804
- * <code>
805
- * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
806
- * </code>
807
- *
808
- * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
809
- * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
810
- * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
811
- *
812
- * Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
813
- * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
814
- * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
815
- * however, they are also less intuitive and more likely to cause you problems.
816
- *
817
- * @see Crypt_DES::disableContinuousBuffer()
818
- * @access public
819
- */
820
- function enableContinuousBuffer()
821
- {
822
- $this->continuousBuffer = true;
823
- }
824
-
825
- /**
826
- * Treat consecutive packets as if they are a discontinuous buffer.
827
- *
828
- * The default behavior.
829
- *
830
- * @see Crypt_DES::enableContinuousBuffer()
831
- * @access public
832
- */
833
- function disableContinuousBuffer()
834
- {
835
- $this->continuousBuffer = false;
836
- $this->encryptIV = $this->iv;
837
- $this->decryptIV = $this->iv;
838
- }
839
-
840
- /**
841
- * Pad "packets".
842
- *
843
- * DES works by encrypting eight bytes at a time. If you ever need to encrypt or decrypt something that's not
844
- * a multiple of eight, it becomes necessary to pad the input so that it's length is a multiple of eight.
845
- *
846
- * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH1,
847
- * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
848
- * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
849
- * transmitted separately)
850
- *
851
- * @see Crypt_DES::disablePadding()
852
- * @access public
853
- */
854
- function enablePadding()
855
- {
856
- $this->padding = true;
857
- }
858
-
859
- /**
860
- * Do not pad packets.
861
- *
862
- * @see Crypt_DES::enablePadding()
863
- * @access public
864
- */
865
- function disablePadding()
866
- {
867
- $this->padding = false;
868
- }
869
-
870
- /**
871
- * Pads a string
872
- *
873
- * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).
874
- * 8 - (strlen($text) & 7) bytes are added, each of which is equal to chr(8 - (strlen($text) & 7)
875
- *
876
- * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
877
- * and padding will, hence forth, be enabled.
878
- *
879
- * @see Crypt_DES::_unpad()
880
- * @access private
881
- */
882
- function _pad($text)
883
- {
884
- $length = strlen($text);
885
-
886
- if (!$this->padding) {
887
- if (($length & 7) == 0) {
888
- return $text;
889
- } else {
890
- user_error("The plaintext's length ($length) is not a multiple of the block size (8)", E_USER_NOTICE);
891
- $this->padding = true;
892
- }
893
- }
894
-
895
- $pad = 8 - ($length & 7);
896
- return str_pad($text, $length + $pad, chr($pad));
897
- }
898
-
899
- /**
900
- * Unpads a string
901
- *
902
- * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
903
- * and false will be returned.
904
- *
905
- * @see Crypt_DES::_pad()
906
- * @access private
907
- */
908
- function _unpad($text)
909
- {
910
- if (!$this->padding) {
911
- return $text;
912
- }
913
-
914
- $length = ord($text[strlen($text) - 1]);
915
-
916
- if (!$length || $length > 8) {
917
- return false;
918
- }
919
-
920
- return substr($text, 0, -$length);
921
- }
922
-
923
- /**
924
- * Encrypts or decrypts a 64-bit block
925
- *
926
- * $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT. See
927
- * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
928
- * idea of what this function does.
929
- *
930
- * @access private
931
- * @param String $block
932
- * @param Integer $mode
933
- * @return String
934
- */
935
- function _processBlock($block, $mode)
936
- {
937
- // s-boxes. in the official DES docs, they're described as being matrices that
938
- // one accesses by using the first and last bits to determine the row and the
939
- // middle four bits to determine the column. in this implementation, they've
940
- // been converted to vectors
941
- static $sbox = array(
942
- array(
943
- 14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1,
944
- 3, 10 ,10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8,
945
- 4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7,
946
- 15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13
947
- ),
948
- array(
949
- 15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14,
950
- 9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5,
951
- 0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2,
952
- 5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9
953
- ),
954
- array(
955
- 10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10,
956
- 1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1,
957
- 13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7,
958
- 11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12
959
- ),
960
- array(
961
- 7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3,
962
- 1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9,
963
- 10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8,
964
- 15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14
965
- ),
966
- array(
967
- 2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1,
968
- 8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6,
969
- 4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13,
970
- 15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3
971
- ),
972
- array(
973
- 12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5,
974
- 0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8,
975
- 9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10,
976
- 7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13
977
- ),
978
- array(
979
- 4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10,
980
- 3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6,
981
- 1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,
982
- 10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12
983
- ),
984
- array(
985
- 13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4,
986
- 10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2,
987
- 7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13,
988
- 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11
989
- )
990
- );
991
-
992
- $keys = $this->keys;
993
-
994
- $temp = unpack('Na/Nb', $block);
995
- $block = array($temp['a'], $temp['b']);
996
-
997
- // because php does arithmetic right shifts, if the most significant bits are set, right
998
- // shifting those into the correct position will add 1's - not 0's. this will intefere
999
- // with the | operation unless a second & is done. so we isolate these bits and left shift
1000
- // them into place. we then & each block with 0x7FFFFFFF to prevennt 1's from being added
1001
- // for any other shifts.
1002
- $msb = array(
1003
- ($block[0] >> 31) & 1,
1004
- ($block[1] >> 31) & 1
1005
- );
1006
- $block[0] &= 0x7FFFFFFF;
1007
- $block[1] &= 0x7FFFFFFF;
1008
-
1009
- // we isolate the appropriate bit in the appropriate integer and shift as appropriate. in
1010
- // some cases, there are going to be multiple bits in the same integer that need to be shifted
1011
- // in the same way. we combine those into one shift operation.
1012
- $block = array(
1013
- (($block[1] & 0x00000040) << 25) | (($block[1] & 0x00004000) << 16) |
1014
- (($block[1] & 0x00400001) << 7) | (($block[1] & 0x40000100) >> 2) |
1015
- (($block[0] & 0x00000040) << 21) | (($block[0] & 0x00004000) << 12) |
1016
- (($block[0] & 0x00400001) << 3) | (($block[0] & 0x40000100) >> 6) |
1017
- (($block[1] & 0x00000010) << 19) | (($block[1] & 0x00001000) << 10) |
1018
- (($block[1] & 0x00100000) << 1) | (($block[1] & 0x10000000) >> 8) |
1019
- (($block[0] & 0x00000010) << 15) | (($block[0] & 0x00001000) << 6) |
1020
- (($block[0] & 0x00100000) >> 3) | (($block[0] & 0x10000000) >> 12) |
1021
- (($block[1] & 0x00000004) << 13) | (($block[1] & 0x00000400) << 4) |
1022
- (($block[1] & 0x00040000) >> 5) | (($block[1] & 0x04000000) >> 14) |
1023
- (($block[0] & 0x00000004) << 9) | ( $block[0] & 0x00000400 ) |
1024
- (($block[0] & 0x00040000) >> 9) | (($block[0] & 0x04000000) >> 18) |
1025
- (($block[1] & 0x00010000) >> 11) | (($block[1] & 0x01000000) >> 20) |
1026
- (($block[0] & 0x00010000) >> 15) | (($block[0] & 0x01000000) >> 24)
1027
- ,
1028
- (($block[1] & 0x00000080) << 24) | (($block[1] & 0x00008000) << 15) |
1029
- (($block[1] & 0x00800002) << 6) | (($block[0] & 0x00000080) << 20) |
1030
- (($block[0] & 0x00008000) << 11) | (($block[0] & 0x00800002) << 2) |
1031
- (($block[1] & 0x00000020) << 18) | (($block[1] & 0x00002000) << 9) |
1032
- ( $block[1] & 0x00200000 ) | (($block[1] & 0x20000000) >> 9) |
1033
- (($block[0] & 0x00000020) << 14) | (($block[0] & 0x00002000) << 5) |
1034
- (($block[0] & 0x00200000) >> 4) | (($block[0] & 0x20000000) >> 13) |
1035
- (($block[1] & 0x00000008) << 12) | (($block[1] & 0x00000800) << 3) |
1036
- (($block[1] & 0x00080000) >> 6) | (($block[1] & 0x08000000) >> 15) |
1037
- (($block[0] & 0x00000008) << 8) | (($block[0] & 0x00000800) >> 1) |
1038
- (($block[0] & 0x00080000) >> 10) | (($block[0] & 0x08000000) >> 19) |
1039
- (($block[1] & 0x00000200) >> 3) | (($block[0] & 0x00000200) >> 7) |
1040
- (($block[1] & 0x00020000) >> 12) | (($block[1] & 0x02000000) >> 21) |
1041
- (($block[0] & 0x00020000) >> 16) | (($block[0] & 0x02000000) >> 25) |
1042
- ($msb[1] << 28) | ($msb[0] << 24)
1043
- );
1044
-
1045
- for ($i = 0; $i < 16; $i++) {
1046
- // start of "the Feistel (F) function" - see the following URL:
1047
- // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
1048
- $temp = (($sbox[0][((($block[1] >> 27) & 0x1F) | (($block[1] & 1) << 5)) ^ $keys[$mode][$i][0]]) << 28)
1049
- | (($sbox[1][(($block[1] & 0x1F800000) >> 23) ^ $keys[$mode][$i][1]]) << 24)
1050
- | (($sbox[2][(($block[1] & 0x01F80000) >> 19) ^ $keys[$mode][$i][2]]) << 20)
1051
- | (($sbox[3][(($block[1] & 0x001F8000) >> 15) ^ $keys[$mode][$i][3]]) << 16)
1052
- | (($sbox[4][(($block[1] & 0x0001F800) >> 11) ^ $keys[$mode][$i][4]]) << 12)
1053
- | (($sbox[5][(($block[1] & 0x00001F80) >> 7) ^ $keys[$mode][$i][5]]) << 8)
1054
- | (($sbox[6][(($block[1] & 0x000001F8) >> 3) ^ $keys[$mode][$i][6]]) << 4)
1055
- | ( $sbox[7][((($block[1] & 0x1F) << 1) | (($block[1] >> 31) & 1)) ^ $keys[$mode][$i][7]]);
1056
-
1057
- $msb = ($temp >> 31) & 1;
1058
- $temp &= 0x7FFFFFFF;
1059
- $newBlock = (($temp & 0x00010000) << 15) | (($temp & 0x02020120) << 5)
1060
- | (($temp & 0x00001800) << 17) | (($temp & 0x01000000) >> 10)
1061
- | (($temp & 0x00000008) << 24) | (($temp & 0x00100000) << 6)
1062
- | (($temp & 0x00000010) << 21) | (($temp & 0x00008000) << 9)
1063
- | (($temp & 0x00000200) << 12) | (($temp & 0x10000000) >> 27)
1064
- | (($temp & 0x00000040) << 14) | (($temp & 0x08000000) >> 8)
1065
- | (($temp & 0x00004000) << 4) | (($temp & 0x00000002) << 16)
1066
- | (($temp & 0x00442000) >> 6) | (($temp & 0x40800000) >> 15)
1067
- | (($temp & 0x00000001) << 11) | (($temp & 0x20000000) >> 20)
1068
- | (($temp & 0x00080000) >> 13) | (($temp & 0x00000004) << 3)
1069
- | (($temp & 0x04000000) >> 22) | (($temp & 0x00000480) >> 7)
1070
- | (($temp & 0x00200000) >> 19) | ($msb << 23);
1071
- // end of "the Feistel (F) function" - $newBlock is F's output
1072
-
1073
- $temp = $block[1];
1074
- $block[1] = $block[0] ^ $newBlock;
1075
- $block[0] = $temp;
1076
- }
1077
-
1078
- $msb = array(
1079
- ($block[0] >> 31) & 1,
1080
- ($block[1] >> 31) & 1
1081
- );
1082
- $block[0] &= 0x7FFFFFFF;
1083
- $block[1] &= 0x7FFFFFFF;
1084
-
1085
- $block = array(
1086
- (($block[0] & 0x01000004) << 7) | (($block[1] & 0x01000004) << 6) |
1087
- (($block[0] & 0x00010000) << 13) | (($block[1] & 0x00010000) << 12) |
1088
- (($block[0] & 0x00000100) << 19) | (($block[1] & 0x00000100) << 18) |
1089
- (($block[0] & 0x00000001) << 25) | (($block[1] & 0x00000001) << 24) |
1090
- (($block[0] & 0x02000008) >> 2) | (($block[1] & 0x02000008) >> 3) |
1091
- (($block[0] & 0x00020000) << 4) | (($block[1] & 0x00020000) << 3) |
1092
- (($block[0] & 0x00000200) << 10) | (($block[1] & 0x00000200) << 9) |
1093
- (($block[0] & 0x00000002) << 16) | (($block[1] & 0x00000002) << 15) |
1094
- (($block[0] & 0x04000000) >> 11) | (($block[1] & 0x04000000) >> 12) |
1095
- (($block[0] & 0x00040000) >> 5) | (($block[1] & 0x00040000) >> 6) |
1096
- (($block[0] & 0x00000400) << 1) | ( $block[1] & 0x00000400 ) |
1097
- (($block[0] & 0x08000000) >> 20) | (($block[1] & 0x08000000) >> 21) |
1098
- (($block[0] & 0x00080000) >> 14) | (($block[1] & 0x00080000) >> 15) |
1099
- (($block[0] & 0x00000800) >> 8) | (($block[1] & 0x00000800) >> 9)
1100
- ,
1101
- (($block[0] & 0x10000040) << 3) | (($block[1] & 0x10000040) << 2) |
1102
- (($block[0] & 0x00100000) << 9) | (($block[1] & 0x00100000) << 8) |
1103
- (($block[0] & 0x00001000) << 15) | (($block[1] & 0x00001000) << 14) |
1104
- (($block[0] & 0x00000010) << 21) | (($block[1] & 0x00000010) << 20) |
1105
- (($block[0] & 0x20000080) >> 6) | (($block[1] & 0x20000080) >> 7) |
1106
- ( $block[0] & 0x00200000 ) | (($block[1] & 0x00200000) >> 1) |
1107
- (($block[0] & 0x00002000) << 6) | (($block[1] & 0x00002000) << 5) |
1108
- (($block[0] & 0x00000020) << 12) | (($block[1] & 0x00000020) << 11) |
1109
- (($block[0] & 0x40000000) >> 15) | (($block[1] & 0x40000000) >> 16) |
1110
- (($block[0] & 0x00400000) >> 9) | (($block[1] & 0x00400000) >> 10) |
1111
- (($block[0] & 0x00004000) >> 3) | (($block[1] & 0x00004000) >> 4) |
1112
- (($block[0] & 0x00800000) >> 18) | (($block[1] & 0x00800000) >> 19) |
1113
- (($block[0] & 0x00008000) >> 12) | (($block[1] & 0x00008000) >> 13) |
1114
- ($msb[0] << 7) | ($msb[1] << 6)
1115
- );
1116
-
1117
- return pack('NN', $block[0], $block[1]);
1118
- }
1119
-
1120
- /**
1121
- * Creates the key schedule.
1122
- *
1123
- * @access private
1124
- * @param String $key
1125
- * @return Array
1126
- */
1127
- function _prepareKey($key)
1128
- {
1129
- static $shifts = array( // number of key bits shifted per round
1130
- 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
1131
- );
1132
-
1133
- // pad the key and remove extra characters as appropriate.
1134
- $key = str_pad(substr($key, 0, 8), 8, chr(0));
1135
-
1136
- $temp = unpack('Na/Nb', $key);
1137
- $key = array($temp['a'], $temp['b']);
1138
- $msb = array(
1139
- ($key[0] >> 31) & 1,
1140
- ($key[1] >> 31) & 1
1141
- );
1142
- $key[0] &= 0x7FFFFFFF;
1143
- $key[1] &= 0x7FFFFFFF;
1144
-
1145
- $key = array(
1146
- (($key[1] & 0x00000002) << 26) | (($key[1] & 0x00000204) << 17) |
1147
- (($key[1] & 0x00020408) << 8) | (($key[1] & 0x02040800) >> 1) |
1148
- (($key[0] & 0x00000002) << 22) | (($key[0] & 0x00000204) << 13) |
1149
- (($key[0] & 0x00020408) << 4) | (($key[0] & 0x02040800) >> 5) |
1150
- (($key[1] & 0x04080000) >> 10) | (($key[0] & 0x04080000) >> 14) |
1151
- (($key[1] & 0x08000000) >> 19) | (($key[0] & 0x08000000) >> 23) |
1152
- (($key[0] & 0x00000010) >> 1) | (($key[0] & 0x00001000) >> 10) |
1153
- (($key[0] & 0x00100000) >> 19) | (($key[0] & 0x10000000) >> 28)
1154
- ,
1155
- (($key[1] & 0x00000080) << 20) | (($key[1] & 0x00008000) << 11) |
1156
- (($key[1] & 0x00800000) << 2) | (($key[0] & 0x00000080) << 16) |
1157
- (($key[0] & 0x00008000) << 7) | (($key[0] & 0x00800000) >> 2) |
1158
- (($key[1] & 0x00000040) << 13) | (($key[1] & 0x00004000) << 4) |
1159
- (($key[1] & 0x00400000) >> 5) | (($key[1] & 0x40000000) >> 14) |
1160
- (($key[0] & 0x00000040) << 9) | ( $key[0] & 0x00004000 ) |
1161
- (($key[0] & 0x00400000) >> 9) | (($key[0] & 0x40000000) >> 18) |
1162
- (($key[1] & 0x00000020) << 6) | (($key[1] & 0x00002000) >> 3) |
1163
- (($key[1] & 0x00200000) >> 12) | (($key[1] & 0x20000000) >> 21) |
1164
- (($key[0] & 0x00000020) << 2) | (($key[0] & 0x00002000) >> 7) |
1165
- (($key[0] & 0x00200000) >> 16) | (($key[0] & 0x20000000) >> 25) |
1166
- (($key[1] & 0x00000010) >> 1) | (($key[1] & 0x00001000) >> 10) |
1167
- (($key[1] & 0x00100000) >> 19) | (($key[1] & 0x10000000) >> 28) |
1168
- ($msb[1] << 24) | ($msb[0] << 20)
1169
- );
1170
-
1171
- $keys = array();
1172
- for ($i = 0; $i < 16; $i++) {
1173
- $key[0] <<= $shifts[$i];
1174
- $temp = ($key[0] & 0xF0000000) >> 28;
1175
- $key[0] = ($key[0] | $temp) & 0x0FFFFFFF;
1176
-
1177
- $key[1] <<= $shifts[$i];
1178
- $temp = ($key[1] & 0xF0000000) >> 28;
1179
- $key[1] = ($key[1] | $temp) & 0x0FFFFFFF;
1180
-
1181
- $temp = array(
1182
- (($key[1] & 0x00004000) >> 9) | (($key[1] & 0x00000800) >> 7) |
1183
- (($key[1] & 0x00020000) >> 14) | (($key[1] & 0x00000010) >> 2) |
1184
- (($key[1] & 0x08000000) >> 26) | (($key[1] & 0x00800000) >> 23)
1185
- ,
1186
- (($key[1] & 0x02400000) >> 20) | (($key[1] & 0x00000001) << 4) |
1187
- (($key[1] & 0x00002000) >> 10) | (($key[1] & 0x00040000) >> 18) |
1188
- (($key[1] & 0x00000080) >> 6)
1189
- ,
1190
- ( $key[1] & 0x00000020 ) | (($key[1] & 0x00000200) >> 5) |
1191
- (($key[1] & 0x00010000) >> 13) | (($key[1] & 0x01000000) >> 22) |
1192
- (($key[1] & 0x00000004) >> 1) | (($key[1] & 0x00100000) >> 20)
1193
- ,
1194
- (($key[1] & 0x00001000) >> 7) | (($key[1] & 0x00200000) >> 17) |
1195
- (($key[1] & 0x00000002) << 2) | (($key[1] & 0x00000100) >> 6) |
1196
- (($key[1] & 0x00008000) >> 14) | (($key[1] & 0x04000000) >> 26)
1197
- ,
1198
- (($key[0] & 0x00008000) >> 10) | ( $key[0] & 0x00000010 ) |
1199
- (($key[0] & 0x02000000) >> 22) | (($key[0] & 0x00080000) >> 17) |
1200
- (($key[0] & 0x00000200) >> 8) | (($key[0] & 0x00000002) >> 1)
1201
- ,
1202
- (($key[0] & 0x04000000) >> 21) | (($key[0] & 0x00010000) >> 12) |
1203
- (($key[0] & 0x00000020) >> 2) | (($key[0] & 0x00000800) >> 9) |
1204
- (($key[0] & 0x00800000) >> 22) | (($key[0] & 0x00000100) >> 8)
1205
- ,
1206
- (($key[0] & 0x00001000) >> 7) | (($key[0] & 0x00000088) >> 3) |
1207
- (($key[0] & 0x00020000) >> 14) | (($key[0] & 0x00000001) << 2) |
1208
- (($key[0] & 0x00400000) >> 21)
1209
- ,
1210
- (($key[0] & 0x00000400) >> 5) | (($key[0] & 0x00004000) >> 10) |
1211
- (($key[0] & 0x00000040) >> 3) | (($key[0] & 0x00100000) >> 18) |
1212
- (($key[0] & 0x08000000) >> 26) | (($key[0] & 0x01000000) >> 24)
1213
- );
1214
-
1215
- $keys[] = $temp;
1216
- }
1217
-
1218
- $temp = array(
1219
- CRYPT_DES_ENCRYPT => $keys,
1220
- CRYPT_DES_DECRYPT => array_reverse($keys)
1221
- );
1222
-
1223
- return $temp;
1224
- }
1225
-
1226
- /**
1227
- * String Shift
1228
- *
1229
- * Inspired by array_shift
1230
- *
1231
- * @param String $string
1232
- * @param optional Integer $index
1233
- * @return String
1234
- * @access private
1235
- */
1236
- function _string_shift(&$string, $index = 1)
1237
- {
1238
- $substr = substr($string, 0, $index);
1239
- $string = substr($string, $index);
1240
- return $substr;
1241
- }
1242
- }
1243
-
1244
- // vim: ts=4:sw=4:et:
1245
- // vim6: fdl=1:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpseclib/Crypt/RC4.php DELETED
@@ -1,505 +0,0 @@
1
- <?php
2
- /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
-
4
- /**
5
- * Pure-PHP implementation of RC4.
6
- *
7
- * Uses mcrypt, if available, and an internal implementation, otherwise.
8
- *
9
- * PHP versions 4 and 5
10
- *
11
- * Useful resources are as follows:
12
- *
13
- * - {@link http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt ARCFOUR Algorithm}
14
- * - {@link http://en.wikipedia.org/wiki/RC4 - Wikipedia: RC4}
15
- *
16
- * RC4 is also known as ARCFOUR or ARC4. The reason is elaborated upon at Wikipedia. This class is named RC4 and not
17
- * ARCFOUR or ARC4 because RC4 is how it is refered to in the SSH1 specification.
18
- *
19
- * Here's a short example of how to use this library:
20
- * <code>
21
- * <?php
22
- * include('Crypt/RC4.php');
23
- *
24
- * $rc4 = new Crypt_RC4();
25
- *
26
- * $rc4->setKey('abcdefgh');
27
- *
28
- * $size = 10 * 1024;
29
- * $plaintext = '';
30
- * for ($i = 0; $i < $size; $i++) {
31
- * $plaintext.= 'a';
32
- * }
33
- *
34
- * echo $rc4->decrypt($rc4->encrypt($plaintext));
35
- * ?>
36
- * </code>
37
- *
38
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
39
- * of this software and associated documentation files (the "Software"), to deal
40
- * in the Software without restriction, including without limitation the rights
41
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
42
- * copies of the Software, and to permit persons to whom the Software is
43
- * furnished to do so, subject to the following conditions:
44
- *
45
- * The above copyright notice and this permission notice shall be included in
46
- * all copies or substantial portions of the Software.
47
- *
48
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
49
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
50
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
51
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
52
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
53
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
54
- * THE SOFTWARE.
55
- *
56
- * @category Crypt
57
- * @package Crypt_RC4
58
- * @author Jim Wigginton <terrafrost@php.net>
59
- * @copyright MMVII Jim Wigginton
60
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
61
- * @version $Id: RC4.php,v 1.8 2009/06/09 04:00:38 terrafrost Exp $
62
- * @link http://phpseclib.sourceforge.net
63
- */
64
-
65
- /**#@+
66
- * @access private
67
- * @see Crypt_RC4::Crypt_RC4()
68
- */
69
- /**
70
- * Toggles the internal implementation
71
- */
72
- define('CRYPT_RC4_MODE_INTERNAL', 1);
73
- /**
74
- * Toggles the mcrypt implementation
75
- */
76
- define('CRYPT_RC4_MODE_MCRYPT', 2);
77
- /**#@-*/
78
-
79
- /**#@+
80
- * @access private
81
- * @see Crypt_RC4::_crypt()
82
- */
83
- define('CRYPT_RC4_ENCRYPT', 0);
84
- define('CRYPT_RC4_DECRYPT', 1);
85
- /**#@-*/
86
-
87
- /**
88
- * Pure-PHP implementation of RC4.
89
- *
90
- * @author Jim Wigginton <terrafrost@php.net>
91
- * @version 0.1.0
92
- * @access public
93
- * @package Crypt_RC4
94
- */
95
- class Crypt_RC4 {
96
- /**
97
- * The Key
98
- *
99
- * @see Crypt_RC4::setKey()
100
- * @var String
101
- * @access private
102
- */
103
- var $key = "\0";
104
-
105
- /**
106
- * The Key Stream for encryption
107
- *
108
- * If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object
109
- *
110
- * @see Crypt_RC4::setKey()
111
- * @var Array
112
- * @access private
113
- */
114
- var $encryptStream = false;
115
-
116
- /**
117
- * The Key Stream for decryption
118
- *
119
- * If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object
120
- *
121
- * @see Crypt_RC4::setKey()
122
- * @var Array
123
- * @access private
124
- */
125
- var $decryptStream = false;
126
-
127
- /**
128
- * The $i and $j indexes for encryption
129
- *
130
- * @see Crypt_RC4::_crypt()
131
- * @var Integer
132
- * @access private
133
- */
134
- var $encryptIndex = 0;
135
-
136
- /**
137
- * The $i and $j indexes for decryption
138
- *
139
- * @see Crypt_RC4::_crypt()
140
- * @var Integer
141
- * @access private
142
- */
143
- var $decryptIndex = 0;
144
-
145
- /**
146
- * MCrypt parameters
147
- *
148
- * @see Crypt_RC4::setMCrypt()
149
- * @var Array
150
- * @access private
151
- */
152
- var $mcrypt = array('', '');
153
-
154
- /**
155
- * The Encryption Algorithm
156
- *
157
- * Only used if CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT. Only possible values are MCRYPT_RC4 or MCRYPT_ARCFOUR.
158
- *
159
- * @see Crypt_RC4::Crypt_RC4()
160
- * @var Integer
161
- * @access private
162
- */
163
- var $mode;
164
-
165
- /**
166
- * Continuous Buffer status
167
- *
168
- * @see Crypt_RC4::enableContinuousBuffer()
169
- * @var Boolean
170
- * @access private
171
- */
172
- var $continuousBuffer = false;
173
-
174
- /**
175
- * Default Constructor.
176
- *
177
- * Determines whether or not the mcrypt extension should be used.
178
- *
179
- * @param optional Integer $mode
180
- * @return Crypt_RC4
181
- * @access public
182
- */
183
- function Crypt_RC4()
184
- {
185
- if ( !defined('CRYPT_RC4_MODE') ) {
186
- switch (true) {
187
- case extension_loaded('mcrypt') && (defined('MCRYPT_ARCFOUR') || defined('MCRYPT_RC4')):
188
- // i'd check to see if rc4 was supported, by doing in_array('arcfour', mcrypt_list_algorithms('')),
189
- // but since that can be changed after the object has been created, there doesn't seem to be
190
- // a lot of point...
191
- define('CRYPT_RC4_MODE', CRYPT_RC4_MODE_MCRYPT);
192
- break;
193
- default:
194
- define('CRYPT_RC4_MODE', CRYPT_RC4_MODE_INTERNAL);
195
- }
196
- }
197
-
198
- switch ( CRYPT_RC4_MODE ) {
199
- case CRYPT_RC4_MODE_MCRYPT:
200
- switch (true) {
201
- case defined('MCRYPT_ARCFOUR'):
202
- $this->mode = MCRYPT_ARCFOUR;
203
- break;
204
- case defined('MCRYPT_RC4');
205
- $this->mode = MCRYPT_RC4;
206
- }
207
- }
208
- }
209
-
210
- /**
211
- * Sets the key.
212
- *
213
- * Keys can be between 1 and 256 bytes long. If they are longer then 256 bytes, the first 256 bytes will
214
- * be used. If no key is explicitly set, it'll be assumed to be a single null byte.
215
- *
216
- * @access public
217
- * @param String $key
218
- */
219
- function setKey($key)
220
- {
221
- $this->key = $key;
222
-
223
- if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
224
- return;
225
- }
226
-
227
- $keyLength = strlen($key);
228
- $keyStream = array();
229
- for ($i = 0; $i < 256; $i++) {
230
- $keyStream[$i] = $i;
231
- }
232
- $j = 0;
233
- for ($i = 0; $i < 256; $i++) {
234
- $j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255;
235
- $temp = $keyStream[$i];
236
- $keyStream[$i] = $keyStream[$j];
237
- $keyStream[$j] = $temp;
238
- }
239
-
240
- $this->encryptIndex = $this->decryptIndex = array(0, 0);
241
- $this->encryptStream = $this->decryptStream = $keyStream;
242
- }
243
-
244
- /**
245
- * Dummy function.
246
- *
247
- * Some protocols, such as WEP, prepend an "initialization vector" to the key, effectively creating a new key [1].
248
- * If you need to use an initialization vector in this manner, feel free to prepend it to the key, yourself, before
249
- * calling setKey().
250
- *
251
- * [1] WEP's initialization vectors (IV's) are used in a somewhat insecure way. Since, in that protocol,
252
- * the IV's are relatively easy to predict, an attack described by
253
- * {@link http://www.drizzle.com/~aboba/IEEE/rc4_ksaproc.pdf Scott Fluhrer, Itsik Mantin, and Adi Shamir}
254
- * can be used to quickly guess at the rest of the key. The following links elaborate:
255
- *
256
- * {@link http://www.rsa.com/rsalabs/node.asp?id=2009 http://www.rsa.com/rsalabs/node.asp?id=2009}
257
- * {@link http://en.wikipedia.org/wiki/Related_key_attack http://en.wikipedia.org/wiki/Related_key_attack}
258
- *
259
- * @param String $iv
260
- * @see Crypt_RC4::setKey()
261
- * @access public
262
- */
263
- function setIV($iv)
264
- {
265
- }
266
-
267
- /**
268
- * Sets MCrypt parameters. (optional)
269
- *
270
- * If MCrypt is being used, empty strings will be used, unless otherwise specified.
271
- *
272
- * @link http://php.net/function.mcrypt-module-open#function.mcrypt-module-open
273
- * @access public
274
- * @param optional Integer $algorithm_directory
275
- * @param optional Integer $mode_directory
276
- */
277
- function setMCrypt($algorithm_directory = '', $mode_directory = '')
278
- {
279
- if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
280
- $this->mcrypt = array($algorithm_directory, $mode_directory);
281
- $this->_closeMCrypt();
282
- }
283
- }
284
-
285
- /**
286
- * Encrypts a message.
287
- *
288
- * @see Crypt_RC4::_crypt()
289
- * @access public
290
- * @param String $plaintext
291
- */
292
- function encrypt($plaintext)
293
- {
294
- return $this->_crypt($plaintext, CRYPT_RC4_ENCRYPT);
295
- }
296
-
297
- /**
298
- * Decrypts a message.
299
- *
300
- * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)).
301
- * Atleast if the continuous buffer is disabled.
302
- *
303
- * @see Crypt_RC4::_crypt()
304
- * @access public
305
- * @param String $ciphertext
306
- */
307
- function decrypt($ciphertext)
308
- {
309
- return $this->_crypt($ciphertext, CRYPT_RC4_DECRYPT);
310
- }
311
-
312
- /**
313
- * Encrypts or decrypts a message.
314
- *
315
- * @see Crypt_RC4::encrypt()
316
- * @see Crypt_RC4::decrypt()
317
- * @access private
318
- * @param String $text
319
- * @param Integer $mode
320
- */
321
- function _crypt($text, $mode)
322
- {
323
- if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
324
- $keyStream = $mode == CRYPT_RC4_ENCRYPT ? 'encryptStream' : 'decryptStream';
325
-
326
- if ($this->$keyStream === false) {
327
- $this->$keyStream = mcrypt_module_open($this->mode, $this->mcrypt[0], MCRYPT_MODE_STREAM, $this->mcrypt[1]);
328
- mcrypt_generic_init($this->$keyStream, $this->key, '');
329
- } else if (!$this->continuousBuffer) {
330
- mcrypt_generic_init($this->$keyStream, $this->key, '');
331
- }
332
- $newText = mcrypt_generic($this->$keyStream, $text);
333
- if (!$this->continuousBuffer) {
334
- mcrypt_generic_deinit($this->$keyStream);
335
- }
336
-
337
- return $newText;
338
- }
339
-
340
- if ($this->encryptStream === false) {
341
- $this->setKey($this->key);
342
- }
343
-
344
- switch ($mode) {
345
- case CRYPT_RC4_ENCRYPT:
346
- $keyStream = $this->encryptStream;
347
- list($i, $j) = $this->encryptIndex;
348
- break;
349
- case CRYPT_RC4_DECRYPT:
350
- $keyStream = $this->decryptStream;
351
- list($i, $j) = $this->decryptIndex;
352
- }
353
-
354
- $newText = '';
355
- for ($k = 0; $k < strlen($text); $k++) {
356
- $i = ($i + 1) & 255;
357
- $j = ($j + $keyStream[$i]) & 255;
358
- $temp = $keyStream[$i];
359
- $keyStream[$i] = $keyStream[$j];
360
- $keyStream[$j] = $temp;
361
- $temp = $keyStream[($keyStream[$i] + $keyStream[$j]) & 255];
362
- $newText.= chr(ord($text[$k]) ^ $temp);
363
- }
364
-
365
- if ($this->continuousBuffer) {
366
- switch ($mode) {
367
- case CRYPT_RC4_ENCRYPT:
368
- $this->encryptStream = $keyStream;
369
- $this->encryptIndex = array($i, $j);
370
- break;
371
- case CRYPT_RC4_DECRYPT:
372
- $this->decryptStream = $keyStream;
373
- $this->decryptIndex = array($i, $j);
374
- }
375
- }
376
-
377
- return $newText;
378
- }
379
-
380
- /**
381
- * Treat consecutive "packets" as if they are a continuous buffer.
382
- *
383
- * Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
384
- * will yield different outputs:
385
- *
386
- * <code>
387
- * echo $rc4->encrypt(substr($plaintext, 0, 8));
388
- * echo $rc4->encrypt(substr($plaintext, 8, 8));
389
- * </code>
390
- * <code>
391
- * echo $rc4->encrypt($plaintext);
392
- * </code>
393
- *
394
- * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
395
- * another, as demonstrated with the following:
396
- *
397
- * <code>
398
- * $rc4->encrypt(substr($plaintext, 0, 8));
399
- * echo $rc4->decrypt($des->encrypt(substr($plaintext, 8, 8)));
400
- * </code>
401
- * <code>
402
- * echo $rc4->decrypt($des->encrypt(substr($plaintext, 8, 8)));
403
- * </code>
404
- *
405
- * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
406
- * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
407
- * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
408
- *
409
- * Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
410
- * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
411
- * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
412
- * however, they are also less intuitive and more likely to cause you problems.
413
- *
414
- * @see Crypt_RC4::disableContinuousBuffer()
415
- * @access public
416
- */
417
- function enableContinuousBuffer()
418
- {
419
- $this->continuousBuffer = true;
420
- }
421
-
422
- /**
423
- * Treat consecutive packets as if they are a discontinuous buffer.
424
- *
425
- * The default behavior.
426
- *
427
- * @see Crypt_RC4::enableContinuousBuffer()
428
- * @access public
429
- */
430
- function disableContinuousBuffer()
431
- {
432
- if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_INTERNAL ) {
433
- $this->encryptIndex = $this->decryptIndex = array(0, 0);
434
- $this->setKey($this->key);
435
- }
436
-
437
- $this->continuousBuffer = false;
438
- }
439
-
440
- /**
441
- * Dummy function.
442
- *
443
- * Since RC4 is a stream cipher and not a block cipher, no padding is necessary. The only reason this function is
444
- * included is so that you can switch between a block cipher and a stream cipher transparently.
445
- *
446
- * @see Crypt_RC4::disablePadding()
447
- * @access public
448
- */
449
- function enablePadding()
450
- {
451
- }
452
-
453
- /**
454
- * Dummy function.
455
- *
456
- * @see Crypt_RC4::enablePadding()
457
- * @access public
458
- */
459
- function disablePadding()
460
- {
461
- }
462
-
463
- /**
464
- * Class destructor.
465
- *
466
- * Will be called, automatically, if you're using PHP5. If you're using PHP4, call it yourself. Only really
467
- * needs to be called if mcrypt is being used.
468
- *
469
- * @access public
470
- */
471
- function __destruct()
472
- {
473
- if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
474
- $this->_closeMCrypt();
475
- }
476
- }
477
-
478
- /**
479
- * Properly close the MCrypt objects.
480
- *
481
- * @access prviate
482
- */
483
- function _closeMCrypt()
484
- {
485
- if ( $this->encryptStream !== false ) {
486
- if ( $this->continuousBuffer ) {
487
- mcrypt_generic_deinit($this->encryptStream);
488
- }
489
-
490
- mcrypt_module_close($this->encryptStream);
491
-
492
- $this->encryptStream = false;
493
- }
494
-
495
- if ( $this->decryptStream !== false ) {
496
- if ( $this->continuousBuffer ) {
497
- mcrypt_generic_deinit($this->decryptStream);
498
- }
499
-
500
- mcrypt_module_close($this->decryptStream);
501
-
502
- $this->decryptStream = false;
503
- }
504
- }
505
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpseclib/Crypt/Random.php DELETED
@@ -1,133 +0,0 @@
1
- <?php
2
- /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
-
4
- /**
5
- * Random Number Generator
6
- *
7
- * PHP versions 4 and 5
8
- *
9
- * Here's a short example of how to use this library:
10
- * <code>
11
- * <?php
12
- * include('Crypt/Random.php');
13
- *
14
- * echo crypt_random();
15
- * ?>
16
- * </code>
17
- *
18
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
19
- * of this software and associated documentation files (the "Software"), to deal
20
- * in the Software without restriction, including without limitation the rights
21
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
22
- * copies of the Software, and to permit persons to whom the Software is
23
- * furnished to do so, subject to the following conditions:
24
- *
25
- * The above copyright notice and this permission notice shall be included in
26
- * all copies or substantial portions of the Software.
27
- *
28
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
33
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
34
- * THE SOFTWARE.
35
- *
36
- * @category Crypt
37
- * @package Crypt_Random
38
- * @author Jim Wigginton <terrafrost@php.net>
39
- * @copyright MMVII Jim Wigginton
40
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
41
- * @version $Id: Random.php,v 1.9 2010/04/24 06:40:48 terrafrost Exp $
42
- * @link http://phpseclib.sourceforge.net
43
- */
44
-
45
- /**
46
- * Generate a random value.
47
- *
48
- * On 32-bit machines, the largest distance that can exist between $min and $max is 2**31.
49
- * If $min and $max are farther apart than that then the last ($max - range) numbers.
50
- *
51
- * Depending on how this is being used, it may be worth while to write a replacement. For example,
52
- * a PHP-based web app that stores its data in an SQL database can collect more entropy than this function
53
- * can.
54
- *
55
- * @param optional Integer $min
56
- * @param optional Integer $max
57
- * @return Integer
58
- * @access public
59
- */
60
- function crypt_random($min = 0, $max = 0x7FFFFFFF)
61
- {
62
- if ($min == $max) {
63
- return $min;
64
- }
65
-
66
- // see http://en.wikipedia.org/wiki//dev/random
67
- static $urandom = true;
68
- if ($urandom === true) {
69
- // Warning's will be output unles the error suppression operator is used. Errors such as
70
- // "open_basedir restriction in effect", "Permission denied", "No such file or directory", etc.
71
- $urandom = @fopen('/dev/urandom', 'rb');
72
- }
73
- if (!is_bool($urandom)) {
74
- extract(unpack('Nrandom', fread($urandom, 4)));
75
-
76
- // say $min = 0 and $max = 3. if we didn't do abs() then we could have stuff like this:
77
- // -4 % 3 + 0 = -1, even though -1 < $min
78
- return abs($random) % ($max - $min) + $min;
79
- }
80
-
81
- /* Prior to PHP 4.2.0, mt_srand() had to be called before mt_rand() could be called.
82
- Prior to PHP 5.2.6, mt_rand()'s automatic seeding was subpar, as elaborated here:
83
-
84
- http://www.suspekt.org/2008/08/17/mt_srand-and-not-so-random-numbers/
85
-
86
- The seeding routine is pretty much ripped from PHP's own internal GENERATE_SEED() macro:
87
-
88
- http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3_2/ext/standard/php_rand.h?view=markup */
89
- if (version_compare(PHP_VERSION, '5.2.5', '<=')) {
90
- static $seeded;
91
- if (!isset($seeded)) {
92
- $seeded = true;
93
- mt_srand(fmod(time() * getmypid(), 0x7FFFFFFF) ^ fmod(1000000 * lcg_value(), 0x7FFFFFFF));
94
- }
95
- }
96
-
97
- static $crypto;
98
-
99
- // The CSPRNG's Yarrow and Fortuna periodically reseed. This function can be reseeded by hitting F5
100
- // in the browser and reloading the page.
101
-
102
- if (!isset($crypto)) {
103
- $key = $iv = '';
104
- for ($i = 0; $i < 8; $i++) {
105
- $key.= pack('n', mt_rand(0, 0xFFFF));
106
- $iv .= pack('n', mt_rand(0, 0xFFFF));
107
- }
108
- switch (true) {
109
- case class_exists('Crypt_AES'):
110
- $crypto = new Crypt_AES(CRYPT_AES_MODE_CTR);
111
- break;
112
- case class_exists('Crypt_TripleDES'):
113
- $crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
114
- break;
115
- case class_exists('Crypt_DES'):
116
- $crypto = new Crypt_DES(CRYPT_DES_MODE_CTR);
117
- break;
118
- case class_exists('Crypt_RC4'):
119
- $crypto = new Crypt_RC4();
120
- break;
121
- default:
122
- extract(unpack('Nrandom', pack('H*', sha1(mt_rand(0, 0x7FFFFFFF)))));
123
- return abs($random) % ($max - $min) + $min;
124
- }
125
- $crypto->setKey($key);
126
- $crypto->setIV($iv);
127
- $crypto->enableContinuousBuffer();
128
- }
129
-
130
- extract(unpack('Nrandom', $crypto->encrypt("\0\0\0\0")));
131
- return abs($random) % ($max - $min) + $min;
132
- }
133
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpseclib/Crypt/Rijndael.php DELETED
@@ -1,1424 +0,0 @@
1
- <?php
2
- /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
-
4
- /**
5
- * Pure-PHP implementation of Rijndael.
6
- *
7
- * Does not use mcrypt, even when available, for reasons that are explained below.
8
- *
9
- * PHP versions 4 and 5
10
- *
11
- * If {@link Crypt_Rijndael::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits. If
12
- * {@link Crypt_Rijndael::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
13
- * {@link Crypt_Rijndael::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's
14
- * 136-bits it'll be null-padded to 160-bits and 160 bits will be the key length until
15
- * {@link Crypt_Rijndael::setKey() setKey()} is called, again, at which point, it'll be recalculated.
16
- *
17
- * Not all Rijndael implementations may support 160-bits or 224-bits as the block length / key length. mcrypt, for example,
18
- * does not. AES, itself, only supports block lengths of 128 and key lengths of 128, 192, and 256.
19
- * {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=10 Rijndael-ammended.pdf#page=10} defines the
20
- * algorithm for block lengths of 192 and 256 but not for block lengths / key lengths of 160 and 224. Indeed, 160 and 224
21
- * are first defined as valid key / block lengths in
22
- * {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=44 Rijndael-ammended.pdf#page=44}:
23
- * Extensions: Other block and Cipher Key lengths.
24
- *
25
- * {@internal The variable names are the same as those in
26
- * {@link http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf#page=10 fips-197.pdf#page=10}.}}
27
- *
28
- * Here's a short example of how to use this library:
29
- * <code>
30
- * <?php
31
- * include('Crypt/Rijndael.php');
32
- *
33
- * $rijndael = new Crypt_Rijndael();
34
- *
35
- * $rijndael->setKey('abcdefghijklmnop');
36
- *
37
- * $size = 10 * 1024;
38
- * $plaintext = '';
39
- * for ($i = 0; $i < $size; $i++) {
40
- * $plaintext.= 'a';
41
- * }
42
- *
43
- * echo $rijndael->decrypt($rijndael->encrypt($plaintext));
44
- * ?>
45
- * </code>
46
- *
47
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
48
- * of this software and associated documentation files (the "Software"), to deal
49
- * in the Software without restriction, including without limitation the rights
50
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
51
- * copies of the Software, and to permit persons to whom the Software is
52
- * furnished to do so, subject to the following conditions:
53
- *
54
- * The above copyright notice and this permission notice shall be included in
55
- * all copies or substantial portions of the Software.
56
- *
57
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
58
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
59
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
60
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
61
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
62
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
63
- * THE SOFTWARE.
64
- *
65
- * @category Crypt
66
- * @package Crypt_Rijndael
67
- * @author Jim Wigginton <terrafrost@php.net>
68
- * @copyright MMVIII Jim Wigginton
69
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
70
- * @version $Id: Rijndael.php,v 1.12 2010/02/09 06:10:26 terrafrost Exp $
71
- * @link http://phpseclib.sourceforge.net
72
- */
73
-
74
- /**#@+
75
- * @access public
76
- * @see Crypt_Rijndael::encrypt()
77
- * @see Crypt_Rijndael::decrypt()
78
- */
79
- /**
80
- * Encrypt / decrypt using the Counter mode.
81
- *
82
- * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
83
- *
84
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
85
- */
86
- define('CRYPT_RIJNDAEL_MODE_CTR', -1);
87
- /**
88
- * Encrypt / decrypt using the Electronic Code Book mode.
89
- *
90
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
91
- */
92
- define('CRYPT_RIJNDAEL_MODE_ECB', 1);
93
- /**
94
- * Encrypt / decrypt using the Code Book Chaining mode.
95
- *
96
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
97
- */
98
- define('CRYPT_RIJNDAEL_MODE_CBC', 2);
99
- /**
100
- * Encrypt / decrypt using the Cipher Feedback mode.
101
- *
102
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
103
- */
104
- define('CRYPT_RIJNDAEL_MODE_CFB', 3);
105
- /**
106
- * Encrypt / decrypt using the Cipher Feedback mode.
107
- *
108
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
109
- */
110
- define('CRYPT_RIJNDAEL_MODE_OFB', 4);
111
- /**#@-*/
112
-
113
- /**#@+
114
- * @access private
115
- * @see Crypt_Rijndael::Crypt_Rijndael()
116
- */
117
- /**
118
- * Toggles the internal implementation
119
- */
120
- define('CRYPT_RIJNDAEL_MODE_INTERNAL', 1);
121
- /**
122
- * Toggles the mcrypt implementation
123
- */
124
- define('CRYPT_RIJNDAEL_MODE_MCRYPT', 2);
125
- /**#@-*/
126
-
127
- /**
128
- * Pure-PHP implementation of Rijndael.
129
- *
130
- * @author Jim Wigginton <terrafrost@php.net>
131
- * @version 0.1.0
132
- * @access public
133
- * @package Crypt_Rijndael
134
- */
135
- class Crypt_Rijndael {
136
- /**
137
- * The Encryption Mode
138
- *
139
- * @see Crypt_Rijndael::Crypt_Rijndael()
140
- * @var Integer
141
- * @access private
142
- */
143
- var $mode;
144
-
145
- /**
146
- * The Key
147
- *
148
- * @see Crypt_Rijndael::setKey()
149
- * @var String
150
- * @access private
151
- */
152
- var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
153
-
154
- /**
155
- * The Initialization Vector
156
- *
157
- * @see Crypt_Rijndael::setIV()
158
- * @var String
159
- * @access private
160
- */
161
- var $iv = '';
162
-
163
- /**
164
- * A "sliding" Initialization Vector
165
- *
166
- * @see Crypt_Rijndael::enableContinuousBuffer()
167
- * @var String
168
- * @access private
169
- */
170
- var $encryptIV = '';
171
-
172
- /**
173
- * A "sliding" Initialization Vector
174
- *
175
- * @see Crypt_Rijndael::enableContinuousBuffer()
176
- * @var String
177
- * @access private
178
- */
179
- var $decryptIV = '';
180
-
181
- /**
182
- * Continuous Buffer status
183
- *
184
- * @see Crypt_Rijndael::enableContinuousBuffer()
185
- * @var Boolean
186
- * @access private
187
- */
188
- var $continuousBuffer = false;
189
-
190
- /**
191
- * Padding status
192
- *
193
- * @see Crypt_Rijndael::enablePadding()
194
- * @var Boolean
195
- * @access private
196
- */
197
- var $padding = true;
198
-
199
- /**
200
- * Does the key schedule need to be (re)calculated?
201
- *
202
- * @see setKey()
203
- * @see setBlockLength()
204
- * @see setKeyLength()
205
- * @var Boolean
206
- * @access private
207
- */
208
- var $changed = true;
209
-
210
- /**
211
- * Has the key length explicitly been set or should it be derived from the key, itself?
212
- *
213
- * @see setKeyLength()
214
- * @var Boolean
215
- * @access private
216
- */
217
- var $explicit_key_length = false;
218
-
219
- /**
220
- * The Key Schedule
221
- *
222
- * @see _setup()
223
- * @var Array
224
- * @access private
225
- */
226
- var $w;
227
-
228
- /**
229
- * The Inverse Key Schedule
230
- *
231
- * @see _setup()
232
- * @var Array
233
- * @access private
234
- */
235
- var $dw;
236
-
237
- /**
238
- * The Block Length
239
- *
240
- * @see setBlockLength()
241
- * @var Integer
242
- * @access private
243
- * @internal The max value is 32, the min value is 16. All valid values are multiples of 4. Exists in conjunction with
244
- * $Nb because we need this value and not $Nb to pad strings appropriately.
245
- */
246
- var $block_size = 16;
247
-
248
- /**
249
- * The Block Length divided by 32
250
- *
251
- * @see setBlockLength()
252
- * @var Integer
253
- * @access private
254
- * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size
255
- * because the encryption / decryption / key schedule creation requires this number and not $block_size. We could
256
- * derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
257
- * of that, we'll just precompute it once.
258
- *
259
- */
260
- var $Nb = 4;
261
-
262
- /**
263
- * The Key Length
264
- *
265
- * @see setKeyLength()
266
- * @var Integer
267
- * @access private
268
- * @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $key_size
269
- * because the encryption / decryption / key schedule creation requires this number and not $key_size. We could
270
- * d