From 73a00aafaa5fd3340b85c153d72b0daa9fa3113a Mon Sep 17 00:00:00 2001 From: Quentin Ligier Date: Wed, 27 Apr 2016 10:10:44 +0200 Subject: [PATCH 01/20] SQL structure changes See #531 --- php/database/update_030102.php | 49 ++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 php/database/update_030102.php diff --git a/php/database/update_030102.php b/php/database/update_030102.php new file mode 100644 index 0000000..c4e2677 --- /dev/null +++ b/php/database/update_030102.php @@ -0,0 +1,49 @@ + \ No newline at end of file From 5b6b64bce3925696e6ad9f8a44264c6daff7f734 Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Mon, 2 May 2016 19:51:06 +0200 Subject: [PATCH 02/20] Updated version --- src/package.json | 2 +- src/scripts/lychee.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/package.json b/src/package.json index 12550fe..cdf7be2 100644 --- a/src/package.json +++ b/src/package.json @@ -1,6 +1,6 @@ { "name": "Lychee", - "version": "3.1.1", + "version": "3.1.2", "description": "Self-hosted photo-management done right.", "authors": "Tobias Reich ", "license": "MIT", diff --git a/src/scripts/lychee.js b/src/scripts/lychee.js index f0187fd..105e5ba 100644 --- a/src/scripts/lychee.js +++ b/src/scripts/lychee.js @@ -6,8 +6,8 @@ lychee = { title : document.title, - version : '3.1.1', - versionCode : '030101', + version : '3.1.2', + versionCode : '030102', updatePath : '//update.electerious.com/index.json', updateURL : 'https://github.com/electerious/Lychee', From 895825ada070c34ecf0646f64546d57be65fa8c4 Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Mon, 2 May 2016 19:51:21 +0200 Subject: [PATCH 03/20] Added #533 to the list of update scripts --- php/Modules/Database.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/Modules/Database.php b/php/Modules/Database.php index 11afdff..11924b5 100755 --- a/php/Modules/Database.php +++ b/php/Modules/Database.php @@ -14,7 +14,8 @@ final class Database { '030000', // 3.0.0 '030001', // 3.0.1 '030003', // 3.0.3 - '030100' // 3.1.0 + '030100', // 3.1.0 + '030102' // 3.1.2 ); /** From c52e93b7ac716432dc5bf03faea4db0f53ac95d1 Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Mon, 2 May 2016 19:51:29 +0200 Subject: [PATCH 04/20] Small syntax adjustment to #533 --- php/database/update_030102.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/database/update_030102.php b/php/database/update_030102.php index c4e2677..06e3eb3 100644 --- a/php/database/update_030102.php +++ b/php/database/update_030102.php @@ -40,7 +40,6 @@ if ($result===false) Response::error('Could not change type of the id field!'); // Change type of the id field $query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `id` `id` BIGINT(14) UNSIGNED NOT NULL", [LYCHEE_TABLE_ALBUMS]); $result = Database::execute($connection, $query, 'update_030102', __LINE__); - if ($result===false) Response::error('Could not change type of the id field!'); // Set version From a5c47cf02298fd7e99f976acc893244a378367dd Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Mon, 2 May 2016 20:04:41 +0200 Subject: [PATCH 05/20] Use array() instead of shorthand as done in the other scripts --- php/database/update_030102.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/php/database/update_030102.php b/php/database/update_030102.php index 06e3eb3..7607284 100644 --- a/php/database/update_030102.php +++ b/php/database/update_030102.php @@ -8,37 +8,37 @@ use Lychee\Modules\Database; use Lychee\Modules\Response; // Change type of the album id field -$query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `album` `album` BIGINT UNSIGNED NOT NULL", [LYCHEE_TABLE_PHOTOS]); +$query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `album` `album` BIGINT UNSIGNED NOT NULL", array(LYCHEE_TABLE_PHOTOS)); $result = Database::execute($connection, $query, 'update_030102', __LINE__); if ($result===false) Response::error('Could not change type of the album id field!'); // Add index to the album id field -$query = Database::prepare($connection, "ALTER TABLE `?` ADD INDEX `Index_album` (`album`)", [LYCHEE_TABLE_PHOTOS]); +$query = Database::prepare($connection, "ALTER TABLE `?` ADD INDEX `Index_album` (`album`)", array(LYCHEE_TABLE_PHOTOS)); $result = Database::execute($connection, $query, 'update_030102', __LINE__); if ($result===false) Response::error('Could not add index to the album id field!'); // Add index to the star field -$query = Database::prepare($connection, "ALTER TABLE `?` ADD INDEX `Index_star` (`star`)", [LYCHEE_TABLE_PHOTOS]); +$query = Database::prepare($connection, "ALTER TABLE `?` ADD INDEX `Index_star` (`star`)", array(LYCHEE_TABLE_PHOTOS)); $result = Database::execute($connection, $query, 'update_030102', __LINE__); if ($result===false) Response::error('Could not add index to the star field!'); // Change type of the checksum field -$query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `checksum` `checksum` CHAR(40) NULL DEFAULT NULL", [LYCHEE_TABLE_PHOTOS]); +$query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `checksum` `checksum` CHAR(40) NULL DEFAULT NULL", array(LYCHEE_TABLE_PHOTOS)); $result = Database::execute($connection, $query, 'update_030102', __LINE__); if ($result===false) Response::error('Could not change type of the checksum field!'); // Change type of the thumbUrl field -$query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `thumbUrl` `thumbUrl` CHAR(37) NOT NULL", [LYCHEE_TABLE_PHOTOS]); +$query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `thumbUrl` `thumbUrl` CHAR(37) NOT NULL", array(LYCHEE_TABLE_PHOTOS)); $result = Database::execute($connection, $query, 'update_030102', __LINE__); if ($result===false) Response::error('Could not change type of the thumbUrl field!'); // Change type of the id field -$query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `id` `id` BIGINT(14) UNSIGNED NOT NULL", [LYCHEE_TABLE_PHOTOS]); +$query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `id` `id` BIGINT(14) UNSIGNED NOT NULL", array(LYCHEE_TABLE_PHOTOS)); $result = Database::execute($connection, $query, 'update_030102', __LINE__); if ($result===false) Response::error('Could not change type of the id field!'); // Change type of the id field -$query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `id` `id` BIGINT(14) UNSIGNED NOT NULL", [LYCHEE_TABLE_ALBUMS]); +$query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `id` `id` BIGINT(14) UNSIGNED NOT NULL", array(LYCHEE_TABLE_ALBUMS)); $result = Database::execute($connection, $query, 'update_030102', __LINE__); if ($result===false) Response::error('Could not change type of the id field!'); From 2ce58d2821ea4b571fbb194167352a01857f9f61 Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Mon, 2 May 2016 20:44:41 +0200 Subject: [PATCH 06/20] Fixed error when executing update script multiple times #533 --- php/database/update_030102.php | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/php/database/update_030102.php b/php/database/update_030102.php index 7607284..c18cdcf 100644 --- a/php/database/update_030102.php +++ b/php/database/update_030102.php @@ -10,36 +10,61 @@ use Lychee\Modules\Response; // Change type of the album id field $query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `album` `album` BIGINT UNSIGNED NOT NULL", array(LYCHEE_TABLE_PHOTOS)); $result = Database::execute($connection, $query, 'update_030102', __LINE__); + if ($result===false) Response::error('Could not change type of the album id field!'); // Add index to the album id field -$query = Database::prepare($connection, "ALTER TABLE `?` ADD INDEX `Index_album` (`album`)", array(LYCHEE_TABLE_PHOTOS)); +$query = Database::prepare($connection, "SHOW INDEX FROM `?` WHERE KEY_NAME = 'Index_album'", array(LYCHEE_TABLE_PHOTOS)); $result = Database::execute($connection, $query, 'update_030102', __LINE__); -if ($result===false) Response::error('Could not add index to the album id field!'); + +if ($result===false) Response::error('Could not check if Index_album exists!'); + +if ($result->num_rows===0) { + + $query = Database::prepare($connection, "ALTER TABLE `?` ADD INDEX `Index_album` (`album`)", array(LYCHEE_TABLE_PHOTOS)); + $result = Database::execute($connection, $query, 'update_030102', __LINE__); + + if ($result===false) Response::error('Could not add index to the album id field!'); + +} // Add index to the star field -$query = Database::prepare($connection, "ALTER TABLE `?` ADD INDEX `Index_star` (`star`)", array(LYCHEE_TABLE_PHOTOS)); +$query = Database::prepare($connection, "SHOW INDEX FROM `?` WHERE KEY_NAME = 'Index_star'", array(LYCHEE_TABLE_PHOTOS)); $result = Database::execute($connection, $query, 'update_030102', __LINE__); -if ($result===false) Response::error('Could not add index to the star field!'); + +if ($result===false) Response::error('Could not check if Index_star exists!'); + +if ($result->num_rows===0) { + + $query = Database::prepare($connection, "ALTER TABLE `?` ADD INDEX `Index_star` (`star`)", array(LYCHEE_TABLE_PHOTOS)); + $result = Database::execute($connection, $query, 'update_030102', __LINE__); + + if ($result===false) Response::error('Could not add index to the star field!'); + +} // Change type of the checksum field $query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `checksum` `checksum` CHAR(40) NULL DEFAULT NULL", array(LYCHEE_TABLE_PHOTOS)); $result = Database::execute($connection, $query, 'update_030102', __LINE__); + if ($result===false) Response::error('Could not change type of the checksum field!'); // Change type of the thumbUrl field $query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `thumbUrl` `thumbUrl` CHAR(37) NOT NULL", array(LYCHEE_TABLE_PHOTOS)); $result = Database::execute($connection, $query, 'update_030102', __LINE__); + if ($result===false) Response::error('Could not change type of the thumbUrl field!'); // Change type of the id field $query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `id` `id` BIGINT(14) UNSIGNED NOT NULL", array(LYCHEE_TABLE_PHOTOS)); $result = Database::execute($connection, $query, 'update_030102', __LINE__); + if ($result===false) Response::error('Could not change type of the id field!'); // Change type of the id field $query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `id` `id` BIGINT(14) UNSIGNED NOT NULL", array(LYCHEE_TABLE_ALBUMS)); $result = Database::execute($connection, $query, 'update_030102', __LINE__); + if ($result===false) Response::error('Could not change type of the id field!'); // Set version From 70cd7f8a47cd469ed1e2409d2e34dd4b0a07933d Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Wed, 1 Jun 2016 21:42:01 +0200 Subject: [PATCH 07/20] Protocol-relative URLs for open graph #546 --- php/helpers/getGraphHeader.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/helpers/getGraphHeader.php b/php/helpers/getGraphHeader.php index 77e48a7..c50b173 100644 --- a/php/helpers/getGraphHeader.php +++ b/php/helpers/getGraphHeader.php @@ -24,8 +24,8 @@ function getGraphHeader($photoID) { else $dir = 'big'; $parseUrl = parse_url('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); - $url = $parseUrl['scheme'] . '://' . $parseUrl['host'] . $parseUrl['path'] . '?' . $parseUrl['query']; - $picture = $parseUrl['scheme'] . '://' . $parseUrl['host'] . $parseUrl['path'] . '/../uploads/' . $dir . '/' . $row->url; + $url = '//' . $parseUrl['host'] . $parseUrl['path'] . '?' . $parseUrl['query']; + $picture = '//' . $parseUrl['host'] . $parseUrl['path'] . '/../uploads/' . $dir . '/' . $row->url; $url = htmlentities($url); $picture = htmlentities($picture); From a9cfa87fd24953cf15023253181817e9880943e4 Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Sun, 5 Jun 2016 15:47:41 +0200 Subject: [PATCH 08/20] Improved orientation-handling with Imagick #556 --- php/Modules/Photo.php | 75 ++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 23 deletions(-) diff --git a/php/Modules/Photo.php b/php/Modules/Photo.php index 8870307..b4fccda 100755 --- a/php/Modules/Photo.php +++ b/php/Modules/Photo.php @@ -472,38 +472,67 @@ final class Photo { if (extension_loaded('imagick')&&Settings::get()['imagick']==='1') { - switch ($info['orientation']) { + $image = new Imagick(); + $image->readImage($path); - case 3: - $rotateImage = 180; - break; + $orientation = $image->getImageOrientation(); - case 6: - $rotateImage = 90; - $swapSize = true; - break; + // Check if the images needs to be adjusted at all + if ($orientation!==Imagick::ORIENTATION_TOPLEFT) { - case 8: - $rotateImage = 270; - $swapSize = true; - break; + switch ($orientation) { - default: - return false; - break; + case Imagick::ORIENTATION_TOPLEFT: + break; - } + case Imagick::ORIENTATION_TOPRIGHT: + $image->flopImage(); + break; - if ($rotateImage!==0) { - $image = new Imagick(); - $image->readImage($path); - $image->rotateImage(new ImagickPixel(), $rotateImage); - $image->setImageOrientation(1); + case Imagick::ORIENTATION_BOTTOMRIGHT: + $image->rotateImage(new ImagickPixel(), 180); + break; + + case Imagick::ORIENTATION_BOTTOMLEFT: + $image->flopImage(); + $image->rotateImage(new ImagickPixel(), 180); + break; + + case Imagick::ORIENTATION_LEFTTOP: + $image->flopImage(); + $image->rotateImage(new ImagickPixel(), -90); + $swapSize = true; + break; + + case Imagick::ORIENTATION_RIGHTTOP: + $image->rotateImage(new ImagickPixel(), 90); + $swapSize = true; + break; + + case Imagick::ORIENTATION_RIGHTBOTTOM: + $image->flopImage(); + $image->rotateImage(new ImagickPixel(), 90); + $swapSize = true; + break; + + case Imagick::ORIENTATION_LEFTBOTTOM: + $image->rotateImage(new ImagickPixel(), -90); + $swapSize = true; + break; + + default: + break; + + } + + $image->setImageOrientation(Imagick::ORIENTATION_TOPLEFT); $image->writeImage($path); - $image->clear(); - $image->destroy(); + } + $image->clear(); + $image->destroy(); + } else { $newWidth = $info['width']; From c6cb750363843a9f9b1fb724697eebe03a220008 Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Sun, 5 Jun 2016 15:53:00 +0200 Subject: [PATCH 09/20] Removed comment that somehow destroyed the whole syntax highlighting in Atom --- php/Modules/Photo.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/Modules/Photo.php b/php/Modules/Photo.php index b4fccda..815a5e9 100755 --- a/php/Modules/Photo.php +++ b/php/Modules/Photo.php @@ -238,7 +238,6 @@ final class Photo { } - // Save to DB $values = array(LYCHEE_TABLE_PHOTOS, $id, $info['title'], $photo_name, $info['description'], $info['tags'], $info['type'], $info['width'], $info['height'], $info['size'], $info['iso'], $info['aperture'], $info['make'], $info['model'], $info['shutter'], $info['focal'], $info['takestamp'], $path_thumb, $albumID, $public, $star, $checksum, $medium); $query = Database::prepare(Database::get(), "INSERT INTO ? (id, title, url, description, tags, type, width, height, size, iso, aperture, make, model, shutter, focal, takestamp, thumbUrl, album, public, star, checksum, medium) VALUES ('?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?')", $values); $result = Database::execute(Database::get(), $query, __METHOD__, __LINE__); From 57acac71da395e9e5e200a5ca6948f7a65b47026 Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Sat, 11 Jun 2016 15:53:13 +0200 Subject: [PATCH 10/20] Renamed thumb quality variable --- php/Modules/Photo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/Modules/Photo.php b/php/Modules/Photo.php index 815a5e9..8ec06ba 100755 --- a/php/Modules/Photo.php +++ b/php/Modules/Photo.php @@ -295,7 +295,7 @@ final class Photo { Plugins::get()->activate(__METHOD__, 0, func_get_args()); // Quality of thumbnails - $thumbQuality = 90; + $quality = 90; // Size of the thumbnail $newWidth = 200; @@ -311,7 +311,7 @@ final class Photo { // Read image $thumb = new Imagick(); $thumb->readImage($url); - $thumb->setImageCompressionQuality($thumbQuality); + $thumb->setImageCompressionQuality($quality); $thumb->setImageFormat('jpeg'); // Copy image for 2nd thumb version From 55628f1f5659cf84a49a84a356ecf0e9670c2a15 Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Sat, 11 Jun 2016 15:54:41 +0200 Subject: [PATCH 11/20] Remove metadata from medium-photos and thumbs + Reduce quality of medium-photos #556 --- php/Modules/Photo.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/php/Modules/Photo.php b/php/Modules/Photo.php index 8ec06ba..923fe75 100755 --- a/php/Modules/Photo.php +++ b/php/Modules/Photo.php @@ -314,6 +314,9 @@ final class Photo { $thumb->setImageCompressionQuality($quality); $thumb->setImageFormat('jpeg'); + // Remove metadata to save some bytes + $thumb->stripImage(); + // Copy image for 2nd thumb version $thumb2x = clone $thumb; @@ -394,6 +397,9 @@ final class Photo { // Call plugins Plugins::get()->activate(__METHOD__, 0, func_get_args()); + // Quality of medium-photo + $quality = 90; + // Set to true when creation of medium-photo failed $error = false; @@ -426,6 +432,8 @@ final class Photo { // Adjust image $medium->scaleImage($newWidth, $newHeight, true); + $medium->stripImage(); + $medium->setImageCompressionQuality($quality); // Save image try { $medium->writeImage($newUrl); } From 9bfa149d29364a0032408d490cf2edc49c2e2177 Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Sat, 11 Jun 2016 15:55:05 +0200 Subject: [PATCH 12/20] EXIF orientation rotation code adjustments #556 --- php/Modules/Photo.php | 87 +++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/php/Modules/Photo.php b/php/Modules/Photo.php index 923fe75..955f0d9 100755 --- a/php/Modules/Photo.php +++ b/php/Modules/Photo.php @@ -484,59 +484,58 @@ final class Photo { $orientation = $image->getImageOrientation(); - // Check if the images needs to be adjusted at all - if ($orientation!==Imagick::ORIENTATION_TOPLEFT) { + switch ($orientation) { - switch ($orientation) { - - case Imagick::ORIENTATION_TOPLEFT: - break; - - case Imagick::ORIENTATION_TOPRIGHT: - $image->flopImage(); - break; - - case Imagick::ORIENTATION_BOTTOMRIGHT: - $image->rotateImage(new ImagickPixel(), 180); - break; + case Imagick::ORIENTATION_TOPLEFT: + return false; + break; - case Imagick::ORIENTATION_BOTTOMLEFT: - $image->flopImage(); - $image->rotateImage(new ImagickPixel(), 180); - break; + case Imagick::ORIENTATION_TOPRIGHT: + $image->flopImage(); + break; - case Imagick::ORIENTATION_LEFTTOP: - $image->flopImage(); - $image->rotateImage(new ImagickPixel(), -90); - $swapSize = true; - break; + case Imagick::ORIENTATION_BOTTOMRIGHT: + $image->rotateImage(new ImagickPixel(), 180); + break; - case Imagick::ORIENTATION_RIGHTTOP: - $image->rotateImage(new ImagickPixel(), 90); - $swapSize = true; - break; + case Imagick::ORIENTATION_BOTTOMLEFT: + $image->flopImage(); + $image->rotateImage(new ImagickPixel(), 180); + break; - case Imagick::ORIENTATION_RIGHTBOTTOM: - $image->flopImage(); - $image->rotateImage(new ImagickPixel(), 90); - $swapSize = true; - break; + case Imagick::ORIENTATION_LEFTTOP: + $image->flopImage(); + $image->rotateImage(new ImagickPixel(), -90); + $swapSize = true; + break; - case Imagick::ORIENTATION_LEFTBOTTOM: - $image->rotateImage(new ImagickPixel(), -90); - $swapSize = true; - break; + case Imagick::ORIENTATION_RIGHTTOP: + $image->rotateImage(new ImagickPixel(), 90); + $swapSize = true; + break; - default: - break; + case Imagick::ORIENTATION_RIGHTBOTTOM: + $image->flopImage(); + $image->rotateImage(new ImagickPixel(), 90); + $swapSize = true; + break; - } + case Imagick::ORIENTATION_LEFTBOTTOM: + $image->rotateImage(new ImagickPixel(), -90); + $swapSize = true; + break; - $image->setImageOrientation(Imagick::ORIENTATION_TOPLEFT); - $image->writeImage($path); + default: + return false; + break; } + // Adjust photo + $image->setImageOrientation(Imagick::ORIENTATION_TOPLEFT); + $image->writeImage($path); + + // Free memory $image->clear(); $image->destroy(); @@ -548,6 +547,11 @@ final class Photo { switch ($info['orientation']) { + case 1: + // do nothing + return false; + break; + case 2: // mirror // not yet implemented @@ -597,6 +601,7 @@ final class Photo { } // Recreate photo + // In this step the photos also loses its metadata :( $newSourceImg = imagecreatetruecolor($newWidth, $newHeight); imagecopyresampled($newSourceImg, $sourceImg, 0, 0, 0, 0, $newWidth, $newHeight, $newWidth, $newHeight); imagejpeg($newSourceImg, $path, 100); From 2bcccc41faf6e227fefd0298ded16b15bcdcd6fc Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Sat, 11 Jun 2016 17:12:08 +0200 Subject: [PATCH 13/20] Adjustment in Changelog --- docs/Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index d770484..ab80c15 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -6,7 +6,7 @@ Released April 30, 2016 - `New` Import of IPTC photo tags (Thanks @qligier, #514) - `New` Added reset username and password to FAQ (#500 #128) - `Improved` Removed will-change from the main image to improve the image rendering in Chrome (#501) -- `Improved ` scroll and rendering performance by removing will-change +- `Improved` scroll and rendering performance by removing will-change - `Improved` Open Facebook and Twitter sharing sheet in new window - `Improved` EXIF and IPTC extraction (Thanks @qligier, #518) - `Fixed` broken URL in Update.md (#516) From 5c4f3413b15dce12c745ae2f1fb20c027c8937b8 Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Sat, 11 Jun 2016 17:12:42 +0200 Subject: [PATCH 14/20] Updated default tables to reflect changes made in #533 --- php/database/albums_table.sql | 4 ++-- php/database/log_table.sql | 4 ++-- php/database/photos_table.sql | 16 +++++++++------- php/database/settings_table.sql | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/php/database/albums_table.sql b/php/database/albums_table.sql index ea94d41..76c4272 100644 --- a/php/database/albums_table.sql +++ b/php/database/albums_table.sql @@ -2,7 +2,7 @@ # ------------------------------------------------------------ CREATE TABLE IF NOT EXISTS `?` ( - `id` bigint(14) NOT NULL, + `id` bigint(14) unsigned NOT NULL, `title` varchar(100) NOT NULL DEFAULT '', `description` varchar(1000) DEFAULT '', `sysstamp` int(11) NOT NULL, @@ -11,4 +11,4 @@ CREATE TABLE IF NOT EXISTS `?` ( `downloadable` tinyint(1) NOT NULL DEFAULT '0', `password` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; \ No newline at end of file +) ENGINE=MyISAM DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/php/database/log_table.sql b/php/database/log_table.sql index c5869bf..64d9c26 100644 --- a/php/database/log_table.sql +++ b/php/database/log_table.sql @@ -7,6 +7,6 @@ CREATE TABLE IF NOT EXISTS `?` ( `type` varchar(11) NOT NULL, `function` varchar(100) NOT NULL, `line` int(11) NOT NULL, - `text` TEXT, + `text` text, PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; +) ENGINE=MyISAM DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/php/database/photos_table.sql b/php/database/photos_table.sql index bd265e8..7e4f0fb 100644 --- a/php/database/photos_table.sql +++ b/php/database/photos_table.sql @@ -2,8 +2,8 @@ # ------------------------------------------------------------ CREATE TABLE IF NOT EXISTS `?` ( - `id` bigint(14) NOT NULL, - `title` varchar(100) NOT NULL, + `id` bigint(14) unsigned NOT NULL, + `title` varchar(100) NOT NULL DEFAULT '', `description` varchar(1000) DEFAULT '', `url` varchar(100) NOT NULL, `tags` varchar(1000) NOT NULL DEFAULT '', @@ -20,9 +20,11 @@ CREATE TABLE IF NOT EXISTS `?` ( `focal` varchar(20) NOT NULL, `takestamp` int(11) DEFAULT NULL, `star` tinyint(1) NOT NULL, - `thumbUrl` varchar(50) NOT NULL, - `album` varchar(30) NOT NULL DEFAULT '0', - `checksum` VARCHAR(100) DEFAULT NULL, + `thumbUrl` char(37) NOT NULL, + `album` bigint(20) unsigned NOT NULL, + `checksum` char(40) DEFAULT NULL, `medium` tinyint(1) NOT NULL DEFAULT '0', - PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; \ No newline at end of file + PRIMARY KEY (`id`), + KEY `Index_album` (`album`), + KEY `Index_star` (`star`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/php/database/settings_table.sql b/php/database/settings_table.sql index bdc1cf2..55cb88c 100644 --- a/php/database/settings_table.sql +++ b/php/database/settings_table.sql @@ -4,4 +4,4 @@ CREATE TABLE IF NOT EXISTS `?` ( `key` varchar(50) NOT NULL DEFAULT '', `value` varchar(200) DEFAULT '' -) ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; \ No newline at end of file +) ENGINE=MyISAM DEFAULT CHARSET=utf8; \ No newline at end of file From a38a5ded4d48788ad75bf4b7a41eb87e837dd0ba Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Sat, 11 Jun 2016 17:12:59 +0200 Subject: [PATCH 15/20] Use bigint(14) for album if in photo table #533 --- php/database/update_030102.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/database/update_030102.php b/php/database/update_030102.php index c18cdcf..145dbee 100644 --- a/php/database/update_030102.php +++ b/php/database/update_030102.php @@ -8,7 +8,7 @@ use Lychee\Modules\Database; use Lychee\Modules\Response; // Change type of the album id field -$query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `album` `album` BIGINT UNSIGNED NOT NULL", array(LYCHEE_TABLE_PHOTOS)); +$query = Database::prepare($connection, "ALTER TABLE `?` CHANGE `album` `album` BIGINT(14) UNSIGNED NOT NULL", array(LYCHEE_TABLE_PHOTOS)); $result = Database::execute($connection, $query, 'update_030102', __LINE__); if ($result===false) Response::error('Could not change type of the album id field!'); From 9cab1c1a8524815f3ca40badbffad714c6de5215 Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Sat, 11 Jun 2016 17:13:09 +0200 Subject: [PATCH 16/20] Updated changelog with v3.1.2 --- docs/Changelog.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index ab80c15..644b496 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -1,3 +1,13 @@ +## v3.1.2 + +Released June ?, 2016 + +- `Improved` Added indexes to SQL fields to improve query execution time (Thanks @qligier, #533) +- `Improved` Protocol-relative URLs for open graph metadata (#546) +- `Improved` Remove metadata from medium-sized images and thumbnails (Imagick only) (#556) +- `Improved` Reduce quality of medium-sized images (Imagick only) (#556) +- `Improved` orientation-handling with Imagick (#556) + ## v3.1.1 Released April 30, 2016 From 1adc2dec00a4bc9174ea5cfca509404504996cab Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Sun, 12 Jun 2016 17:06:25 +0200 Subject: [PATCH 17/20] Fixed GD thumb quality using wrong variable --- php/Modules/Photo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/Modules/Photo.php b/php/Modules/Photo.php index 955f0d9..0da0fbb 100755 --- a/php/Modules/Photo.php +++ b/php/Modules/Photo.php @@ -361,12 +361,12 @@ final class Photo { // Create thumb fastImageCopyResampled($thumb, $sourceImg, 0, 0, $startWidth, $startHeight, $newWidth, $newHeight, $newSize, $newSize); - imagejpeg($thumb, $newUrl, $thumbQuality); + imagejpeg($thumb, $newUrl, $quality); imagedestroy($thumb); // Create retina thumb fastImageCopyResampled($thumb2x, $sourceImg, 0, 0, $startWidth, $startHeight, $newWidth*2, $newHeight*2, $newSize, $newSize); - imagejpeg($thumb2x, $newUrl2x, $thumbQuality); + imagejpeg($thumb2x, $newUrl2x, $quality); imagedestroy($thumb2x); // Free memory From 659a570b2ec4ca5ea1569598f1ab9a7f42a744f5 Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Sun, 12 Jun 2016 17:44:33 +0200 Subject: [PATCH 18/20] Save database update version for 3.1.2 --- php/database/update_030102.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/database/update_030102.php b/php/database/update_030102.php index 145dbee..cf89ddc 100644 --- a/php/database/update_030102.php +++ b/php/database/update_030102.php @@ -68,6 +68,6 @@ $result = Database::execute($connection, $query, 'update_030102', __LINE__); if ($result===false) Response::error('Could not change type of the id field!'); // Set version -//if (Database::setVersion($connection, '030102')===false) Response::error('Could not update version of database!'); +if (Database::setVersion($connection, '030102')===false) Response::error('Could not update version of database!'); ?> \ No newline at end of file From a50f2c997a5531c8b30cd0dac7448e7fa4535a23 Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Sun, 12 Jun 2016 17:47:32 +0200 Subject: [PATCH 19/20] Added release date to change log --- docs/Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index 644b496..63cd607 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -1,6 +1,6 @@ ## v3.1.2 -Released June ?, 2016 +Released June 12, 2016 - `Improved` Added indexes to SQL fields to improve query execution time (Thanks @qligier, #533) - `Improved` Protocol-relative URLs for open graph metadata (#546) From 8c279a5550fdcc9bcb01e4711a225bb0b0d66858 Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Sun, 12 Jun 2016 18:16:51 +0200 Subject: [PATCH 20/20] Rebuild --- dist/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/main.js b/dist/main.js index b6d91fb..8bae640 100644 --- a/dist/main.js +++ b/dist/main.js @@ -2,5 +2,5 @@ function _taggedTemplateLiteral(e,t){return Object.freeze(Object.definePropertie return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:c(function(){return[0]}),last:c(function(e,t){return[t-1]}),eq:c(function(e,t,n){return[0>n?n+t:n]}),even:c(function(e,t){for(var n=0;t>n;n+=2)e.push(n);return e}),odd:c(function(e,t){for(var n=1;t>n;n+=2)e.push(n);return e}),lt:c(function(e,t,n){for(var o=0>n?n+t:n;--o>=0;)e.push(o);return e}),gt:c(function(e,t,n){for(var o=0>n?n+t:n;++o2&&"ID"===(r=a[0]).type&&x.getById&&9===t.nodeType&&P&&_.relative[a[1].type]){if(t=(_.find.ID(r.matches[0].replace(we,xe),t)||[])[0],!t)return n;c&&(t=t.parentNode),e=e.slice(a.shift().value.length)}for(i=he.needsContext.test(e)?0:a.length;i--&&(r=a[i],!_.relative[l=r.type]);)if((s=_.find[l])&&(o=s(r.matches[0].replace(we,xe),ve.test(a[0].type)&&u(t.parentNode)||t))){if(a.splice(i,1),e=o.length&&p(a),!e)return Q.apply(n,o),n;break}}return(c||k(e,d))(o,t,!P,n,!t||ve.test(e)&&u(t.parentNode)||t),n},x.sortStable=R.split("").sort(z).join("")===R,x.detectDuplicates=!!A,E(),x.sortDetached=i(function(e){return 1&e.compareDocumentPosition(S.createElement("div"))}),i(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||a("type|href|height|width",function(e,t,n){return n?void 0:e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),x.attributes&&i(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||a("value",function(e,t,n){return n||"input"!==e.nodeName.toLowerCase()?void 0:e.defaultValue}),i(function(e){return null==e.getAttribute("disabled")})||a(te,function(e,t,n){var o;return n?void 0:e[t]===!0?t.toLowerCase():(o=e.getAttributeNode(t))&&o.specified?o.value:null}),t}(e);ae.find=ue,ae.expr=ue.selectors,ae.expr[":"]=ae.expr.pseudos,ae.uniqueSort=ae.unique=ue.uniqueSort,ae.text=ue.getText,ae.isXMLDoc=ue.isXML,ae.contains=ue.contains;var de=function(e,t,n){for(var o=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&ae(e).is(n))break;o.push(e)}return o},pe=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},he=ae.expr.match.needsContext,fe=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,be=/^.[^:#\[\.,]*$/;ae.filter=function(e,t,n){var o=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===o.nodeType?ae.find.matchesSelector(o,e)?[o]:[]:ae.find.matches(e,ae.grep(t,function(e){return 1===e.nodeType}))},ae.fn.extend({find:function(e){var t,n=this.length,o=[],i=this;if("string"!=typeof e)return this.pushStack(ae(e).filter(function(){for(t=0;n>t;t++)if(ae.contains(i[t],this))return!0}));for(t=0;n>t;t++)ae.find(e,i[t],o);return o=this.pushStack(n>1?ae.unique(o):o),o.selector=this.selector?this.selector+" "+e:e,o},filter:function(e){return this.pushStack(o(this,e||[],!1))},not:function(e){return this.pushStack(o(this,e||[],!0))},is:function(e){return!!o(this,"string"==typeof e&&he.test(e)?ae(e):e||[],!1).length}});var me,ge=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,ve=ae.fn.init=function(e,t,n){var o,i;if(!e)return this;if(n=n||me,"string"==typeof e){if(o="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:ge.exec(e),!o||!o[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(o[1]){if(t=t instanceof ae?t[0]:t,ae.merge(this,ae.parseHTML(o[1],t&&t.nodeType?t.ownerDocument||t:V,!0)),fe.test(o[1])&&ae.isPlainObject(t))for(o in t)ae.isFunction(this[o])?this[o](t[o]):this.attr(o,t[o]);return this}return i=V.getElementById(o[2]),i&&i.parentNode&&(this.length=1,this[0]=i),this.context=V,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):ae.isFunction(e)?void 0!==n.ready?n.ready(e):e(ae):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),ae.makeArray(e,this))};ve.prototype=ae.fn,me=ae(V);var ye=/^(?:parents|prev(?:Until|All))/,we={children:!0,contents:!0,next:!0,prev:!0};ae.fn.extend({has:function(e){var t=ae(e,this),n=t.length;return this.filter(function(){for(var e=0;n>e;e++)if(ae.contains(this,t[e]))return!0})},closest:function(e,t){for(var n,o=0,i=this.length,a=[],r=he.test(e)||"string"!=typeof e?ae(e,t||this.context):0;i>o;o++)for(n=this[o];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(r?r.index(n)>-1:1===n.nodeType&&ae.find.matchesSelector(n,e))){a.push(n);break}return this.pushStack(a.length>1?ae.uniqueSort(a):a)},index:function(e){return e?"string"==typeof e?J.call(ae(e),this[0]):J.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(ae.uniqueSort(ae.merge(this.get(),ae(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),ae.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return de(e,"parentNode")},parentsUntil:function(e,t,n){return de(e,"parentNode",n)},next:function(e){return i(e,"nextSibling")},prev:function(e){return i(e,"previousSibling")},nextAll:function(e){return de(e,"nextSibling")},prevAll:function(e){return de(e,"previousSibling")},nextUntil:function(e,t,n){return de(e,"nextSibling",n)},prevUntil:function(e,t,n){return de(e,"previousSibling",n)},siblings:function(e){return pe((e.parentNode||{}).firstChild,e)},children:function(e){return pe(e.firstChild)},contents:function(e){return e.contentDocument||ae.merge([],e.childNodes)}},function(e,t){ae.fn[e]=function(n,o){var i=ae.map(this,t,n);return"Until"!==e.slice(-5)&&(o=n),o&&"string"==typeof o&&(i=ae.filter(o,i)),this.length>1&&(we[e]||ae.uniqueSort(i),ye.test(e)&&i.reverse()),this.pushStack(i)}});var xe=/\S+/g;ae.Callbacks=function(e){e="string"==typeof e?a(e):ae.extend({},e);var t,n,o,i,r=[],l=[],s=-1,c=function(){for(i=e.once,o=t=!0;l.length;s=-1)for(n=l.shift();++s-1;)r.splice(n,1),s>=n&&s--}),this},has:function(e){return e?ae.inArray(e,r)>-1:r.length>0},empty:function(){return r&&(r=[]),this},disable:function(){return i=l=[],r=n="",this},disabled:function(){return!r},lock:function(){return i=l=[],n||(r=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=n||[],n=[e,n.slice?n.slice():n],l.push(n),t||c()),this},fire:function(){return u.fireWith(this,arguments),this},fired:function(){return!!o}};return u},ae.extend({Deferred:function(e){var t=[["resolve","done",ae.Callbacks("once memory"),"resolved"],["reject","fail",ae.Callbacks("once memory"),"rejected"],["notify","progress",ae.Callbacks("memory")]],n="pending",o={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return ae.Deferred(function(n){ae.each(t,function(t,a){var r=ae.isFunction(e[t])&&e[t];i[a[1]](function(){var e=r&&r.apply(this,arguments);e&&ae.isFunction(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[a[0]+"With"](this===o?n.promise():this,r?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?ae.extend(e,o):o}},i={};return o.pipe=o.then,ae.each(t,function(e,a){var r=a[2],l=a[3];o[a[1]]=r.add,l&&r.add(function(){n=l},t[1^e][2].disable,t[2][2].lock),i[a[0]]=function(){return i[a[0]+"With"](this===i?o:this,arguments),this},i[a[0]+"With"]=r.fireWith}),o.promise(i),e&&e.call(i,i),i},when:function(e){var t,n,o,i=0,a=G.call(arguments),r=a.length,l=1!==r||e&&ae.isFunction(e.promise)?r:0,s=1===l?e:ae.Deferred(),c=function(e,n,o){return function(i){n[e]=this,o[e]=arguments.length>1?G.call(arguments):i,o===t?s.notifyWith(n,o):--l||s.resolveWith(n,o)}};if(r>1)for(t=new Array(r),n=new Array(r),o=new Array(r);r>i;i++)a[i]&&ae.isFunction(a[i].promise)?a[i].promise().progress(c(i,n,t)).done(c(i,o,a)).fail(s.reject):--l;return l||s.resolveWith(o,a),s.promise()}});var _e;ae.fn.ready=function(e){return ae.ready.promise().done(e),this},ae.extend({isReady:!1,readyWait:1,holdReady:function(e){e?ae.readyWait++:ae.ready(!0)},ready:function(e){(e===!0?--ae.readyWait:ae.isReady)||(ae.isReady=!0,e!==!0&&--ae.readyWait>0||(_e.resolveWith(V,[ae]),ae.fn.triggerHandler&&(ae(V).triggerHandler("ready"),ae(V).off("ready"))))}}),ae.ready.promise=function(t){return _e||(_e=ae.Deferred(),"complete"===V.readyState||"loading"!==V.readyState&&!V.documentElement.doScroll?e.setTimeout(ae.ready):(V.addEventListener("DOMContentLoaded",r),e.addEventListener("load",r))),_e.promise(t)},ae.ready.promise();var je=function(e,t,n,o,i,a,r){var l=0,s=e.length,c=null==n;if("object"===ae.type(n)){i=!0;for(l in n)je(e,t,l,n[l],!0,a,r)}else if(void 0!==o&&(i=!0,ae.isFunction(o)||(r=!0),c&&(r?(t.call(e,o),t=null):(c=t,t=function(e,t,n){return c.call(ae(e),n)})),t))for(;s>l;l++)t(e[l],n,r?o:o.call(e[l],l,t(e[l],n)));return i?e:c?t.call(e):s?t(e[0],n):a},Te=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};l.uid=1,l.prototype={register:function(e,t){var n=t||{};return e.nodeType?e[this.expando]=n:Object.defineProperty(e,this.expando,{value:n,writable:!0,configurable:!0}),e[this.expando]},cache:function(e){if(!Te(e))return{};var t=e[this.expando];return t||(t={},Te(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var o,i=this.cache(e);if("string"==typeof t)i[t]=n;else for(o in t)i[o]=t[o];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][t]},access:function(e,t,n){var o;return void 0===t||t&&"string"==typeof t&&void 0===n?(o=this.get(e,t),void 0!==o?o:this.get(e,ae.camelCase(t))):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,o,i,a=e[this.expando];if(void 0!==a){if(void 0===t)this.register(e);else{ae.isArray(t)?o=t.concat(t.map(ae.camelCase)):(i=ae.camelCase(t),t in a?o=[t,i]:(o=i,o=o in a?[o]:o.match(xe)||[])),n=o.length;for(;n--;)delete a[o[n]]}(void 0===t||ae.isEmptyObject(a))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!ae.isEmptyObject(t)}};var Me=new l,ke=new l,Ce=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,$e=/[A-Z]/g;ae.extend({hasData:function(e){return ke.hasData(e)||Me.hasData(e)},data:function(e,t,n){return ke.access(e,t,n)},removeData:function(e,t){ke.remove(e,t)},_data:function(e,t,n){return Me.access(e,t,n)},_removeData:function(e,t){Me.remove(e,t)}}),ae.fn.extend({data:function(e,t){var n,o,i,a=this[0],r=a&&a.attributes;if(void 0===e){if(this.length&&(i=ke.get(a),1===a.nodeType&&!Me.get(a,"hasDataAttrs"))){for(n=r.length;n--;)r[n]&&(o=r[n].name,0===o.indexOf("data-")&&(o=ae.camelCase(o.slice(5)),s(a,o,i[o])));Me.set(a,"hasDataAttrs",!0)}return i}return"object"==typeof e?this.each(function(){ke.set(this,e)}):je(this,function(t){var n,o;if(a&&void 0===t){if(n=ke.get(a,e)||ke.get(a,e.replace($e,"-$&").toLowerCase()),void 0!==n)return n;if(o=ae.camelCase(e),n=ke.get(a,o),void 0!==n)return n;if(n=s(a,o,void 0),void 0!==n)return n}else o=ae.camelCase(e),this.each(function(){var n=ke.get(this,o);ke.set(this,o,t),e.indexOf("-")>-1&&void 0!==n&&ke.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){ke.remove(this,e)})}}),ae.extend({queue:function(e,t,n){var o;return e?(t=(t||"fx")+"queue",o=Me.get(e,t),n&&(!o||ae.isArray(n)?o=Me.access(e,t,ae.makeArray(n)):o.push(n)),o||[]):void 0},dequeue:function(e,t){t=t||"fx";var n=ae.queue(e,t),o=n.length,i=n.shift(),a=ae._queueHooks(e,t),r=function(){ae.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),o--),i&&("fx"===t&&n.unshift("inprogress"),delete a.stop,i.call(e,r,a)),!o&&a&&a.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Me.get(e,n)||Me.access(e,n,{empty:ae.Callbacks("once memory").add(function(){Me.remove(e,[t+"queue",n])})})}}),ae.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length",""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};Oe.optgroup=Oe.option,Oe.tbody=Oe.tfoot=Oe.colgroup=Oe.caption=Oe.thead,Oe.th=Oe.td;var Ne=/<|&#?\w+;/;!function(){var e=V.createDocumentFragment(),t=e.appendChild(V.createElement("div")),n=V.createElement("input");n.setAttribute("type","radio"),n.setAttribute("checked","checked"),n.setAttribute("name","t"),t.appendChild(n),oe.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,t.innerHTML="",oe.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue}();var qe=/^key/,Re=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Fe=/^([^.]*)(?:\.(.+)|)/;ae.event={global:{},add:function(e,t,n,o,i){var a,r,l,s,c,u,d,p,h,f,b,m=Me.get(e);if(m)for(n.handler&&(a=n,n=a.handler,i=a.selector),n.guid||(n.guid=ae.guid++),(s=m.events)||(s=m.events={}),(r=m.handle)||(r=m.handle=function(t){return"undefined"!=typeof ae&&ae.event.triggered!==t.type?ae.event.dispatch.apply(e,arguments):void 0}),t=(t||"").match(xe)||[""],c=t.length;c--;)l=Fe.exec(t[c])||[],h=b=l[1],f=(l[2]||"").split(".").sort(),h&&(d=ae.event.special[h]||{},h=(i?d.delegateType:d.bindType)||h,d=ae.event.special[h]||{},u=ae.extend({type:h,origType:b,data:o,handler:n,guid:n.guid,selector:i,needsContext:i&&ae.expr.match.needsContext.test(i),namespace:f.join(".")},a),(p=s[h])||(p=s[h]=[],p.delegateCount=0,d.setup&&d.setup.call(e,o,f,r)!==!1||e.addEventListener&&e.addEventListener(h,r)),d.add&&(d.add.call(e,u),u.handler.guid||(u.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,u):p.push(u),ae.event.global[h]=!0)},remove:function(e,t,n,o,i){var a,r,l,s,c,u,d,p,h,f,b,m=Me.hasData(e)&&Me.get(e);if(m&&(s=m.events)){for(t=(t||"").match(xe)||[""],c=t.length;c--;)if(l=Fe.exec(t[c])||[],h=b=l[1],f=(l[2]||"").split(".").sort(),h){for(d=ae.event.special[h]||{},h=(o?d.delegateType:d.bindType)||h,p=s[h]||[],l=l[2]&&new RegExp("(^|\\.)"+f.join("\\.(?:.*\\.|)")+"(\\.|$)"),r=a=p.length;a--;)u=p[a],!i&&b!==u.origType||n&&n.guid!==u.guid||l&&!l.test(u.namespace)||o&&o!==u.selector&&("**"!==o||!u.selector)||(p.splice(a,1),u.selector&&p.delegateCount--,d.remove&&d.remove.call(e,u));r&&!p.length&&(d.teardown&&d.teardown.call(e,f,m.handle)!==!1||ae.removeEvent(e,h,m.handle),delete s[h])}else for(h in s)ae.event.remove(e,h+t[c],n,o,!0);ae.isEmptyObject(s)&&Me.remove(e,"handle events")}},dispatch:function(e){e=ae.event.fix(e);var t,n,o,i,a,r=[],l=G.call(arguments),s=(Me.get(this,"events")||{})[e.type]||[],c=ae.event.special[e.type]||{};if(l[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){for(r=ae.event.handlers.call(this,e,s),t=0;(i=r[t++])&&!e.isPropagationStopped();)for(e.currentTarget=i.elem,n=0;(a=i.handlers[n++])&&!e.isImmediatePropagationStopped();)e.rnamespace&&!e.rnamespace.test(a.namespace)||(e.handleObj=a,e.data=a.data,o=((ae.event.special[a.origType]||{}).handle||a.handler).apply(i.elem,l),void 0!==o&&(e.result=o)===!1&&(e.preventDefault(),e.stopPropagation()));return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,o,i,a,r=[],l=t.delegateCount,s=e.target;if(l&&s.nodeType&&("click"!==e.type||isNaN(e.button)||e.button<1))for(;s!==this;s=s.parentNode||this)if(1===s.nodeType&&(s.disabled!==!0||"click"!==e.type)){for(o=[],n=0;l>n;n++)a=t[n],i=a.selector+" ",void 0===o[i]&&(o[i]=a.needsContext?ae(i,this).index(s)>-1:ae.find(i,this,null,[s]).length),o[i]&&o.push(a);o.length&&r.push({elem:s,handlers:o})}return l]*)\/>/gi,Ue=/\s*$/g;ae.extend({htmlPrefilter:function(e){return e.replace(He,"<$1>")},clone:function(e,t,n){var o,i,a,r,l=e.cloneNode(!0),s=ae.contains(e.ownerDocument,e);if(!(oe.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||ae.isXMLDoc(e)))for(r=u(l),a=u(e),o=0,i=a.length;i>o;o++)x(a[o],r[o]);if(t)if(n)for(a=a||u(e),r=r||u(l),o=0,i=a.length;i>o;o++)w(a[o],r[o]);else w(e,l);return r=u(l,"script"),r.length>0&&d(r,!s&&u(e,"script")),l},cleanData:function(e){for(var t,n,o,i=ae.event.special,a=0;void 0!==(n=e[a]);a++)if(Te(n)){if(t=n[Me.expando]){if(t.events)for(o in t.events)i[o]?ae.event.remove(n,o):ae.removeEvent(n,o,t.handle);n[Me.expando]=void 0}n[ke.expando]&&(n[ke.expando]=void 0)}}}),ae.fn.extend({domManip:_,detach:function(e){return j(this,e,!0)},remove:function(e){return j(this,e)},text:function(e){return je(this,function(e){return void 0===e?ae.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return _(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=g(this,e);t.appendChild(e)}})},prepend:function(){return _(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=g(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return _(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return _(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(ae.cleanData(u(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return ae.clone(this,e,t)})},html:function(e){return je(this,function(e){var t=this[0]||{},n=0,o=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ue.test(e)&&!Oe[(Pe.exec(e)||["",""])[1].toLowerCase()]){e=ae.htmlPrefilter(e);try{for(;o>n;n++)t=this[n]||{},1===t.nodeType&&(ae.cleanData(u(t,!1)),t.innerHTML=e);t=0}catch(i){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return _(this,arguments,function(t){var n=this.parentNode;ae.inArray(this,e)<0&&(ae.cleanData(u(this)),n&&n.replaceChild(t,this))},e)}}),ae.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){ae.fn[e]=function(e){for(var n,o=[],i=ae(e),a=i.length-1,r=0;a>=r;r++)n=r===a?this:this.clone(!0),ae(i[r])[t](n),Q.apply(o,n.get());return this.pushStack(o)}});var ze,Ye={HTML:"block",BODY:"block"},Ke=/^margin/,Ve=new RegExp("^("+De+")(?!px)[a-z%]+$","i"),Ge=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)},Ze=function(e,t,n,o){var i,a,r={};for(a in t)r[a]=e.style[a],e.style[a]=t[a];i=n.apply(e,o||[]);for(a in t)e.style[a]=r[a];return i},Qe=V.documentElement;!function(){function t(){l.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",l.innerHTML="",Qe.appendChild(r);var t=e.getComputedStyle(l);n="1%"!==t.top,a="2px"===t.marginLeft,o="4px"===t.width,l.style.marginRight="50%",i="4px"===t.marginRight,Qe.removeChild(r)}var n,o,i,a,r=V.createElement("div"),l=V.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",oe.clearCloneStyle="content-box"===l.style.backgroundClip,r.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",r.appendChild(l),ae.extend(oe,{pixelPosition:function(){return t(),n},boxSizingReliable:function(){return null==o&&t(),o},pixelMarginRight:function(){return null==o&&t(),i},reliableMarginLeft:function(){return null==o&&t(),a},reliableMarginRight:function(){var t,n=l.appendChild(V.createElement("div"));return n.style.cssText=l.style.cssText="-webkit-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",n.style.marginRight=n.style.width="0",l.style.width="1px",Qe.appendChild(r),t=!parseFloat(e.getComputedStyle(n).marginRight),Qe.removeChild(r),l.removeChild(n),t}}))}();var Je=/^(none|table(?!-c[ea]).+)/,et={position:"absolute",visibility:"hidden",display:"block"},tt={letterSpacing:"0",fontWeight:"400"},nt=["Webkit","O","Moz","ms"],ot=V.createElement("div").style;ae.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=k(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(e,t,n,o){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,a,r,l=ae.camelCase(t),s=e.style;return t=ae.cssProps[l]||(ae.cssProps[l]=$(l)||l),r=ae.cssHooks[t]||ae.cssHooks[l],void 0===n?r&&"get"in r&&void 0!==(i=r.get(e,!1,o))?i:s[t]:(a=typeof n,"string"===a&&(i=Ae.exec(n))&&i[1]&&(n=c(e,t,i),a="number"),void(null!=n&&n===n&&("number"===a&&(n+=i&&i[3]||(ae.cssNumber[l]?"":"px")),oe.clearCloneStyle||""!==n||0!==t.indexOf("background")||(s[t]="inherit"),r&&"set"in r&&void 0===(n=r.set(e,n,o))||(s[t]=n))))}},css:function(e,t,n,o){var i,a,r,l=ae.camelCase(t);return t=ae.cssProps[l]||(ae.cssProps[l]=$(l)||l),r=ae.cssHooks[t]||ae.cssHooks[l],r&&"get"in r&&(i=r.get(e,!0,n)),void 0===i&&(i=k(e,t,o)),"normal"===i&&t in tt&&(i=tt[t]),""===n||n?(a=parseFloat(i),n===!0||isFinite(a)?a||0:i):i}}),ae.each(["height","width"],function(e,t){ae.cssHooks[t]={get:function(e,n,o){return n?Je.test(ae.css(e,"display"))&&0===e.offsetWidth?Ze(e,et,function(){return E(e,t,o)}):E(e,t,o):void 0},set:function(e,n,o){var i,a=o&&Ge(e),r=o&&A(e,t,o,"border-box"===ae.css(e,"boxSizing",!1,a),a);return r&&(i=Ae.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=ae.css(e,t)),D(e,n,r)}}}),ae.cssHooks.marginLeft=C(oe.reliableMarginLeft,function(e,t){return t?(parseFloat(k(e,"marginLeft"))||e.getBoundingClientRect().left-Ze(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px":void 0}),ae.cssHooks.marginRight=C(oe.reliableMarginRight,function(e,t){return t?Ze(e,{display:"inline-block"},k,[e,"marginRight"]):void 0}),ae.each({margin:"",padding:"",border:"Width"},function(e,t){ae.cssHooks[e+t]={expand:function(n){for(var o=0,i={},a="string"==typeof n?n.split(" "):[n];4>o;o++)i[e+Ee[o]+t]=a[o]||a[o-2]||a[0];return i}},Ke.test(e)||(ae.cssHooks[e+t].set=D)}),ae.fn.extend({css:function(e,t){return je(this,function(e,t,n){var o,i,a={},r=0;if(ae.isArray(t)){for(o=Ge(e),i=t.length;i>r;r++)a[t[r]]=ae.css(e,t[r],!1,o);return a}return void 0!==n?ae.style(e,t,n):ae.css(e,t)},e,t,arguments.length>1)},show:function(){return S(this,!0)},hide:function(){return S(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){Se(this)?ae(this).show():ae(this).hide()})}}),ae.Tween=L,L.prototype={constructor:L,init:function(e,t,n,o,i,a){this.elem=e,this.prop=n,this.easing=i||ae.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=o,this.unit=a||(ae.cssNumber[n]?"":"px")},cur:function(){var e=L.propHooks[this.prop];return e&&e.get?e.get(this):L.propHooks._default.get(this)},run:function(e){var t,n=L.propHooks[this.prop];return this.options.duration?this.pos=t=ae.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):L.propHooks._default.set(this),this}},L.prototype.init.prototype=L.prototype,L.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=ae.css(e.elem,e.prop,""),t&&"auto"!==t?t:0)},set:function(e){ae.fx.step[e.prop]?ae.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[ae.cssProps[e.prop]]&&!ae.cssHooks[e.prop]?e.elem[e.prop]=e.now:ae.style(e.elem,e.prop,e.now+e.unit)}}},L.propHooks.scrollTop=L.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},ae.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},ae.fx=L.prototype.init,ae.fx.step={};var it,at,rt=/^(?:toggle|show|hide)$/,lt=/queueHooks$/;ae.Animation=ae.extend(R,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return c(n.elem,e,Ae.exec(t),n),n}]},tweener:function(e,t){ae.isFunction(e)?(t=e,e=["*"]):e=e.match(xe);for(var n,o=0,i=e.length;i>o;o++)n=e[o],R.tweeners[n]=R.tweeners[n]||[],R.tweeners[n].unshift(t)},prefilters:[N],prefilter:function(e,t){t?R.prefilters.unshift(e):R.prefilters.push(e)}}),ae.speed=function(e,t,n){var o=e&&"object"==typeof e?ae.extend({},e):{complete:n||!n&&t||ae.isFunction(e)&&e,duration:e,easing:n&&t||t&&!ae.isFunction(t)&&t};return o.duration=ae.fx.off?0:"number"==typeof o.duration?o.duration:o.duration in ae.fx.speeds?ae.fx.speeds[o.duration]:ae.fx.speeds._default,null!=o.queue&&o.queue!==!0||(o.queue="fx"),o.old=o.complete,o.complete=function(){ae.isFunction(o.old)&&o.old.call(this),o.queue&&ae.dequeue(this,o.queue)},o},ae.fn.extend({fadeTo:function(e,t,n,o){return this.filter(Se).css("opacity",0).show().end().animate({opacity:t},e,n,o)},animate:function(e,t,n,o){var i=ae.isEmptyObject(e),a=ae.speed(t,n,o),r=function(){var t=R(this,ae.extend({},e),a);(i||Me.get(this,"finish"))&&t.stop(!0)};return r.finish=r,i||a.queue===!1?this.each(r):this.queue(a.queue,r)},stop:function(e,t,n){var o=function(e){var t=e.stop;delete e.stop,t(n)};return"string"!=typeof e&&(n=t,t=e,e=void 0),t&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,i=null!=e&&e+"queueHooks",a=ae.timers,r=Me.get(this);if(i)r[i]&&r[i].stop&&o(r[i]);else for(i in r)r[i]&&r[i].stop&<.test(i)&&o(r[i]);for(i=a.length;i--;)a[i].elem!==this||null!=e&&a[i].queue!==e||(a[i].anim.stop(n),t=!1,a.splice(i,1));!t&&n||ae.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=Me.get(this),o=n[e+"queue"],i=n[e+"queueHooks"],a=ae.timers,r=o?o.length:0;for(n.finish=!0,ae.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=a.length;t--;)a[t].elem===this&&a[t].queue===e&&(a[t].anim.stop(!0),a.splice(t,1));for(t=0;r>t;t++)o[t]&&o[t].finish&&o[t].finish.call(this);delete n.finish})}}),ae.each(["toggle","show","hide"],function(e,t){var n=ae.fn[t];ae.fn[t]=function(e,o,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(I(t,!0),e,o,i)}}),ae.each({ slideDown:I("show"),slideUp:I("hide"),slideToggle:I("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){ae.fn[e]=function(e,n,o){return this.animate(t,e,n,o)}}),ae.timers=[],ae.fx.tick=function(){var e,t=0,n=ae.timers;for(it=ae.now();t1)},removeAttr:function(e){return this.each(function(){ae.removeAttr(this,e)})}}),ae.extend({attr:function(e,t,n){var o,i,a=e.nodeType;return 3!==a&&8!==a&&2!==a?"undefined"==typeof e.getAttribute?ae.prop(e,t,n):(1===a&&ae.isXMLDoc(e)||(t=t.toLowerCase(),i=ae.attrHooks[t]||(ae.expr.match.bool.test(t)?st:void 0)),void 0!==n?null===n?void ae.removeAttr(e,t):i&&"set"in i&&void 0!==(o=i.set(e,n,t))?o:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(o=i.get(e,t))?o:(o=ae.find.attr(e,t),null==o?void 0:o)):void 0},attrHooks:{type:{set:function(e,t){if(!oe.radioValue&&"radio"===t&&ae.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,o,i=0,a=t&&t.match(xe);if(a&&1===e.nodeType)for(;n=a[i++];)o=ae.propFix[n]||n,ae.expr.match.bool.test(n)&&(e[o]=!1),e.removeAttribute(n)}}),st={set:function(e,t,n){return t===!1?ae.removeAttr(e,n):e.setAttribute(n,n),n}},ae.each(ae.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ct[t]||ae.find.attr;ct[t]=function(e,t,o){var i,a;return o||(a=ct[t],ct[t]=i,i=null!=n(e,t,o)?t.toLowerCase():null,ct[t]=a),i}});var ut=/^(?:input|select|textarea|button)$/i,dt=/^(?:a|area)$/i;ae.fn.extend({prop:function(e,t){return je(this,ae.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[ae.propFix[e]||e]})}}),ae.extend({prop:function(e,t,n){var o,i,a=e.nodeType;return 3!==a&&8!==a&&2!==a?(1===a&&ae.isXMLDoc(e)||(t=ae.propFix[t]||t,i=ae.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(o=i.set(e,n,t))?o:e[t]=n:i&&"get"in i&&null!==(o=i.get(e,t))?o:e[t]):void 0},propHooks:{tabIndex:{get:function(e){var t=ae.find.attr(e,"tabindex");return t?parseInt(t,10):ut.test(e.nodeName)||dt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),oe.optSelected||(ae.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),ae.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){ae.propFix[this.toLowerCase()]=this});var pt=/[\t\r\n\f]/g;ae.fn.extend({addClass:function(e){var t,n,o,i,a,r,l,s=0;if(ae.isFunction(e))return this.each(function(t){ae(this).addClass(e.call(this,t,F(this)))});if("string"==typeof e&&e)for(t=e.match(xe)||[];n=this[s++];)if(i=F(n),o=1===n.nodeType&&(" "+i+" ").replace(pt," ")){for(r=0;a=t[r++];)o.indexOf(" "+a+" ")<0&&(o+=a+" ");l=ae.trim(o),i!==l&&n.setAttribute("class",l)}return this},removeClass:function(e){var t,n,o,i,a,r,l,s=0;if(ae.isFunction(e))return this.each(function(t){ae(this).removeClass(e.call(this,t,F(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof e&&e)for(t=e.match(xe)||[];n=this[s++];)if(i=F(n),o=1===n.nodeType&&(" "+i+" ").replace(pt," ")){for(r=0;a=t[r++];)for(;o.indexOf(" "+a+" ")>-1;)o=o.replace(" "+a+" "," ");l=ae.trim(o),i!==l&&n.setAttribute("class",l)}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):ae.isFunction(e)?this.each(function(n){ae(this).toggleClass(e.call(this,n,F(this),t),t)}):this.each(function(){var t,o,i,a;if("string"===n)for(o=0,i=ae(this),a=e.match(xe)||[];t=a[o++];)i.hasClass(t)?i.removeClass(t):i.addClass(t);else void 0!==e&&"boolean"!==n||(t=F(this),t&&Me.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||e===!1?"":Me.get(this,"__className__")||""))})},hasClass:function(e){var t,n,o=0;for(t=" "+e+" ";n=this[o++];)if(1===n.nodeType&&(" "+F(n)+" ").replace(pt," ").indexOf(t)>-1)return!0;return!1}});var ht=/\r/g,ft=/[\x20\t\r\n\f]+/g;ae.fn.extend({val:function(e){var t,n,o,i=this[0];return arguments.length?(o=ae.isFunction(e),this.each(function(n){var i;1===this.nodeType&&(i=o?e.call(this,n,ae(this).val()):e,null==i?i="":"number"==typeof i?i+="":ae.isArray(i)&&(i=ae.map(i,function(e){return null==e?"":e+""})),t=ae.valHooks[this.type]||ae.valHooks[this.nodeName.toLowerCase()],t&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))})):i?(t=ae.valHooks[i.type]||ae.valHooks[i.nodeName.toLowerCase()],t&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:(n=i.value,"string"==typeof n?n.replace(ht,""):null==n?"":n)):void 0}}),ae.extend({valHooks:{option:{get:function(e){var t=ae.find.attr(e,"value");return null!=t?t:ae.trim(ae.text(e)).replace(ft," ")}},select:{get:function(e){for(var t,n,o=e.options,i=e.selectedIndex,a="select-one"===e.type||0>i,r=a?null:[],l=a?i+1:o.length,s=0>i?l:a?i:0;l>s;s++)if(n=o[s],(n.selected||s===i)&&(oe.optDisabled?!n.disabled:null===n.getAttribute("disabled"))&&(!n.parentNode.disabled||!ae.nodeName(n.parentNode,"optgroup"))){if(t=ae(n).val(),a)return t;r.push(t)}return r},set:function(e,t){for(var n,o,i=e.options,a=ae.makeArray(t),r=i.length;r--;)o=i[r],(o.selected=ae.inArray(ae.valHooks.option.get(o),a)>-1)&&(n=!0);return n||(e.selectedIndex=-1),a}}}}),ae.each(["radio","checkbox"],function(){ae.valHooks[this]={set:function(e,t){return ae.isArray(t)?e.checked=ae.inArray(ae(e).val(),t)>-1:void 0}},oe.checkOn||(ae.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var bt=/^(?:focusinfocus|focusoutblur)$/;ae.extend(ae.event,{trigger:function(t,n,o,i){var a,r,l,s,c,u,d,p=[o||V],h=ne.call(t,"type")?t.type:t,f=ne.call(t,"namespace")?t.namespace.split("."):[];if(r=l=o=o||V,3!==o.nodeType&&8!==o.nodeType&&!bt.test(h+ae.event.triggered)&&(h.indexOf(".")>-1&&(f=h.split("."),h=f.shift(),f.sort()),c=h.indexOf(":")<0&&"on"+h,t=t[ae.expando]?t:new ae.Event(h,"object"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=f.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+f.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=o),n=null==n?[t]:ae.makeArray(n,[t]),d=ae.event.special[h]||{},i||!d.trigger||d.trigger.apply(o,n)!==!1)){if(!i&&!d.noBubble&&!ae.isWindow(o)){for(s=d.delegateType||h,bt.test(s+h)||(r=r.parentNode);r;r=r.parentNode)p.push(r),l=r;l===(o.ownerDocument||V)&&p.push(l.defaultView||l.parentWindow||e)}for(a=0;(r=p[a++])&&!t.isPropagationStopped();)t.type=a>1?s:d.bindType||h,u=(Me.get(r,"events")||{})[t.type]&&Me.get(r,"handle"),u&&u.apply(r,n),u=c&&r[c],u&&u.apply&&Te(r)&&(t.result=u.apply(r,n),t.result===!1&&t.preventDefault());return t.type=h,i||t.isDefaultPrevented()||d._default&&d._default.apply(p.pop(),n)!==!1||!Te(o)||c&&ae.isFunction(o[h])&&!ae.isWindow(o)&&(l=o[c],l&&(o[c]=null),ae.event.triggered=h,o[h](),ae.event.triggered=void 0,l&&(o[c]=l)),t.result}},simulate:function(e,t,n){var o=ae.extend(new ae.Event,n,{type:e,isSimulated:!0});ae.event.trigger(o,null,t),o.isDefaultPrevented()&&n.preventDefault()}}),ae.fn.extend({trigger:function(e,t){return this.each(function(){ae.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];return n?ae.event.trigger(e,t,n,!0):void 0}}),ae.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){ae.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),ae.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),oe.focusin="onfocusin"in e,oe.focusin||ae.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){ae.event.simulate(t,e.target,ae.event.fix(e))};ae.event.special[t]={setup:function(){var o=this.ownerDocument||this,i=Me.access(o,t);i||o.addEventListener(e,n,!0),Me.access(o,t,(i||0)+1)},teardown:function(){var o=this.ownerDocument||this,i=Me.access(o,t)-1;i?Me.access(o,t,i):(o.removeEventListener(e,n,!0),Me.remove(o,t))}}});var mt=e.location,gt=ae.now(),vt=/\?/;ae.parseJSON=function(e){return JSON.parse(e+"")},ae.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(o){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||ae.error("Invalid XML: "+t),n};var yt=/#.*$/,wt=/([?&])_=[^&]*/,xt=/^(.*?):[ \t]*([^\r\n]*)$/gm,_t=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,jt=/^(?:GET|HEAD)$/,Tt=/^\/\//,Mt={},kt={},Ct="*/".concat("*"),$t=V.createElement("a");$t.href=mt.href,ae.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:mt.href,type:"GET",isLocal:_t.test(mt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Ct,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":ae.parseJSON,"text xml":ae.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?B(B(e,ae.ajaxSettings),t):B(ae.ajaxSettings,e)},ajaxPrefilter:H(Mt),ajaxTransport:H(kt),ajax:function(t,n){function o(t,n,o,l){var c,d,v,y,x,j=n;2!==w&&(w=2,s&&e.clearTimeout(s),i=void 0,r=l||"",_.readyState=t>0?4:0,c=t>=200&&300>t||304===t,o&&(y=W(p,_,o)),y=X(p,y,_,c),c?(p.ifModified&&(x=_.getResponseHeader("Last-Modified"),x&&(ae.lastModified[a]=x),x=_.getResponseHeader("etag"),x&&(ae.etag[a]=x)),204===t||"HEAD"===p.type?j="nocontent":304===t?j="notmodified":(j=y.state,d=y.data,v=y.error,c=!v)):(v=j,!t&&j||(j="error",0>t&&(t=0))),_.status=t,_.statusText=(n||j)+"",c?b.resolveWith(h,[d,j,_]):b.rejectWith(h,[_,j,v]),_.statusCode(g),g=void 0,u&&f.trigger(c?"ajaxSuccess":"ajaxError",[_,p,c?d:v]),m.fireWith(h,[_,j]),u&&(f.trigger("ajaxComplete",[_,p]),--ae.active||ae.event.trigger("ajaxStop")))}"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,a,r,l,s,c,u,d,p=ae.ajaxSetup({},n),h=p.context||p,f=p.context&&(h.nodeType||h.jquery)?ae(h):ae.event,b=ae.Deferred(),m=ae.Callbacks("once memory"),g=p.statusCode||{},v={},y={},w=0,x="canceled",_={readyState:0,getResponseHeader:function(e){var t;if(2===w){if(!l)for(l={};t=xt.exec(r);)l[t[1].toLowerCase()]=t[2];t=l[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===w?r:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return w||(e=y[n]=y[n]||e,v[e]=t),this},overrideMimeType:function(e){return w||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>w)for(t in e)g[t]=[g[t],e[t]];else _.always(e[_.status]);return this},abort:function(e){var t=e||x;return i&&i.abort(t),o(0,t),this}};if(b.promise(_).complete=m.add,_.success=_.done,_.error=_.fail,p.url=((t||p.url||mt.href)+"").replace(yt,"").replace(Tt,mt.protocol+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=ae.trim(p.dataType||"*").toLowerCase().match(xe)||[""],null==p.crossDomain){c=V.createElement("a");try{c.href=p.url,c.href=c.href,p.crossDomain=$t.protocol+"//"+$t.host!=c.protocol+"//"+c.host}catch(j){p.crossDomain=!0}}if(p.data&&p.processData&&"string"!=typeof p.data&&(p.data=ae.param(p.data,p.traditional)),U(Mt,p,n,_),2===w)return _;u=ae.event&&p.global,u&&0===ae.active++&&ae.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!jt.test(p.type),a=p.url,p.hasContent||(p.data&&(a=p.url+=(vt.test(a)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wt.test(a)?a.replace(wt,"$1_="+gt++):a+(vt.test(a)?"&":"?")+"_="+gt++)),p.ifModified&&(ae.lastModified[a]&&_.setRequestHeader("If-Modified-Since",ae.lastModified[a]),ae.etag[a]&&_.setRequestHeader("If-None-Match",ae.etag[a])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&_.setRequestHeader("Content-Type",p.contentType),_.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Ct+"; q=0.01":""):p.accepts["*"]);for(d in p.headers)_.setRequestHeader(d,p.headers[d]);if(p.beforeSend&&(p.beforeSend.call(h,_,p)===!1||2===w))return _.abort();x="abort";for(d in{success:1,error:1,complete:1})_[d](p[d]);if(i=U(kt,p,n,_)){if(_.readyState=1,u&&f.trigger("ajaxSend",[_,p]),2===w)return _;p.async&&p.timeout>0&&(s=e.setTimeout(function(){_.abort("timeout")},p.timeout));try{w=1,i.send(v,o)}catch(j){if(!(2>w))throw j;o(-1,j)}}else o(-1,"No Transport");return _},getJSON:function(e,t,n){return ae.get(e,t,n,"json")},getScript:function(e,t){return ae.get(e,void 0,t,"script")}}),ae.each(["get","post"],function(e,t){ae[t]=function(e,n,o,i){return ae.isFunction(n)&&(i=i||o,o=n,n=void 0),ae.ajax(ae.extend({url:e,type:t,dataType:i,data:n,success:o},ae.isPlainObject(e)&&e))}}),ae._evalUrl=function(e){return ae.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},ae.fn.extend({wrapAll:function(e){var t;return ae.isFunction(e)?this.each(function(t){ae(this).wrapAll(e.call(this,t))}):(this[0]&&(t=ae(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this)},wrapInner:function(e){return ae.isFunction(e)?this.each(function(t){ae(this).wrapInner(e.call(this,t))}):this.each(function(){var t=ae(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=ae.isFunction(e);return this.each(function(n){ae(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){ae.nodeName(this,"body")||ae(this).replaceWith(this.childNodes)}).end()}}),ae.expr.filters.hidden=function(e){return!ae.expr.filters.visible(e)},ae.expr.filters.visible=function(e){return e.offsetWidth>0||e.offsetHeight>0||e.getClientRects().length>0};var Dt=/%20/g,At=/\[\]$/,Et=/\r?\n/g,St=/^(?:submit|button|image|reset|file)$/i,Lt=/^(?:input|select|textarea|keygen)/i;ae.param=function(e,t){var n,o=[],i=function(e,t){t=ae.isFunction(t)?t():null==t?"":t,o[o.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(void 0===t&&(t=ae.ajaxSettings&&ae.ajaxSettings.traditional),ae.isArray(e)||e.jquery&&!ae.isPlainObject(e))ae.each(e,function(){i(this.name,this.value)});else for(n in e)z(n,e[n],t,i);return o.join("&").replace(Dt,"+")},ae.fn.extend({serialize:function(){return ae.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=ae.prop(this,"elements");return e?ae.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!ae(this).is(":disabled")&&Lt.test(this.nodeName)&&!St.test(e)&&(this.checked||!Le.test(e))}).map(function(e,t){var n=ae(this).val();return null==n?null:ae.isArray(n)?ae.map(n,function(e){return{name:t.name,value:e.replace(Et,"\r\n")}}):{name:t.name,value:n.replace(Et,"\r\n")}}).get()}}),ae.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(t){}};var Pt={0:200,1223:204},It=ae.ajaxSettings.xhr();oe.cors=!!It&&"withCredentials"in It,oe.ajax=It=!!It,ae.ajaxTransport(function(t){var n,o;return oe.cors||It&&!t.crossDomain?{send:function(i,a){var r,l=t.xhr();if(l.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(r in t.xhrFields)l[r]=t.xhrFields[r];t.mimeType&&l.overrideMimeType&&l.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(r in i)l.setRequestHeader(r,i[r]);n=function(e){return function(){n&&(n=o=l.onload=l.onerror=l.onabort=l.onreadystatechange=null,"abort"===e?l.abort():"error"===e?"number"!=typeof l.status?a(0,"error"):a(l.status,l.statusText):a(Pt[l.status]||l.status,l.statusText,"text"!==(l.responseType||"text")||"string"!=typeof l.responseText?{binary:l.response}:{text:l.responseText},l.getAllResponseHeaders()))}},l.onload=n(),o=l.onerror=n("error"),void 0!==l.onabort?l.onabort=o:l.onreadystatechange=function(){4===l.readyState&&e.setTimeout(function(){n&&o()})},n=n("abort");try{l.send(t.hasContent&&t.data||null)}catch(s){if(n)throw s}},abort:function(){n&&n()}}:void 0}),ae.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return ae.globalEval(e),e}}}),ae.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),ae.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(o,i){t=ae("