diff --git a/multimedia/CHANGES.txt b/multimedia/CHANGES.txt index 29bd2c4..cb5bc9d 100644 --- a/multimedia/CHANGES.txt +++ b/multimedia/CHANGES.txt @@ -1,6 +1,13 @@ NetComomns2-multimedia Changelog =============================== +/* FIXME */ +2013/08/28: Version 2.4.0.1 +=============================== +- スマホ対応(Android、iOS) +- IE以外で、一覧表示の状態でチャンネル編集リンクをクリックした際にブロックが表示されなくなるバグを修正 + + 2013/05/20: Version 2.4.0.1 =============================== - ルームのリストア時にタグデータの重複エラーが発生することがあるバグを修正 diff --git a/multimedia/action/main/album/delete/Delete.class.php b/multimedia/action/main/album/delete/Delete.class.php index ca3f34b..a2f98a2 100644 --- a/multimedia/action/main/album/delete/Delete.class.php +++ b/multimedia/action/main/album/delete/Delete.class.php @@ -1,37 +1,37 @@ -multimediaAction->deleteAlbum($this->album['multimedia_id'], $this->album['album_id'])) { - return 'error'; - } - - return 'success'; - } -} -?> +multimediaAction->deleteAlbum($this->album['multimedia_id'], $this->album['album_id'])) { + return 'error'; + } + + return 'success'; + } +} +?> diff --git a/multimedia/action/main/album/entry/Entry.class.php b/multimedia/action/main/album/entry/Entry.class.php index f79b2fd..9f2075a 100644 --- a/multimedia/action/main/album/entry/Entry.class.php +++ b/multimedia/action/main/album/entry/Entry.class.php @@ -1,67 +1,67 @@ -upload_id)) { - $imageSize = $this->multimediaView->getImageSize($this->album_jacket); - } else { - $imageSize = $this->multimediaView->getImageSize($this->upload_id); - } - - $params = array( - "album_name" => $this->album_name, - "upload_id" => $this->upload_id, - "album_jacket" => $this->album_jacket, - "width" => $imageSize[0], - "height" => $imageSize[1], - "album_description" => $this->album_description, - "public_flag" => intval($this->public_flag) - ); - - if (empty($this->album_id)) { - $params["multimedia_id"] = $this->multimedia_id; - $albumSequence = $this->db->maxExecute("multimedia_album", "album_sequence", array("multimedia_id" => $this->multimedia_id)); - $params["album_sequence"] = $albumSequence + 1; - $result = $this->db->insertExecute("multimedia_album", $params, true, "album_id"); - } else { - $result = $this->db->updateExecute("multimedia_album", $params, array("album_id" => $this->album_id), true); - } - if ($result === false) { - return 'error'; - } - - return 'success'; - } -} -?> +upload_id)) { + $imageSize = $this->multimediaView->getImageSize($this->album_jacket); + } else { + $imageSize = $this->multimediaView->getImageSize($this->upload_id); + } + + $params = array( + "album_name" => $this->album_name, + "upload_id" => $this->upload_id, + "album_jacket" => $this->album_jacket, + "width" => $imageSize[0], + "height" => $imageSize[1], + "album_description" => $this->album_description, + "public_flag" => intval($this->public_flag) + ); + + if (empty($this->album_id)) { + $params["multimedia_id"] = $this->multimedia_id; + $albumSequence = $this->db->maxExecute("multimedia_album", "album_sequence", array("multimedia_id" => $this->multimedia_id)); + $params["album_sequence"] = $albumSequence + 1; + $result = $this->db->insertExecute("multimedia_album", $params, true, "album_id"); + } else { + $result = $this->db->updateExecute("multimedia_album", $params, array("album_id" => $this->album_id), true); + } + if ($result === false) { + return 'error'; + } + + return 'success'; + } +} +?> diff --git a/multimedia/action/main/album/jacket/Jacket.class.php b/multimedia/action/main/album/jacket/Jacket.class.php index 04f2c4c..57d685f 100644 --- a/multimedia/action/main/album/jacket/Jacket.class.php +++ b/multimedia/action/main/album/jacket/Jacket.class.php @@ -1,21 +1,21 @@ -uploadsAction->uploads(); - $this->session->setParameter("multimedia_jacket_upload_id", $files[0]["upload_id"]); - - return true; - } -} +uploadsAction->uploads(); + $this->session->setParameter("multimedia_jacket_upload_id", $files[0]["upload_id"]); + + return true; + } +} ?> \ No newline at end of file diff --git a/multimedia/action/main/comment/delete/Delete.class.php b/multimedia/action/main/comment/delete/Delete.class.php index bd6b707..8251dfd 100644 --- a/multimedia/action/main/comment/delete/Delete.class.php +++ b/multimedia/action/main/comment/delete/Delete.class.php @@ -1,40 +1,40 @@ - $this->comment_id - ); - if (!$this->db->deleteExecute("multimedia_comment", $params)) { - return 'error'; - } - - return 'success'; - } -} -?> + $this->comment_id + ); + if (!$this->db->deleteExecute("multimedia_comment", $params)) { + return 'error'; + } + + return 'success'; + } +} +?> diff --git a/multimedia/action/main/comment/entry/Entry.class.php b/multimedia/action/main/comment/entry/Entry.class.php index ff81422..04487db 100644 --- a/multimedia/action/main/comment/entry/Entry.class.php +++ b/multimedia/action/main/comment/entry/Entry.class.php @@ -1,57 +1,57 @@ -comment_id)) { - $params = array( - "item_id" => $this->item['item_id'], - "album_id" => $this->album['album_id'], - "multimedia_id" => $this->album['multimedia_id'], - "comment_value" => $this->comment_value - ); - $result = $this->db->insertExecute("multimedia_comment", $params, true, "comment_id"); - } else { - $params = array( - "comment_id" => $this->comment_id, - "comment_value" => $this->comment_value - ); - $result = $this->db->updateExecute("multimedia_comment", $params, "comment_id", true); - } - if (!$result) { - return 'error'; - } - - return 'success'; - } -} -?> +comment_id)) { + $params = array( + "item_id" => $this->item['item_id'], + "album_id" => $this->album['album_id'], + "multimedia_id" => $this->album['multimedia_id'], + "comment_value" => $this->comment_value + ); + $result = $this->db->insertExecute("multimedia_comment", $params, true, "comment_id"); + } else { + $params = array( + "comment_id" => $this->comment_id, + "comment_value" => $this->comment_value + ); + $result = $this->db->updateExecute("multimedia_comment", $params, "comment_id", true); + } + if (!$result) { + return 'error'; + } + + return 'success'; + } +} +?> diff --git a/multimedia/action/main/item/delete/Delete.class.php b/multimedia/action/main/item/delete/Delete.class.php index 69f449e..d37f8b0 100644 --- a/multimedia/action/main/item/delete/Delete.class.php +++ b/multimedia/action/main/item/delete/Delete.class.php @@ -1,37 +1,37 @@ -multimediaAction->deleteItem($this->item_id)) { - return 'error'; - } - - return 'success'; - } -} +multimediaAction->deleteItem($this->item_id)) { + return 'error'; + } + + return 'success'; + } +} ?> \ No newline at end of file diff --git a/multimedia/action/main/item/edit/Edit.class.php b/multimedia/action/main/item/edit/Edit.class.php index f9cfbf1..40e3368 100644 --- a/multimedia/action/main/item/edit/Edit.class.php +++ b/multimedia/action/main/item/edit/Edit.class.php @@ -1,66 +1,66 @@ - $this->album_id, - "item_name" => $this->item_name, - "item_description" => $this->item_description, - "privacy" => $this->privacy - ); - $where_params = array( - "item_id" => $this->item_id - ); - $result = $this->db->updateExecute("multimedia_item", $params, $where_params, true); - if ($result === false) { - return 'error'; - } - - if($this->album_id != $this->item['album_id']) { - if(!$this->multimediaAction->setItemCount($this->album_id, 1)) { - return 'error'; - } - if(!$this->multimediaAction->setItemCount($this->item['album_id'], -1)) { - return 'error'; - } - } - - if(!empty($this->item_tag)) { - if(!$this->multimediaAction->setItemTag($this->item_id, $this->item_tag)) { - return 'error'; - } - } - - return 'success'; - } -} -?> + $this->album_id, + "item_name" => $this->item_name, + "item_description" => $this->item_description, + "privacy" => $this->privacy + ); + $where_params = array( + "item_id" => $this->item_id + ); + $result = $this->db->updateExecute("multimedia_item", $params, $where_params, true); + if ($result === false) { + return 'error'; + } + + if($this->album_id != $this->item['album_id']) { + if(!$this->multimediaAction->setItemCount($this->album_id, 1)) { + return 'error'; + } + if(!$this->multimediaAction->setItemCount($this->item['album_id'], -1)) { + return 'error'; + } + } + + if(!empty($this->item_tag)) { + if(!$this->multimediaAction->setItemTag($this->item_id, $this->item_tag)) { + return 'error'; + } + } + + return 'success'; + } +} +?> diff --git a/multimedia/action/main/item/play/Play.class.php b/multimedia/action/main/item/play/Play.class.php index 043456c..4cc652d 100644 --- a/multimedia/action/main/item/play/Play.class.php +++ b/multimedia/action/main/item/play/Play.class.php @@ -14,22 +14,21 @@ */ class Multimedia_Action_Main_Item_Play extends Action { - // リクエストパラメータを受け取るため - - // バリデートによりセット - var $item = null; - var $uploadsView = null; - - - // 値をセットするため - - /** - * [[機能説明]] - * - * @access public - */ - function execute() - { + // 使用コンポーネントを受け取るため + var $session = null; + var $uploadsView = null; + var $db = null; + + // バリデートによりセット + var $item = null; + + /** + * [[機能説明]] + * + * @access public + */ + function execute() + { list($pathname,$filename,$physical_file_name, $cache_flag) = $this->uploadsView->downloadCheck($this->item['upload_id'], null); if (!isset($pathname)) { exit; @@ -41,8 +40,113 @@ function execute() $caching = false; } - $this->uploadsView->headerOutput($pathname, $filename, $physical_file_name, $caching); - exit; - } + //Rangeヘッダが設定されている場合(iOS) + if(isset($_SERVER['HTTP_RANGE'])) { + //動画ファイルサイズ取得 + $file = $pathname . $filename; + $file_size = filesize($file) - 1; //Rangeヘッダのオフセットが0であるため、-1 + + //Rangeヘッダを解析 + list($range_header, $range) = explode('=', $_SERVER['HTTP_RANGE']); + list($range_offset, $range_limit) = explode('-', $range); + $playback_session_id_array = array(); + + //Rangeヘッダが0からファイル終端の場合(ファイル存在確認後、1度のみリクエストされる) + if($range_offset == 0 && $range_limit == $file_size - 1) { + //再生回数更新 + $params = array( + $this->item['item_id'] + ); + $sql = "UPDATE {multimedia_item} ". + "SET item_play_count = item_play_count + 1 ". + "WHERE item_id = ? "; + $result = $this->db->execute($sql, $params); + if ($result === false) { + return 'error'; + } + } + + // Rangeヘッダの終了値が省略されている場合はファイルサイズを設定 + if(is_null($range_limit)) { + $range_limit = $file_size; + } + + //Rangeヘッダが指定するコンテンツの長さを設定(Rangeヘッダのオフセットが0であるため、+1) + $content_length = $range_limit - $range_offset + 1; + + //Rangeヘッダで指定された範囲の動画を取得 + $content = file_get_contents($file, FILE_BINARY, null, $range_offset, $range_limit); + + //ヘッダ出力 + @ob_end_clean(); + header('Content-type: video/mp4'); + header('Content-Disposition: attachment; filename="' . $filename . '"'); + header('Content-Transfer-Encoding: binary'); + header('Accept-Ranges: bytes'); + header('HTTP/1.1 206 Partial Content'); + header('Content-Length: ' . $content_length); + header('Content-Range: bytes ' . $range_offset . '-' . $range_limit . '/' . $file_size); +// header("Etag: \"" . md5( $_SERVER["REQUEST_URI"] ) . $file_size . "\"" ); + header("Last-Modified: " . gmdate( "D, d M Y H:i:s", filemtime($file)) . " GMT"); + +// 以下、webapp/components/uploads/View.class.php の function _headerOutput より + $stats = stat($file); + $etag = sprintf( '"%x-%x-%x"', $stats['ino'], $stats['size'], $stats['mtime'] ); + header('Etag: '.$etag); + + if($caching == true) { + // 1Week + header("Cache-Control: max-age=604800, public"); + header('Pragma: cache'); //no-cache以外の文字列をセット + $offset = 60 * 60 * 24 * 7; // 1Week + header('Expires: '.gmdate('D, d M Y H:i:s', time() + $offset).' GMT'); + if (isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) && + stripcslashes( $_SERVER['HTTP_IF_NONE_MATCH'] ) == $etag ) { + header( 'HTTP/1.1 304 Not Modified' ); + $status_code = "304"; + } + //} else if (isset($_SERVER['HTTPS']) && stristr($_SERVER['HTTP_USER_AGENT'], "MSIE")) { + // // IE + サイト全体SSLの場合、ダウンロードが正常に行われない。 + // // ダウンロードさせるためには、以下コメントをはずす必要があるが、 + // // アップロードした画像ファイル等をローカルキャッシュにとられてしまう弊害がある。 + // // 1Week + // header("Cache-Control: max-age=604800, public"); + // header('Pragma: cache'); //no-cache以外の文字列をセット + // $offset = 60 * 60 * 24 * 7; // 1Week + // header('Expires: '.gmdate('D, d M Y H:i:s', time() + $offset).' GMT'); + } else { + header("Cache-Control: no-store, no-cache, must-revalidate"); + header("Pragma: no-cache"); + } +// 以上、webapp/components/uploads/View.class.php の function _headerOutput より + + //ファイル出力 + $fp = fopen($file, "rb"); + fseek($fp, $range_offset, SEEK_SET); + echo fread($fp, $content_length); + exit; + } + //Rangeヘッダが設定されていない場合 + else { + //HTTP_USER_AGENTが設定されている場合のみ再生数をカウント(Android Chrome対策) + if(isset($_SERVER['HTTP_USER_AGENT'])) { + //再生回数更新 + $params = array( + $this->item['item_id'] + ); + $sql = "UPDATE {multimedia_item} ". + "SET item_play_count = item_play_count + 1 ". + "WHERE item_id = ? "; + $result = $this->db->execute($sql, $params); + if ($result === false) { + return 'error'; + } + } + + //動画出力 + $this->uploadsView->headerOutput($pathname, $filename, $physical_file_name, $caching); + exit; + } + } } ?> \ No newline at end of file diff --git a/multimedia/action/main/item/play/maple.ini b/multimedia/action/main/item/play/maple.ini index 95258cb..40e7c9d 100644 --- a/multimedia/action/main/item/play/maple.ini +++ b/multimedia/action/main/item/play/maple.ini @@ -11,7 +11,7 @@ request = BOTH upload_id.multimedia.playCheck = "1:lang.multimedia_err_incorrectauth" [Action] -actionChain = "ref:ActionChain" +db = "ref:DbObject" uploadsView = "ref:uploadsView" session = "ref:Session" diff --git a/multimedia/action/main/item/sequence/Sequence.class.php b/multimedia/action/main/item/sequence/Sequence.class.php index 05b5cb9..3ca3d7a 100644 --- a/multimedia/action/main/item/sequence/Sequence.class.php +++ b/multimedia/action/main/item/sequence/Sequence.class.php @@ -1,77 +1,77 @@ -album_id, - $this->drag_sequence, - $this->drop_sequence - ); - - if ($this->drag_sequence > $this->drop_sequence) { - $sql = "UPDATE {multimedia_item} ". - "SET item_sequence = item_sequence + 1 ". - "WHERE album_id = ? ". - "AND item_sequence < ? ". - "AND item_sequence > ?"; - } else { - $sql = "UPDATE {multimedia_item} ". - "SET item_sequence = item_sequence - 1 ". - "WHERE album_id = ? ". - "AND item_sequence > ? ". - "AND item_sequence <= ?"; - } - - $result = $this->db->execute($sql, $params); - if($result === false) { - return 'error'; - } - - if ($this->drag_sequence > $this->drop_sequence) { - $this->drop_sequence++; - } - $params = array( - $this->drop_sequence, - $this->drag_item_id - ); - - $sql = "UPDATE {multimedia_item} ". - "SET item_sequence = ? ". - "WHERE item_id = ?"; - $result = $this->db->execute($sql, $params); - if($result === false) { - return 'error'; - } - - return 'success'; - } -} +album_id, + $this->drag_sequence, + $this->drop_sequence + ); + + if ($this->drag_sequence > $this->drop_sequence) { + $sql = "UPDATE {multimedia_item} ". + "SET item_sequence = item_sequence + 1 ". + "WHERE album_id = ? ". + "AND item_sequence < ? ". + "AND item_sequence > ?"; + } else { + $sql = "UPDATE {multimedia_item} ". + "SET item_sequence = item_sequence - 1 ". + "WHERE album_id = ? ". + "AND item_sequence > ? ". + "AND item_sequence <= ?"; + } + + $result = $this->db->execute($sql, $params); + if($result === false) { + return 'error'; + } + + if ($this->drag_sequence > $this->drop_sequence) { + $this->drop_sequence++; + } + $params = array( + $this->drop_sequence, + $this->drag_item_id + ); + + $sql = "UPDATE {multimedia_item} ". + "SET item_sequence = ? ". + "WHERE item_id = ?"; + $result = $this->db->execute($sql, $params); + if($result === false) { + return 'error'; + } + + return 'success'; + } +} ?> \ No newline at end of file diff --git a/multimedia/action/main/item/upload/Upload.class.php b/multimedia/action/main/item/upload/Upload.class.php index cde0f54..a11cdb3 100644 --- a/multimedia/action/main/item/upload/Upload.class.php +++ b/multimedia/action/main/item/upload/Upload.class.php @@ -1,28 +1,28 @@ - \ No newline at end of file diff --git a/multimedia/action/main/item/vote/Vote.class.php b/multimedia/action/main/item/vote/Vote.class.php index 23bdf91..25a7fa6 100644 --- a/multimedia/action/main/item/vote/Vote.class.php +++ b/multimedia/action/main/item/vote/Vote.class.php @@ -1,71 +1,71 @@ -session->getParameter("_user_id"); - - if (empty($user_id)) { - $votes = $this->session->getParameter("multimedia_votes"); - $votes[] = $this->item_id; - $session->setParameter("multimedia_votes", $votes); - } else { - $params = array( - "user_id" => $user_id, - "item_id" => $this->item_id, - "vote_flag" => _ON - ); - if (!$this->db->insertExecute("mutlimedia_user_item", $params, true)) { - return 'error'; - } - } - - $params = array($this->item_id); - $sql = "UPDATE {multimedia_item} ". - "SET item_vote_count = item_vote_count + 1 ". - "WHERE item_id = ?"; - $result = $this->db->execute($sql, $params); - if ($result === false) { - return 'error'; - } - - $params = array($this->album_id); - $sql = "UPDATE {multimedia_album} ". - "SET album_vote_count = album_vote_count + 1 ". - "WHERE album_id = ?"; - $result = $this->db->execute($sql, $params); - if ($result === false) { - return 'error'; - } - - return 'success'; - } -} +session->getParameter("_user_id"); + + if (empty($user_id)) { + $votes = $this->session->getParameter("multimedia_votes"); + $votes[] = $this->item_id; + $session->setParameter("multimedia_votes", $votes); + } else { + $params = array( + "user_id" => $user_id, + "item_id" => $this->item_id, + "vote_flag" => _ON + ); + if (!$this->db->insertExecute("mutlimedia_user_item", $params, true)) { + return 'error'; + } + } + + $params = array($this->item_id); + $sql = "UPDATE {multimedia_item} ". + "SET item_vote_count = item_vote_count + 1 ". + "WHERE item_id = ?"; + $result = $this->db->execute($sql, $params); + if ($result === false) { + return 'error'; + } + + $params = array($this->album_id); + $sql = "UPDATE {multimedia_album} ". + "SET album_vote_count = album_vote_count + 1 ". + "WHERE album_id = ?"; + $result = $this->db->execute($sql, $params); + if ($result === false) { + return 'error'; + } + + return 'success'; + } +} ?> \ No newline at end of file diff --git a/multimedia/components/Action.class.php b/multimedia/components/Action.class.php index 165e255..4b5716a 100644 --- a/multimedia/components/Action.class.php +++ b/multimedia/components/Action.class.php @@ -1,575 +1,631 @@ -_db =& $container->getComponent("DbObject"); - $this->_request =& $container->getComponent("Request"); - } - - function hasFfmpegLib() { - $extension_fullname = PHP_EXTENSION_DIR . "/" . MULTIMEDIA_EXTENSION.".".PHP_SHLIB_SUFFIX; - if (!extension_loaded(MULTIMEDIA_EXTENSION)) { - //dl($extension_soname) or die("Can't load extension $extension_fullname\n"); - return false; - } - return true; - } - - function deleteMultimedia() { - $params = array( - "multimedia_id" => $this->_request->getParameter("multimedia_id") - ); - - if (!$this->_db->deleteExecute("multimedia_block", $params)) { - return false; - } - - if (!$this->_db->deleteExecute("multimedia_comment", $params)) { - return false; - } - - $sql = "SELECT item_id, upload_id, file_path ". - "FROM {multimedia_item} ". - "WHERE multimedia_id = ?"; - $items = $this->_db->execute($sql, $params); - if ($items === false) { - $this->_db->addError(); - return false; - } - if (!$this->deleteItemFile($items)) { - return false; - } - if (!$this->_db->deleteExecute("multimedia_item", $params)) { - return false; - } - if (!$this->_db->deleteExecute("multimedia_album", $params)) { - return false; - } - if (!$this->_db->deleteExecute("multimedia", $params)) { - return false; - } - - return true; - } - - //動画ファイル削除 - function deleteItemFile($items) - { - if (empty($items)) { - return true; - } - - $container =& DIContainerFactory::getContainer(); - $commonMain =& $container->getComponent("commonMain"); - $uploads =& $commonMain->registerClass(WEBAPP_DIR.'/components/uploads/Action.class.php', "Uploads_Action", "uploadsAction"); - $item_ids = array(); - foreach ($items as $item) { - if (!$uploads->delUploadsById($item['upload_id'])) { - return false; - } - //動画のサムネイル画像があれば、削除 - $thumbnail_path = FILEUPLOADS_DIR.$item['file_path'].$item['upload_id']."_thumbnail.jpg"; - if(file_exists($thumbnail_path)) { - @chmod($thumbnail_path, 0777); - unlink($thumbnail_path); - } - //タグ削除 - $sql = "SELECT tag_id " - . "FROM {multimedia_item_tag} " - . "WHERE item_id = ?;"; - $params = array( - "item_id" => $item['item_id'] - ); - $tag_id_string = $this->_db->execute($sql, $params, $limit = null, $offset = null, false, array($this, "_makeImplodeString")); - if ($tag_id_string === false) { - $this->_db->addError(); - return false; - } - if (!empty($tag_id_string)) { - if(!$this->_db->deleteExecute("multimedia_item_tag", $params)) { - return false; - } - } - $this->_tagReCount($tag_id_string); - - if (!$this->_db->deleteExecute("multimedia_item_tag", $params)) { - return false; - } - } - - return true; - } - - //カテゴリ削除 - function deleteAlbum($multimedia_id, $album_id) { - $params = array( - "album_id" => $album_id - ); - - if (!$this->_db->deleteExecute("multimedia_comment", $params)) { - return false; - } - - $sql = "SELECT item_id, upload_id, file_path ". - "FROM {multimedia_item} ". - "WHERE album_id = ?"; - $items = $this->_db->execute($sql, $params); - if ($items === false) { - $this->_db->addError(); - return false; - } - if (!$this->deleteItemFile($items)) { - return false; - } - if (!$this->_db->deleteExecute("multimedia_item", $params)) { - return false; - } - - $sql = "SELECT album_sequence, upload_id ". - "FROM {multimedia_album} ". - "WHERE album_id = ?"; - $albums = $this->_db->execute($sql, $params); - if ($albums === false) { - $this->_db->addError(); - return false; - } - - if (!$this->_db->deleteExecute("multimedia_album", $params)) { - return false; - } - - if(!empty($albums[0]['upload_id'])) { - $container =& DIContainerFactory::getContainer(); - $commonMain =& $container->getComponent("commonMain"); - $uploads =& $commonMain->registerClass(WEBAPP_DIR.'/components/uploads/Action.class.php', "Uploads_Action", "uploadsAction"); - if (!$uploads->delUploadsById($albums[0]['upload_id'])) { - return false; - } - } - - $params = array( - "multimedia_id" => $multimedia_id - ); - $sequenceParam = array( - "album_sequence" => $albums[0]['album_sequence'] - ); - if (!$this->_db->seqExecute("multimedia_album", $params, $sequenceParam)) { - return false; - } - - return true; - } - - //動画削除 - function deleteItem($item_id) { - $params = array( - "item_id" => $item_id - ); - - //コメント削除 - if (!$this->_db->deleteExecute("multimedia_comment", $params)) { - return false; - } - - //動画削除 - $sql = "SELECT item_id, album_id, upload_id, file_path ". - "FROM {multimedia_item} ". - "WHERE item_id = ?"; - $item = $this->_db->execute($sql, $params); - if ($item === false) { - $this->_db->addError(); - return false; - } - if (!$this->deleteItemFile($item)) { - return false; - } - if (!$this->_db->deleteExecute("multimedia_item", $params)) { - return false; - } - - if(!$this->setItemCount($item[0]['album_id'], -1)) { - return false; - } - - return true; - } - - //アルバムの動画件数を計算 - function setItemCount($album_id, $count) { - if(empty($album_id)) { - return false; - } - - $params = array( - "album_id" => $album_id - ); - - $album = $this->_db->selectExecute("multimedia_album", $params); - if(empty($album) || !isset($album[0])) { - return false; - } - - $sql = "UPDATE {multimedia_album} ". - "SET item_count = item_count + ".($count)." ". - "WHERE album_id = ?"; - $result = $this->_db->execute($sql, $params); - if ($result === false) { - $this->_db->addError(); - return false; - } - - return true; - } - - /** - * 動画タグデータを登録する - * - * @param string $item_id 対象の動画ID - * @return boolean true or false - * @access public - */ - function setItemTag($item_id, $item_tag) { - if(empty($item_id)) { - return false; - } - - $container =& DIContainerFactory::getContainer(); - - $tag_values = array(); - if (!empty($item_tag)) { - $item_tag = str_replace(',', MULTIMEDIA_TAG_SEPARATOR, $item_tag); - $item_tag = str_replace('、', MULTIMEDIA_TAG_SEPARATOR, $item_tag); - $item_tag = str_replace('、', MULTIMEDIA_TAG_SEPARATOR, $item_tag); - $tag_values = split(MULTIMEDIA_TAG_SEPARATOR, $item_tag); - } - - foreach ($tag_values as $key => $value) { - $value = preg_replace("/^[  ]+/u","",$value); - $value = preg_replace("/[  ]+$/u","",$value); - $tag_values[$key] = $value; - } - - $tag_values = array_unique($tag_values); - - $sql = "SELECT R.tag_id " - . "FROM {multimedia_item_tag} AS R " - . "INNER JOIN {multimedia_tag} AS T " - . "ON R.tag_id = T.tag_id " - . "WHERE R.item_id = ? "; - $params = array( - $item_id - ); - $tag_id_string = $this->_db->execute($sql, $params, $limit = null, $offset = null, false, array($this, "_makeImplodeString")); - - if ($tag_id_string === false) { - $this->_db->addError(); - return false; - } - if (!empty($tag_id_string)) { - $sql = "DELETE FROM {multimedia_item_tag} " - . "WHERE item_id = ? " - . "AND tag_id IN (" . $tag_id_string . ") "; - $params = array( - $item_id - ); - if ($this->_db->execute($sql, $params) === false) { - $this->_db->addError(); - return false; - } - } - - $sequence = 1; - $tag_ids = array(); - foreach ($tag_values as $tag_value) { - if (empty($tag_value)) { - continue; - } - $sql = "SELECT tag_id " - . "FROM {multimedia_tag} " - . "WHERE tag_value = ? AND room_id = ? "; - $params = array( - $this->getSynonym($tag_value), - $this->_request->getParameter("room_id") - ); - $item_tag_ids = $this->_db->execute($sql, $params); - if ($item_tag_ids === false) { - $this->_db->addError(); - return false; - } - if (empty($item_tag_ids)) { - $params = array( - 'tag_value' => $this->getSynonym($tag_value), - 'used_number' => 1 - ); - - $tag_id = $this->_db->insertExecute('multimedia_tag', $params, true, 'tag_id'); - if (empty($tag_id)) { - return false; - } - - } else { - $tag_id = $item_tag_ids[0]['tag_id']; - } - $tag_ids[] = $tag_id; - - $item_tag = array( - 'item_id' => $item_id, - 'tag_id' => $tag_id, - 'tag_value' => $tag_value, - 'sequence' => $sequence - ); - if (!$this->_db->insertExecute('multimedia_item_tag', $item_tag, true)){ - return false; - } - $sequence++; - } - - if (!empty($tag_id_string) && !empty($tag_ids)) { - $tag_id_string .= ','; - } - $tag_id_string .= implode(',', $tag_ids); - - if (!$this->_tagReCount($tag_id_string)) { - return false; - } - - return true; - } - - /** - * 動画タグの使用回数を再カウント。0件ならmultimedia_tagから削除。 - * - * @param string $tagIDString 区切り文字 - * @return boolean true or false - * @access private - */ - function _tagReCount($tag_id_string) { - $counted_tag_ids = array(); - if (!empty($tag_id_string)) { - $sql = "SELECT tag_id, " - . "COUNT(DISTINCT item_id) AS tag_count " - . "FROM {multimedia_item_tag} " - . "WHERE tag_id IN (" . $tag_id_string . ") " - . "GROUP BY tag_id;"; - $tags = $this->_db->execute($sql); - if ($tags === false) { - $this->_db->addError(); - return false; - } - if(!empty($tags)) { - foreach ($tags as $tag) { - $tag_used_number = array( - 'tag_id' => $tag['tag_id'], - 'used_number' => $tag['tag_count'] - ); - if (!$this->_db->updateExecute('multimedia_tag', $tag_used_number, 'tag_id', true)) { - return false; - } - - $counted_tag_ids[] = $tag['tag_id']; - } - } - } - - $tag_ids = explode(',', $tag_id_string); - $tag_ids = array_diff($tag_ids, $counted_tag_ids); - foreach ($tag_ids as $tag_id) { - $tag_used_number = array( - 'tag_id' => $tag_id - ); - if (!$this->_db->deleteExecute('multimedia_tag', $tag_used_number)) { - return false; - } - } - - return true; - } - - /** - * ADORecordSetの1カラム目を指定文字区切りの文字列にする - * - * @param array $recordSet ADORecordSet - * @param array $glue 区切り文字 - * @return array 指定文字区切りの文字列 - * @access private - */ - function &_makeImplodeString(&$recordSet, $glue = ",") { - $string = ""; - if ($recordSet->EOF) { - return $string; - } - - while ($row = $recordSet->fetchRow()) { - $string .= $row[0] . $glue; - } - if (!empty($glue)) { - $string = substr($string, 0, strlen($glue) * -1); - } - - return $string; - } - - function getSynonym($str) { - //半角カナ(濁点付き)→全角カナに変換 - $replace_of = array('ヴ', 'ガ', 'ギ', 'グ', - 'ゲ', 'ゴ', 'ザ', 'ジ', - 'ズ', 'ゼ', 'ゾ', 'ダ', - 'ヂ', 'ヅ', 'デ', 'ド', - 'バ', 'ビ', 'ブ', 'ベ', - 'ボ', 'パ', 'ピ', 'プ', 'ペ', 'ポ'); - - $replace_by = array('ヴ', 'ガ', 'ギ', 'グ', - 'ゲ', 'ゴ', 'ザ', 'ジ', - 'ズ', 'ゼ', 'ゾ', 'ダ', - 'ヂ', 'ヅ', 'デ', 'ド', - 'バ', 'ビ', 'ブ', 'ベ', - 'ボ', 'パ', 'ピ', 'プ', 'ペ', 'ポ'); - $_result = str_replace($replace_of, $replace_by, $str); - - //半角カナ→全角カナに変換 - $replace_of = array('ア', 'イ', 'ウ', 'エ', 'オ', - 'カ', 'キ', 'ク', 'ケ', 'コ', - 'サ', 'シ', 'ス', 'セ', 'ソ', - 'タ', 'チ', 'ツ', 'テ', 'ト', - 'ナ', 'ニ', 'ヌ', 'ネ', 'ノ', - 'ハ', 'ヒ', 'フ', 'ヘ', 'ホ', - 'マ', 'ミ', 'ム', 'メ', 'モ', - 'ヤ', 'ユ', 'ヨ', 'ラ', 'リ', - 'ル', 'レ', 'ロ', 'ワ', 'ヲ', - 'ン', 'ァ', 'ィ', 'ゥ', 'ェ', - 'ォ', 'ヵ', 'ヶ', 'ャ', 'ュ', - 'ョ', 'ッ', '、', '。', 'ー', - '「', '」', '゙', '゚'); - - $replace_by = array('ア', 'イ', 'ウ', 'エ', 'オ', - 'カ', 'キ', 'ク', 'ケ', 'コ', - 'サ', 'シ', 'ス', 'セ', 'ソ', - 'タ', 'チ', 'ツ', 'テ', 'ト', - 'ナ', 'ニ', 'ヌ', 'ネ', 'ノ', - 'ハ', 'ヒ', 'フ', 'ヘ', 'ホ', - 'マ', 'ミ', 'ム', 'メ', 'モ', - 'ヤ', 'ユ', 'ヨ', 'ラ', 'リ', - 'ル', 'レ', 'ロ', 'ワ', 'ヲ', - 'ン', 'ァ', 'ィ', 'ゥ', 'ェ', - 'ォ', 'ヶ', 'ヶ', 'ャ', 'ュ', - 'ョ', 'ッ', '、', '。', 'ー', - '「', '」', '”', ''); - - $_result = str_replace($replace_of, $replace_by, $_result); - - //全角数字→半角数字に変換 - $replace_of = array('1', '2', '3', '4', '5', - '6', '7', '8', '9', '0'); - - $replace_by = array('1', '2', '3', '4', '5', - '6', '7', '8', '9', '0'); - - $_result = str_replace($replace_of, $replace_by, $_result); - - //全角英字→半角英字に変換 - $replace_of = array('A', 'B', 'C', 'D', 'E', - 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', - 'Z', - 'a', 'b', 'c', 'd', 'e', - 'f', 'g', 'h', 'i', 'j', - 'k', 'l', 'm', 'n', 'o', - 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', - 'z'); - - $replace_by = array('A', 'B', 'C', 'D', 'E', - 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', - 'Z', - 'a', 'b', 'c', 'd', 'e', - 'f', 'g', 'h', 'i', 'j', - 'k', 'l', 'm', 'n', 'o', - 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', - 'z'); - - $_result = str_replace($replace_of, $replace_by, $_result); - -/* - //小文字ひらがな→小文字カナに変換 - $replace_of = array('ぁ', 'ぃ', 'ぅ', 'ぇ', 'ぉ', - 'ゃ', 'ゅ', 'ょ', 'っ'); - - $replace_by = array('ァ', 'ィ', 'ゥ', 'ェ', 'ォ', - 'ャ', 'ュ', 'ョ', 'ッ'); - - $_result = str_replace($replace_of, $replace_by, $_result); -*/ - //その他記号に変換 - $replace_of = array('ー', '-', '-', '~', ',', - '、', ',', '・', '・', '=', - '=', ' ', ' ', '。', '.', - '.', '/', '/', '―', '‐', - '’', '′', '´', '‘', '゜', - '\'', '"', '〝', '″', '゛', - '“', '”', 'ッ', 'ュ', 'ィ', - 'ゅ', 'ぃ'); - - $replace_by = array('', '', '', '', '', - '', '', '', '', '', - '', '', '', '', '', - '', '', '', '', '', - '', '', '', '', '', - '', '', '', '', '', - '', '', '', '', '', - '', ''); - - $_result = str_replace($replace_of, $replace_by, $_result); - -/* - //小文字カナ→大文字カナに変換 - $replace_of = array('ァ', 'ィ', 'ゥ', 'ェ', 'ォ', - 'ヶ', 'ヶ', 'ャ', 'ュ', 'ョ', 'ッ'); - - $replace_by = array('ア', 'イ', 'ウ', 'エ', 'オ', - 'ケ', 'ケ', 'ヤ', 'ユ', 'ヨ', 'ツ'); - - $_result = str_replace($replace_of, $replace_by, $_result); -*/ - return $_result; - } -} +_db =& $container->getComponent("DbObject"); + $this->_request =& $container->getComponent("Request"); + } + + /** + * ffmpegインストールチェック処理 + * + * @param void + * @return boolean true or false + * @access public + */ + function hasFfmpeg() { + if (!file_exists(MULTIMEDIA_FFMPEG_PATH)) { + return false; + } + return true; + } + + /** + * MP4Bpxインストールチェック処理 + * + * @param void + * @return boolean true or false + * @access public + */ + function hasMp4box() { + if (!file_exists(MULTIMEDIA_MP4BOX_PATH)) { + return false; + } + return true; + } + + /** + * サムネイル画像及び仮サムネイル画像削除処理 + * + * @param string $thumbnail_path サムネイル画像のパス(縮小後) + * @param string $temp_thumbnail_path キャプチャ画像のパス(縮小前) + * @return void + * @access public + */ +# function deleteImages($thumbnail_path, $temp_thumbnail_path) { +# //画像削除 +# unlink($thumbnail_path); +# unlink($temp_thumbnail_path); +# } + + /** + * ファイル削除処理 + * + * @param array $image_paths 削除対象ファイルパス + * @return void + * @access public + */ + function deleteFiles($file_paths) { + foreach($file_paths as $path) { + //ファイル削除 + unlink($path); + } + } + + function hasFfmpegLib() { + $extension_fullname = PHP_EXTENSION_DIR . "/" . MULTIMEDIA_EXTENSION.".".PHP_SHLIB_SUFFIX; + if (!extension_loaded(MULTIMEDIA_EXTENSION)) { + //dl($extension_soname) or die("Can't load extension $extension_fullname\n"); + return false; + } + return true; + } + + function deleteMultimedia() { + $params = array( + "multimedia_id" => $this->_request->getParameter("multimedia_id") + ); + + if (!$this->_db->deleteExecute("multimedia_block", $params)) { + return false; + } + + if (!$this->_db->deleteExecute("multimedia_comment", $params)) { + return false; + } + + $sql = "SELECT item_id, upload_id, file_path ". + "FROM {multimedia_item} ". + "WHERE multimedia_id = ?"; + $items = $this->_db->execute($sql, $params); + if ($items === false) { + $this->_db->addError(); + return false; + } + if (!$this->deleteItemFile($items)) { + return false; + } + if (!$this->_db->deleteExecute("multimedia_item", $params)) { + return false; + } + if (!$this->_db->deleteExecute("multimedia_album", $params)) { + return false; + } + if (!$this->_db->deleteExecute("multimedia", $params)) { + return false; + } + + return true; + } + + //動画ファイル削除 + function deleteItemFile($items) + { + if (empty($items)) { + return true; + } + + $container =& DIContainerFactory::getContainer(); + $commonMain =& $container->getComponent("commonMain"); + $uploads =& $commonMain->registerClass(WEBAPP_DIR.'/components/uploads/Action.class.php', "Uploads_Action", "uploadsAction"); + $item_ids = array(); + foreach ($items as $item) { + if (!$uploads->delUploadsById($item['upload_id'])) { + return false; + } + //動画のサムネイル画像があれば、削除 + $thumbnail_path = FILEUPLOADS_DIR.$item['file_path'].$item['upload_id']."_thumbnail.jpg"; + if(file_exists($thumbnail_path)) { + @chmod($thumbnail_path, 0777); + unlink($thumbnail_path); + } + //タグ削除 + $sql = "SELECT tag_id " + . "FROM {multimedia_item_tag} " + . "WHERE item_id = ?;"; + $params = array( + "item_id" => $item['item_id'] + ); + $tag_id_string = $this->_db->execute($sql, $params, $limit = null, $offset = null, false, array($this, "_makeImplodeString")); + if ($tag_id_string === false) { + $this->_db->addError(); + return false; + } + if (!empty($tag_id_string)) { + if(!$this->_db->deleteExecute("multimedia_item_tag", $params)) { + return false; + } + } + $this->_tagReCount($tag_id_string); + + if (!$this->_db->deleteExecute("multimedia_item_tag", $params)) { + return false; + } + } + + return true; + } + + //カテゴリ削除 + function deleteAlbum($multimedia_id, $album_id) { + $params = array( + "album_id" => $album_id + ); + + if (!$this->_db->deleteExecute("multimedia_comment", $params)) { + return false; + } + + $sql = "SELECT item_id, upload_id, file_path ". + "FROM {multimedia_item} ". + "WHERE album_id = ?"; + $items = $this->_db->execute($sql, $params); + if ($items === false) { + $this->_db->addError(); + return false; + } + if (!$this->deleteItemFile($items)) { + return false; + } + if (!$this->_db->deleteExecute("multimedia_item", $params)) { + return false; + } + + $sql = "SELECT album_sequence, upload_id ". + "FROM {multimedia_album} ". + "WHERE album_id = ?"; + $albums = $this->_db->execute($sql, $params); + if ($albums === false) { + $this->_db->addError(); + return false; + } + + if (!$this->_db->deleteExecute("multimedia_album", $params)) { + return false; + } + + if(!empty($albums[0]['upload_id'])) { + $container =& DIContainerFactory::getContainer(); + $commonMain =& $container->getComponent("commonMain"); + $uploads =& $commonMain->registerClass(WEBAPP_DIR.'/components/uploads/Action.class.php', "Uploads_Action", "uploadsAction"); + if (!$uploads->delUploadsById($albums[0]['upload_id'])) { + return false; + } + } + + $params = array( + "multimedia_id" => $multimedia_id + ); + $sequenceParam = array( + "album_sequence" => $albums[0]['album_sequence'] + ); + if (!$this->_db->seqExecute("multimedia_album", $params, $sequenceParam)) { + return false; + } + + return true; + } + + //動画削除 + function deleteItem($item_id) { + $params = array( + "item_id" => $item_id + ); + + //コメント削除 + if (!$this->_db->deleteExecute("multimedia_comment", $params)) { + return false; + } + + //動画削除 + $sql = "SELECT item_id, album_id, upload_id, file_path ". + "FROM {multimedia_item} ". + "WHERE item_id = ?"; + $item = $this->_db->execute($sql, $params); + if ($item === false) { + $this->_db->addError(); + return false; + } + if (!$this->deleteItemFile($item)) { + return false; + } + if (!$this->_db->deleteExecute("multimedia_item", $params)) { + return false; + } + + if(!$this->setItemCount($item[0]['album_id'], -1)) { + return false; + } + + return true; + } + + //アルバムの動画件数を計算 + function setItemCount($album_id, $count) { + if(empty($album_id)) { + return false; + } + + $params = array( + "album_id" => $album_id + ); + + $album = $this->_db->selectExecute("multimedia_album", $params); + if(empty($album) || !isset($album[0])) { + return false; + } + + $sql = "UPDATE {multimedia_album} ". + "SET item_count = item_count + ".($count)." ". + "WHERE album_id = ?"; + $result = $this->_db->execute($sql, $params); + if ($result === false) { + $this->_db->addError(); + return false; + } + + return true; + } + + /** + * 動画タグデータを登録する + * + * @param string $item_id 対象の動画ID + * @return boolean true or false + * @access public + */ + function setItemTag($item_id, $item_tag) { + if(empty($item_id)) { + return false; + } + + $container =& DIContainerFactory::getContainer(); + + $tag_values = array(); + if (!empty($item_tag)) { + $item_tag = str_replace(',', MULTIMEDIA_TAG_SEPARATOR, $item_tag); + $item_tag = str_replace('、', MULTIMEDIA_TAG_SEPARATOR, $item_tag); + $item_tag = str_replace('、', MULTIMEDIA_TAG_SEPARATOR, $item_tag); + $tag_values = split(MULTIMEDIA_TAG_SEPARATOR, $item_tag); + } + + foreach ($tag_values as $key => $value) { + $value = preg_replace("/^[  ]+/u","",$value); + $value = preg_replace("/[  ]+$/u","",$value); + $tag_values[$key] = $value; + } + + $tag_values = array_unique($tag_values); + + $sql = "SELECT R.tag_id " + . "FROM {multimedia_item_tag} AS R " + . "INNER JOIN {multimedia_tag} AS T " + . "ON R.tag_id = T.tag_id " + . "WHERE R.item_id = ? "; + $params = array( + $item_id + ); + $tag_id_string = $this->_db->execute($sql, $params, $limit = null, $offset = null, false, array($this, "_makeImplodeString")); + + if ($tag_id_string === false) { + $this->_db->addError(); + return false; + } + if (!empty($tag_id_string)) { + $sql = "DELETE FROM {multimedia_item_tag} " + . "WHERE item_id = ? " + . "AND tag_id IN (" . $tag_id_string . ") "; + $params = array( + $item_id + ); + if ($this->_db->execute($sql, $params) === false) { + $this->_db->addError(); + return false; + } + } + + $sequence = 1; + $tag_ids = array(); + foreach ($tag_values as $tag_value) { + if (empty($tag_value)) { + continue; + } + $sql = "SELECT tag_id " + . "FROM {multimedia_tag} " + . "WHERE tag_value = ? AND room_id = ? "; + $params = array( + $this->getSynonym($tag_value), + $this->_request->getParameter("room_id") + ); + $item_tag_ids = $this->_db->execute($sql, $params); + if ($item_tag_ids === false) { + $this->_db->addError(); + return false; + } + if (empty($item_tag_ids)) { + $params = array( + 'tag_value' => $this->getSynonym($tag_value), + 'used_number' => 1 + ); + + $tag_id = $this->_db->insertExecute('multimedia_tag', $params, true, 'tag_id'); + if (empty($tag_id)) { + return false; + } + + } else { + $tag_id = $item_tag_ids[0]['tag_id']; + } + $tag_ids[] = $tag_id; + + $item_tag = array( + 'item_id' => $item_id, + 'tag_id' => $tag_id, + 'tag_value' => $tag_value, + 'sequence' => $sequence + ); + if (!$this->_db->insertExecute('multimedia_item_tag', $item_tag, true)){ + return false; + } + $sequence++; + } + + if (!empty($tag_id_string) && !empty($tag_ids)) { + $tag_id_string .= ','; + } + $tag_id_string .= implode(',', $tag_ids); + + if (!$this->_tagReCount($tag_id_string)) { + return false; + } + + return true; + } + + /** + * 動画タグの使用回数を再カウント。0件ならmultimedia_tagから削除。 + * + * @param string $tagIDString 区切り文字 + * @return boolean true or false + * @access private + */ + function _tagReCount($tag_id_string) { + $counted_tag_ids = array(); + if (!empty($tag_id_string)) { + $sql = "SELECT tag_id, " + . "COUNT(DISTINCT item_id) AS tag_count " + . "FROM {multimedia_item_tag} " + . "WHERE tag_id IN (" . $tag_id_string . ") " + . "GROUP BY tag_id;"; + $tags = $this->_db->execute($sql); + if ($tags === false) { + $this->_db->addError(); + return false; + } + if(!empty($tags)) { + foreach ($tags as $tag) { + $tag_used_number = array( + 'tag_id' => $tag['tag_id'], + 'used_number' => $tag['tag_count'] + ); + if (!$this->_db->updateExecute('multimedia_tag', $tag_used_number, 'tag_id', true)) { + return false; + } + + $counted_tag_ids[] = $tag['tag_id']; + } + } + } + + $tag_ids = explode(',', $tag_id_string); + $tag_ids = array_diff($tag_ids, $counted_tag_ids); + foreach ($tag_ids as $tag_id) { + $tag_used_number = array( + 'tag_id' => $tag_id + ); + if (!$this->_db->deleteExecute('multimedia_tag', $tag_used_number)) { + return false; + } + } + + return true; + } + + /** + * ADORecordSetの1カラム目を指定文字区切りの文字列にする + * + * @param array $recordSet ADORecordSet + * @param array $glue 区切り文字 + * @return array 指定文字区切りの文字列 + * @access private + */ + function &_makeImplodeString(&$recordSet, $glue = ",") { + $string = ""; + if ($recordSet->EOF) { + return $string; + } + + while ($row = $recordSet->fetchRow()) { + $string .= $row[0] . $glue; + } + if (!empty($glue)) { + $string = substr($string, 0, strlen($glue) * -1); + } + + return $string; + } + + function getSynonym($str) { + //半角カナ(濁点付き)→全角カナに変換 + $replace_of = array('ヴ', 'ガ', 'ギ', 'グ', + 'ゲ', 'ゴ', 'ザ', 'ジ', + 'ズ', 'ゼ', 'ゾ', 'ダ', + 'ヂ', 'ヅ', 'デ', 'ド', + 'バ', 'ビ', 'ブ', 'ベ', + 'ボ', 'パ', 'ピ', 'プ', 'ペ', 'ポ'); + + $replace_by = array('ヴ', 'ガ', 'ギ', 'グ', + 'ゲ', 'ゴ', 'ザ', 'ジ', + 'ズ', 'ゼ', 'ゾ', 'ダ', + 'ヂ', 'ヅ', 'デ', 'ド', + 'バ', 'ビ', 'ブ', 'ベ', + 'ボ', 'パ', 'ピ', 'プ', 'ペ', 'ポ'); + $_result = str_replace($replace_of, $replace_by, $str); + + //半角カナ→全角カナに変換 + $replace_of = array('ア', 'イ', 'ウ', 'エ', 'オ', + 'カ', 'キ', 'ク', 'ケ', 'コ', + 'サ', 'シ', 'ス', 'セ', 'ソ', + 'タ', 'チ', 'ツ', 'テ', 'ト', + 'ナ', 'ニ', 'ヌ', 'ネ', 'ノ', + 'ハ', 'ヒ', 'フ', 'ヘ', 'ホ', + 'マ', 'ミ', 'ム', 'メ', 'モ', + 'ヤ', 'ユ', 'ヨ', 'ラ', 'リ', + 'ル', 'レ', 'ロ', 'ワ', 'ヲ', + 'ン', 'ァ', 'ィ', 'ゥ', 'ェ', + 'ォ', 'ヵ', 'ヶ', 'ャ', 'ュ', + 'ョ', 'ッ', '、', '。', 'ー', + '「', '」', '゙', '゚'); + + $replace_by = array('ア', 'イ', 'ウ', 'エ', 'オ', + 'カ', 'キ', 'ク', 'ケ', 'コ', + 'サ', 'シ', 'ス', 'セ', 'ソ', + 'タ', 'チ', 'ツ', 'テ', 'ト', + 'ナ', 'ニ', 'ヌ', 'ネ', 'ノ', + 'ハ', 'ヒ', 'フ', 'ヘ', 'ホ', + 'マ', 'ミ', 'ム', 'メ', 'モ', + 'ヤ', 'ユ', 'ヨ', 'ラ', 'リ', + 'ル', 'レ', 'ロ', 'ワ', 'ヲ', + 'ン', 'ァ', 'ィ', 'ゥ', 'ェ', + 'ォ', 'ヶ', 'ヶ', 'ャ', 'ュ', + 'ョ', 'ッ', '、', '。', 'ー', + '「', '」', '”', ''); + + $_result = str_replace($replace_of, $replace_by, $_result); + + //全角数字→半角数字に変換 + $replace_of = array('1', '2', '3', '4', '5', + '6', '7', '8', '9', '0'); + + $replace_by = array('1', '2', '3', '4', '5', + '6', '7', '8', '9', '0'); + + $_result = str_replace($replace_of, $replace_by, $_result); + + //全角英字→半角英字に変換 + $replace_of = array('A', 'B', 'C', 'D', 'E', + 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', + 'Z', + 'a', 'b', 'c', 'd', 'e', + 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', + 'z'); + + $replace_by = array('A', 'B', 'C', 'D', 'E', + 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', + 'Z', + 'a', 'b', 'c', 'd', 'e', + 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', + 'z'); + + $_result = str_replace($replace_of, $replace_by, $_result); + +/* + //小文字ひらがな→小文字カナに変換 + $replace_of = array('ぁ', 'ぃ', 'ぅ', 'ぇ', 'ぉ', + 'ゃ', 'ゅ', 'ょ', 'っ'); + + $replace_by = array('ァ', 'ィ', 'ゥ', 'ェ', 'ォ', + 'ャ', 'ュ', 'ョ', 'ッ'); + + $_result = str_replace($replace_of, $replace_by, $_result); +*/ + //その他記号に変換 + $replace_of = array('ー', '-', '-', '~', ',', + '、', ',', '・', '・', '=', + '=', ' ', ' ', '。', '.', + '.', '/', '/', '―', '‐', + '’', '′', '´', '‘', '゜', + '\'', '"', '〝', '″', '゛', + '“', '”', 'ッ', 'ュ', 'ィ', + 'ゅ', 'ぃ'); + + $replace_by = array('', '', '', '', '', + '', '', '', '', '', + '', '', '', '', '', + '', '', '', '', '', + '', '', '', '', '', + '', '', '', '', '', + '', '', '', '', '', + '', ''); + + $_result = str_replace($replace_of, $replace_by, $_result); + +/* + //小文字カナ→大文字カナに変換 + $replace_of = array('ァ', 'ィ', 'ゥ', 'ェ', 'ォ', + 'ヶ', 'ヶ', 'ャ', 'ュ', 'ョ', 'ッ'); + + $replace_by = array('ア', 'イ', 'ウ', 'エ', 'オ', + 'ケ', 'ケ', 'ヤ', 'ユ', 'ヨ', 'ツ'); + + $_result = str_replace($replace_of, $replace_by, $_result); +*/ + return $_result; + } +} ?> \ No newline at end of file diff --git a/multimedia/components/View.class.php b/multimedia/components/View.class.php index 89c36c7..c65f307 100644 --- a/multimedia/components/View.class.php +++ b/multimedia/components/View.class.php @@ -1,966 +1,966 @@ -_db =& $container->getComponent("DbObject"); - $this->_request =& $container->getComponent("Request"); - $this->_session =& $container->getComponent("Session"); - } - - /** - * 配置されている動画配信IDを取得する - * - * @return string 配置されている動画配信ID - * @access public - */ - function &getCurrentMultimediaId() { - $params = array($this->_request->getParameter("block_id")); - $sql = "SELECT multimedia_id ". - "FROM {multimedia_block} ". - "WHERE block_id = ?"; - $result = $this->_db->execute($sql, $params); - if ($result === false) { - $this->_db->addError(); - return $result; - } - - return $result[0]["multimedia_id"]; - } - - /** - * 現在登録されている動画配信IDを取得する - * - * @return string 配置されている動画配信ID - * @access pblic - */ - function &getFirstMultimediaId() { - $params = array( - $this->_request->getParameter('room_id') - ); - $sql = "SELECT multimedia_id " - . "FROM {multimedia} " - . "WHERE room_id = ?"; - $result = $this->_db->execute($sql, $params, 1); - if ($result === false) { - $this->_db->addError(); - return $result; - } - - return $result[0]['multimedia_id']; - } - - /** - * 動画配信が配置されているブロックデータを取得する - * - * @return string ブロックデータ - * @access public - */ - function &getBlock() { - $params = array($this->_request->getParameter("multimedia_id")); - $sql = "SELECT M.room_id, B.block_id ". - "FROM {multimedia} M ". - "INNER JOIN {multimedia_block} B ". - "ON M.multimedia_id = B.multimedia_id ". - "WHERE M.multimedia_id = ? ". - "ORDER BY B.block_id"; - $result = $this->_db->execute($sql, $params, 1); - if ($result === false) { - $this->_db->addError(); - return $result; - } - - return $result[0]; - } - - /** - * 動画配信が存在するか判断する - * - * @return boolean true:存在する、false:存在しない - * @access public - */ - function multimediaExist() { - $params = array( - $this->_request->getParameter("multimedia_id"), - $this->_request->getParameter("room_id") - ); - $sql = "SELECT multimedia_id ". - "FROM {multimedia} ". - "WHERE multimedia_id = ? ". - "AND room_id = ?"; - $result = $this->_db->execute($sql, $params); - if ($result === false) { - $this->_db->addError(); - return $result; - } - - if (count($result) > 0) { - return true; - } - - return false; - } - - function getMultimediaCount() { - $params["room_id"] = $this->_request->getParameter("room_id"); - $count = $this->_db->countExecute("multimedia", $params); - if($count === false) { - $this->_db->addError(); - } - - return $count; - } - - /** - * 動画配信の設定データを取得する - * - * @return string 設定データ配列 - * @access public - */ - function &getConfig() { - $container =& DIContainerFactory::getContainer(); - $configView =& $container->getComponent("configView"); - $module_id = $this->_request->getParameter("module_id"); - $config = $configView->getConfig($module_id, false); - - return $config; - } - - /** - * 動画配信用デフォルトデータを取得する - * - * @return array 動画配信用デフォルトデータ配列 - * @access public - */ - function &getDefaultMultimedia() { - $config = $this->getConfig(); - if ($config === false) { - return $config; - } - - $multimedia = array( - "album_authority" => constant($config['album_authority']['conf_value']), - "vote_flag" => constant($config['vote_flag']['conf_value']), - "comment_flag" => constant($config['comment_flag']['conf_value']), - "confirm_flag" => constant($config['confirm_flag']['conf_value']), - "display" => constant($config['display']['conf_value']), - "autoplay_flag" => constant($config['autoplay_flag']['conf_value']), - "buffer_time" => $config['buffer_time']['conf_value'], - "album_visible_row" => $config['album_visible_row']['conf_value'], - "new_period" => $config['new_period']['conf_value'], - "album_jacket" => $config['album_jacket']['conf_value'] - ); - - return $multimedia; - } - - /** - * 動画配信データを取得する - * - * @return array 動画配信データ - * @access public - */ - function &getCurrentMultimedia() { - $params = array($this->_request->getParameter("block_id")); - $sql = "SELECT B.block_id, B.multimedia_id, B.display, ". - "B.autoplay_flag, B.buffer_time, ". - "B.album_visible_row, B.new_period, ". - "M.album_authority, M.vote_flag, M.comment_flag, M.confirm_flag ". - "FROM {multimedia_block} B ". - "INNER JOIN {multimedia} M ". - "ON B.multimedia_id = M.multimedia_id ". - "WHERE block_id = ?"; - $result = $this->_db->execute($sql, $params); - if ($result === false) { - $this->_db->addError(); - } - if (empty($result)) { - return $result; - } - - $result[0]['album_authority'] = $this->_hasAlbumAuthority($result[0]); - $result[0]['new_period_time'] = $this->_getNewPeriodTime($result[0]['new_period']); - - return $result[0]; - } - - /** - * アルバム作成権限を取得する - * - * @param array $photoalbum フォトアルバムデータ配列 - * @return boolean true:権限有り、false:権限無し - * @access public - */ - function _hasAlbumAuthority($multimedia) { - $auth_id = $this->_session->getParameter("_auth_id"); - if ($auth_id >= $multimedia['album_authority']) { - return true; - } - - return false; - } - - function getMultimediaById($multimedia_id) { - $params = array( - "multimedia_id" => $multimedia_id - ); - - $result = $this->_db->selectExecute("multimedia", $params); - if ($result === false) { - $this->_db->addError(); - } - - if(!empty($result) && isset($result[0])) { - return $result[0]; - } - - return $result; - } - - /** - * フォトアルバムデータを取得する - * - * @return array フォトアルバムデータ - * @access public - */ - function &getMultimedia() { - $params = array($this->_request->getParameter("multimedia_id")); - $sql = "SELECT multimedia_id, album_authority, vote_flag, comment_flag, confirm_flag ". - "FROM {multimedia} ". - "WHERE multimedia_id = ?"; - $result = $this->_db->execute($sql, $params); - if ($result === false) { - $this->_db->addError(); - return $result; - } - - return $result[0]; - } - - /** - * new記号表示期間から対象年月日を取得する - * - * @param string $new_period new記号表示期間 - * @return string new記号表示対象年月日(YmdHis) - * @access public - */ - function &_getNewPeriodTime($new_period) { - if (empty($new_period)) { - $new_period = -1; - } - - $time = timezone_date(); - $time = mktime(0, 0, 0, - intval(substr($time, 4, 2)), - intval(substr($time, 6, 2)) - $new_period, - intval(substr($time, 0, 4)) - ); - $time = date("YmdHis", $time); - - return $time; - } - - /** - * 動画配信のアルバムの計数を取得する - * - * @param string $new_period new記号表示期間 - * @return string new記号表示対象年月日(YmdHis) - * @access public - */ - function getAlbumCount($multimedia_id) { - $params[] = $multimedia_id; - - $sql = "SELECT COUNT(*) as count ". - "FROM {multimedia_album} A "; - $sql .= $this->_getAuthorityFromSQL(); - $sql .= "WHERE A.multimedia_id = ? "; - $sql .= $this->_getAuthorityWhereSQL($params); - if(!empty($order_params)) { - $sql .= $this->_db->getOrderSQL($order_params); - } - $result = $this->_db->execute($sql, $params); - if ( $result === false ) { - // エラーが発生した場合、エラーリストに追加 - $this->_db->addError(); - return $result; - } - return $result[0]['count']; - } - - /** - * アルバム一覧を取得する - * - * @return array アルバム一覧データ - * @access public - */ - function getAlbumList($multimedia_id, $order_params=null, $disp_cnt=null, $begin=null) { - $params[] = $multimedia_id; - - $sql = "SELECT A.* ". - "FROM {multimedia_album} A "; - $sql .= $this->_getAuthorityFromSQL(); - $sql .= "WHERE A.multimedia_id = ? "; - $sql .= $this->_getAuthorityWhereSQL($params); - if(!empty($order_params)) { - $sql .= $this->_db->getOrderSQL($order_params); - } - $result = $this->_db->execute($sql, $params, $disp_cnt, $begin, true, array($this, "_makeAlbumArray")); - if ( $result === false ) { - // エラーが発生した場合、エラーリストに追加 - $this->_db->addError(); - } - - return $result; - } - - /** - * アルバムデータ配列を生成する - * - * @param array $recordSet タスクADORecordSet - * @return array タスクデータ配列 - * @access private - */ - function &_makeAlbumArray(&$recordSet) { - $multimedia = $this->_request->getParameter("multimedia_obj"); - - $albums = array(); - while ($row = $recordSet->fetchRow()) { - if (!empty($row["album_jacket"])) { - $row["jacket_style"] = $this->getImageStyle($row["width"], $row["height"], MULTIMEDIA_JACKET_WIDTH, MULTIMEDIA_JACKET_HEIGHT); - } - - $row["edit_authority"] = false; - if ($multimedia["album_authority"] - && $this->_hasEditAuthority($row["insert_user_id"])) { - $row["edit_authority"] = true; - } - - $albums[] = $row; - } - - return $albums; - } - - /** - * アルバムのサムネイルのスタイル属性値を取得する - * - * @param string $width 幅 - * @param string $height 高さ - * @param string $maxWidth 最大幅 - * @param string $maxHeight 最大高さ - * @return array 画像のスタイル属性値 - * @access private - */ - function &getImageStyle($width, $height, $maxWidth, $maxHeight) { - $ratio = $height / $width; - - $widthRatio = $width / $maxWidth; - $heightRatio = $height / $maxHeight; - - if ($widthRatio > $heightRatio) { - $height = $maxHeight; - $widht = intval($height / $ratio); - $top = 0; - $right = intval(($widht + $maxWidth) / 2); - $bottom = $maxHeight; - $left = intval(($widht - $maxWidth) / 2); - $marginLeft = $left * -1; - $marginTop = $top; - } else { - $widht = $maxWidth; - $height = intval($widht * $ratio); - $top = intval(($height - $maxHeight) / 2); - $right = $maxWidth; - $bottom = intval(($height + $maxHeight) / 2); - $left = 0; - $marginLeft = $left; - $marginTop = $top * -1; - } - - $style = sprintf(MULTIMEDIA_THUMBNAIL_STYLE, $widht, $height, $top, $right, $bottom, $left, $marginLeft, $marginTop); - - return $style; - } - - /** - * アルバムを取得する - * - * @return array アルバムデータ - * @access public - */ - function getAlbum($album_id) { - $params = array( - "album_id" => intval($album_id) - ); - - $result = $this->_db->selectExecute("multimedia_album", $params, null, null, null, array($this, "_makeAlbumArray")); - if ($result === false) { - $this->_db->addError(); - } - - if(!empty($result) && isset($result[0])) { - return $result[0]; - } - - return $result; - } - - /** - * 動画を取得する - * - * @return array 動画データ - * @access public - */ - function getItem($item_id) { - $params = array( - "item_id" => intval($item_id) - ); - - $result = $this->_db->selectExecute("multimedia_item", $params, null, null, null, array($this, "_makeItemArray")); - if ($result === false) { - $this->_db->addError(); - } - - if(!empty($result) && isset($result[0])) { - $result[0]['vote_authority'] = $this->_hasVoteAuthority($item_id); - $result[0]['comment_authority'] = $this->_hasCommentAuthority(); - return $result[0]; - } - - return $result; - } - - /** - * 編集権限を取得する - * - * @param array $insertUserID 登録者ID - * @return boolean true:権限有り、false:権限無し - * @access public - */ - function _hasEditAuthority(&$insertUserID) { - $container =& DIContainerFactory::getContainer(); - - $authID = $this->_session->getParameter("_auth_id"); - if ($authID >= _AUTH_CHIEF) { - return true; - } - - $userID = $this->_session->getParameter("_user_id"); - if ($insertUserID == $userID) { - return true; - } - - $hierarchy = $this->_session->getParameter("_hierarchy"); - $authCheck =& $container->getComponent("authCheck"); - $insetUserHierarchy = $authCheck->getPageHierarchy($insertUserID); - if ($hierarchy > $insetUserHierarchy) { - return true; - } - - return false; - } - - /** - * 投票権限を取得する - * - * @param array $item 動画データ配列 - * @return boolean true:権限有り、false:権限無し - * @access public - */ - function _hasVoteAuthority($item_id) { - $multimedia = $this->_request->getParameter("multimedia_obj"); - if ($multimedia['vote_flag'] != _ON) { - return false; - } - - $votes = $this->_session->getParameter("multimedia_votes"); - if (!empty($votes) && in_array($item_id, $votes)) { - return false; - } - - $user_id = $this->_session->getParameter("_user_id"); - if (empty($user_id)) { - return true; - } - - $params = array( - $user_id, - $item_id - ); - $sql = "SELECT vote_flag ". - "FROM {mutlimedia_user_item} ". - "WHERE user_id = ? ". - "AND item_id = ?"; - $vote_flags = $this->_db->execute($sql, $params, null, null, false); - if ($vote_flags === false) { - $this->_db->addError(); - return false; - } - - if (empty($vote_flags) || $vote_flags[0][0] != _ON) { - return true; - } - - return false; - } - - /** - * コメント権限を取得する - * - * @return boolean true:権限有り、false:権限無し - * @access public - */ - function _hasCommentAuthority() { - $multimedia = $this->_request->getParameter("multimedia_obj"); - if ($multimedia['comment_flag'] != _ON) { - return false; - } - - $auth_id = $this->_session->getParameter("_auth_id"); - if ($auth_id <= _AUTH_GUEST) { - return false; - } - - return true; - } - - /** - * 動画のコメントの計数を取得する - * - * @param string $item_id 動画id - * @return string 動画のコメントの計数 - * @access public - */ - function getCommentCount($item_id) { - $params = array( - "item_id" => intval($item_id) - ); - $commentCount = $this->_db->countExecute("multimedia_comment", $params); - - if($commentCount === false) { - $this->_db->addError(); - } - - return $commentCount; - } - - /** - * 動画のコメントを取得する - * - * @param string $item_id 動画id - * @return string 動画のコメント - * @access public - */ - function getComments($item_id, $begin=null) { - $comments = $this->_db->selectExecute("multimedia_comment", array("item_id" => intval($item_id)), array("insert_time" => "DESC"), MULTIMEDIA_VISIBLE_ITEM_COMMENT, $begin, array($this, "_makeCommentArray")); - if($comments === false) { - $this->_db->addError(); - } - - return $comments; - } - - /** - * コメントデータ配列を生成する - * - * @param array $recordSet タスクADORecordSet - * @return array タスクデータ配列 - * @access private - */ - function &_makeCommentArray(&$recordSet) { - $comments = array(); - while ($row = $recordSet->fetchRow()) { - $row["edit_authority"] = false; - if ($this->_hasEditAuthority($row["insert_user_id"])) { - $row["edit_authority"] = true; - } - - $comments[] = $row; - } - - return $comments; - } - - /** - * 画像の大きさを取得 - * - * @return string 画像の大きさ - * @access public - */ - function &getImageSize($image) { - if (is_numeric($image)) { - $container =& DIContainerFactory::getContainer(); - - $uploads =& $container->getComponent("uploadsView"); - $uploadFiles = $uploads->getUploadById($image); - if (empty($uploadFiles)) { - return false; - } - - $imageSize = getimagesize(FILEUPLOADS_DIR. "multimedia/". $uploadFiles[0]["physical_file_name"]); - } else { - $imageSize = getimagesize(HTDOCS_DIR.MULTIMEDIA_SAMPLR_JACKET_PATH.MULTIMEDIA_SAMPLR_JACKET_DIR.$image); - } - - return $imageSize; - } - - /** - * 権限判断用のSQL文FROM句を取得する - * - * @return string 権限判断用のSQL文FROM句 - * @access public - */ - function &_getAuthorityFromSQL() { - $auth_id = $this->_session->getParameter("_auth_id"); - - $sql = ""; - if ($auth_id >= _AUTH_CHIEF) { - return $sql; - } - - $sql .= "LEFT JOIN {pages_users_link} PU ". - "ON A.insert_user_id = PU.user_id ". - "AND A.room_id = PU.room_id "; - $sql .= "LEFT JOIN {authorities} AU ". - "ON PU.role_authority_id = AU.role_authority_id "; - - return $sql; - } - - /** - * 権限判断用のSQL文WHERE句を取得する - * パラメータ用配列に必要な値を追加する - * - * @param array $params パラメータ用配列 - * @return string 権限判断用のSQL文WHERE句 - * @access public - */ - function &_getAuthorityWhereSQL(&$params) { - $auth_id = $this->_session->getParameter("_auth_id"); - - $sql = ""; - if ($auth_id >= _AUTH_CHIEF) { - return $sql; - } - - $sql .= " AND (A.public_flag = ? OR AU.hierarchy < ? OR A.insert_user_id = ? "; - - $default_entry = $this->_session->getParameter("_default_entry_flag"); - $hierarchy = $this->_session->getParameter("_hierarchy"); - if ($default_entry == _ON && $hierarchy > $this->_session->getParameter("_default_entry_hierarchy")) { - $sql .= " OR AU.hierarchy IS NULL) "; - } else { - $sql .= ") "; - } - - $params[] = _ON; - $params[] = $hierarchy; - $params[] = $this->_session->getParameter("_user_id"); - - return $sql; - } - - /** - * 動画データ配列を生成する - * - * @param array $recordSet 動画ADORecordSet - * @return array 動画データ配列 - * @access private - */ - function &_makeItemArray(&$recordSet) { - $items = array(); - while ($row = $recordSet->fetchRow()) { - $row['edit_authority'] = false; - if ($this->_hasEditAuthority($row['insert_user_id'])) { - $row['edit_authority'] = true; - } - $tags = $this->getTags($row['item_id']); - $row['item_tag'] = $this->_makeTagString($tags); - $row['duration'] = floor($row['duration']/60).":".floor(($row['duration']-60*floor($row['duration']/60))); - $items[] = $row; - } - - return $items; - } - - /** - * 動画一覧共通のSQL - * - * @return  array 動画件数データ - * @access public - */ - function _getItemListSQL(&$params, $where_params, $order_params=null, $count_flag=false) { - $sql = ""; - if(empty($order_params)) { - $order_params = array( - "insert_time" => "DESC" - ); - } - - if($count_flag) { - $sql = "SELECT COUNT(T.item_id) as count FROM {multimedia_item} T "; - }else { - $sql = "SELECT T.* FROM {multimedia_item} T "; - } - $sql .= "LEFT JOIN {multimedia_album} A ON T.album_id=A.album_id "; - $sql .= $this->_getAuthorityFromSQL(); - if(!empty($where_params)) { - foreach($where_params as $key => $val) { - if($val == "") { - continue; - } - $where_params["T.".$key] = $val; - unset($where_params[$key]); - } - $sql .= $this->_db->getWhereSQL($params, $where_params); - } - $sql .= $this->_getAuthorityWhereSQL($params); - if(!$count_flag) { - foreach($order_params as $key => $val) { - $order_params["T.".$key] = $val; - unset($order_params[$key]); - } - $sql .= $this->_db->getOrderSQL($order_params); - } - - return $sql; - } - - /** - * 動画一覧件数を取得する - * - * @return  array 動画件数データ - * @access public - */ - function getItemListCount($where_params) { - if(empty($where_params)) { - return false; - } - - $sql = ""; - $params = array(); - $sql = $this->_getItemListSQL($params, $where_params, null, true); - $result = $this->_db->execute($sql, $params); - if ( $result === false ) { - // エラーが発生した場合、エラーリストに追加 - $this->_db->addError(); - return $result; - } - return $result[0]['count']; - } - - /** - * 動画一覧を取得する - * - * @param int $multimedia_id ID - * @return  array 動画データ - * @access public - */ - function getItemList($where_params, $order_params, $begin=null) { - if(empty($where_params)) { - return false; - } - - $sql = ""; - $params = array(); - $sql = $this->_getItemListSQL($params, $where_params, $order_params); - - $result = $this->_db->execute($sql, $params ,MULTIMEDIA_VISIBLE_ITEM_CNT, $begin, true, array($this, "_makeItemArray")); - if ( $result === false ) { - // エラーが発生した場合、エラーリストに追加 - $this->_db->addError(); - return $result; - } - return $result; - } - - /** - * 検索動画一覧を取得する - * - * @return  array 動画データ - * @access public - */ - function getSearchItemList($sql, $where_params, $begin=null) { - $result = $this->_db->execute($sql, $where_params ,MULTIMEDIA_SEARCH_VISIBLE_ITEM_CNT, $begin, true, array($this, "_makeItemArray")); - if ( $result === false ) { - // エラーが発生した場合、エラーリストに追加 - $this->_db->addError(); - } - return $result; - } - - /** - * タグデータ配列を取得する - * - * @return array タグデータ配列 - * @access public - */ - function getTags($item_id) { - $sql = "SELECT R.tag_value, T.used_number, R.tag_id, R.item_id, R.sequence " . - "FROM {multimedia_item_tag} AS R, {multimedia_tag} AS T " . - "WHERE R.tag_id = T.tag_id " . - "AND R.item_id = ? " . - "ORDER BY R.sequence;"; - - $params = array( - $item_id - ); - $tags = $this->_db->execute($sql, $params); - if ($tags === false) { - $this->_db->addError(); - return false; - } - return $tags; - } - - /** - * 関連動画配列を取得する - * - * @return array タグデータ配列 - * @access public - */ - function getSimilarItems($item_id) { - $tags = $this->getTags($item_id); - if(empty($tags)) { - return $tags; - } - - $params = array(); - $where_sql = ""; - foreach($tags as $tag) { - $params[] = $tag['tag_id']; - $where_sql .= " G.tag_id=? OR"; - } - $where_sql = " ( ".substr($where_sql, 0, -2)." ) "; - $sql = "SELECT T.*,count(*) as count " . - "FROM {multimedia_item_tag} AS G, {multimedia_item} AS T "; - $sql .= "LEFT JOIN {multimedia_album} A ON T.album_id=A.album_id "; - $sql .= $this->_getAuthorityFromSQL(); - $sql .= "WHERE G.item_id=T.item_id AND T.item_id <> ".$item_id." AND ".$where_sql; - $sql .= $this->_getAuthorityWhereSQL($params); - $sql .= " GROUP BY T.item_id ORDER BY count DESC"; - $items = $this->_db->execute($sql, $params, MULTIMEDIA_TAG_ITEMS_NUMBER, 0, true, array($this, "_makeItemArray")); - if ($items === false) { - $this->_db->addError(); - return false; - } - return $items; - } - - /** - * タグストリングを生成する - */ - function &_makeTagString($tags) { - $string = ""; - if(empty($tags)) { - return $string; - } - $string = ""; - foreach($tags as $tag) { - $string .= $tag['tag_value'].MULTIMEDIA_TAG_SEPARATOR; - } - $string = substr($string, 0, -1); - - return $string; - } - - /** - * ページに関する設定を行います - * - * @param int disp_cnt 1ページ当り表示件数 - * @param int now_page 現ページ - */ - function setPageInfo(&$pager, $data_cnt, $disp_cnt, $now_page = NULL){ - $pager['data_cnt'] = 0; - $pager['total_page'] = 0; - $pager['next_link'] = FALSE; - $pager['prev_link'] = FALSE; - $pager['disp_begin'] = 0; - $pager['disp_end'] = 0; - $pager['link_array'] = NULL; - - if(empty($disp_cnt)) { - return false; - } - - $pager['data_cnt'] = $data_cnt; - // now page - $pager['now_page'] = (NULL == $now_page) ? 1 : $now_page; - // total page - $pager['total_page'] = ceil($pager['data_cnt'] / $disp_cnt); - if($pager['total_page'] < $pager['now_page']) { - $pager['now_page'] = 1; - } - // link array {{ - if(($pager['now_page'] - MULTIMEDIA_FRONT_AND_BEHIND_LINK_CNT) > 0){ - $start = $pager['now_page'] - MULTIMEDIA_FRONT_AND_BEHIND_LINK_CNT; - }else{ - $start = 1; - } - if(($pager['now_page'] + MULTIMEDIA_FRONT_AND_BEHIND_LINK_CNT) >= $pager['total_page']){ - $end = $pager['total_page']; - }else{ - $end = $pager['now_page'] + MULTIMEDIA_FRONT_AND_BEHIND_LINK_CNT; - } - $i = 0; - for($i = $start; $i <= $end; $i++){ - $pager['link_array'][] = $i; - } - // next link - if($disp_cnt < $pager['data_cnt']){ - if($pager['now_page'] < $pager['total_page']){ - $pager['next_link'] = TRUE; - } - } - // prev link - if(1 < $pager['now_page']){ - $pager['prev_link'] = TRUE; - } - // begin disp number - $pager['disp_begin'] = ($pager['now_page'] - 1) * $disp_cnt; - // end disp number - $tmp_cnt = $pager['now_page'] * $disp_cnt; - $pager['disp_end'] = ($pager['data_cnt'] < $tmp_cnt) ? $pager['data_cnt'] : $tmp_cnt; - } -} +_db =& $container->getComponent("DbObject"); + $this->_request =& $container->getComponent("Request"); + $this->_session =& $container->getComponent("Session"); + } + + /** + * 配置されている動画配信IDを取得する + * + * @return string 配置されている動画配信ID + * @access public + */ + function &getCurrentMultimediaId() { + $params = array($this->_request->getParameter("block_id")); + $sql = "SELECT multimedia_id ". + "FROM {multimedia_block} ". + "WHERE block_id = ?"; + $result = $this->_db->execute($sql, $params); + if ($result === false) { + $this->_db->addError(); + return $result; + } + + return $result[0]["multimedia_id"]; + } + + /** + * 現在登録されている動画配信IDを取得する + * + * @return string 配置されている動画配信ID + * @access pblic + */ + function &getFirstMultimediaId() { + $params = array( + $this->_request->getParameter('room_id') + ); + $sql = "SELECT multimedia_id " + . "FROM {multimedia} " + . "WHERE room_id = ?"; + $result = $this->_db->execute($sql, $params, 1); + if ($result === false) { + $this->_db->addError(); + return $result; + } + + return $result[0]['multimedia_id']; + } + + /** + * 動画配信が配置されているブロックデータを取得する + * + * @return string ブロックデータ + * @access public + */ + function &getBlock() { + $params = array($this->_request->getParameter("multimedia_id")); + $sql = "SELECT M.room_id, B.block_id ". + "FROM {multimedia} M ". + "INNER JOIN {multimedia_block} B ". + "ON M.multimedia_id = B.multimedia_id ". + "WHERE M.multimedia_id = ? ". + "ORDER BY B.block_id"; + $result = $this->_db->execute($sql, $params, 1); + if ($result === false) { + $this->_db->addError(); + return $result; + } + + return $result[0]; + } + + /** + * 動画配信が存在するか判断する + * + * @return boolean true:存在する、false:存在しない + * @access public + */ + function multimediaExist() { + $params = array( + $this->_request->getParameter("multimedia_id"), + $this->_request->getParameter("room_id") + ); + $sql = "SELECT multimedia_id ". + "FROM {multimedia} ". + "WHERE multimedia_id = ? ". + "AND room_id = ?"; + $result = $this->_db->execute($sql, $params); + if ($result === false) { + $this->_db->addError(); + return $result; + } + + if (count($result) > 0) { + return true; + } + + return false; + } + + function getMultimediaCount() { + $params["room_id"] = $this->_request->getParameter("room_id"); + $count = $this->_db->countExecute("multimedia", $params); + if($count === false) { + $this->_db->addError(); + } + + return $count; + } + + /** + * 動画配信の設定データを取得する + * + * @return string 設定データ配列 + * @access public + */ + function &getConfig() { + $container =& DIContainerFactory::getContainer(); + $configView =& $container->getComponent("configView"); + $module_id = $this->_request->getParameter("module_id"); + $config = $configView->getConfig($module_id, false); + + return $config; + } + + /** + * 動画配信用デフォルトデータを取得する + * + * @return array 動画配信用デフォルトデータ配列 + * @access public + */ + function &getDefaultMultimedia() { + $config = $this->getConfig(); + if ($config === false) { + return $config; + } + + $multimedia = array( + "album_authority" => constant($config['album_authority']['conf_value']), + "vote_flag" => constant($config['vote_flag']['conf_value']), + "comment_flag" => constant($config['comment_flag']['conf_value']), + "confirm_flag" => constant($config['confirm_flag']['conf_value']), + "display" => constant($config['display']['conf_value']), + "autoplay_flag" => constant($config['autoplay_flag']['conf_value']), + "buffer_time" => $config['buffer_time']['conf_value'], + "album_visible_row" => $config['album_visible_row']['conf_value'], + "new_period" => $config['new_period']['conf_value'], + "album_jacket" => $config['album_jacket']['conf_value'] + ); + + return $multimedia; + } + + /** + * 動画配信データを取得する + * + * @return array 動画配信データ + * @access public + */ + function &getCurrentMultimedia() { + $params = array($this->_request->getParameter("block_id")); + $sql = "SELECT B.block_id, B.multimedia_id, B.display, ". + "B.autoplay_flag, B.buffer_time, ". + "B.album_visible_row, B.new_period, ". + "M.album_authority, M.vote_flag, M.comment_flag, M.confirm_flag ". + "FROM {multimedia_block} B ". + "INNER JOIN {multimedia} M ". + "ON B.multimedia_id = M.multimedia_id ". + "WHERE block_id = ?"; + $result = $this->_db->execute($sql, $params); + if ($result === false) { + $this->_db->addError(); + } + if (empty($result)) { + return $result; + } + + $result[0]['album_authority'] = $this->_hasAlbumAuthority($result[0]); + $result[0]['new_period_time'] = $this->_getNewPeriodTime($result[0]['new_period']); + + return $result[0]; + } + + /** + * アルバム作成権限を取得する + * + * @param array $photoalbum フォトアルバムデータ配列 + * @return boolean true:権限有り、false:権限無し + * @access public + */ + function _hasAlbumAuthority($multimedia) { + $auth_id = $this->_session->getParameter("_auth_id"); + if ($auth_id >= $multimedia['album_authority']) { + return true; + } + + return false; + } + + function getMultimediaById($multimedia_id) { + $params = array( + "multimedia_id" => $multimedia_id + ); + + $result = $this->_db->selectExecute("multimedia", $params); + if ($result === false) { + $this->_db->addError(); + } + + if(!empty($result) && isset($result[0])) { + return $result[0]; + } + + return $result; + } + + /** + * フォトアルバムデータを取得する + * + * @return array フォトアルバムデータ + * @access public + */ + function &getMultimedia() { + $params = array($this->_request->getParameter("multimedia_id")); + $sql = "SELECT multimedia_id, album_authority, vote_flag, comment_flag, confirm_flag ". + "FROM {multimedia} ". + "WHERE multimedia_id = ?"; + $result = $this->_db->execute($sql, $params); + if ($result === false) { + $this->_db->addError(); + return $result; + } + + return $result[0]; + } + + /** + * new記号表示期間から対象年月日を取得する + * + * @param string $new_period new記号表示期間 + * @return string new記号表示対象年月日(YmdHis) + * @access public + */ + function &_getNewPeriodTime($new_period) { + if (empty($new_period)) { + $new_period = -1; + } + + $time = timezone_date(); + $time = mktime(0, 0, 0, + intval(substr($time, 4, 2)), + intval(substr($time, 6, 2)) - $new_period, + intval(substr($time, 0, 4)) + ); + $time = date("YmdHis", $time); + + return $time; + } + + /** + * 動画配信のアルバムの計数を取得する + * + * @param string $new_period new記号表示期間 + * @return string new記号表示対象年月日(YmdHis) + * @access public + */ + function getAlbumCount($multimedia_id) { + $params[] = $multimedia_id; + + $sql = "SELECT COUNT(*) as count ". + "FROM {multimedia_album} A "; + $sql .= $this->_getAuthorityFromSQL(); + $sql .= "WHERE A.multimedia_id = ? "; + $sql .= $this->_getAuthorityWhereSQL($params); + if(!empty($order_params)) { + $sql .= $this->_db->getOrderSQL($order_params); + } + $result = $this->_db->execute($sql, $params); + if ( $result === false ) { + // エラーが発生した場合、エラーリストに追加 + $this->_db->addError(); + return $result; + } + return $result[0]['count']; + } + + /** + * アルバム一覧を取得する + * + * @return array アルバム一覧データ + * @access public + */ + function getAlbumList($multimedia_id, $order_params=null, $disp_cnt=null, $begin=null) { + $params[] = $multimedia_id; + + $sql = "SELECT A.* ". + "FROM {multimedia_album} A "; + $sql .= $this->_getAuthorityFromSQL(); + $sql .= "WHERE A.multimedia_id = ? "; + $sql .= $this->_getAuthorityWhereSQL($params); + if(!empty($order_params)) { + $sql .= $this->_db->getOrderSQL($order_params); + } + $result = $this->_db->execute($sql, $params, $disp_cnt, $begin, true, array($this, "_makeAlbumArray")); + if ( $result === false ) { + // エラーが発生した場合、エラーリストに追加 + $this->_db->addError(); + } + + return $result; + } + + /** + * アルバムデータ配列を生成する + * + * @param array $recordSet タスクADORecordSet + * @return array タスクデータ配列 + * @access private + */ + function &_makeAlbumArray(&$recordSet) { + $multimedia = $this->_request->getParameter("multimedia_obj"); + + $albums = array(); + while ($row = $recordSet->fetchRow()) { + if (!empty($row["album_jacket"])) { + $row["jacket_style"] = $this->getImageStyle($row["width"], $row["height"], MULTIMEDIA_JACKET_WIDTH, MULTIMEDIA_JACKET_HEIGHT); + } + + $row["edit_authority"] = false; + if ($multimedia["album_authority"] + && $this->_hasEditAuthority($row["insert_user_id"])) { + $row["edit_authority"] = true; + } + + $albums[] = $row; + } + + return $albums; + } + + /** + * アルバムのサムネイルのスタイル属性値を取得する + * + * @param string $width 幅 + * @param string $height 高さ + * @param string $maxWidth 最大幅 + * @param string $maxHeight 最大高さ + * @return array 画像のスタイル属性値 + * @access private + */ + function &getImageStyle($width, $height, $maxWidth, $maxHeight) { + $ratio = $height / $width; + + $widthRatio = $width / $maxWidth; + $heightRatio = $height / $maxHeight; + + if ($widthRatio > $heightRatio) { + $height = $maxHeight; + $widht = intval($height / $ratio); + $top = 0; + $right = intval(($widht + $maxWidth) / 2); + $bottom = $maxHeight; + $left = intval(($widht - $maxWidth) / 2); + $marginLeft = $left * -1; + $marginTop = $top; + } else { + $widht = $maxWidth; + $height = intval($widht * $ratio); + $top = intval(($height - $maxHeight) / 2); + $right = $maxWidth; + $bottom = intval(($height + $maxHeight) / 2); + $left = 0; + $marginLeft = $left; + $marginTop = $top * -1; + } + + $style = sprintf(MULTIMEDIA_THUMBNAIL_STYLE, $widht, $height, $top, $right, $bottom, $left, $marginLeft, $marginTop); + + return $style; + } + + /** + * アルバムを取得する + * + * @return array アルバムデータ + * @access public + */ + function getAlbum($album_id) { + $params = array( + "album_id" => intval($album_id) + ); + + $result = $this->_db->selectExecute("multimedia_album", $params, null, null, null, array($this, "_makeAlbumArray")); + if ($result === false) { + $this->_db->addError(); + } + + if(!empty($result) && isset($result[0])) { + return $result[0]; + } + + return $result; + } + + /** + * 動画を取得する + * + * @return array 動画データ + * @access public + */ + function getItem($item_id) { + $params = array( + "item_id" => intval($item_id) + ); + + $result = $this->_db->selectExecute("multimedia_item", $params, null, null, null, array($this, "_makeItemArray")); + if ($result === false) { + $this->_db->addError(); + } + + if(!empty($result) && isset($result[0])) { + $result[0]['vote_authority'] = $this->_hasVoteAuthority($item_id); + $result[0]['comment_authority'] = $this->_hasCommentAuthority(); + return $result[0]; + } + + return $result; + } + + /** + * 編集権限を取得する + * + * @param array $insertUserID 登録者ID + * @return boolean true:権限有り、false:権限無し + * @access public + */ + function _hasEditAuthority(&$insertUserID) { + $container =& DIContainerFactory::getContainer(); + + $authID = $this->_session->getParameter("_auth_id"); + if ($authID >= _AUTH_CHIEF) { + return true; + } + + $userID = $this->_session->getParameter("_user_id"); + if ($insertUserID == $userID) { + return true; + } + + $hierarchy = $this->_session->getParameter("_hierarchy"); + $authCheck =& $container->getComponent("authCheck"); + $insetUserHierarchy = $authCheck->getPageHierarchy($insertUserID); + if ($hierarchy > $insetUserHierarchy) { + return true; + } + + return false; + } + + /** + * 投票権限を取得する + * + * @param array $item 動画データ配列 + * @return boolean true:権限有り、false:権限無し + * @access public + */ + function _hasVoteAuthority($item_id) { + $multimedia = $this->_request->getParameter("multimedia_obj"); + if ($multimedia['vote_flag'] != _ON) { + return false; + } + + $votes = $this->_session->getParameter("multimedia_votes"); + if (!empty($votes) && in_array($item_id, $votes)) { + return false; + } + + $user_id = $this->_session->getParameter("_user_id"); + if (empty($user_id)) { + return true; + } + + $params = array( + $user_id, + $item_id + ); + $sql = "SELECT vote_flag ". + "FROM {mutlimedia_user_item} ". + "WHERE user_id = ? ". + "AND item_id = ?"; + $vote_flags = $this->_db->execute($sql, $params, null, null, false); + if ($vote_flags === false) { + $this->_db->addError(); + return false; + } + + if (empty($vote_flags) || $vote_flags[0][0] != _ON) { + return true; + } + + return false; + } + + /** + * コメント権限を取得する + * + * @return boolean true:権限有り、false:権限無し + * @access public + */ + function _hasCommentAuthority() { + $multimedia = $this->_request->getParameter("multimedia_obj"); + if ($multimedia['comment_flag'] != _ON) { + return false; + } + + $auth_id = $this->_session->getParameter("_auth_id"); + if ($auth_id <= _AUTH_GUEST) { + return false; + } + + return true; + } + + /** + * 動画のコメントの計数を取得する + * + * @param string $item_id 動画id + * @return string 動画のコメントの計数 + * @access public + */ + function getCommentCount($item_id) { + $params = array( + "item_id" => intval($item_id) + ); + $commentCount = $this->_db->countExecute("multimedia_comment", $params); + + if($commentCount === false) { + $this->_db->addError(); + } + + return $commentCount; + } + + /** + * 動画のコメントを取得する + * + * @param string $item_id 動画id + * @return string 動画のコメント + * @access public + */ + function getComments($item_id, $begin=null) { + $comments = $this->_db->selectExecute("multimedia_comment", array("item_id" => intval($item_id)), array("insert_time" => "DESC"), MULTIMEDIA_VISIBLE_ITEM_COMMENT, $begin, array($this, "_makeCommentArray")); + if($comments === false) { + $this->_db->addError(); + } + + return $comments; + } + + /** + * コメントデータ配列を生成する + * + * @param array $recordSet タスクADORecordSet + * @return array タスクデータ配列 + * @access private + */ + function &_makeCommentArray(&$recordSet) { + $comments = array(); + while ($row = $recordSet->fetchRow()) { + $row["edit_authority"] = false; + if ($this->_hasEditAuthority($row["insert_user_id"])) { + $row["edit_authority"] = true; + } + + $comments[] = $row; + } + + return $comments; + } + + /** + * 画像の大きさを取得 + * + * @return string 画像の大きさ + * @access public + */ + function &getImageSize($image) { + if (is_numeric($image)) { + $container =& DIContainerFactory::getContainer(); + + $uploads =& $container->getComponent("uploadsView"); + $uploadFiles = $uploads->getUploadById($image); + if (empty($uploadFiles)) { + return false; + } + + $imageSize = getimagesize(FILEUPLOADS_DIR. "multimedia/". $uploadFiles[0]["physical_file_name"]); + } else { + $imageSize = getimagesize(HTDOCS_DIR.MULTIMEDIA_SAMPLR_JACKET_PATH.MULTIMEDIA_SAMPLR_JACKET_DIR.$image); + } + + return $imageSize; + } + + /** + * 権限判断用のSQL文FROM句を取得する + * + * @return string 権限判断用のSQL文FROM句 + * @access public + */ + function &_getAuthorityFromSQL() { + $auth_id = $this->_session->getParameter("_auth_id"); + + $sql = ""; + if ($auth_id >= _AUTH_CHIEF) { + return $sql; + } + + $sql .= "LEFT JOIN {pages_users_link} PU ". + "ON A.insert_user_id = PU.user_id ". + "AND A.room_id = PU.room_id "; + $sql .= "LEFT JOIN {authorities} AU ". + "ON PU.role_authority_id = AU.role_authority_id "; + + return $sql; + } + + /** + * 権限判断用のSQL文WHERE句を取得する + * パラメータ用配列に必要な値を追加する + * + * @param array $params パラメータ用配列 + * @return string 権限判断用のSQL文WHERE句 + * @access public + */ + function &_getAuthorityWhereSQL(&$params) { + $auth_id = $this->_session->getParameter("_auth_id"); + + $sql = ""; + if ($auth_id >= _AUTH_CHIEF) { + return $sql; + } + + $sql .= " AND (A.public_flag = ? OR AU.hierarchy < ? OR A.insert_user_id = ? "; + + $default_entry = $this->_session->getParameter("_default_entry_flag"); + $hierarchy = $this->_session->getParameter("_hierarchy"); + if ($default_entry == _ON && $hierarchy > $this->_session->getParameter("_default_entry_hierarchy")) { + $sql .= " OR AU.hierarchy IS NULL) "; + } else { + $sql .= ") "; + } + + $params[] = _ON; + $params[] = $hierarchy; + $params[] = $this->_session->getParameter("_user_id"); + + return $sql; + } + + /** + * 動画データ配列を生成する + * + * @param array $recordSet 動画ADORecordSet + * @return array 動画データ配列 + * @access private + */ + function &_makeItemArray(&$recordSet) { + $items = array(); + while ($row = $recordSet->fetchRow()) { + $row['edit_authority'] = false; + if ($this->_hasEditAuthority($row['insert_user_id'])) { + $row['edit_authority'] = true; + } + $tags = $this->getTags($row['item_id']); + $row['item_tag'] = $this->_makeTagString($tags); + $row['duration'] = floor($row['duration']/60).":".floor(($row['duration']-60*floor($row['duration']/60))); + $items[] = $row; + } + + return $items; + } + + /** + * 動画一覧共通のSQL + * + * @return  array 動画件数データ + * @access public + */ + function _getItemListSQL(&$params, $where_params, $order_params=null, $count_flag=false) { + $sql = ""; + if(empty($order_params)) { + $order_params = array( + "insert_time" => "DESC" + ); + } + + if($count_flag) { + $sql = "SELECT COUNT(T.item_id) as count FROM {multimedia_item} T "; + }else { + $sql = "SELECT T.* FROM {multimedia_item} T "; + } + $sql .= "LEFT JOIN {multimedia_album} A ON T.album_id=A.album_id "; + $sql .= $this->_getAuthorityFromSQL(); + if(!empty($where_params)) { + foreach($where_params as $key => $val) { + if($val == "") { + continue; + } + $where_params["T.".$key] = $val; + unset($where_params[$key]); + } + $sql .= $this->_db->getWhereSQL($params, $where_params); + } + $sql .= $this->_getAuthorityWhereSQL($params); + if(!$count_flag) { + foreach($order_params as $key => $val) { + $order_params["T.".$key] = $val; + unset($order_params[$key]); + } + $sql .= $this->_db->getOrderSQL($order_params); + } + + return $sql; + } + + /** + * 動画一覧件数を取得する + * + * @return  array 動画件数データ + * @access public + */ + function getItemListCount($where_params) { + if(empty($where_params)) { + return false; + } + + $sql = ""; + $params = array(); + $sql = $this->_getItemListSQL($params, $where_params, null, true); + $result = $this->_db->execute($sql, $params); + if ( $result === false ) { + // エラーが発生した場合、エラーリストに追加 + $this->_db->addError(); + return $result; + } + return $result[0]['count']; + } + + /** + * 動画一覧を取得する + * + * @param int $multimedia_id ID + * @return  array 動画データ + * @access public + */ + function getItemList($where_params, $order_params, $begin=null) { + if(empty($where_params)) { + return false; + } + + $sql = ""; + $params = array(); + $sql = $this->_getItemListSQL($params, $where_params, $order_params); + + $result = $this->_db->execute($sql, $params ,MULTIMEDIA_VISIBLE_ITEM_CNT, $begin, true, array($this, "_makeItemArray")); + if ( $result === false ) { + // エラーが発生した場合、エラーリストに追加 + $this->_db->addError(); + return $result; + } + return $result; + } + + /** + * 検索動画一覧を取得する + * + * @return  array 動画データ + * @access public + */ + function getSearchItemList($sql, $where_params, $begin=null) { + $result = $this->_db->execute($sql, $where_params ,MULTIMEDIA_SEARCH_VISIBLE_ITEM_CNT, $begin, true, array($this, "_makeItemArray")); + if ( $result === false ) { + // エラーが発生した場合、エラーリストに追加 + $this->_db->addError(); + } + return $result; + } + + /** + * タグデータ配列を取得する + * + * @return array タグデータ配列 + * @access public + */ + function getTags($item_id) { + $sql = "SELECT R.tag_value, T.used_number, R.tag_id, R.item_id, R.sequence " . + "FROM {multimedia_item_tag} AS R, {multimedia_tag} AS T " . + "WHERE R.tag_id = T.tag_id " . + "AND R.item_id = ? " . + "ORDER BY R.sequence;"; + + $params = array( + $item_id + ); + $tags = $this->_db->execute($sql, $params); + if ($tags === false) { + $this->_db->addError(); + return false; + } + return $tags; + } + + /** + * 関連動画配列を取得する + * + * @return array タグデータ配列 + * @access public + */ + function getSimilarItems($item_id) { + $tags = $this->getTags($item_id); + if(empty($tags)) { + return $tags; + } + + $params = array(); + $where_sql = ""; + foreach($tags as $tag) { + $params[] = $tag['tag_id']; + $where_sql .= " G.tag_id=? OR"; + } + $where_sql = " ( ".substr($where_sql, 0, -2)." ) "; + $sql = "SELECT T.*,count(*) as count " . + "FROM {multimedia_item_tag} AS G, {multimedia_item} AS T "; + $sql .= "LEFT JOIN {multimedia_album} A ON T.album_id=A.album_id "; + $sql .= $this->_getAuthorityFromSQL(); + $sql .= "WHERE G.item_id=T.item_id AND T.item_id <> ".$item_id." AND ".$where_sql; + $sql .= $this->_getAuthorityWhereSQL($params); + $sql .= " GROUP BY T.item_id ORDER BY count DESC"; + $items = $this->_db->execute($sql, $params, MULTIMEDIA_TAG_ITEMS_NUMBER, 0, true, array($this, "_makeItemArray")); + if ($items === false) { + $this->_db->addError(); + return false; + } + return $items; + } + + /** + * タグストリングを生成する + */ + function &_makeTagString($tags) { + $string = ""; + if(empty($tags)) { + return $string; + } + $string = ""; + foreach($tags as $tag) { + $string .= $tag['tag_value'].MULTIMEDIA_TAG_SEPARATOR; + } + $string = substr($string, 0, -1); + + return $string; + } + + /** + * ページに関する設定を行います + * + * @param int disp_cnt 1ページ当り表示件数 + * @param int now_page 現ページ + */ + function setPageInfo(&$pager, $data_cnt, $disp_cnt, $now_page = NULL){ + $pager['data_cnt'] = 0; + $pager['total_page'] = 0; + $pager['next_link'] = FALSE; + $pager['prev_link'] = FALSE; + $pager['disp_begin'] = 0; + $pager['disp_end'] = 0; + $pager['link_array'] = NULL; + + if(empty($disp_cnt)) { + return false; + } + + $pager['data_cnt'] = $data_cnt; + // now page + $pager['now_page'] = (NULL == $now_page) ? 1 : $now_page; + // total page + $pager['total_page'] = ceil($pager['data_cnt'] / $disp_cnt); + if($pager['total_page'] < $pager['now_page']) { + $pager['now_page'] = 1; + } + // link array {{ + if(($pager['now_page'] - MULTIMEDIA_FRONT_AND_BEHIND_LINK_CNT) > 0){ + $start = $pager['now_page'] - MULTIMEDIA_FRONT_AND_BEHIND_LINK_CNT; + }else{ + $start = 1; + } + if(($pager['now_page'] + MULTIMEDIA_FRONT_AND_BEHIND_LINK_CNT) >= $pager['total_page']){ + $end = $pager['total_page']; + }else{ + $end = $pager['now_page'] + MULTIMEDIA_FRONT_AND_BEHIND_LINK_CNT; + } + $i = 0; + for($i = $start; $i <= $end; $i++){ + $pager['link_array'][] = $i; + } + // next link + if($disp_cnt < $pager['data_cnt']){ + if($pager['now_page'] < $pager['total_page']){ + $pager['next_link'] = TRUE; + } + } + // prev link + if(1 < $pager['now_page']){ + $pager['prev_link'] = TRUE; + } + // begin disp number + $pager['disp_begin'] = ($pager['now_page'] - 1) * $disp_cnt; + // end disp number + $tmp_cnt = $pager['now_page'] * $disp_cnt; + $pager['disp_end'] = ($pager['data_cnt'] < $tmp_cnt) ? $pager['data_cnt'] : $tmp_cnt; + } +} ?> \ No newline at end of file diff --git a/multimedia/config/main.ini b/multimedia/config/main.ini index 6b4517e..65e8da9 100644 --- a/multimedia/config/main.ini +++ b/multimedia/config/main.ini @@ -16,6 +16,7 @@ define:MULTIMEDIA_EXTENSION = "ffmpeg" define:MULTIMEDIA_MOVIE_THUMBNAIL_WIDTH = 120 define:MULTIMEDIA_MOVIE_THUMBNAIL_HEIGHT = 90 define:MULTIMEDIA_MOVIE_THUMBNAIL_NAME = "_thumbnail.jpg" +define:MULTIMEDIA_MOVIE_CAPTUER_NAME = "_temp.jpg" define:MULTIMEDIA_MOVIE_THUMBNAIL_ROW_NUMBER = 4 define:MULTIMEDIA_MOVIE_TYPE_NEW = "new" define:MULTIMEDIA_MOVIE_TYPE_POP = "pop" @@ -37,7 +38,14 @@ define:MULTIMEDIA_TAG_SEPARATOR = "," define:MULTIMEDIA_TAG_ITEMS_NUMBER = 6 define:MULTIMEDIA_MOVIE_PLAYER_WIDTH = 504 define:MULTIMEDIA_MOVIE_PLAYER_HEIGHT = 290 +define:MULTIMEDIA_MOVIE_PLAYER_CONTROLLER_HEIGHT = 24 ;sv +define:MULTIMEDIA_MOVIE_PLAYER_EMBEDED_WIDTH = 400 +define:MULTIMEDIA_MOVIE_PLAYER_EMBEDED_HEIGHT = 300 define:MULTIMEDIA_GET_FLASH_LINK = "http://www.adobe.com/go/getflashplayer" define:MULTIMEDIA_GET_FLASH_ICON = "http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" define:MULTIMEDIA_VISIBLE_ITEM_COMMENT = 5 -define:MULTIMEDIA_SEARCH_VISIBLE_ITEM_CNT = 5 \ No newline at end of file +define:MULTIMEDIA_SEARCH_VISIBLE_ITEM_CNT = 5 +define:MULTIMEDIA_FFMPEG_PATH = "/usr/bin/ffmpeg" +define:MULTIMEDIA_FFMPEG_OPTION = "-acodec libfaac -ar 44100 -vcodec libx264 -vpre medium -r 30 -b 500k" +define:MULTIMEDIA_MP4BOX_PATH = "/usr/local/bin/MP4Box" +define:MULTIMEDIA_THUMBNAIL_SECONDS = 10 diff --git a/multimedia/files/css/default/style.css b/multimedia/files/css/default/style.css index 2e7a62e..bd2b71c 100644 --- a/multimedia/files/css/default/style.css +++ b/multimedia/files/css/default/style.css @@ -589,4 +589,537 @@ div.multimedia_search_title { } .multimedia_upload_table_td{ width:260px; -} \ No newline at end of file +} +.multimedia_player_background{ + border:1px solid #bbb; +} +.multimedia_player_thumbnail{ + width:100%; + height:100%; +} +.multimedia_player_error_block{ + position:absolute; + margin-top:-27px; + height:26px; + background-color:#000; + border-top:1px solid #bbb; +} +.multimedia_player_error_detail{ + margin:5px; + font-size:13px; + color:#fff; +} + +/* 以下、動画プレイヤー用 */ +div.jp-video { + font-size:1.25em; /* 1.25em for testing in site pages */ /* No parent CSS that can effect the size in the demos ZIP */ + font-family:Verdana, Arial, sans-serif; + line-height:1.6; + color: #000; + background-color:#eee; +} + +div.jp-video-embeded { + width:400px; /* 幅を変更する場合はここを修正 */ +} +div.jp-video-normal { + width:504px; /* 幅を変更する場合はここを修正 */ +} +div.jp-video-full { + position:static !important; position:relative +} + +div.jp-video-full div div { + z-index:1000; +} + +div.jp-video-full div.jp-jplayer { + top: 0; + left: 0; + position: fixed !important; position: relative; + overflow: hidden; +} + +div.jp-video-full div.jp-gui { + position: fixed !important; position: static; + top: 0; + left: 0; + width:100%; + height:100%; + z-index:1001; +} + +div.jp-video-full div.jp-interface { + position: absolute !important; position: relative; + bottom: 0; + left: 0; +} + +div.jp-gui div.jp-interface { + position: relative; + background-color:#eee; + width:100%; + margin-top: -21px; +} + +div.jp-video div.jp-interface { +} + +/* @group CONTROLS */ + +div.jp-controls-holder { + clear: both; + margin:0 auto; + position: relative; + overflow:hidden; + height:18px; + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") 0 -101px repeat-x; + border-left: 1px solid #bbb; + border-right: 1px solid #bbb; +} + +div.jp-interface ul.jp-controls { + list-style-type:none; + margin:0; + padding: 0; + overflow:hidden; +} + +div.jp-interface ul.jp-controls-left { + list-style-type:none; + margin:0; + padding: 0; + overflow:hidden; + margin-top: 1px; +} + +div.jp-interface ul.jp-controls-right { + list-style-type:none; + margin:0; + padding: 0; + overflow:hidden; + margin-top: 1px; +} + +div.jp-video div.jp-type-single ul.jp-controls { + width: 78px; + margin-left: 200px; +} + +div.jp-video div.jp-type-single ul.jp-controls-left { +} + +div.jp-video div.jp-type-single ul.jp-controls-right { +} + +div.jp-video ul.jp-controls, +div.jp-interface ul.jp-controls li { + display:inline; + float: left; +} + +div.jp-video ul.jp-controls-left, +div.jp-interface ul.jp-controls-left li { + display:inline; + float: left; +} + +div.jp-video ul.jp-controls-right, +div.jp-interface ul.jp-controls-right li { + display:inline; + float: right; +} + +div.jp-interface ul.jp-controls a { + display:block; + overflow:hidden; + text-indent:-9999px; +} + +div.jp-interface ul.jp-controls-left a { + display:block; + overflow:hidden; + text-indent:-9999px; +} + +div.jp-interface ul.jp-controls-right a { + display:block; + overflow:hidden; + text-indent:-9999px; +} + +a.jp-play, +a.jp-pause { + width: 15px; + height: 15px; +} + +a.jp-play { + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") 0 0 no-repeat; + margin-left: 6px; +} +a.jp-play:hover { + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") -17px 0 no-repeat; +} +a.jp-pause { + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") 0 -16px no-repeat; + margin-left: 6px; + display: none; +} +a.jp-pause:hover { + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") -17px -16px no-repeat; +} + +a.jp-stop { + display: none; +} + +/* @group progress bar */ + +div.jp-progress { + overflow:hidden; + background-color: #ddd; +} + +div.jp-video div.jp-progress { + top:0px; + left:0px; + width:100%; + height:3px; +} +div.jp-seek-bar { + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") 0 -81px repeat-x; + width:0px; + height:100%; + cursor: pointer; +} +div.jp-play-bar { + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") 0 -85px repeat-x ; + width:0px; + height:100%; +} + +div.jp-seeking-bg { + background: url("jplayer/jplayer.blue.monday.seeking.gif"); +} + +/* @group volume controls */ + +a.jp-mute, +a.jp-unmute, +a.jp-volume-max { + width:16px; + height:15px; + margin-left: 3px; +} + +div.jp-video a.jp-mute, +div.jp-video a.jp-unmute, +div.jp-video a.jp-volume-max { +} + +div.jp-video a.jp-mute, +div.jp-video a.jp-unmute { + left: 50px; +} + +div.jp-video a.jp-volume-max { + left: 134px; +} + +a.jp-mute { + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") 0 -48px no-repeat; +} +a.jp-mute:hover { + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") -17px -48px no-repeat; +} +a.jp-unmute { + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") 0 -32px no-repeat; + display: none; +} +a.jp-unmute:hover { + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") -17px -32px no-repeat; +} + +a.jp-volume-max { + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") 0 -32px no-repeat; +} +a.jp-volume-max:hover { + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") -17px -32px no-repeat; +} + +div.jp-volume-bar { + overflow:hidden; + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") 0 -89px repeat-x; + width:100px; + height:5px; + cursor: pointer; + margin-top: 5px; + margin-left:3px; +} + +div.jp-video div.jp-volume-bar { +} +div.jp-volume-bar-value { + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") 0 -95px repeat-x; + width:0px; + height:5px; +} + +/* @group current time and duration */ + +div.jp-audio div.jp-time-holder { + position:absolute; + top:50px; +} +div.jp-audio div.jp-type-single div.jp-time-holder { + left:110px; + width:186px; +} +div.jp-audio div.jp-type-playlist div.jp-time-holder { + left:166px; + width:130px; +} + +div.jp-current-time, +div.jp-duration { + font-size: 9px; +} +div.jp-current-time { +} +div.jp-duration { +} + +div.jp-video div.jp-current-time { + margin-left: 5px; +} +div.jp-video div.jp-duration { + margin-left: 5px; +} + +/* @group playlist */ + +div.jp-title { + font-weight:bold; + text-align:center; +} + +div.jp-title, +div.jp-playlist { + width:100%; + background-color:#ccc; + border-top:1px solid #009be3; +} +div.jp-type-single div.jp-title, +div.jp-type-playlist div.jp-title, +div.jp-type-single div.jp-playlist { + border-top:none; +} +div.jp-title ul, +div.jp-playlist ul { + list-style-type:none; + margin:0; + padding:0 20px; + font-size:.72em; +} + +div.jp-title li { + padding:5px 0; + font-weight:bold; +} +div.jp-playlist li { + padding:5px 0 4px 20px; + border-bottom:1px solid #eee; +} + +div.jp-playlist li div { + display:inline; +} + +div.jp-type-playlist div.jp-playlist li:last-child { + padding:5px 0 5px 20px; + border-bottom:none; +} +div.jp-type-playlist div.jp-playlist li.jp-playlist-current { + list-style-type:square; + list-style-position:inside; + padding-left:7px; +} +div.jp-type-playlist div.jp-playlist a { + color: #333; + text-decoration: none; +} +div.jp-type-playlist div.jp-playlist a:hover { + color:#0d88c1; +} +div.jp-type-playlist div.jp-playlist a.jp-playlist-current { + color:#0d88c1; +} + +div.jp-type-playlist div.jp-playlist a.jp-playlist-item-remove { + float:right; + display:inline; + text-align:right; + margin-right:10px; + font-weight:bold; + color:#666; +} +div.jp-type-playlist div.jp-playlist a.jp-playlist-item-remove:hover { + color:#0d88c1; +} +div.jp-type-playlist div.jp-playlist span.jp-free-media { + float:right; + display:inline; + text-align:right; + margin-right:10px; +} +div.jp-type-playlist div.jp-playlist span.jp-free-media a{ + color:#666; +} +div.jp-type-playlist div.jp-playlist span.jp-free-media a:hover{ + color:#0d88c1; +} +span.jp-artist { + font-size:.8em; + color:#666; +} + +/* @end */ + +div.jp-video-play { + width:100%; + overflow:hidden; + cursor:pointer; + background-color:rgba(0,0,0,0); +} +div.jp-video-embeded div.jp-video-play { + /* 高さを変更する場合はここを修正 */ + margin-top:-300px; + height:300px; +} +div.jp-video-normal div.jp-video-play { + /* 高さを変更する場合はここを修正 */ + margin-top:-290px; + height:290px; +} +div.jp-video-full div.jp-video-play { + height:100%; +} +a.jp-video-play-icon { + position:relative; + display:block; + width: 80px; + height: 80px; + margin-left:-40px; + margin-top:-40px; + left:50%; + top:50%; + background: url("jplayer/jplayer.netcommons.video.play.png") 0 0 no-repeat; + text-indent:-9999px; +} + +div.jp-video-full a.jp-video-play-icon { + position:absolute; + z-index:1002; +} + +div.jp-jplayer { + width:0px; + height:0px; +} + +div.jp-jplayer { + background-color: #000000; + border:1px solid #bbb; +} + +/* @group TOGGLES */ + +ul.jp-toggles { + list-style-type:none; + padding:0; + margin:0 auto; + overflow:hidden; +} + +div.jp-video ul.jp-toggles { + margin-top:10px; + width:100px; +} + +ul.jp-toggles li { + display:block; + float:right; +} + +ul.jp-toggles li a { + display:block; + width:25px; + height:18px; + text-indent:-9999px; + line-height:100%; +} + +a.jp-full-screen { + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") 0 -64px no-repeat; + width: 16px; + height: 15px; + margin-left: 5px; + margin-right: 5px; +} + +a.jp-full-screen:hover { + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") -17px -64px no-repeat; +} + +a.jp-restore-screen { + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") 0 -64px no-repeat; + width: 16px; + height: 15px; + margin-left: 5px; + margin-right: 5px; +} + +a.jp-restore-screen:hover { + background: url("<{$smarty.const.CORE_BASE_URL}>/images/multimedia/jplayer/jplayer.netcommons.jpg") -17px -64px no-repeat; +} + +a.jp-repeat { + display: none; +} + +a.jp-repeat-off { + display: none; +} + +a.jp-shuffle { + display: none; +} + +a.jp-shuffle-off { + display: none; +} + +/* @group NO SOLUTION error feedback */ + +.jp-no-solution { + padding:5px; + font-size:.8em; + background-color:#eee; + border:2px solid #009be3; + color:#000; + display:none; +} + +.jp-no-solution a { + color:#000; +} + +.jp-no-solution span { + font-size:1em; + display:block; + text-align:center; + font-weight:bold; +} + +/* @end */ diff --git a/multimedia/files/images/Jplayer.swf b/multimedia/files/images/Jplayer.swf new file mode 100644 index 0000000..aca11a5 Binary files /dev/null and b/multimedia/files/images/Jplayer.swf differ diff --git a/multimedia/files/images/jplayer/jplayer.blue.monday.jpg b/multimedia/files/images/jplayer/jplayer.blue.monday.jpg new file mode 100644 index 0000000..adab53f Binary files /dev/null and b/multimedia/files/images/jplayer/jplayer.blue.monday.jpg differ diff --git a/multimedia/files/images/jplayer/jplayer.blue.monday.seeking.gif b/multimedia/files/images/jplayer/jplayer.blue.monday.seeking.gif new file mode 100644 index 0000000..dbd2105 Binary files /dev/null and b/multimedia/files/images/jplayer/jplayer.blue.monday.seeking.gif differ diff --git a/multimedia/files/images/jplayer/jplayer.blue.monday.video.play.png b/multimedia/files/images/jplayer/jplayer.blue.monday.video.play.png new file mode 100644 index 0000000..8e97df0 Binary files /dev/null and b/multimedia/files/images/jplayer/jplayer.blue.monday.video.play.png differ diff --git a/multimedia/files/images/jplayer/jplayer.netcommons.jpg b/multimedia/files/images/jplayer/jplayer.netcommons.jpg new file mode 100644 index 0000000..59d821e Binary files /dev/null and b/multimedia/files/images/jplayer/jplayer.netcommons.jpg differ diff --git a/multimedia/files/images/jplayer/jplayer.netcommons.video.play.png b/multimedia/files/images/jplayer/jplayer.netcommons.video.play.png new file mode 100644 index 0000000..2ad92e4 Binary files /dev/null and b/multimedia/files/images/jplayer/jplayer.netcommons.video.play.png differ diff --git a/multimedia/files/images/jquery-1.7.1.min.js b/multimedia/files/images/jquery-1.7.1.min.js new file mode 100644 index 0000000..198b3ff --- /dev/null +++ b/multimedia/files/images/jquery-1.7.1.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.7.1 jquery.com | jquery.org/license */ +(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
"+""+"
",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
t
",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; +f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<(?:"+V+")","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() +{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/multimedia/files/images/jquery-1.8.3.min.js b/multimedia/files/images/jquery-1.8.3.min.js new file mode 100644 index 0000000..83589da --- /dev/null +++ b/multimedia/files/images/jquery-1.8.3.min.js @@ -0,0 +1,2 @@ +/*! jQuery v1.8.3 jquery.com | jquery.org/license */ +(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write(""),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u<1&&o?n:(u.resolveWith(e,[f]),!1)},f=u.promise({elem:e,props:v.extend({},t),opts:v.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:qn||$n(),duration:n.duration,tweens:[],createTween:function(t,n,r){var i=v.Tween(e,f.opts,t,n,f.opts.specialEasing[t]||f.opts.easing);return f.tweens.push(i),i},stop:function(t){var n=0,r=t?f.tweens.length:0;for(;n)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t
a",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="
t
",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="
",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n<0&&(s+=t[o]+" ");i.className=v.trim(s)}}}return this},removeClass:function(e){var n,r,i,s,o,u,a;if(v.isFunction(e))return this.each(function(t){v(this).removeClass(e.call(this,t,this.className))});if(e&&typeof e=="string"||e===t){n=(e||"").split(y);for(u=0,a=this.length;u=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;ti.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="
",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="

",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t0)for(i=r;i=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/<(?:"+ct+")[\\s/>]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*\s*$/g,Nt={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X
","
"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1>");try{for(;r1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]===""&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("
").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window); \ No newline at end of file diff --git a/multimedia/files/images/jquery.jplayer.js b/multimedia/files/images/jquery.jplayer.js new file mode 100644 index 0000000..f1ffed7 --- /dev/null +++ b/multimedia/files/images/jquery.jplayer.js @@ -0,0 +1,2663 @@ +/* + * jPlayer Plugin for jQuery JavaScript Library + * http://www.jplayer.org + * + * Copyright (c) 2009 - 2012 Happyworm Ltd + * Dual licensed under the MIT and GPL licenses. + * - http://www.opensource.org/licenses/mit-license.php + * - http://www.gnu.org/copyleft/gpl.html + * + * Author: Mark J Panaghiston + * Version: 2.2.15 + * Date: 19th November 2012 + */ + +/* Code verified using http://www.jshint.com/ */ +/*jshint asi:false, bitwise:false, boss:false, browser:true, curly:true, debug:false, eqeqeq:true, eqnull:false, evil:false, forin:false, immed:false, jquery:true, laxbreak:false, newcap:true, noarg:true, noempty:true, nonew:true, onevar:false, passfail:false, plusplus:false, regexp:false, undef:true, sub:false, strict:false, white:false smarttabs:true */ +/*global define:false, ActiveXObject:false, alert:false */ + +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else { + // Browser globals + factory(root.jQuery); + } +}(this, function ($, undefined) { + + // Adapted from jquery.ui.widget.js (1.8.7): $.widget.bridge + $.fn.jPlayer = function( options ) { + var name = "jPlayer"; + var isMethodCall = typeof options === "string", + args = Array.prototype.slice.call( arguments, 1 ), + returnValue = this; + + // allow multiple hashes to be passed on init + options = !isMethodCall && args.length ? + $.extend.apply( null, [ true, options ].concat(args) ) : + options; + + // prevent calls to internal methods + if ( isMethodCall && options.charAt( 0 ) === "_" ) { + return returnValue; + } + + if ( isMethodCall ) { + this.each(function() { + var instance = $.data( this, name ), + methodValue = instance && $.isFunction( instance[options] ) ? + instance[ options ].apply( instance, args ) : + instance; + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue; + return false; + } + }); + } else { + this.each(function() { + var instance = $.data( this, name ); + if ( instance ) { + // instance.option( options || {} )._init(); // Orig jquery.ui.widget.js code: Not recommend for jPlayer. ie., Applying new options to an existing instance (via the jPlayer constructor) and performing the _init(). The _init() is what concerns me. It would leave a lot of event handlers acting on jPlayer instance and the interface. + instance.option( options || {} ); // The new constructor only changes the options. Changing options only has basic support atm. + } else { + $.data( this, name, new $.jPlayer( options, this ) ); + } + }); + } + + return returnValue; + }; + + $.jPlayer = function( options, element ) { + // allow instantiation without initializing for simple inheritance + if ( arguments.length ) { + this.element = $(element); + this.options = $.extend(true, {}, + this.options, + options + ); + var self = this; + this.element.bind( "remove.jPlayer", function() { + self.destroy(); + }); + this._init(); + } + }; + // End of: (Adapted from jquery.ui.widget.js (1.8.7)) + + // Emulated HTML5 methods and properties + $.jPlayer.emulateMethods = "load play pause"; + $.jPlayer.emulateStatus = "src readyState networkState currentTime duration paused ended playbackRate"; + $.jPlayer.emulateOptions = "muted volume"; + + // Reserved event names generated by jPlayer that are not part of the HTML5 Media element spec + $.jPlayer.reservedEvent = "ready flashreset resize repeat error warning"; + + // Events generated by jPlayer + $.jPlayer.event = {}; + $.each( + [ + 'ready', + 'flashreset', // Similar to the ready event if the Flash solution is set to display:none and then shown again or if it's reloaded for another reason by the browser. For example, using CSS position:fixed on Firefox for the full screen feature. + 'resize', // Occurs when the size changes through a full/restore screen operation or if the size/sizeFull options are changed. + 'repeat', // Occurs when the repeat status changes. Usually through clicks on the repeat button of the interface. + 'click', // Occurs when the user clicks on one of the following: poster image, html video, flash video. + 'error', // Event error code in event.jPlayer.error.type. See $.jPlayer.error + 'warning', // Event warning code in event.jPlayer.warning.type. See $.jPlayer.warning + + // Other events match HTML5 spec. + 'loadstart', + 'progress', + 'suspend', + 'abort', + 'emptied', + 'stalled', + 'play', + 'pause', + 'loadedmetadata', + 'loadeddata', + 'waiting', + 'playing', + 'canplay', + 'canplaythrough', + 'seeking', + 'seeked', + 'timeupdate', + 'ended', + 'ratechange', + 'durationchange', + 'volumechange' + ], + function() { + $.jPlayer.event[ this ] = 'jPlayer_' + this; + } + ); + + $.jPlayer.htmlEvent = [ // These HTML events are bubbled through to the jPlayer event, without any internal action. + "loadstart", + // "progress", // jPlayer uses internally before bubbling. + // "suspend", // jPlayer uses internally before bubbling. + "abort", + // "error", // jPlayer uses internally before bubbling. + "emptied", + "stalled", + // "play", // jPlayer uses internally before bubbling. + // "pause", // jPlayer uses internally before bubbling. + "loadedmetadata", + "loadeddata", + // "waiting", // jPlayer uses internally before bubbling. + // "playing", // jPlayer uses internally before bubbling. + "canplay", + "canplaythrough", + // "seeking", // jPlayer uses internally before bubbling. + // "seeked", // jPlayer uses internally before bubbling. + // "timeupdate", // jPlayer uses internally before bubbling. + // "ended", // jPlayer uses internally before bubbling. + "ratechange" + // "durationchange" // jPlayer uses internally before bubbling. + // "volumechange" // jPlayer uses internally before bubbling. + ]; + + $.jPlayer.pause = function() { + $.each($.jPlayer.prototype.instances, function(i, element) { + if(element.data("jPlayer").status.srcSet) { // Check that media is set otherwise would cause error event. + element.jPlayer("pause"); + } + }); + }; + + $.jPlayer.timeFormat = { + showHour: false, + showMin: true, + showSec: true, + padHour: false, + padMin: true, + padSec: true, + sepHour: ":", + sepMin: ":", + sepSec: "" + }; + + $.jPlayer.convertTime = function(s) { + s = (s && typeof s === 'number') ? s : 0; + + var myTime = new Date(s * 1000), + hour = myTime.getUTCHours(), + min = $.jPlayer.timeFormat.showHour ? myTime.getUTCMinutes() : myTime.getUTCMinutes() + hour * 60, + sec = $.jPlayer.timeFormat.showMin ? myTime.getUTCSeconds() : myTime.getUTCSeconds() + min * 60, + strHour = ($.jPlayer.timeFormat.padHour && hour < 10) ? "0" + hour : hour, + strMin = ($.jPlayer.timeFormat.padMin && min < 10) ? "0" + min : min, + strSec = ($.jPlayer.timeFormat.padSec && sec < 10) ? "0" + sec : sec, + strTime = ""; + + strTime += $.jPlayer.timeFormat.showHour ? strHour + $.jPlayer.timeFormat.sepHour : ""; + strTime += $.jPlayer.timeFormat.showMin ? strMin + $.jPlayer.timeFormat.sepMin : ""; + strTime += $.jPlayer.timeFormat.showSec ? strSec + $.jPlayer.timeFormat.sepSec : ""; + + return strTime; + }; + + // Adapting jQuery 1.4.4 code for jQuery.browser. Required since jQuery 1.3.2 does not detect Chrome as webkit. + $.jPlayer.uaBrowser = function( userAgent ) { + var ua = userAgent.toLowerCase(); + + // Useragent RegExp + var rwebkit = /(webkit)[ \/]([\w.]+)/; + var ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/; + var rmsie = /(msie) ([\w.]+)/; + var rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/; + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }; + + // Platform sniffer for detecting mobile devices + $.jPlayer.uaPlatform = function( userAgent ) { + var ua = userAgent.toLowerCase(); + + // Useragent RegExp + var rplatform = /(ipad|iphone|ipod|android|blackberry|playbook|windows ce|webos)/; + var rtablet = /(ipad|playbook)/; + var randroid = /(android)/; + var rmobile = /(mobile)/; + + var platform = rplatform.exec( ua ) || []; + var tablet = rtablet.exec( ua ) || + !rmobile.exec( ua ) && randroid.exec( ua ) || + []; + + if(platform[1]) { + platform[1] = platform[1].replace(/\s/g, "_"); // Change whitespace to underscore. Enables dot notation. + } + + return { platform: platform[1] || "", tablet: tablet[1] || "" }; + }; + + $.jPlayer.browser = { + }; + $.jPlayer.platform = { + }; + + var browserMatch = $.jPlayer.uaBrowser(navigator.userAgent); + if ( browserMatch.browser ) { + $.jPlayer.browser[ browserMatch.browser ] = true; + $.jPlayer.browser.version = browserMatch.version; + } + var platformMatch = $.jPlayer.uaPlatform(navigator.userAgent); + if ( platformMatch.platform ) { + $.jPlayer.platform[ platformMatch.platform ] = true; + $.jPlayer.platform.mobile = !platformMatch.tablet; + $.jPlayer.platform.tablet = !!platformMatch.tablet; + } + + // Internet Explorer (IE) Browser Document Mode Sniffer. Based on code at: + // http://msdn.microsoft.com/en-us/library/cc288325%28v=vs.85%29.aspx#GetMode + $.jPlayer.getDocMode = function() { + var docMode; + if ($.jPlayer.browser.msie) { + if (document.documentMode) { // IE8 or later + docMode = document.documentMode; + } else { // IE 5-7 + docMode = 5; // Assume quirks mode unless proven otherwise + if (document.compatMode) { + if (document.compatMode === "CSS1Compat") { + docMode = 7; // standards mode + } + } + } + } + return docMode; + }; + $.jPlayer.browser.documentMode = $.jPlayer.getDocMode(); + + $.jPlayer.nativeFeatures = { + init: function() { + + /* Fullscreen function naming influenced by W3C naming. + * No support for: Mozilla Proposal: https://wiki.mozilla.org/Gecko:FullScreenAPI + */ + + var d = document, + v = d.createElement('video'), + spec = { + // http://www.w3.org/TR/fullscreen/ + w3c: [ + 'fullscreenEnabled', + 'fullscreenElement', + 'requestFullscreen', + 'exitFullscreen', + 'fullscreenchange', + 'fullscreenerror' + ], + // https://developer.mozilla.org/en-US/docs/DOM/Using_fullscreen_mode + moz: [ + 'mozFullScreenEnabled', + 'mozFullScreenElement', + 'mozRequestFullScreen', + 'mozCancelFullScreen', + 'mozfullscreenchange', + 'mozfullscreenerror' + ], + // http://developer.apple.com/library/safari/#documentation/WebKit/Reference/ElementClassRef/Element/Element.html + // http://developer.apple.com/library/safari/#documentation/UserExperience/Reference/DocumentAdditionsReference/DocumentAdditions/DocumentAdditions.html + webkit: [ + '', + 'webkitCurrentFullScreenElement', + 'webkitRequestFullScreen', + 'webkitCancelFullScreen', + 'webkitfullscreenchange', + '' + ], + // http://developer.apple.com/library/safari/#documentation/AudioVideo/Reference/HTMLVideoElementClassReference/HTMLVideoElement/HTMLVideoElement.html + webkitVideo: [ + 'webkitSupportsFullscreen', + 'webkitDisplayingFullscreen', + 'webkitEnterFullscreen', + 'webkitExitFullscreen', + '', + '' + ] + }, + specOrder = [ + 'w3c', + 'moz', + 'webkit', + 'webkitVideo' + ], + fs, i, il; + + this.fullscreen = fs = { + support: { + w3c: !!d[spec.w3c[0]], + moz: !!d[spec.moz[0]], + webkit: typeof d[spec.webkit[3]] === 'function', + webkitVideo: typeof v[spec.webkitVideo[2]] === 'function' + }, + used: {} + }; + + // Store the name of the spec being used and as a handy boolean. + for(i = 0, il = specOrder.length; i < il; i++) { + var n = specOrder[i]; + if(fs.support[n]) { + fs.spec = n; + fs.used[n] = true; + break; + } + } + + if(fs.spec) { + var s = spec[fs.spec]; + fs.api = { + fullscreenEnabled: true, + fullscreenElement: function(elem) { + elem = elem ? elem : d; // Video element required for webkitVideo + return elem[s[1]]; + }, + requestFullscreen: function(elem) { + return elem[s[2]](); + }, + exitFullscreen: function(elem) { + elem = elem ? elem : d; // Video element required for webkitVideo + return elem[s[3]](); + } + }; + fs.event = { + fullscreenchange: s[4], + fullscreenerror: s[5] + }; + } else { + fs.api = { + fullscreenEnabled: false, + fullscreenElement: function() { + return null; + }, + requestFullscreen: function() {}, + exitFullscreen: function() {} + }; + fs.event = {}; + } + } + }; + $.jPlayer.nativeFeatures.init(); + + $.jPlayer.prototype = { + count: 0, // Static Variable: Change it via prototype. + version: { // Static Object + script: "2.2.15", + needFlash: "2.2.0", + flash: "unknown" + }, + options: { // Instanced in $.jPlayer() constructor + swfPath: "js", // Path to Jplayer.swf. Can be relative, absolute or server root relative. + solution: "html, flash", // Valid solutions: html, flash. Order defines priority. 1st is highest, + supplied: "mp3", // Defines which formats jPlayer will try and support and the priority by the order. 1st is highest, + preload: 'metadata', // HTML5 Spec values: none, metadata, auto. + volume: 0.8, // The volume. Number 0 to 1. + muted: false, + wmode: "opaque", // Valid wmode: window, transparent, opaque, direct, gpu. + allowFullScreen: true, + backgroundColor: "#000000", // To define the jPlayer div and Flash background color. + cssSelectorAncestor: "#jp_container_1", + cssSelector: { // * denotes properties that should only be required when video media type required. _cssSelector() would require changes to enable splitting these into Audio and Video defaults. + videoPlay: ".jp-video-play", // * + play: ".jp-play", + pause: ".jp-pause", + stop: ".jp-stop", + seekBar: ".jp-seek-bar", + playBar: ".jp-play-bar", + mute: ".jp-mute", + unmute: ".jp-unmute", + volumeBar: ".jp-volume-bar", + volumeBarValue: ".jp-volume-bar-value", + volumeMax: ".jp-volume-max", + currentTime: ".jp-current-time", + duration: ".jp-duration", + fullScreen: ".jp-full-screen", // * + restoreScreen: ".jp-restore-screen", // * + repeat: ".jp-repeat", + repeatOff: ".jp-repeat-off", + gui: ".jp-gui", // The interface used with autohide feature. + noSolution: ".jp-no-solution" // For error feedback when jPlayer cannot find a solution. + }, + fullScreen: false, // Native Full Screen + fullWindow: false, + autohide: { + restored: false, // Controls the interface autohide feature. + full: true, // Controls the interface autohide feature. + fadeIn: 200, // Milliseconds. The period of the fadeIn anim. + fadeOut: 600, // Milliseconds. The period of the fadeOut anim. + hold: 1000 // Milliseconds. The period of the pause before autohide beings. + }, + loop: false, + repeat: function(event) { // The default jPlayer repeat event handler + if(event.jPlayer.options.loop) { + $(this).unbind(".jPlayerRepeat").bind($.jPlayer.event.ended + ".jPlayer.jPlayerRepeat", function() { + $(this).jPlayer("play"); + }); + } else { + $(this).unbind(".jPlayerRepeat"); + } + }, + nativeVideoControls: { + // Works well on standard browsers. + // Phone and tablet browsers can have problems with the controls disappearing. + }, + noFullWindow: { + msie: /msie [0-6]\./, + ipad: /ipad.*?os [0-4]\./, + iphone: /iphone/, + ipod: /ipod/, + android_pad: /android [0-4]\.(?!.*?mobile)/, + android_phone: /android.*?mobile/, + blackberry: /blackberry/, + windows_ce: /windows ce/, + iemobile: /iemobile/, + webos: /webos/ + }, + noVolume: { + ipad: /ipad/, + iphone: /iphone/, + ipod: /ipod/, + android_pad: /android(?!.*?mobile)/, + android_phone: /android.*?mobile/, + blackberry: /blackberry/, + windows_ce: /windows ce/, + iemobile: /iemobile/, + webos: /webos/, + playbook: /playbook/ + }, + verticalVolume: false, // Calculate volume from the bottom of the volume bar. Default is from the left. Also volume affects either width or height. + // globalVolume: false, // Not implemented: Set to make volume changes affect all jPlayer instances + // globalMute: false, // Not implemented: Set to make mute changes affect all jPlayer instances + idPrefix: "jp", // Prefix for the ids of html elements created by jPlayer. For flash, this must not include characters: . - + * / \ + noConflict: "jQuery", + emulateHtml: false, // Emulates the HTML5 Media element on the jPlayer element. + errorAlerts: false, + warningAlerts: false + }, + optionsAudio: { + size: { + width: "0px", + height: "0px", + cssClass: "" + }, + sizeFull: { + width: "0px", + height: "0px", + cssClass: "" + } + }, + optionsVideo: { + size: { + width: "480px", + height: "270px", + cssClass: "jp-video-270p" + }, + sizeFull: { + width: "100%", + height: "100%", + cssClass: "jp-video-full" + } + }, + instances: {}, // Static Object + status: { // Instanced in _init() + src: "", + media: {}, + paused: true, + format: {}, + formatType: "", + waitForPlay: true, // Same as waitForLoad except in case where preloading. + waitForLoad: true, + srcSet: false, + video: false, // True if playing a video + seekPercent: 0, + currentPercentRelative: 0, + currentPercentAbsolute: 0, + currentTime: 0, + duration: 0, + readyState: 0, + networkState: 0, + playbackRate: 1, + ended: 0 + +/* Persistant status properties created dynamically at _init(): + width + height + cssClass + nativeVideoControls + noFullWindow + noVolume +*/ + }, + + internal: { // Instanced in _init() + ready: false + // instance: undefined + // domNode: undefined + // htmlDlyCmdId: undefined + // autohideId: undefined + // cmdsIgnored + }, + solution: { // Static Object: Defines the solutions built in jPlayer. + html: true, + flash: true + }, + // 'MPEG-4 support' : canPlayType('video/mp4; codecs="mp4v.20.8"') + format: { // Static Object + mp3: { + codec: 'audio/mpeg; codecs="mp3"', + flashCanPlay: true, + media: 'audio' + }, + m4a: { // AAC / MP4 + codec: 'audio/mp4; codecs="mp4a.40.2"', + flashCanPlay: true, + media: 'audio' + }, + oga: { // OGG + codec: 'audio/ogg; codecs="vorbis"', + flashCanPlay: false, + media: 'audio' + }, + wav: { // PCM + codec: 'audio/wav; codecs="1"', + flashCanPlay: false, + media: 'audio' + }, + webma: { // WEBM + codec: 'audio/webm; codecs="vorbis"', + flashCanPlay: false, + media: 'audio' + }, + fla: { // FLV / F4A + codec: 'audio/x-flv', + flashCanPlay: true, + media: 'audio' + }, + rtmpa: { // RTMP AUDIO + codec: 'audio/rtmp; codecs="rtmp"', + flashCanPlay: true, + media: 'audio' + }, + m4v: { // H.264 / MP4 + codec: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"', + flashCanPlay: true, + media: 'video' + }, + ogv: { // OGG + codec: 'video/ogg; codecs="theora, vorbis"', + flashCanPlay: false, + media: 'video' + }, + webmv: { // WEBM + codec: 'video/webm; codecs="vorbis, vp8"', + flashCanPlay: false, + media: 'video' + }, + flv: { // FLV / F4V + codec: 'video/x-flv', + flashCanPlay: true, + media: 'video' + }, + rtmpv: { // RTMP VIDEO + codec: 'video/rtmp; codecs="rtmp"', + flashCanPlay: true, + media: 'video' + } + }, + _init: function() { + var self = this; + + this.element.empty(); + + this.status = $.extend({}, this.status); // Copy static to unique instance. + this.internal = $.extend({}, this.internal); // Copy static to unique instance. + + // On iOS, assume commands will be ignored before user initiates them. + this.internal.cmdsIgnored = $.jPlayer.platform.ipad || $.jPlayer.platform.iphone || $.jPlayer.platform.ipod; + + this.internal.domNode = this.element.get(0); + + this.formats = []; // Array based on supplied string option. Order defines priority. + this.solutions = []; // Array based on solution string option. Order defines priority. + this.require = {}; // Which media types are required: video, audio. + + this.htmlElement = {}; // DOM elements created by jPlayer + this.html = {}; // In _init()'s this.desired code and setmedia(): Accessed via this[solution], where solution from this.solutions array. + this.html.audio = {}; + this.html.video = {}; + this.flash = {}; // In _init()'s this.desired code and setmedia(): Accessed via this[solution], where solution from this.solutions array. + + this.css = {}; + this.css.cs = {}; // Holds the css selector strings + this.css.jq = {}; // Holds jQuery selectors. ie., $(css.cs.method) + + this.ancestorJq = []; // Holds jQuery selector of cssSelectorAncestor. Init would use $() instead of [], but it is only 1.4+ + + this.options.volume = this._limitValue(this.options.volume, 0, 1); // Limit volume value's bounds. + + // Create the formats array, with prority based on the order of the supplied formats string + $.each(this.options.supplied.toLowerCase().split(","), function(index1, value1) { + var format = value1.replace(/^\s+|\s+$/g, ""); //trim + if(self.format[format]) { // Check format is valid. + var dupFound = false; + $.each(self.formats, function(index2, value2) { // Check for duplicates + if(format === value2) { + dupFound = true; + return false; + } + }); + if(!dupFound) { + self.formats.push(format); + } + } + }); + + // Create the solutions array, with prority based on the order of the solution string + $.each(this.options.solution.toLowerCase().split(","), function(index1, value1) { + var solution = value1.replace(/^\s+|\s+$/g, ""); //trim + if(self.solution[solution]) { // Check solution is valid. + var dupFound = false; + $.each(self.solutions, function(index2, value2) { // Check for duplicates + if(solution === value2) { + dupFound = true; + return false; + } + }); + if(!dupFound) { + self.solutions.push(solution); + } + } + }); + + this.internal.instance = "jp_" + this.count; + this.instances[this.internal.instance] = this.element; + + // Check the jPlayer div has an id and create one if required. Important for Flash to know the unique id for comms. + if(!this.element.attr("id")) { + this.element.attr("id", this.options.idPrefix + "_jplayer_" + this.count); + } + + this.internal.self = $.extend({}, { + id: this.element.attr("id"), + jq: this.element + }); + this.internal.audio = $.extend({}, { + id: this.options.idPrefix + "_audio_" + this.count, + jq: undefined + }); + this.internal.video = $.extend({}, { + id: this.options.idPrefix + "_video_" + this.count, + jq: undefined + }); + this.internal.flash = $.extend({}, { + id: this.options.idPrefix + "_flash_" + this.count, + jq: undefined, + swf: this.options.swfPath + (this.options.swfPath.toLowerCase().slice(-4) !== ".swf" ? (this.options.swfPath && this.options.swfPath.slice(-1) !== "/" ? "/" : "") + "Jplayer.swf" : "") + }); + this.internal.poster = $.extend({}, { + id: this.options.idPrefix + "_poster_" + this.count, + jq: undefined + }); + + // Register listeners defined in the constructor + $.each($.jPlayer.event, function(eventName,eventType) { + if(self.options[eventName] !== undefined) { + self.element.bind(eventType + ".jPlayer", self.options[eventName]); // With .jPlayer namespace. + self.options[eventName] = undefined; // Destroy the handler pointer copy on the options. Reason, events can be added/removed in other ways so this could be obsolete and misleading. + } + }); + + // Determine if we require solutions for audio, video or both media types. + this.require.audio = false; + this.require.video = false; + $.each(this.formats, function(priority, format) { + self.require[self.format[format].media] = true; + }); + + // Now required types are known, finish the options default settings. + if(this.require.video) { + this.options = $.extend(true, {}, + this.optionsVideo, + this.options + ); + } else { + this.options = $.extend(true, {}, + this.optionsAudio, + this.options + ); + } + this._setSize(); // update status and jPlayer element size + + // Determine the status for Blocklisted options. + this.status.nativeVideoControls = this._uaBlocklist(this.options.nativeVideoControls); + this.status.noFullWindow = this._uaBlocklist(this.options.noFullWindow); + this.status.noVolume = this._uaBlocklist(this.options.noVolume); + + // Create event handlers if native fullscreen is supported + if($.jPlayer.nativeFeatures.fullscreen.api.fullscreenEnabled) { + this._fullscreenAddEventListeners(); + } + + // The native controls are only for video and are disabled when audio is also used. + this._restrictNativeVideoControls(); + + // Create the poster image. + this.htmlElement.poster = document.createElement('img'); + this.htmlElement.poster.id = this.internal.poster.id; + this.htmlElement.poster.onload = function() { // Note that this did not work on Firefox 3.6: poster.addEventListener("onload", function() {}, false); Did not investigate x-browser. + if(!self.status.video || self.status.waitForPlay) { + self.internal.poster.jq.show(); + } + }; + this.element.append(this.htmlElement.poster); + this.internal.poster.jq = $("#" + this.internal.poster.id); + this.internal.poster.jq.css({'width': this.status.width, 'height': this.status.height}); + this.internal.poster.jq.hide(); + this.internal.poster.jq.bind("click.jPlayer", function() { + self._trigger($.jPlayer.event.click); + }); + + // Generate the required media elements + this.html.audio.available = false; + if(this.require.audio) { // If a supplied format is audio + this.htmlElement.audio = document.createElement('audio'); + this.htmlElement.audio.id = this.internal.audio.id; + this.html.audio.available = !!this.htmlElement.audio.canPlayType && this._testCanPlayType(this.htmlElement.audio); // Test is for IE9 on Win Server 2008. + } + this.html.video.available = false; + if(this.require.video) { // If a supplied format is video + this.htmlElement.video = document.createElement('video'); + this.htmlElement.video.id = this.internal.video.id; + this.html.video.available = !!this.htmlElement.video.canPlayType && this._testCanPlayType(this.htmlElement.video); // Test is for IE9 on Win Server 2008. + } + + this.flash.available = this._checkForFlash(10.1); + + this.html.canPlay = {}; + this.flash.canPlay = {}; + $.each(this.formats, function(priority, format) { + self.html.canPlay[format] = self.html[self.format[format].media].available && "" !== self.htmlElement[self.format[format].media].canPlayType(self.format[format].codec); + self.flash.canPlay[format] = self.format[format].flashCanPlay && self.flash.available; + }); + this.html.desired = false; + this.flash.desired = false; + $.each(this.solutions, function(solutionPriority, solution) { + if(solutionPriority === 0) { + self[solution].desired = true; + } else { + var audioCanPlay = false; + var videoCanPlay = false; + $.each(self.formats, function(formatPriority, format) { + if(self[self.solutions[0]].canPlay[format]) { // The other solution can play + if(self.format[format].media === 'video') { + videoCanPlay = true; + } else { + audioCanPlay = true; + } + } + }); + self[solution].desired = (self.require.audio && !audioCanPlay) || (self.require.video && !videoCanPlay); + } + }); + // This is what jPlayer will support, based on solution and supplied. + this.html.support = {}; + this.flash.support = {}; + $.each(this.formats, function(priority, format) { + self.html.support[format] = self.html.canPlay[format] && self.html.desired; + self.flash.support[format] = self.flash.canPlay[format] && self.flash.desired; + }); + // If jPlayer is supporting any format in a solution, then the solution is used. + this.html.used = false; + this.flash.used = false; + $.each(this.solutions, function(solutionPriority, solution) { + $.each(self.formats, function(formatPriority, format) { + if(self[solution].support[format]) { + self[solution].used = true; + return false; + } + }); + }); + + // Init solution active state and the event gates to false. + this._resetActive(); + this._resetGate(); + + // Set up the css selectors for the control and feedback entities. + this._cssSelectorAncestor(this.options.cssSelectorAncestor); + + // If neither html nor flash are being used by this browser, then media playback is not possible. Trigger an error event. + if(!(this.html.used || this.flash.used)) { + this._error( { + type: $.jPlayer.error.NO_SOLUTION, + context: "{solution:'" + this.options.solution + "', supplied:'" + this.options.supplied + "'}", + message: $.jPlayer.errorMsg.NO_SOLUTION, + hint: $.jPlayer.errorHint.NO_SOLUTION + }); + if(this.css.jq.noSolution.length) { + this.css.jq.noSolution.show(); + } + } else { + if(this.css.jq.noSolution.length) { + this.css.jq.noSolution.hide(); + } + } + + // Add the flash solution if it is being used. + if(this.flash.used) { + var htmlObj, + flashVars = 'jQuery=' + encodeURI(this.options.noConflict) + '&id=' + encodeURI(this.internal.self.id) + '&vol=' + this.options.volume + '&muted=' + this.options.muted; + + // Code influenced by SWFObject 2.2: http://code.google.com/p/swfobject/ + // Non IE browsers have an initial Flash size of 1 by 1 otherwise the wmode affected the Flash ready event. + + if($.jPlayer.browser.msie && (Number($.jPlayer.browser.version) < 9 || $.jPlayer.browser.documentMode < 9)) { + var objStr = ''; + var paramStr = [ + '', + '', + '', + '', + '', + '' + ]; + + htmlObj = document.createElement(objStr); + for(var i=0; i < paramStr.length; i++) { + htmlObj.appendChild(document.createElement(paramStr[i])); + } + } else { + var createParam = function(el, n, v) { + var p = document.createElement("param"); + p.setAttribute("name", n); + p.setAttribute("value", v); + el.appendChild(p); + }; + + htmlObj = document.createElement("object"); + htmlObj.setAttribute("id", this.internal.flash.id); + htmlObj.setAttribute("data", this.internal.flash.swf); + htmlObj.setAttribute("type", "application/x-shockwave-flash"); + htmlObj.setAttribute("width", "1"); // Non-zero + htmlObj.setAttribute("height", "1"); // Non-zero + htmlObj.setAttribute("tabindex", "-1"); + htmlObj.setAttribute("allowFullScreen", "true"); + createParam(htmlObj, "flashvars", flashVars); + createParam(htmlObj, "allowscriptaccess", "always"); + createParam(htmlObj, "bgcolor", this.options.backgroundColor); + createParam(htmlObj, "wmode", this.options.wmode); + createParam(htmlObj, "allowFullScreen", "true"); + } + + this.element.append(htmlObj); + this.internal.flash.jq = $(htmlObj); + } + + // Add the HTML solution if being used. + if(this.html.used) { + + // The HTML Audio handlers + if(this.html.audio.available) { + this._addHtmlEventListeners(this.htmlElement.audio, this.html.audio); + this.element.append(this.htmlElement.audio); + this.internal.audio.jq = $("#" + this.internal.audio.id); + } + + // The HTML Video handlers + if(this.html.video.available) { + this._addHtmlEventListeners(this.htmlElement.video, this.html.video); + this.element.append(this.htmlElement.video); + this.internal.video.jq = $("#" + this.internal.video.id); + if(this.status.nativeVideoControls) { + this.internal.video.jq.css({'width': this.status.width, 'height': this.status.height}); + } else { + this.internal.video.jq.css({'width':'0px', 'height':'0px'}); // Using size 0x0 since a .hide() causes issues in iOS + } + this.internal.video.jq.bind("click.jPlayer", function() { + self._trigger($.jPlayer.event.click); + }); + } + } + + // Create the bridge that emulates the HTML Media element on the jPlayer DIV + if( this.options.emulateHtml ) { + this._emulateHtmlBridge(); + } + + if(this.html.used && !this.flash.used) { // If only HTML, then emulate flash ready() call after 100ms. + setTimeout( function() { + self.internal.ready = true; + self.version.flash = "n/a"; + self._trigger($.jPlayer.event.repeat); // Trigger the repeat event so its handler can initialize itself with the loop option. + self._trigger($.jPlayer.event.ready); + }, 100); + } + + // Initialize the interface components with the options. + this._updateNativeVideoControls(); // Must do this first, otherwise there is a bizarre bug in iOS 4.3.2, where the native controls are not shown. Fails in iOS if called after _updateButtons() below. Works if called later in setMedia too, so it odd. + this._updateInterface(); + this._updateButtons(false); + this._updateAutohide(); + this._updateVolume(this.options.volume); + this._updateMute(this.options.muted); + if(this.css.jq.videoPlay.length) { + this.css.jq.videoPlay.hide(); + } + + $.jPlayer.prototype.count++; // Change static variable via prototype. + }, + destroy: function() { + // MJP: The background change remains. Would need to store the original to restore it correctly. + // MJP: The jPlayer element's size change remains. + + // Clear the media to reset the GUI and stop any downloads. Streams on some browsers had persited. (Chrome) + this.clearMedia(); + // Remove the size/sizeFull cssClass from the cssSelectorAncestor + this._removeUiClass(); + // Remove the times from the GUI + if(this.css.jq.currentTime.length) { + this.css.jq.currentTime.text(""); + } + if(this.css.jq.duration.length) { + this.css.jq.duration.text(""); + } + // Remove any bindings from the interface controls. + $.each(this.css.jq, function(fn, jq) { + // Check selector is valid before trying to execute method. + if(jq.length) { + jq.unbind(".jPlayer"); + } + }); + // Remove the click handlers for $.jPlayer.event.click + this.internal.poster.jq.unbind(".jPlayer"); + if(this.internal.video.jq) { + this.internal.video.jq.unbind(".jPlayer"); + } + // Remove the fullscreen event handlers + this._fullscreenRemoveEventListeners(); + // Destroy the HTML bridge. + if(this.options.emulateHtml) { + this._destroyHtmlBridge(); + } + this.element.removeData("jPlayer"); // Remove jPlayer data + this.element.unbind(".jPlayer"); // Remove all event handlers created by the jPlayer constructor + this.element.empty(); // Remove the inserted child elements + + delete this.instances[this.internal.instance]; // Clear the instance on the static instance object + }, + enable: function() { // Plan to implement + // options.disabled = false + }, + disable: function () { // Plan to implement + // options.disabled = true + }, + _testCanPlayType: function(elem) { + // IE9 on Win Server 2008 did not implement canPlayType(), but it has the property. + try { + elem.canPlayType(this.format.mp3.codec); // The type is irrelevant. + return true; + } catch(err) { + return false; + } + }, + _uaBlocklist: function(list) { + // list : object with properties that are all regular expressions. Property names are irrelevant. + // Returns true if the user agent is matched in list. + var ua = navigator.userAgent.toLowerCase(), + block = false; + + $.each(list, function(p, re) { + if(re && re.test(ua)) { + block = true; + return false; // exit $.each. + } + }); + return block; + }, + _restrictNativeVideoControls: function() { + // Fallback to noFullWindow when nativeVideoControls is true and audio media is being used. Affects when both media types are used. + if(this.require.audio) { + if(this.status.nativeVideoControls) { + this.status.nativeVideoControls = false; + this.status.noFullWindow = true; + } + } + }, + _updateNativeVideoControls: function() { + if(this.html.video.available && this.html.used) { + // Turn the HTML Video controls on/off + this.htmlElement.video.controls = this.status.nativeVideoControls; + // Show/hide the jPlayer GUI. + this._updateAutohide(); + // For when option changed. The poster image is not updated, as it is dealt with in setMedia(). Acceptable degradation since seriously doubt these options will change on the fly. Can again review later. + if(this.status.nativeVideoControls && this.require.video) { + this.internal.poster.jq.hide(); + this.internal.video.jq.css({'width': this.status.width, 'height': this.status.height}); + } else if(this.status.waitForPlay && this.status.video) { + this.internal.poster.jq.show(); + this.internal.video.jq.css({'width': '0px', 'height': '0px'}); + } + } + }, + _addHtmlEventListeners: function(mediaElement, entity) { + var self = this; + mediaElement.preload = this.options.preload; + mediaElement.muted = this.options.muted; + mediaElement.volume = this.options.volume; + + // Create the event listeners + // Only want the active entity to affect jPlayer and bubble events. + // Using entity.gate so that object is referenced and gate property always current + + mediaElement.addEventListener("progress", function() { + if(entity.gate) { + if(self.internal.cmdsIgnored && this.readyState > 0) { // Detect iOS executed the command + self.internal.cmdsIgnored = false; + } + self._getHtmlStatus(mediaElement); + self._updateInterface(); + self._trigger($.jPlayer.event.progress); + } + }, false); + mediaElement.addEventListener("timeupdate", function() { + if(entity.gate) { + self._getHtmlStatus(mediaElement); + self._updateInterface(); + self._trigger($.jPlayer.event.timeupdate); + } + }, false); + mediaElement.addEventListener("durationchange", function() { + if(entity.gate) { + self._getHtmlStatus(mediaElement); + self._updateInterface(); + self._trigger($.jPlayer.event.durationchange); + } + }, false); + mediaElement.addEventListener("play", function() { + if(entity.gate) { + self._updateButtons(true); + self._html_checkWaitForPlay(); // So the native controls update this variable and puts the hidden interface in the correct state. Affects toggling native controls. + self._trigger($.jPlayer.event.play); + } + }, false); + mediaElement.addEventListener("playing", function() { + if(entity.gate) { + self._updateButtons(true); + self._seeked(); + self._trigger($.jPlayer.event.playing); + } + }, false); + mediaElement.addEventListener("pause", function() { + if(entity.gate) { + self._updateButtons(false); + self._trigger($.jPlayer.event.pause); + } + }, false); + mediaElement.addEventListener("waiting", function() { + if(entity.gate) { + self._seeking(); + self._trigger($.jPlayer.event.waiting); + } + }, false); + mediaElement.addEventListener("seeking", function() { + if(entity.gate) { + self._seeking(); + self._trigger($.jPlayer.event.seeking); + } + }, false); + mediaElement.addEventListener("seeked", function() { + if(entity.gate) { + self._seeked(); + self._trigger($.jPlayer.event.seeked); + } + }, false); + mediaElement.addEventListener("volumechange", function() { + if(entity.gate) { + // Read the values back from the element as the Blackberry PlayBook shares the volume with the physical buttons master volume control. + // However, when tested 6th July 2011, those buttons do not generate an event. The physical play/pause button does though. + self.options.volume = mediaElement.volume; + self.options.muted = mediaElement.muted; + self._updateMute(); + self._updateVolume(); + self._trigger($.jPlayer.event.volumechange); + } + }, false); + mediaElement.addEventListener("suspend", function() { // Seems to be the only way of capturing that the iOS4 browser did not actually play the media from the page code. ie., It needs a user gesture. + if(entity.gate) { + self._seeked(); + self._trigger($.jPlayer.event.suspend); + } + }, false); + mediaElement.addEventListener("ended", function() { + if(entity.gate) { + // Order of the next few commands are important. Change the time and then pause. + // Solves a bug in Firefox, where issuing pause 1st causes the media to play from the start. ie., The pause is ignored. + if(!$.jPlayer.browser.webkit) { // Chrome crashes if you do this in conjunction with a setMedia command in an ended event handler. ie., The playlist demo. + self.htmlElement.media.currentTime = 0; // Safari does not care about this command. ie., It works with or without this line. (Both Safari and Chrome are Webkit.) + } + self.htmlElement.media.pause(); // Pause otherwise a click on the progress bar will play from that point, when it shouldn't, since it stopped playback. + self._updateButtons(false); + self._getHtmlStatus(mediaElement, true); // With override true. Otherwise Chrome leaves progress at full. + self._updateInterface(); + self._trigger($.jPlayer.event.ended); + } + }, false); + mediaElement.addEventListener("error", function() { + if(entity.gate) { + self._updateButtons(false); + self._seeked(); + if(self.status.srcSet) { // Deals with case of clearMedia() causing an error event. + clearTimeout(self.internal.htmlDlyCmdId); // Clears any delayed commands used in the HTML solution. + self.status.waitForLoad = true; // Allows the load operation to try again. + self.status.waitForPlay = true; // Reset since a play was captured. + if(self.status.video && !self.status.nativeVideoControls) { + self.internal.video.jq.css({'width':'0px', 'height':'0px'}); + } + if(self._validString(self.status.media.poster) && !self.status.nativeVideoControls) { + self.internal.poster.jq.show(); + } + if(self.css.jq.videoPlay.length) { + self.css.jq.videoPlay.show(); + } + self._error( { + type: $.jPlayer.error.URL, + context: self.status.src, // this.src shows absolute urls. Want context to show the url given. + message: $.jPlayer.errorMsg.URL, + hint: $.jPlayer.errorHint.URL + }); + } + } + }, false); + // Create all the other event listeners that bubble up to a jPlayer event from html, without being used by jPlayer. + $.each($.jPlayer.htmlEvent, function(i, eventType) { + mediaElement.addEventListener(this, function() { + if(entity.gate) { + self._trigger($.jPlayer.event[eventType]); + } + }, false); + }); + }, + _getHtmlStatus: function(media, override) { + var ct = 0, cpa = 0, sp = 0, cpr = 0; + + // Fixes the duration bug in iOS, where the durationchange event occurs when media.duration is not always correct. + // Fixes the initial duration bug in BB OS7, where the media.duration is infinity and displays as NaN:NaN due to Date() using inifity. + if(isFinite(media.duration)) { + this.status.duration = media.duration; + } + + ct = media.currentTime; + cpa = (this.status.duration > 0) ? 100 * ct / this.status.duration : 0; + if((typeof media.seekable === "object") && (media.seekable.length > 0)) { + sp = (this.status.duration > 0) ? 100 * media.seekable.end(media.seekable.length-1) / this.status.duration : 100; + cpr = (this.status.duration > 0) ? 100 * media.currentTime / media.seekable.end(media.seekable.length-1) : 0; // Duration conditional for iOS duration bug. ie., seekable.end is a NaN in that case. + } else { + sp = 100; + cpr = cpa; + } + + if(override) { + ct = 0; + cpr = 0; + cpa = 0; + } + + this.status.seekPercent = sp; + this.status.currentPercentRelative = cpr; + this.status.currentPercentAbsolute = cpa; + this.status.currentTime = ct; + + this.status.readyState = media.readyState; + this.status.networkState = media.networkState; + this.status.playbackRate = media.playbackRate; + this.status.ended = media.ended; + }, + _resetStatus: function() { + this.status = $.extend({}, this.status, $.jPlayer.prototype.status); // Maintains the status properties that persist through a reset. + }, + _trigger: function(eventType, error, warning) { // eventType always valid as called using $.jPlayer.event.eventType + var event = $.Event(eventType); + event.jPlayer = {}; + event.jPlayer.version = $.extend({}, this.version); + event.jPlayer.options = $.extend(true, {}, this.options); // Deep copy + event.jPlayer.status = $.extend(true, {}, this.status); // Deep copy + event.jPlayer.html = $.extend(true, {}, this.html); // Deep copy + event.jPlayer.flash = $.extend(true, {}, this.flash); // Deep copy + if(error) { + event.jPlayer.error = $.extend({}, error); + } + if(warning) { + event.jPlayer.warning = $.extend({}, warning); + } + this.element.trigger(event); + }, + jPlayerFlashEvent: function(eventType, status) { // Called from Flash + if(eventType === $.jPlayer.event.ready) { + if(!this.internal.ready) { + this.internal.ready = true; + this.internal.flash.jq.css({'width':'0px', 'height':'0px'}); // Once Flash generates the ready event, minimise to zero as it is not affected by wmode anymore. + + this.version.flash = status.version; + if(this.version.needFlash !== this.version.flash) { + this._error( { + type: $.jPlayer.error.VERSION, + context: this.version.flash, + message: $.jPlayer.errorMsg.VERSION + this.version.flash, + hint: $.jPlayer.errorHint.VERSION + }); + } + this._trigger($.jPlayer.event.repeat); // Trigger the repeat event so its handler can initialize itself with the loop option. + this._trigger(eventType); + } else { + // This condition occurs if the Flash is hidden and then shown again. + // Firefox also reloads the Flash if the CSS position changes. position:fixed is used for full screen. + + // Only do this if the Flash is the solution being used at the moment. Affects Media players where both solution may be being used. + if(this.flash.gate) { + + // Send the current status to the Flash now that it is ready (available) again. + if(this.status.srcSet) { + + // Need to read original status before issuing the setMedia command. + var currentTime = this.status.currentTime, + paused = this.status.paused; + + this.setMedia(this.status.media); + if(currentTime > 0) { + if(paused) { + this.pause(currentTime); + } else { + this.play(currentTime); + } + } + } + this._trigger($.jPlayer.event.flashreset); + } + } + } + if(this.flash.gate) { + switch(eventType) { + case $.jPlayer.event.progress: + this._getFlashStatus(status); + this._updateInterface(); + this._trigger(eventType); + break; + case $.jPlayer.event.timeupdate: + this._getFlashStatus(status); + this._updateInterface(); + this._trigger(eventType); + break; + case $.jPlayer.event.play: + this._seeked(); + this._updateButtons(true); + this._trigger(eventType); + break; + case $.jPlayer.event.pause: + this._updateButtons(false); + this._trigger(eventType); + break; + case $.jPlayer.event.ended: + this._updateButtons(false); + this._trigger(eventType); + break; + case $.jPlayer.event.click: + this._trigger(eventType); // This could be dealt with by the default + break; + case $.jPlayer.event.error: + this.status.waitForLoad = true; // Allows the load operation to try again. + this.status.waitForPlay = true; // Reset since a play was captured. + if(this.status.video) { + this.internal.flash.jq.css({'width':'0px', 'height':'0px'}); + } + if(this._validString(this.status.media.poster)) { + this.internal.poster.jq.show(); + } + if(this.css.jq.videoPlay.length && this.status.video) { + this.css.jq.videoPlay.show(); + } + if(this.status.video) { // Set up for another try. Execute before error event. + this._flash_setVideo(this.status.media); + } else { + this._flash_setAudio(this.status.media); + } + this._updateButtons(false); + this._error( { + type: $.jPlayer.error.URL, + context:status.src, + message: $.jPlayer.errorMsg.URL, + hint: $.jPlayer.errorHint.URL + }); + break; + case $.jPlayer.event.seeking: + this._seeking(); + this._trigger(eventType); + break; + case $.jPlayer.event.seeked: + this._seeked(); + this._trigger(eventType); + break; + case $.jPlayer.event.ready: + // The ready event is handled outside the switch statement. + // Captured here otherwise 2 ready events would be generated if the ready event handler used setMedia. + break; + default: + this._trigger(eventType); + } + } + return false; + }, + _getFlashStatus: function(status) { + this.status.seekPercent = status.seekPercent; + this.status.currentPercentRelative = status.currentPercentRelative; + this.status.currentPercentAbsolute = status.currentPercentAbsolute; + this.status.currentTime = status.currentTime; + this.status.duration = status.duration; + + // The Flash does not generate this information in this release + this.status.readyState = 4; // status.readyState; + this.status.networkState = 0; // status.networkState; + this.status.playbackRate = 1; // status.playbackRate; + this.status.ended = false; // status.ended; + }, + _updateButtons: function(playing) { + if(playing !== undefined) { + this.status.paused = !playing; + if(this.css.jq.play.length && this.css.jq.pause.length) { + if(playing) { + this.css.jq.play.hide(); + this.css.jq.pause.show(); + this.css.jq.videoPlay.hide(); // Original for NetCommons + } else { + this.css.jq.play.show(); + this.css.jq.pause.hide(); + this.css.jq.videoPlay.show(); // Original for NetCommons + } + } + } + if(this.css.jq.restoreScreen.length && this.css.jq.fullScreen.length) { + if(this.status.noFullWindow) { + this.css.jq.fullScreen.hide(); + this.css.jq.restoreScreen.hide(); + } else if(this.options.fullWindow) { + this.css.jq.fullScreen.hide(); + this.css.jq.restoreScreen.show(); + } else { + this.css.jq.fullScreen.show(); + this.css.jq.restoreScreen.hide(); + } + } + if(this.css.jq.repeat.length && this.css.jq.repeatOff.length) { + if(this.options.loop) { + this.css.jq.repeat.hide(); + this.css.jq.repeatOff.show(); + } else { + this.css.jq.repeat.show(); + this.css.jq.repeatOff.hide(); + } + } + }, + _updateInterface: function() { + if(this.css.jq.seekBar.length) { + this.css.jq.seekBar.width(this.status.seekPercent+"%"); + } + if(this.css.jq.playBar.length) { + this.css.jq.playBar.width(this.status.currentPercentRelative+"%"); + } + if(this.css.jq.currentTime.length) { + this.css.jq.currentTime.text($.jPlayer.convertTime(this.status.currentTime)); + } + if(this.css.jq.duration.length) { + this.css.jq.duration.text($.jPlayer.convertTime(this.status.duration)); + } + }, + _seeking: function() { + if(this.css.jq.seekBar.length) { + this.css.jq.seekBar.addClass("jp-seeking-bg"); + } + }, + _seeked: function() { + if(this.css.jq.seekBar.length) { + this.css.jq.seekBar.removeClass("jp-seeking-bg"); + } + }, + _resetGate: function() { + this.html.audio.gate = false; + this.html.video.gate = false; + this.flash.gate = false; + }, + _resetActive: function() { + this.html.active = false; + this.flash.active = false; + }, + setMedia: function(media) { + + /* media[format] = String: URL of format. Must contain all of the supplied option's video or audio formats. + * media.poster = String: Video poster URL. + * media.subtitles = String: * NOT IMPLEMENTED * URL of subtitles SRT file + * media.chapters = String: * NOT IMPLEMENTED * URL of chapters SRT file + * media.stream = Boolean: * NOT IMPLEMENTED * Designating actual media streams. ie., "false/undefined" for files. Plan to refresh the flash every so often. + */ + + var self = this, + supported = false, + posterChanged = this.status.media.poster !== media.poster; // Compare before reset. Important for OSX Safari as this.htmlElement.poster.src is absolute, even if original poster URL was relative. + + this._resetMedia(); + this._resetGate(); + this._resetActive(); + + $.each(this.formats, function(formatPriority, format) { + var isVideo = self.format[format].media === 'video'; + $.each(self.solutions, function(solutionPriority, solution) { + if(self[solution].support[format] && self._validString(media[format])) { // Format supported in solution and url given for format. + var isHtml = solution === 'html'; + + if(isVideo) { + if(isHtml) { + self.html.video.gate = true; + self._html_setVideo(media); + self.html.active = true; + } else { + self.flash.gate = true; + self._flash_setVideo(media); + self.flash.active = true; + } + if(self.css.jq.videoPlay.length) { + self.css.jq.videoPlay.show(); + } + self.status.video = true; + } else { + if(isHtml) { + self.html.audio.gate = true; + self._html_setAudio(media); + self.html.active = true; + } else { + self.flash.gate = true; + self._flash_setAudio(media); + self.flash.active = true; + } + if(self.css.jq.videoPlay.length) { + self.css.jq.videoPlay.hide(); + } + self.status.video = false; + } + + supported = true; + return false; // Exit $.each + } + }); + if(supported) { + return false; // Exit $.each + } + }); + + if(supported) { + if(!(this.status.nativeVideoControls && this.html.video.gate)) { + // Set poster IMG if native video controls are not being used + // Note: With IE the IMG onload event occurs immediately when cached. + // Note: Poster hidden by default in _resetMedia() + if(this._validString(media.poster)) { + if(posterChanged) { // Since some browsers do not generate img onload event. + this.htmlElement.poster.src = media.poster; + } else { + this.internal.poster.jq.show(); + } + } + } + this.status.srcSet = true; + this.status.media = $.extend({}, media); + this._updateButtons(false); + this._updateInterface(); + } else { // jPlayer cannot support any formats provided in this browser + // Send an error event + this._error( { + type: $.jPlayer.error.NO_SUPPORT, + context: "{supplied:'" + this.options.supplied + "'}", + message: $.jPlayer.errorMsg.NO_SUPPORT, + hint: $.jPlayer.errorHint.NO_SUPPORT + }); + } + }, + _resetMedia: function() { + this._resetStatus(); + this._updateButtons(false); + this._updateInterface(); + this._seeked(); + this.internal.poster.jq.hide(); + + clearTimeout(this.internal.htmlDlyCmdId); + + if(this.html.active) { + this._html_resetMedia(); + } else if(this.flash.active) { + this._flash_resetMedia(); + } + }, + clearMedia: function() { + this._resetMedia(); + + if(this.html.active) { + this._html_clearMedia(); + } else if(this.flash.active) { + this._flash_clearMedia(); + } + + this._resetGate(); + this._resetActive(); + }, + load: function() { + if(this.status.srcSet) { + if(this.html.active) { + this._html_load(); + } else if(this.flash.active) { + this._flash_load(); + } + } else { + this._urlNotSetError("load"); + } + }, + play: function(time) { + time = (typeof time === "number") ? time : NaN; // Remove jQuery event from click handler + if(this.status.srcSet) { + if(this.html.active) { + this._html_play(time); + } else if(this.flash.active) { + this._flash_play(time); + } + } else { + this._urlNotSetError("play"); + } + }, + videoPlay: function() { // Handles clicks on the play button over the video poster + this.play(); + }, + pause: function(time) { + time = (typeof time === "number") ? time : NaN; // Remove jQuery event from click handler + if(this.status.srcSet) { + if(this.html.active) { + this._html_pause(time); + } else if(this.flash.active) { + this._flash_pause(time); + } + } else { + this._urlNotSetError("pause"); + } + }, + pauseOthers: function() { + var self = this; + $.each(this.instances, function(i, element) { + if(self.element !== element) { // Do not this instance. + if(element.data("jPlayer").status.srcSet) { // Check that media is set otherwise would cause error event. + element.jPlayer("pause"); + } + } + }); + }, + stop: function() { + if(this.status.srcSet) { + if(this.html.active) { + this._html_pause(0); + } else if(this.flash.active) { + this._flash_pause(0); + } + } else { + this._urlNotSetError("stop"); + } + }, + playHead: function(p) { + p = this._limitValue(p, 0, 100); + if(this.status.srcSet) { + if(this.html.active) { + this._html_playHead(p); + } else if(this.flash.active) { + this._flash_playHead(p); + } + } else { + this._urlNotSetError("playHead"); + } + }, + _muted: function(muted) { + this.options.muted = muted; + if(this.html.used) { + this._html_mute(muted); + } + if(this.flash.used) { + this._flash_mute(muted); + } + + // The HTML solution generates this event from the media element itself. + if(!this.html.video.gate && !this.html.audio.gate) { + this._updateMute(muted); + this._updateVolume(this.options.volume); + this._trigger($.jPlayer.event.volumechange); + } + }, + mute: function(mute) { // mute is either: undefined (true), an event object (true) or a boolean (muted). + mute = mute === undefined ? true : !!mute; + this._muted(mute); + }, + unmute: function(unmute) { // unmute is either: undefined (true), an event object (true) or a boolean (!muted). + unmute = unmute === undefined ? true : !!unmute; + this._muted(!unmute); + }, + _updateMute: function(mute) { + if(mute === undefined) { + mute = this.options.muted; + } + if(this.css.jq.mute.length && this.css.jq.unmute.length) { + if(this.status.noVolume) { + this.css.jq.mute.hide(); + this.css.jq.unmute.hide(); + } else if(mute) { + this.css.jq.mute.hide(); + this.css.jq.unmute.show(); + } else { + this.css.jq.mute.show(); + this.css.jq.unmute.hide(); + } + } + }, + volume: function(v) { + v = this._limitValue(v, 0, 1); + this.options.volume = v; + + if(this.html.used) { + this._html_volume(v); + } + if(this.flash.used) { + this._flash_volume(v); + } + + // The HTML solution generates this event from the media element itself. + if(!this.html.video.gate && !this.html.audio.gate) { + this._updateVolume(v); + this._trigger($.jPlayer.event.volumechange); + } + }, + volumeBar: function(e) { // Handles clicks on the volumeBar + if(this.css.jq.volumeBar.length) { + var offset = this.css.jq.volumeBar.offset(), + x = e.pageX - offset.left, + w = this.css.jq.volumeBar.width(), + y = this.css.jq.volumeBar.height() - e.pageY + offset.top, + h = this.css.jq.volumeBar.height(); + + if(this.options.verticalVolume) { + this.volume(y/h); + } else { + this.volume(x/w); + } + } + if(this.options.muted) { + this._muted(false); + } + }, + volumeBarValue: function(e) { // Handles clicks on the volumeBarValue + this.volumeBar(e); + }, + _updateVolume: function(v) { + if(v === undefined) { + v = this.options.volume; + } + v = this.options.muted ? 0 : v; + + if(this.status.noVolume) { + if(this.css.jq.volumeBar.length) { + this.css.jq.volumeBar.hide(); + } + if(this.css.jq.volumeBarValue.length) { + this.css.jq.volumeBarValue.hide(); + } + if(this.css.jq.volumeMax.length) { + this.css.jq.volumeMax.hide(); + } + } else { + if(this.css.jq.volumeBar.length) { + this.css.jq.volumeBar.show(); + } + if(this.css.jq.volumeBarValue.length) { + this.css.jq.volumeBarValue.show(); + this.css.jq.volumeBarValue[this.options.verticalVolume ? "height" : "width"]((v*100)+"%"); + } + if(this.css.jq.volumeMax.length) { + this.css.jq.volumeMax.show(); + } + } + }, + volumeMax: function() { // Handles clicks on the volume max + this.volume(1); + if(this.options.muted) { + this._muted(false); + } + }, + _cssSelectorAncestor: function(ancestor) { + var self = this; + this.options.cssSelectorAncestor = ancestor; + this._removeUiClass(); + this.ancestorJq = ancestor ? $(ancestor) : []; // Would use $() instead of [], but it is only 1.4+ + if(ancestor && this.ancestorJq.length !== 1) { // So empty strings do not generate the warning. + this._warning( { + type: $.jPlayer.warning.CSS_SELECTOR_COUNT, + context: ancestor, + message: $.jPlayer.warningMsg.CSS_SELECTOR_COUNT + this.ancestorJq.length + " found for cssSelectorAncestor.", + hint: $.jPlayer.warningHint.CSS_SELECTOR_COUNT + }); + } + this._addUiClass(); + $.each(this.options.cssSelector, function(fn, cssSel) { + self._cssSelector(fn, cssSel); + }); + }, + _cssSelector: function(fn, cssSel) { + var self = this; + if(typeof cssSel === 'string') { + if($.jPlayer.prototype.options.cssSelector[fn]) { + if(this.css.jq[fn] && this.css.jq[fn].length) { + this.css.jq[fn].unbind(".jPlayer"); + } + this.options.cssSelector[fn] = cssSel; + this.css.cs[fn] = this.options.cssSelectorAncestor + " " + cssSel; + + if(cssSel) { // Checks for empty string + this.css.jq[fn] = $(this.css.cs[fn]); + } else { + this.css.jq[fn] = []; // To comply with the css.jq[fn].length check before its use. As of jQuery 1.4 could have used $() for an empty set. + } + + if(this.css.jq[fn].length) { + var handler = function(e) { + self[fn](e); + $(this).blur(); + return false; + }; + this.css.jq[fn].bind("click.jPlayer", handler); // Using jPlayer namespace + } + + if(cssSel && this.css.jq[fn].length !== 1) { // So empty strings do not generate the warning. ie., they just remove the old one. + this._warning( { + type: $.jPlayer.warning.CSS_SELECTOR_COUNT, + context: this.css.cs[fn], + message: $.jPlayer.warningMsg.CSS_SELECTOR_COUNT + this.css.jq[fn].length + " found for " + fn + " method.", + hint: $.jPlayer.warningHint.CSS_SELECTOR_COUNT + }); + } + } else { + this._warning( { + type: $.jPlayer.warning.CSS_SELECTOR_METHOD, + context: fn, + message: $.jPlayer.warningMsg.CSS_SELECTOR_METHOD, + hint: $.jPlayer.warningHint.CSS_SELECTOR_METHOD + }); + } + } else { + this._warning( { + type: $.jPlayer.warning.CSS_SELECTOR_STRING, + context: cssSel, + message: $.jPlayer.warningMsg.CSS_SELECTOR_STRING, + hint: $.jPlayer.warningHint.CSS_SELECTOR_STRING + }); + } + }, + seekBar: function(e) { // Handles clicks on the seekBar + if(this.css.jq.seekBar) { + var offset = this.css.jq.seekBar.offset(); + var x = e.pageX - offset.left; + var w = this.css.jq.seekBar.width(); + var p = 100*x/w; + this.playHead(p); + } + }, + playBar: function(e) { // Handles clicks on the playBar + this.seekBar(e); + }, + repeat: function() { // Handle clicks on the repeat button + this._loop(true); + }, + repeatOff: function() { // Handle clicks on the repeatOff button + this._loop(false); + }, + _loop: function(loop) { + if(this.options.loop !== loop) { + this.options.loop = loop; + this._updateButtons(); + this._trigger($.jPlayer.event.repeat); + } + }, + + // Plan to review the cssSelector method to cope with missing associated functions accordingly. + + currentTime: function() { // Handles clicks on the text + // Added to avoid errors using cssSelector system for the text + }, + duration: function() { // Handles clicks on the text + // Added to avoid errors using cssSelector system for the text + }, + gui: function() { // Handles clicks on the gui + // Added to avoid errors using cssSelector system for the gui + }, + noSolution: function() { // Handles clicks on the error message + // Added to avoid errors using cssSelector system for no-solution + }, + + // Options code adapted from ui.widget.js (1.8.7). Made changes so the key can use dot notation. To match previous getData solution in jPlayer 1. + option: function(key, value) { + var options = key; + + // Enables use: options(). Returns a copy of options object + if ( arguments.length === 0 ) { + return $.extend( true, {}, this.options ); + } + + if(typeof key === "string") { + var keys = key.split("."); + + // Enables use: options("someOption") Returns a copy of the option. Supports dot notation. + if(value === undefined) { + + var opt = $.extend(true, {}, this.options); + for(var i = 0; i < keys.length; i++) { + if(opt[keys[i]] !== undefined) { + opt = opt[keys[i]]; + } else { + this._warning( { + type: $.jPlayer.warning.OPTION_KEY, + context: key, + message: $.jPlayer.warningMsg.OPTION_KEY, + hint: $.jPlayer.warningHint.OPTION_KEY + }); + return undefined; + } + } + return opt; + } + + // Enables use: options("someOptionObject", someObject}). Creates: {someOptionObject:someObject} + // Enables use: options("someOption", someValue). Creates: {someOption:someValue} + // Enables use: options("someOptionObject.someOption", someValue). Creates: {someOptionObject:{someOption:someValue}} + + options = {}; + var opts = options; + + for(var j = 0; j < keys.length; j++) { + if(j < keys.length - 1) { + opts[keys[j]] = {}; + opts = opts[keys[j]]; + } else { + opts[keys[j]] = value; + } + } + } + + // Otherwise enables use: options(optionObject). Uses original object (the key) + + this._setOptions(options); + + return this; + }, + _setOptions: function(options) { + var self = this; + $.each(options, function(key, value) { // This supports the 2 level depth that the options of jPlayer has. Would review if we ever need more depth. + self._setOption(key, value); + }); + + return this; + }, + _setOption: function(key, value) { + var self = this; + + // The ability to set options is limited at this time. + + switch(key) { + case "volume" : + this.volume(value); + break; + case "muted" : + this._muted(value); + break; + case "cssSelectorAncestor" : + this._cssSelectorAncestor(value); // Set and refresh all associations for the new ancestor. + break; + case "cssSelector" : + $.each(value, function(fn, cssSel) { + self._cssSelector(fn, cssSel); // NB: The option is set inside this function, after further validity checks. + }); + break; + case "fullScreen" : + if(this.options[key] !== value) { // if changed + var wkv = $.jPlayer.nativeFeatures.fullscreen.used.webkitVideo; + if(!wkv || wkv && !this.status.waitForPlay) { + if(!wkv) { // No sensible way to unset option on these devices. + this.options[key] = value; + } + if(value) { + this._requestFullscreen(); + } else { + this._exitFullscreen(); + } + if(!wkv) { + this._setOption("fullWindow", value); + } + } + } + break; + case "fullWindow" : + if(this.options[key] !== value) { // if changed + this._removeUiClass(); + this.options[key] = value; + this._refreshSize(); + } + break; + case "size" : + if(!this.options.fullWindow && this.options[key].cssClass !== value.cssClass) { + this._removeUiClass(); + } + this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed. + this._refreshSize(); + break; + case "sizeFull" : + if(this.options.fullWindow && this.options[key].cssClass !== value.cssClass) { + this._removeUiClass(); + } + this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed. + this._refreshSize(); + break; + case "autohide" : + this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed. + this._updateAutohide(); + break; + case "loop" : + this._loop(value); + break; + case "nativeVideoControls" : + this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed. + this.status.nativeVideoControls = this._uaBlocklist(this.options.nativeVideoControls); + this._restrictNativeVideoControls(); + this._updateNativeVideoControls(); + break; + case "noFullWindow" : + this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed. + this.status.nativeVideoControls = this._uaBlocklist(this.options.nativeVideoControls); // Need to check again as noFullWindow can depend on this flag and the restrict() can override it. + this.status.noFullWindow = this._uaBlocklist(this.options.noFullWindow); + this._restrictNativeVideoControls(); + this._updateButtons(); + break; + case "noVolume" : + this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed. + this.status.noVolume = this._uaBlocklist(this.options.noVolume); + this._updateVolume(); + this._updateMute(); + break; + case "emulateHtml" : + if(this.options[key] !== value) { // To avoid multiple event handlers being created, if true already. + this.options[key] = value; + if(value) { + this._emulateHtmlBridge(); + } else { + this._destroyHtmlBridge(); + } + } + break; + } + + return this; + }, + // End of: (Options code adapted from ui.widget.js) + + _refreshSize: function() { + this._setSize(); // update status and jPlayer element size + this._addUiClass(); // update the ui class + this._updateSize(); // update internal sizes + this._updateButtons(); + this._updateAutohide(); + this._trigger($.jPlayer.event.resize); + }, + _setSize: function() { + // Determine the current size from the options + if(this.options.fullWindow) { + this.status.width = this.options.sizeFull.width; + this.status.height = this.options.sizeFull.height; + this.status.cssClass = this.options.sizeFull.cssClass; + } else { + this.status.width = this.options.size.width; + this.status.height = this.options.size.height; + this.status.cssClass = this.options.size.cssClass; + } + + // Set the size of the jPlayer area. + this.element.css({'width': this.status.width, 'height': this.status.height}); + }, + _addUiClass: function() { + if(this.ancestorJq.length) { + this.ancestorJq.addClass(this.status.cssClass); + } + }, + _removeUiClass: function() { + if(this.ancestorJq.length) { + this.ancestorJq.removeClass(this.status.cssClass); + } + }, + _updateSize: function() { + // The poster uses show/hide so can simply resize it. + this.internal.poster.jq.css({'width': this.status.width, 'height': this.status.height}); + + // Video html or flash resized if necessary at this time, or if native video controls being used. + if(!this.status.waitForPlay && this.html.active && this.status.video || this.html.video.available && this.html.used && this.status.nativeVideoControls) { + this.internal.video.jq.css({'width': this.status.width, 'height': this.status.height}); + } + else if(!this.status.waitForPlay && this.flash.active && this.status.video) { + this.internal.flash.jq.css({'width': this.status.width, 'height': this.status.height}); + } + }, + _updateAutohide: function() { + var self = this, + event = "mousemove.jPlayer", + namespace = ".jPlayerAutohide", + eventType = event + namespace, + handler = function() { + self.css.jq.gui.fadeIn(self.options.autohide.fadeIn, function() { + clearTimeout(self.internal.autohideId); + self.internal.autohideId = setTimeout( function() { + self.css.jq.gui.fadeOut(self.options.autohide.fadeOut); + }, self.options.autohide.hold); + }); + }; + + if(this.css.jq.gui.length) { + + // End animations first so that its callback is executed now. + // Otherwise an in progress fadeIn animation still has the callback to fadeOut again. + this.css.jq.gui.stop(true, true); + + // Removes the fadeOut operation from the fadeIn callback. + clearTimeout(this.internal.autohideId); + + this.element.unbind(namespace); + this.css.jq.gui.unbind(namespace); + + if(!this.status.nativeVideoControls) { + if(this.options.fullWindow && this.options.autohide.full || !this.options.fullWindow && this.options.autohide.restored) { + this.element.bind(eventType, handler); + this.css.jq.gui.bind(eventType, handler); + this.css.jq.gui.hide(); + } else { + this.css.jq.gui.show(); + } + } else { + this.css.jq.gui.hide(); + } + } + }, + fullScreen: function() { + this._setOption("fullScreen", true); + }, + restoreScreen: function() { + this._setOption("fullScreen", false); + }, + _fullscreenAddEventListeners: function() { + var self = this, + fs = $.jPlayer.nativeFeatures.fullscreen; + + if(fs.api.fullscreenEnabled) { + if(fs.event.fullscreenchange) { + // Create the event handler function and store it for removal. + if(typeof this.internal.fullscreenchangeHandler !== 'function') { + this.internal.fullscreenchangeHandler = function() { + self._fullscreenchange(); + }; + } + document.addEventListener(fs.event.fullscreenchange, this.internal.fullscreenchangeHandler, false); + } + // No point creating handler for fullscreenerror. + // Either logic avoids fullscreen occurring (w3c/moz), or their is no event on the browser (webkit). + } + }, + _fullscreenRemoveEventListeners: function() { + var fs = $.jPlayer.nativeFeatures.fullscreen; + if(this.internal.fullscreenchangeHandler) { + document.addEventListener(fs.event.fullscreenchange, this.internal.fullscreenchangeHandler, false); + } + }, + _fullscreenchange: function() { + // If nothing is fullscreen, then we cannot be in fullscreen mode. + if(this.options.fullScreen && !$.jPlayer.nativeFeatures.fullscreen.api.fullscreenElement()) { + this._setOption("fullScreen", false); + } + }, + _requestFullscreen: function() { + // Either the container or the jPlayer div + var e = this.ancestorJq.length ? this.ancestorJq[0] : this.element[0], + fs = $.jPlayer.nativeFeatures.fullscreen; + + // This method needs the video element. For iOS and Android. + if(fs.used.webkitVideo) { + e = this.htmlElement.video; + } + + if(fs.api.fullscreenEnabled) { + fs.api.requestFullscreen(e); + } + }, + _exitFullscreen: function() { + + var fs = $.jPlayer.nativeFeatures.fullscreen, + e; + + // This method needs the video element. For iOS and Android. + if(fs.used.webkitVideo) { + e = this.htmlElement.video; + } + + if(fs.api.fullscreenEnabled) { + fs.api.exitFullscreen(e); + } + }, + _html_initMedia: function(media) { + // Remove any existing track elements + var $media = $(this.htmlElement.media).empty(); + + // Create any track elements given with the media, as an Array of track Objects. + $.each(media.track || [], function(i,v) { + var track = document.createElement('track'); + track.setAttribute("kind", v.kind ? v.kind : ""); + track.setAttribute("src", v.src ? v.src : ""); + track.setAttribute("srclang", v.srclang ? v.srclang : ""); + track.setAttribute("label", v.label ? v.label : ""); + if(v.def) { + track.setAttribute("default", v.def); + } + $media.append(track); + }); + + this.htmlElement.media.src = this.status.src; + + if(this.options.preload !== 'none') { + this._html_load(); // See function for comments + } + this._trigger($.jPlayer.event.timeupdate); // The flash generates this event for its solution. + }, + _html_setFormat: function(media) { + var self = this; + // Always finds a format due to checks in setMedia() + $.each(this.formats, function(priority, format) { + if(self.html.support[format] && media[format]) { + self.status.src = media[format]; + self.status.format[format] = true; + self.status.formatType = format; + return false; + } + }); + }, + _html_setAudio: function(media) { + this._html_setFormat(media); + this.htmlElement.media = this.htmlElement.audio; + this._html_initMedia(media); + }, + _html_setVideo: function(media) { + this._html_setFormat(media); + if(this.status.nativeVideoControls) { + this.htmlElement.video.poster = this._validString(media.poster) ? media.poster : ""; + } + this.htmlElement.media = this.htmlElement.video; + this._html_initMedia(media); + }, + _html_resetMedia: function() { + if(this.htmlElement.media) { + if(this.htmlElement.media.id === this.internal.video.id && !this.status.nativeVideoControls) { + this.internal.video.jq.css({'width':'0px', 'height':'0px'}); + } + this.htmlElement.media.pause(); + } + }, + _html_clearMedia: function() { + if(this.htmlElement.media) { + this.htmlElement.media.src = "about:blank"; + // The following load() is only required for Firefox 3.6 (PowerMacs). + // Recent HTMl5 browsers only require the src change. Due to changes in W3C spec and load() effect. + this.htmlElement.media.load(); // Stops an old, "in progress" download from continuing the download. Triggers the loadstart, error and emptied events, due to the empty src. Also an abort event if a download was in progress. + } + }, + _html_load: function() { + // This function remains to allow the early HTML5 browsers to work, such as Firefox 3.6 + // A change in the W3C spec for the media.load() command means that this is no longer necessary. + // This command should be removed and actually causes minor undesirable effects on some browsers. Such as loading the whole file and not only the metadata. + if(this.status.waitForLoad) { + this.status.waitForLoad = false; + this.htmlElement.media.load(); + } + clearTimeout(this.internal.htmlDlyCmdId); + }, + _html_play: function(time) { + var self = this, + media = this.htmlElement.media; + + this._html_load(); // Loads if required and clears any delayed commands. + + if(!isNaN(time)) { + + // Attempt to play it, since iOS has been ignoring commands + if(this.internal.cmdsIgnored) { + media.play(); + } + + try { + // !media.seekable is for old HTML5 browsers, like Firefox 3.6. + // Checking seekable.length is important for iOS6 to work with setMedia().play(time) + if(!media.seekable || typeof media.seekable === "object" && media.seekable.length > 0) { + media.currentTime = time; + media.play(); + } else { + throw 1; + } + } catch(err) { + this.internal.htmlDlyCmdId = setTimeout(function() { + self.play(time); + }, 250); + return; // Cancel execution and wait for the delayed command. + } + } else { + media.play(); + } + this._html_checkWaitForPlay(); + }, + _html_pause: function(time) { + var self = this, + media = this.htmlElement.media; + + if(time > 0) { // We do not want the stop() command, which does pause(0), causing a load operation. + this._html_load(); // Loads if required and clears any delayed commands. + } else { + clearTimeout(this.internal.htmlDlyCmdId); + } + + // Order of these commands is important for Safari (Win) and IE9. Pause then change currentTime. + media.pause(); + + if(!isNaN(time)) { + try { + if(!media.seekable || typeof media.seekable === "object" && media.seekable.length > 0) { + media.currentTime = time; + } else { + throw 1; + } + } catch(err) { + this.internal.htmlDlyCmdId = setTimeout(function() { + self.pause(time); + }, 250); + return; // Cancel execution and wait for the delayed command. + } + } + if(time > 0) { // Avoids a setMedia() followed by stop() or pause(0) hiding the video play button. + this._html_checkWaitForPlay(); + } + }, + _html_playHead: function(percent) { + var self = this, + media = this.htmlElement.media; + + this._html_load(); // Loads if required and clears any delayed commands. + + try { + if(typeof media.seekable === "object" && media.seekable.length > 0) { + media.currentTime = percent * media.seekable.end(media.seekable.length-1) / 100; + } else if(media.duration > 0 && !isNaN(media.duration)) { + media.currentTime = percent * media.duration / 100; + } else { + throw "e"; + } + } catch(err) { + this.internal.htmlDlyCmdId = setTimeout(function() { + self.playHead(percent); + }, 250); + return; // Cancel execution and wait for the delayed command. + } + if(!this.status.waitForLoad) { + this._html_checkWaitForPlay(); + } + }, + _html_checkWaitForPlay: function() { + if(this.status.waitForPlay) { + this.status.waitForPlay = false; + if(this.css.jq.videoPlay.length) { + this.css.jq.videoPlay.hide(); + } + if(this.status.video) { + this.internal.poster.jq.hide(); + this.internal.video.jq.css({'width': this.status.width, 'height': this.status.height}); + } + } + }, + _html_volume: function(v) { + if(this.html.audio.available) { + this.htmlElement.audio.volume = v; + } + if(this.html.video.available) { + this.htmlElement.video.volume = v; + } + }, + _html_mute: function(m) { + if(this.html.audio.available) { + this.htmlElement.audio.muted = m; + } + if(this.html.video.available) { + this.htmlElement.video.muted = m; + } + }, + _flash_setAudio: function(media) { + var self = this; + try { + // Always finds a format due to checks in setMedia() + $.each(this.formats, function(priority, format) { + if(self.flash.support[format] && media[format]) { + switch (format) { + case "m4a" : + case "fla" : + self._getMovie().fl_setAudio_m4a(media[format]); + break; + case "mp3" : + self._getMovie().fl_setAudio_mp3(media[format]); + break; + case "rtmpa": + self._getMovie().fl_setAudio_rtmp(media[format]); + break; + } + self.status.src = media[format]; + self.status.format[format] = true; + self.status.formatType = format; + return false; + } + }); + + if(this.options.preload === 'auto') { + this._flash_load(); + this.status.waitForLoad = false; + } + } catch(err) { this._flashError(err); } + }, + _flash_setVideo: function(media) { + var self = this; + try { + // Always finds a format due to checks in setMedia() + $.each(this.formats, function(priority, format) { + if(self.flash.support[format] && media[format]) { + switch (format) { + case "m4v" : + case "flv" : + self._getMovie().fl_setVideo_m4v(media[format]); + break; + case "rtmpv": + self._getMovie().fl_setVideo_rtmp(media[format]); + break; + } + self.status.src = media[format]; + self.status.format[format] = true; + self.status.formatType = format; + return false; + } + }); + + if(this.options.preload === 'auto') { + this._flash_load(); + this.status.waitForLoad = false; + } + } catch(err) { this._flashError(err); } + }, + _flash_resetMedia: function() { + this.internal.flash.jq.css({'width':'0px', 'height':'0px'}); // Must do via CSS as setting attr() to zero causes a jQuery error in IE. + this._flash_pause(NaN); + }, + _flash_clearMedia: function() { + try { + this._getMovie().fl_clearMedia(); + } catch(err) { this._flashError(err); } + }, + _flash_load: function() { + try { + this._getMovie().fl_load(); + } catch(err) { this._flashError(err); } + this.status.waitForLoad = false; + }, + _flash_play: function(time) { + try { + this._getMovie().fl_play(time); + } catch(err) { this._flashError(err); } + this.status.waitForLoad = false; + this._flash_checkWaitForPlay(); + }, + _flash_pause: function(time) { + try { + this._getMovie().fl_pause(time); + } catch(err) { this._flashError(err); } + if(time > 0) { // Avoids a setMedia() followed by stop() or pause(0) hiding the video play button. + this.status.waitForLoad = false; + this._flash_checkWaitForPlay(); + } + }, + _flash_playHead: function(p) { + try { + this._getMovie().fl_play_head(p); + } catch(err) { this._flashError(err); } + if(!this.status.waitForLoad) { + this._flash_checkWaitForPlay(); + } + }, + _flash_checkWaitForPlay: function() { + if(this.status.waitForPlay) { + this.status.waitForPlay = false; + if(this.css.jq.videoPlay.length) { + this.css.jq.videoPlay.hide(); + } + if(this.status.video) { + this.internal.poster.jq.hide(); + this.internal.flash.jq.css({'width': this.status.width, 'height': this.status.height}); + } + } + }, + _flash_volume: function(v) { + try { + this._getMovie().fl_volume(v); + } catch(err) { this._flashError(err); } + }, + _flash_mute: function(m) { + try { + this._getMovie().fl_mute(m); + } catch(err) { this._flashError(err); } + }, + _getMovie: function() { + return document[this.internal.flash.id]; + }, + _getFlashPluginVersion: function() { + + // _getFlashPluginVersion() code influenced by: + // - FlashReplace 1.01: http://code.google.com/p/flashreplace/ + // - SWFObject 2.2: http://code.google.com/p/swfobject/ + + var version = 0, + flash; + if(window.ActiveXObject) { + try { + flash = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); + if (flash) { // flash will return null when ActiveX is disabled + var v = flash.GetVariable("$version"); + if(v) { + v = v.split(" ")[1].split(","); + version = parseInt(v[0], 10) + "." + parseInt(v[1], 10); + } + } + } catch(e) {} + } + else if(navigator.plugins && navigator.mimeTypes.length > 0) { + flash = navigator.plugins["Shockwave Flash"]; + if(flash) { + version = navigator.plugins["Shockwave Flash"].description.replace(/.*\s(\d+\.\d+).*/, "$1"); + } + } + return version * 1; // Converts to a number + }, + _checkForFlash: function (version) { + var flashOk = false; + if(this._getFlashPluginVersion() >= version) { + flashOk = true; + } + return flashOk; + }, + _validString: function(url) { + return (url && typeof url === "string"); // Empty strings return false + }, + _limitValue: function(value, min, max) { + return (value < min) ? min : ((value > max) ? max : value); + }, + _urlNotSetError: function(context) { + this._error( { + type: $.jPlayer.error.URL_NOT_SET, + context: context, + message: $.jPlayer.errorMsg.URL_NOT_SET, + hint: $.jPlayer.errorHint.URL_NOT_SET + }); + }, + _flashError: function(error) { + var errorType; + if(!this.internal.ready) { + errorType = "FLASH"; + } else { + errorType = "FLASH_DISABLED"; + } + this._error( { + type: $.jPlayer.error[errorType], + context: this.internal.flash.swf, + message: $.jPlayer.errorMsg[errorType] + error.message, + hint: $.jPlayer.errorHint[errorType] + }); + // Allow the audio player to recover if display:none and then shown again, or with position:fixed on Firefox. + // This really only affects audio in a media player, as an audio player could easily move the jPlayer element away from such issues. + this.internal.flash.jq.css({'width':'1px', 'height':'1px'}); + }, + _error: function(error) { + this._trigger($.jPlayer.event.error, error); + if(this.options.errorAlerts) { + this._alert("Error!" + (error.message ? "\n\n" + error.message : "") + (error.hint ? "\n\n" + error.hint : "") + "\n\nContext: " + error.context); + } + }, + _warning: function(warning) { + this._trigger($.jPlayer.event.warning, undefined, warning); + if(this.options.warningAlerts) { + this._alert("Warning!" + (warning.message ? "\n\n" + warning.message : "") + (warning.hint ? "\n\n" + warning.hint : "") + "\n\nContext: " + warning.context); + } + }, + _alert: function(message) { + alert("jPlayer " + this.version.script + " : id='" + this.internal.self.id +"' : " + message); + }, + _emulateHtmlBridge: function() { + var self = this; + + // Emulate methods on jPlayer's DOM element. + $.each( $.jPlayer.emulateMethods.split(/\s+/g), function(i, name) { + self.internal.domNode[name] = function(arg) { + self[name](arg); + }; + + }); + + // Bubble jPlayer events to its DOM element. + $.each($.jPlayer.event, function(eventName,eventType) { + var nativeEvent = true; + $.each( $.jPlayer.reservedEvent.split(/\s+/g), function(i, name) { + if(name === eventName) { + nativeEvent = false; + return false; + } + }); + if(nativeEvent) { + self.element.bind(eventType + ".jPlayer.jPlayerHtml", function() { // With .jPlayer & .jPlayerHtml namespaces. + self._emulateHtmlUpdate(); + var domEvent = document.createEvent("Event"); + domEvent.initEvent(eventName, false, true); + self.internal.domNode.dispatchEvent(domEvent); + }); + } + // The error event would require a special case + }); + + // IE9 has a readyState property on all elements. The document should have it, but all (except media) elements inherit it in IE9. This conflicts with Popcorn, which polls the readyState. + }, + _emulateHtmlUpdate: function() { + var self = this; + + $.each( $.jPlayer.emulateStatus.split(/\s+/g), function(i, name) { + self.internal.domNode[name] = self.status[name]; + }); + $.each( $.jPlayer.emulateOptions.split(/\s+/g), function(i, name) { + self.internal.domNode[name] = self.options[name]; + }); + }, + _destroyHtmlBridge: function() { + var self = this; + + // Bridge event handlers are also removed by destroy() through .jPlayer namespace. + this.element.unbind(".jPlayerHtml"); // Remove all event handlers created by the jPlayer bridge. So you can change the emulateHtml option. + + // Remove the methods and properties + var emulated = $.jPlayer.emulateMethods + " " + $.jPlayer.emulateStatus + " " + $.jPlayer.emulateOptions; + $.each( emulated.split(/\s+/g), function(i, name) { + delete self.internal.domNode[name]; + }); + } + }; + + $.jPlayer.error = { + FLASH: "e_flash", + FLASH_DISABLED: "e_flash_disabled", + NO_SOLUTION: "e_no_solution", + NO_SUPPORT: "e_no_support", + URL: "e_url", + URL_NOT_SET: "e_url_not_set", + VERSION: "e_version" + }; + + $.jPlayer.errorMsg = { + FLASH: "jPlayer's Flash fallback is not configured correctly, or a command was issued before the jPlayer Ready event. Details: ", // Used in: _flashError() + FLASH_DISABLED: "jPlayer's Flash fallback has been disabled by the browser due to the CSS rules you have used. Details: ", // Used in: _flashError() + NO_SOLUTION: "No solution can be found by jPlayer in this browser. Neither HTML nor Flash can be used.", // Used in: _init() + NO_SUPPORT: "It is not possible to play any media format provided in setMedia() on this browser using your current options.", // Used in: setMedia() + URL: "Media URL could not be loaded.", // Used in: jPlayerFlashEvent() and _addHtmlEventListeners() + URL_NOT_SET: "Attempt to issue media playback commands, while no media url is set.", // Used in: load(), play(), pause(), stop() and playHead() + VERSION: "jPlayer " + $.jPlayer.prototype.version.script + " needs Jplayer.swf version " + $.jPlayer.prototype.version.needFlash + " but found " // Used in: jPlayerReady() + }; + + $.jPlayer.errorHint = { + FLASH: "Check your swfPath option and that Jplayer.swf is there.", + FLASH_DISABLED: "Check that you have not display:none; the jPlayer entity or any ancestor.", + NO_SOLUTION: "Review the jPlayer options: support and supplied.", + NO_SUPPORT: "Video or audio formats defined in the supplied option are missing.", + URL: "Check media URL is valid.", + URL_NOT_SET: "Use setMedia() to set the media URL.", + VERSION: "Update jPlayer files." + }; + + $.jPlayer.warning = { + CSS_SELECTOR_COUNT: "e_css_selector_count", + CSS_SELECTOR_METHOD: "e_css_selector_method", + CSS_SELECTOR_STRING: "e_css_selector_string", + OPTION_KEY: "e_option_key" + }; + + $.jPlayer.warningMsg = { + CSS_SELECTOR_COUNT: "The number of css selectors found did not equal one: ", + CSS_SELECTOR_METHOD: "The methodName given in jPlayer('cssSelector') is not a valid jPlayer method.", + CSS_SELECTOR_STRING: "The methodCssSelector given in jPlayer('cssSelector') is not a String or is empty.", + OPTION_KEY: "The option requested in jPlayer('option') is undefined." + }; + + $.jPlayer.warningHint = { + CSS_SELECTOR_COUNT: "Check your css selector and the ancestor.", + CSS_SELECTOR_METHOD: "Check your method name.", + CSS_SELECTOR_STRING: "Check your css selector is a string.", + OPTION_KEY: "Check your option name." + }; +})); diff --git a/multimedia/files/js/default/multimedia.js b/multimedia/files/js/default/multimedia.js index ea23263..e0a8d6b 100644 --- a/multimedia/files/js/default/multimedia.js +++ b/multimedia/files/js/default/multimedia.js @@ -1,452 +1,448 @@ -var clsMultimedia = Class.create(); -var multimediaCls = Array(); - -clsMultimedia.prototype = { - initialize: function(id) { - this.id = id; - this.multimedia_id = null; - this.album_id = null; - this.album_edit_flag = null; - this.item_id = null; - this.dragDrop = null; - }, - initializeMultimedia: function() { - var post = { - "action":"multimedia_action_edit_initialize" - } - commonCls.sendPost(this.id, post); - }, - editMultimedia: function(form_el) { - commonCls.sendPost(this.id, "action=multimedia_action_edit_entry" + "&" + Form.serialize(form_el), {"target_el":$(this.id)}); - }, - editDisplay: function(form_el) { - commonCls.sendPost(this.id, "action=multimedia_action_edit_display" + "&" + Form.serialize(form_el), {"target_el":$(this.id)}); - }, - showAlbumEntry: function(event, multimedia_id, album_id) { - var params = new Object(); - params["prefix_id_name"] = "popup_multimedia_album_entry"; - params["action"] = "multimedia_view_main_album_entry"; - params["multimedia_id"] = multimedia_id; - params["album_id"] = album_id; - - var optionParams = new Object(); - var top_el = $(this.id); - optionParams["top_el"] = top_el; - optionParams["modal_flag"] = true; - optionParams["target_el"] = top_el; - - commonCls.sendPopupView(event, params, optionParams); - }, - showAlbumEdit: function() { - var params = new Object(); - params["action"] = "multimedia_view_main_init"; - params["multimedia_id"] = this.multimedia_id; - params["album_edit_flag"] = this.album_edit_flag = 1; - commonCls.sendView(this.id, params); - }, - showAlbumList: function(param) { - var params = new Object(); - params["action"] = "multimedia_view_main_init"; - params["multimedia_id"] = this.multimedia_id; - Object.extend(params, param); - - commonCls.sendView(this.id, params); - }, - deleteAlbum: function(album_id, confirmMessage) { - if (!confirm(confirmMessage)) return false; - var post = { - "action":"multimedia_action_main_album_delete", - "album_id":album_id - }; - - var params = new Object(); - params["callbackfunc"] = function(res){ - if(this.album_edit_flag == 1) { - commonCls.sendView(this.id, {action:'multimedia_view_main_init', album_edit_flag:1}); - }else { - commonCls.sendView(this.id, {action:'multimedia_view_main_init', album_edit_flag:0}); - } - }.bind(this); - commonCls.sendPost(this.id, post, params); - }, - showItem: function(event, item_id) { - var play_count_el = $("multimedia_play_count_" + item_id + this.id); - var play_count = parseInt(play_count_el.innerHTML.match(/\d+/)[0]) + 1; - play_count_el.innerHTML = play_count_el.innerHTML.replace(/\d+/, play_count); - - var params = new Object(); - params = { - "action":"multimedia_view_main_item_detail", - "item_id":item_id, - "prefix_id_name":"popup_multimedia_item_detail" - }; - - var popupParams = new Object(); - var top_el = $(this.id); - popupParams["top_el"] = top_el; - popupParams['modal_flag'] = true; - popupParams['target_el'] = top_el; - - commonCls.sendPopupView(event, params, popupParams); - }, - showItemUpload: function(event, album_id) { - var params = new Object(); - params = { - "action":"multimedia_view_main_item_upload", - "album_id":album_id, - "prefix_id_name":"multimedia_item_upload" - }; - - var popupParams = new Object(); - var top_el = $(this.id); - popupParams['top_el'] = top_el; - popupParams['target_el'] = top_el; - popupParams['modal_flag'] = true; - - commonCls.sendPopupView(event, params, popupParams); - }, - upload: function(form_el) { - var upload_el = $('multimedia_item_upload_area' + this.id); - commonCls.displayNone(upload_el); - var loading_el = $('multimedia_item_upload_loading' + this.id); - commonCls.displayVisible(loading_el); - var contrl_el = $('multimedia_item_upload_control' + this.id); - commonCls.displayNone(contrl_el); - var cancel_el = $('multimedia_item_upload_cancel' + this.id); - commonCls.displayVisible(cancel_el); - var params = new Object(); - params["param"] = {"action":"multimedia_action_main_item_upload"}; - params["top_el"] = $(this.id); - params["method"] = "post"; - params["form_prefix"] = "multimedia_attachment"; - params["timeout_flag"] = false; - params["callbackfunc"] = function(files, res) { - if(this.id.indexOf("_multimedia_item_upload")<0) { - commonCls.sendView(this.id, {'action':'multimedia_view_main_init'}); - }else { - var refreshElement_id = this.id.replace("_multimedia_item_upload", ""); - if($(refreshElement_id)) { - commonCls.sendRefresh(refreshElement_id); - } - } - commonCls.removeBlock(this.id); - }.bind(this); - params["callbackfunc_error"] = function(file, res){ - commonCls.alert(res); - commonCls.displayNone(cancel_el); - commonCls.displayNone(loading_el); - commonCls.displayVisible(upload_el); - commonCls.displayVisible(contrl_el); - }.bind(this); - commonCls.sendAttachment(params); - }, - showItemEdit: function(event, item_id) { - var params = new Object(); - params = { - "action":"multimedia_view_main_item_edit", - "item_id":item_id, - "prefix_id_name":"popup_multimedia_item_edit" - }; - - var popupParams = new Object(); - var top_el = $(this.id); - popupParams["top_el"] = top_el; - popupParams["modal_flag"] = true; - popupParams["target_el"] = top_el; - - commonCls.sendPopupView(event, params, popupParams); - }, - selectJacket: function(src, album_id) { - var form = $("multimedia_album_form" + this.id); - form["album_jacket"].value = src.substring(src.lastIndexOf("/") + 1, src.length); - form["upload_id"].value = ""; - - var params = new Object(); - params["param"] = { - "action":"multimedia_view_main_album_jacket", - "multimedia_id":this.multimedia_id, - "album_id":album_id, - "album_jacket":form["album_jacket"].value - }; - params["top_el"] = $(this.id); - params["target_el"] = $("multimedia_album_jacket" + this.id).parentNode; - - commonCls.send(params); - }, - uploadJacket: function() { - var form = $("multimedia_album_form" + this.id); - - var params = new Object(); - params["param"] = { - "action":"multimedia_action_main_album_jacket", - "multimedia_id":form["multimedia_id"], - "album_id":form["album_id"] - }; - - params["top_el"] = $(this.id); - params['form_prefix'] = "multimedia_jacket"; - - params["callbackfunc"] = function(files, res){ - form["album_jacket"].value = "?action="+ files[0]['action_name'] + "&upload_id=" + files[0]['upload_id']; - form["upload_id"].value = files[0]["upload_id"]; - - var params = new Object(); - params["param"] = { - "action":"multimedia_view_main_album_jacket", - "multimedia_id":this.multimedia_id, - "album_id":this.album_id, - "upload_id":form["upload_id"].value, - "album_jacket":form["album_jacket"].value - }; - - params["top_el"] = $(this.id); - params["target_el"] = $("multimedia_album_jacket" + this.id).parentNode; - - commonCls.send(params); - }.bind(this); - - commonCls.sendAttachment(params); - }, - editItem: function(form_el) { - var params = new Object(); - params["callbackfunc"] = function(res){ - commonCls.removeBlock(this.id); - commonCls.sendRefresh(this.id.replace("_popup_multimedia_item_edit", "")); - }.bind(this); - commonCls.sendPost(this.id, "action=multimedia_action_main_item_edit" + "&" + Form.serialize(form_el), params); - }, - deleteItem: function(confirmMessage, item_id) { - if (!confirm(confirmMessage)) return false; - var post = { - "action":"multimedia_action_main_item_delete", - "item_id":item_id - }; - var params = new Object(); - params["callbackfunc"] = function(res){ - commonCls.sendRefresh(this.id); - }.bind(this); - - commonCls.sendPost(this.id, post, params); - }, - enterAlbum: function() { - var post = "action=multimedia_action_main_album_entry&" + Form.serialize($("multimedia_album_form" + this.id)); - var params = new Object(); - params["callbackfunc"] = function(res){ - var id = this.id.replace("_popup_multimedia_album_entry", ""); - commonCls.removeBlock(this.id); - if(multimediaCls[id].album_edit_flag == 1) { - commonCls.sendView(id, {action:'multimedia_view_main_init', album_edit_flag:1}); - }else { - commonCls.sendView(id, {action:'multimedia_view_main_init', album_edit_flag:0}); - } - }.bind(this); - - commonCls.sendPost(this.id, post, params); - }, - showAlbumSeq: function(event, multimedia_id) { - var param_popup = new Object(); - param_popup = { - "action":"multimedia_view_main_album_sequence", - "multimedia_id":multimedia_id, - "prefix_id_name":"multimedia_album_sequence_popup" - }; - - var params = new Object(); - params['top_el'] = $(this.id); - params['modal_flag'] = true; - commonCls.sendPopupView(event, param_popup, params); - }, - closeAlbumSeq: function() { - var id = this.id.replace("_multimedia_album_sequence_popup", ""); - commonCls.removeBlock(this.id); - if(multimediaCls[id].album_edit_flag == 1) { - commonCls.sendView(id, {action:'multimedia_view_main_init', album_edit_flag:1}); - }else { - commonCls.sendView(id, {action:'multimedia_view_main_init', album_edit_flag:0}); - } - }, - vote: function(album_id, item_id) { - var post = { - "action":"multimedia_action_main_item_vote", - "album_id":album_id, - "item_id":item_id - }; - var params = new Object(); - params["callbackfunc"] = function(res) { - var id = this.id.replace("_popup_multimedia_item_detail", ""); - var top_vote_count_el = $("multimedia_vote_count_" + item_id + id); - var detail_vote_count_el = $("multimedia_vote_count" + this.id); - var vote_count = parseInt(top_vote_count_el.innerHTML.match(/\d+/)[0]) + 1; - top_vote_count_el.innerHTML = top_vote_count_el.innerHTML.replace(/\d+/, vote_count); - detail_vote_count_el.innerHTML = detail_vote_count_el.innerHTML.replace(/\d+/, vote_count); - var vote_link_el = $("multimedia_vote_link" + this.id); - vote_link_el.innerHTML = ""; - }.bind(this); - commonCls.sendPost(this.id, post, params); - }, - showComment: function(album_id, item_id) { - var params = new Object(); - params["param"] = { - "action":"multimedia_view_main_comment", - "item_id":item_id - }; - params["top_el"] = $(this.id); - params["target_el"] = $("multimedia_comment_area" + this.id); - - commonCls.send(params); - }, - enterComment: function(album_id, item_id) { - var params = new Object(); - params["target_el"] = $("multimedia_comment_area" + this.id); - params["callbackfunc"] = function(res) { - var count_el = $("multimedia_comment_count" + this.id); - var count = parseInt(count_el.innerHTML.match(/\d+/)[0]) + 1; - count_el.innerHTML = count_el.innerHTML.replace(/\d+/, count); - }.bind(this); - commonCls.sendPost(this.id, Form.serialize($("multimedia_comment_form" + this.id)), params); - }, - cancelComment: function() { - commonCls.displayNone($("multimedia_comment_area" + this.id)); - commonCls.focus($("_href" + this.id)); - }, - showCommentEntry: function(comment_id) { - var commentForm = $("multimedia_comment_form" + this.id); - commentForm["comment_value"].value = $("multimedia_comment_value" + comment_id + this.id).innerHTML.replace(/\n/ig,"").replace(/()/ig,"\n").unescapeHTML(); - commentForm["comment_id"].value = comment_id; - - commentForm["comment_value"].focus(); - commentForm["comment_value"].select(); - }, - deleteComment: function(comment_id, item_id, album_id, confirmMessage) { - if (!confirm(confirmMessage)) return false; - - var post = { - "action":"multimedia_action_main_comment_delete", - "album_id":album_id, - "item_id":item_id, - "comment_id":comment_id - }; - - var params = new Object(); - params["target_el"] = $("multimedia_comment_area" + this.id); - params["callbackfunc"] = function(res){ - this.showFooter(album_id, item_id); - }.bind(this); - - commonCls.sendPost(this.id, post, params); - }, - itemMouseOver: function(div) { - if (this.dragDrop && !this.dragDrop.hasSelection()) { - Element.addClassName(div, "multimedia_item_over"); - } - }, - itemMouseOut: function(div) { - if (this.dragDrop && !this.dragDrop.hasSelection()) { - Element.removeClassName(div, 'multimedia_item_over'); - } - }, - setItem: function(type, data) { - var top_el = $(this.id); - var obj_el = $('multimedia_toolbar_' + type + '_text' + this.id); - var params = new Object(); - switch(type) { - case "list": - obj_el = $('multimedia_toolbar_' + data + '_text' + this.id); - params["target_el"] = top_el; - params["param"] = {"action":"multimedia_view_main_init","view_type":data,"now_page":1}; - break; - case "album": - params["target_el"] = top_el; - params["param"] = {"action":"multimedia_view_main_init","album":data,"now_page":1}; - break; - case "date": - params["target_el"] = top_el; - params["param"] = {"action":"multimedia_view_main_init","date":data,"now_page":1}; - break; - case "sort": - params["target_el"] = top_el; - params["param"] = {"action":"multimedia_view_main_init","sort":data,"now_page":1}; - break; - case "search": - params["method"] = "post"; - params["target_el"] = $("multimedia_top_main" + this.id); - var form_el = $("multimedia_search_form" + this.id); - form_el.sort.value = data; - params["param"] = "action=multimedia_action_main_search&now_page=1&"+Form.serialize(form_el); - break; - } - params["top_el"] = top_el; - params["loading_el"] = obj_el; - commonCls.send(params); - }, - toPage: function(el, now_page, type) { - var top_el = $(this.id); - var params = new Object(); - switch(type) { - case "search": - params["method"] = "post"; - params["target_el"] = $("multimedia_top_main" + this.id); - params["param"] = "action=multimedia_action_main_search&now_page="+ now_page +"&" +Form.serialize($("multimedia_search_form" + this.id)); - break; - case "item": - params["target_el"] = top_el; - params["param"] = "action=multimedia_view_main_item_init&now_page="+ now_page +"&" +Form.serialize($("multimedia_item_init_form" + this.id)); - break; - case "comment": - params["target_el"] = $("multimedia_comment_area" + this.id); - params["param"] = "action=multimedia_view_main_comment&now_page="+ now_page +"&item_id=" + this.item_id; - break; - default: - params["target_el"] = top_el; - params["param"] = "action=multimedia_view_main_init&now_page="+ now_page; - break; - } - params["top_el"] = top_el; - params["loading_el"] = el; - commonCls.send(params); - }, - search : function(el, type, condition) { - condition = condition.unescapeHTML(); - var params = new Object(); - var id = ""; - if(this.id.indexOf("_popup_multimedia_item_detail") < 0) { - id = this.id; - }else { - id = this.id.replace("_popup_multimedia_item_detail", ""); - params["callbackfunc"] = function(res) { - commonCls.removeBlock(this.id); - }.bind(this); - } - var form_el = $("multimedia_search_form" + id); - params["method"] = "post"; - params["param"] = "action=multimedia_action_main_search&"; - params["loading_el"] = el; - params["target_el"] = $("multimedia_top_main" + id); - switch(type) { - case "user": - form_el.keyword.value = condition; - form_el.poster_check.checked = true; - form_el.tag_check.checked = false; - form_el.name_check.checked = false; - form_el.description_check.checked = false; - break; - case "tag": - form_el.keyword.value = condition; - form_el.poster_check.checked = false; - form_el.tag_check.checked = true; - form_el.name_check.checked = false; - form_el.description_check.checked = false; - break; - case "channel": - form_el.keyword.value = ""; - form_el.poster_check.checked = true; - form_el.tag_check.checked = true; - form_el.name_check.checked = true; - form_el.description_check.checked = true; - form_el.search_album.value = condition; - break; - } - params["param"] += Form.serialize(form_el); - commonCls.send(params); - } +var clsMultimedia = Class.create(); +var multimediaCls = Array(); + +clsMultimedia.prototype = { + initialize: function(id) { + this.id = id; + this.multimedia_id = null; + this.album_id = null; + this.album_edit_flag = null; + this.item_id = null; + this.dragDrop = null; + }, + initializeMultimedia: function() { + var post = { + "action":"multimedia_action_edit_initialize" + } + commonCls.sendPost(this.id, post); + }, + editMultimedia: function(form_el) { + commonCls.sendPost(this.id, "action=multimedia_action_edit_entry" + "&" + Form.serialize(form_el), {"target_el":$(this.id)}); + }, + editDisplay: function(form_el) { + commonCls.sendPost(this.id, "action=multimedia_action_edit_display" + "&" + Form.serialize(form_el), {"target_el":$(this.id)}); + }, + showAlbumEntry: function(event, multimedia_id, album_id) { + var params = new Object(); + params["prefix_id_name"] = "popup_multimedia_album_entry"; + params["action"] = "multimedia_view_main_album_entry"; + params["multimedia_id"] = multimedia_id; + params["album_id"] = album_id; + + var optionParams = new Object(); + var top_el = $(this.id); + optionParams["top_el"] = top_el; + optionParams["modal_flag"] = true; + optionParams["target_el"] = top_el; + + commonCls.sendPopupView(event, params, optionParams); + }, + showAlbumEdit: function() { + var params = new Object(); + params["action"] = "multimedia_view_main_init"; + params["multimedia_id"] = this.multimedia_id; + params["album_edit_flag"] = this.album_edit_flag = 1; + commonCls.sendView(this.id, params); + }, + showAlbumList: function(param) { + var params = new Object(); + params["action"] = "multimedia_view_main_init"; + params["multimedia_id"] = this.multimedia_id; + Object.extend(params, param); + + commonCls.sendView(this.id, params); + }, + deleteAlbum: function(album_id, confirmMessage) { + if (!confirm(confirmMessage)) return false; + var post = { + "action":"multimedia_action_main_album_delete", + "album_id":album_id + }; + + var params = new Object(); + params["callbackfunc"] = function(res){ + if(this.album_edit_flag == 1) { + commonCls.sendView(this.id, {action:'multimedia_view_main_init', album_edit_flag:1}); + }else { + commonCls.sendView(this.id, {action:'multimedia_view_main_init', album_edit_flag:0}); + } + }.bind(this); + commonCls.sendPost(this.id, post, params); + }, + showItem: function(event, item_id) { + var params = new Object(); + params = { + "action":"multimedia_view_main_item_detail", + "item_id":item_id, + "prefix_id_name":"popup_multimedia_item_detail" + }; + + var popupParams = new Object(); + var top_el = $(this.id); + popupParams["top_el"] = top_el; + popupParams['modal_flag'] = true; + popupParams['target_el'] = top_el; + + commonCls.sendPopupView(event, params, popupParams); + }, + showItemUpload: function(event, album_id) { + var params = new Object(); + params = { + "action":"multimedia_view_main_item_upload", + "album_id":album_id, + "prefix_id_name":"multimedia_item_upload" + }; + + var popupParams = new Object(); + var top_el = $(this.id); + popupParams['top_el'] = top_el; + popupParams['target_el'] = top_el; + popupParams['modal_flag'] = true; + + commonCls.sendPopupView(event, params, popupParams); + }, + upload: function(form_el) { + var upload_el = $('multimedia_item_upload_area' + this.id); + commonCls.displayNone(upload_el); + var loading_el = $('multimedia_item_upload_loading' + this.id); + commonCls.displayVisible(loading_el); + var contrl_el = $('multimedia_item_upload_control' + this.id); + commonCls.displayNone(contrl_el); + var cancel_el = $('multimedia_item_upload_cancel' + this.id); + commonCls.displayVisible(cancel_el); + var params = new Object(); + params["param"] = {"action":"multimedia_action_main_item_upload"}; + params["top_el"] = $(this.id); + params["method"] = "post"; + params["form_prefix"] = "multimedia_attachment"; + params["timeout_flag"] = false; + params["callbackfunc"] = function(files, res) { + if(this.id.indexOf("_multimedia_item_upload")<0) { + commonCls.sendView(this.id, {'action':'multimedia_view_main_init'}); + }else { + var refreshElement_id = this.id.replace("_multimedia_item_upload", ""); + if($(refreshElement_id)) { + commonCls.sendRefresh(refreshElement_id); + } + } + commonCls.removeBlock(this.id); + }.bind(this); + params["callbackfunc_error"] = function(file, res){ + commonCls.alert(res); + commonCls.displayNone(cancel_el); + commonCls.displayNone(loading_el); + commonCls.displayVisible(upload_el); + commonCls.displayVisible(contrl_el); + }.bind(this); + commonCls.sendAttachment(params); + }, + showItemEdit: function(event, item_id) { + var params = new Object(); + params = { + "action":"multimedia_view_main_item_edit", + "item_id":item_id, + "prefix_id_name":"popup_multimedia_item_edit" + }; + + var popupParams = new Object(); + var top_el = $(this.id); + popupParams["top_el"] = top_el; + popupParams["modal_flag"] = true; + popupParams["target_el"] = top_el; + + commonCls.sendPopupView(event, params, popupParams); + }, + selectJacket: function(src, album_id) { + var form = $("multimedia_album_form" + this.id); + form["album_jacket"].value = src.substring(src.lastIndexOf("/") + 1, src.length); + form["upload_id"].value = ""; + + var params = new Object(); + params["param"] = { + "action":"multimedia_view_main_album_jacket", + "multimedia_id":this.multimedia_id, + "album_id":album_id, + "album_jacket":form["album_jacket"].value + }; + params["top_el"] = $(this.id); + params["target_el"] = $("multimedia_album_jacket" + this.id).parentNode; + + commonCls.send(params); + }, + uploadJacket: function() { + var form = $("multimedia_album_form" + this.id); + + var params = new Object(); + params["param"] = { + "action":"multimedia_action_main_album_jacket", + "multimedia_id":form["multimedia_id"], + "album_id":form["album_id"] + }; + + params["top_el"] = $(this.id); + params['form_prefix'] = "multimedia_jacket"; + + params["callbackfunc"] = function(files, res){ + form["album_jacket"].value = "?action="+ files[0]['action_name'] + "&upload_id=" + files[0]['upload_id']; + form["upload_id"].value = files[0]["upload_id"]; + + var params = new Object(); + params["param"] = { + "action":"multimedia_view_main_album_jacket", + "multimedia_id":this.multimedia_id, + "album_id":this.album_id, + "upload_id":form["upload_id"].value, + "album_jacket":form["album_jacket"].value + }; + + params["top_el"] = $(this.id); + params["target_el"] = $("multimedia_album_jacket" + this.id).parentNode; + + commonCls.send(params); + }.bind(this); + + commonCls.sendAttachment(params); + }, + editItem: function(form_el) { + var params = new Object(); + params["callbackfunc"] = function(res){ + commonCls.removeBlock(this.id); + commonCls.sendRefresh(this.id.replace("_popup_multimedia_item_edit", "")); + }.bind(this); + commonCls.sendPost(this.id, "action=multimedia_action_main_item_edit" + "&" + Form.serialize(form_el), params); + }, + deleteItem: function(confirmMessage, item_id) { + if (!confirm(confirmMessage)) return false; + var post = { + "action":"multimedia_action_main_item_delete", + "item_id":item_id + }; + var params = new Object(); + params["callbackfunc"] = function(res){ + commonCls.sendRefresh(this.id); + }.bind(this); + + commonCls.sendPost(this.id, post, params); + }, + enterAlbum: function() { + var post = "action=multimedia_action_main_album_entry&" + Form.serialize($("multimedia_album_form" + this.id)); + var params = new Object(); + params["callbackfunc"] = function(res){ + var id = this.id.replace("_popup_multimedia_album_entry", ""); + commonCls.removeBlock(this.id); + if(multimediaCls[id].album_edit_flag == 1) { + commonCls.sendView(id, {action:'multimedia_view_main_init', album_edit_flag:1}); + }else { + commonCls.sendView(id, {action:'multimedia_view_main_init', album_edit_flag:0}); + } + }.bind(this); + + commonCls.sendPost(this.id, post, params); + }, + showAlbumSeq: function(event, multimedia_id) { + var param_popup = new Object(); + param_popup = { + "action":"multimedia_view_main_album_sequence", + "multimedia_id":multimedia_id, + "prefix_id_name":"multimedia_album_sequence_popup" + }; + + var params = new Object(); + params['top_el'] = $(this.id); + params['modal_flag'] = true; + commonCls.sendPopupView(event, param_popup, params); + }, + closeAlbumSeq: function() { + var id = this.id.replace("_multimedia_album_sequence_popup", ""); + commonCls.removeBlock(this.id); + if(multimediaCls[id].album_edit_flag == 1) { + commonCls.sendView(id, {action:'multimedia_view_main_init', album_edit_flag:1}); + }else { + commonCls.sendView(id, {action:'multimedia_view_main_init', album_edit_flag:0}); + } + }, + vote: function(album_id, item_id) { + var post = { + "action":"multimedia_action_main_item_vote", + "album_id":album_id, + "item_id":item_id + }; + var params = new Object(); + params["callbackfunc"] = function(res) { + var id = this.id.replace("_popup_multimedia_item_detail", ""); + var top_vote_count_el = $("multimedia_vote_count_" + item_id + id); + var detail_vote_count_el = $("multimedia_vote_count" + this.id); + var vote_count = parseInt(top_vote_count_el.innerHTML.match(/\d+/)[0]) + 1; + top_vote_count_el.innerHTML = top_vote_count_el.innerHTML.replace(/\d+/, vote_count); + detail_vote_count_el.innerHTML = detail_vote_count_el.innerHTML.replace(/\d+/, vote_count); + var vote_link_el = $("multimedia_vote_link" + this.id); + vote_link_el.innerHTML = ""; + }.bind(this); + commonCls.sendPost(this.id, post, params); + }, + showComment: function(album_id, item_id) { + var params = new Object(); + params["param"] = { + "action":"multimedia_view_main_comment", + "item_id":item_id + }; + params["top_el"] = $(this.id); + params["target_el"] = $("multimedia_comment_area" + this.id); + + commonCls.send(params); + }, + enterComment: function(album_id, item_id) { + var params = new Object(); + params["target_el"] = $("multimedia_comment_area" + this.id); + params["callbackfunc"] = function(res) { + var count_el = $("multimedia_comment_count" + this.id); + var count = parseInt(count_el.innerHTML.match(/\d+/)[0]) + 1; + count_el.innerHTML = count_el.innerHTML.replace(/\d+/, count); + }.bind(this); + commonCls.sendPost(this.id, Form.serialize($("multimedia_comment_form" + this.id)), params); + }, + cancelComment: function() { + commonCls.displayNone($("multimedia_comment_area" + this.id)); + commonCls.focus($("_href" + this.id)); + }, + showCommentEntry: function(comment_id) { + var commentForm = $("multimedia_comment_form" + this.id); + commentForm["comment_value"].value = $("multimedia_comment_value" + comment_id + this.id).innerHTML.replace(/\n/ig,"").replace(/()/ig,"\n").unescapeHTML(); + commentForm["comment_id"].value = comment_id; + + commentForm["comment_value"].focus(); + commentForm["comment_value"].select(); + }, + deleteComment: function(comment_id, item_id, album_id, confirmMessage) { + if (!confirm(confirmMessage)) return false; + + var post = { + "action":"multimedia_action_main_comment_delete", + "album_id":album_id, + "item_id":item_id, + "comment_id":comment_id + }; + + var params = new Object(); + params["target_el"] = $("multimedia_comment_area" + this.id); + params["callbackfunc"] = function(res){ + this.showFooter(album_id, item_id); + }.bind(this); + + commonCls.sendPost(this.id, post, params); + }, + itemMouseOver: function(div) { + if (this.dragDrop && !this.dragDrop.hasSelection()) { + Element.addClassName(div, "multimedia_item_over"); + } + }, + itemMouseOut: function(div) { + if (this.dragDrop && !this.dragDrop.hasSelection()) { + Element.removeClassName(div, 'multimedia_item_over'); + } + }, + setItem: function(type, data) { + var top_el = $(this.id); + var obj_el = $('multimedia_toolbar_' + type + '_text' + this.id); + var params = new Object(); + switch(type) { + case "list": + obj_el = $('multimedia_toolbar_' + data + '_text' + this.id); + params["target_el"] = top_el; + params["param"] = {"action":"multimedia_view_main_init","view_type":data,"now_page":1}; + break; + case "album": + params["target_el"] = top_el; + params["param"] = {"action":"multimedia_view_main_init","album":data,"now_page":1}; + break; + case "date": + params["target_el"] = top_el; + params["param"] = {"action":"multimedia_view_main_init","date":data,"now_page":1}; + break; + case "sort": + params["target_el"] = top_el; + params["param"] = {"action":"multimedia_view_main_init","sort":data,"now_page":1}; + break; + case "search": + params["method"] = "post"; + params["target_el"] = $("multimedia_top_main" + this.id); + var form_el = $("multimedia_search_form" + this.id); + form_el.sort.value = data; + params["param"] = "action=multimedia_action_main_search&now_page=1&"+Form.serialize(form_el); + break; + } + params["top_el"] = top_el; + params["loading_el"] = obj_el; + commonCls.send(params); + }, + toPage: function(el, now_page, type) { + var top_el = $(this.id); + var params = new Object(); + switch(type) { + case "search": + params["method"] = "post"; + params["target_el"] = $("multimedia_top_main" + this.id); + params["param"] = "action=multimedia_action_main_search&now_page="+ now_page +"&" +Form.serialize($("multimedia_search_form" + this.id)); + break; + case "item": + params["target_el"] = top_el; + params["param"] = "action=multimedia_view_main_item_init&now_page="+ now_page +"&" +Form.serialize($("multimedia_item_init_form" + this.id)); + break; + case "comment": + params["target_el"] = $("multimedia_comment_area" + this.id); + params["param"] = "action=multimedia_view_main_comment&now_page="+ now_page +"&item_id=" + this.item_id; + break; + default: + params["target_el"] = top_el; + params["param"] = "action=multimedia_view_main_init&now_page="+ now_page; + break; + } + params["top_el"] = top_el; + params["loading_el"] = el; + commonCls.send(params); + }, + search : function(el, type, condition) { + condition = condition.unescapeHTML(); + var params = new Object(); + var id = ""; + if(this.id.indexOf("_popup_multimedia_item_detail") < 0) { + id = this.id; + }else { + id = this.id.replace("_popup_multimedia_item_detail", ""); + params["callbackfunc"] = function(res) { + commonCls.removeBlock(this.id); + }.bind(this); + } + var form_el = $("multimedia_search_form" + id); + params["method"] = "post"; + params["param"] = "action=multimedia_action_main_search&"; + params["loading_el"] = el; + params["target_el"] = $("multimedia_top_main" + id); + switch(type) { + case "user": + form_el.keyword.value = condition; + form_el.poster_check.checked = true; + form_el.tag_check.checked = false; + form_el.name_check.checked = false; + form_el.description_check.checked = false; + break; + case "tag": + form_el.keyword.value = condition; + form_el.poster_check.checked = false; + form_el.tag_check.checked = true; + form_el.name_check.checked = false; + form_el.description_check.checked = false; + break; + case "channel": + form_el.keyword.value = ""; + form_el.poster_check.checked = true; + form_el.tag_check.checked = true; + form_el.name_check.checked = true; + form_el.description_check.checked = true; + form_el.search_album.value = condition; + break; + } + params["param"] += Form.serialize(form_el); + commonCls.send(params); + } } \ No newline at end of file diff --git a/multimedia/language/english/main.ini b/multimedia/language/english/main.ini index 582693a..e0654f5 100644 --- a/multimedia/language/english/main.ini +++ b/multimedia/language/english/main.ini @@ -148,6 +148,7 @@ multimedia_item_description = "Description" [Multimedia_Action_Main_Item_Upload] multimedia_item_upload_video_convert_error = "Error occurred when video file was converted.\nerror code:%s" multimedia_item_upload_video_update_error = "Error occurred when video data was updated." +multimedia_item_upload_video_information_error = "Error occurred when video information get." multimedia_item_upload_video_extension_error = "No extension %s found." multimedia_item_upload_thmbnail_create_error = "Error occurred when make thumbnail." multimedia_item_upload_video_insert_error = "Error occurred when video data was written." @@ -156,8 +157,15 @@ multimedia_item_upload_video_type_error = "This is not a supported video file." multimedia_item_upload_video_count_error = "Error occurred when video category was updated." multimedia_item_upload_video_nogd_error = "Error occurred when create thumnail, please install PHP GD library." multimedia_item_upload_thmbnail_get_error = "Error occurred when try to get thumbnail." +multimedia_item_upload_video_no_ffmpeg_error = "No ffmpeg library found at the path below.\nPlease check server settings.\n\n%s" +multimedia_item_upload_video_no_mp4box_error = "No MP4Box library found at the path below.\nPlease check server settings.\n\n%s" +multimedia_item_upload_video_no_gd_error = "No extension php-gd found. \nPlease install this extension for create thumbnail image." [Multimedia_View_Main_Comment:Multimedia_Action_Main_Comment] multimedia_comment = "Comment" multimedia_comment_number = "Comments(%s)" -multimedia_comment_value = "Post a comment" \ No newline at end of file +multimedia_comment_value = "Post a comment" + +[Multimedia_View_Main_Item_Iframe] +multimedia_err_no_item = "No video found." +multimedia_err_incorrectauth="This video is only opened to the login user." diff --git a/multimedia/language/japanese/main.ini b/multimedia/language/japanese/main.ini index 9c923fb..15d7623 100644 --- a/multimedia/language/japanese/main.ini +++ b/multimedia/language/japanese/main.ini @@ -148,6 +148,7 @@ multimedia_item_description = "説明" [Multimedia_Action_Main_Item_Upload] multimedia_item_upload_video_convert_error = "動画変換処理エラーが発生しました。\nerror code:%s" multimedia_item_upload_video_update_error = "動画データ更新エラーが発生しました。" +multimedia_item_upload_video_information_error = "動画情報取得処理エラーが発生しました。" multimedia_item_upload_video_extension_error = "PHP拡張ライブラリ「%s」が見つかりませんでした。" multimedia_item_upload_thmbnail_create_error = "動画サムネイル処理エラーが発生しました。" multimedia_item_upload_video_insert_error = "動画データ登録エラーが発生しました。" @@ -156,8 +157,15 @@ multimedia_item_upload_video_type_error = "サポートしている動画ファ multimedia_item_upload_video_count_error = "動画カテゴリ更新エラーが発生しました。" multimedia_item_upload_video_nogd_error = "サムネイルの作成に失敗しました。PHP GD libraryをインストールしてください。" multimedia_item_upload_thmbnail_get_error = "サムネイル作成処理で何らかのエラーが発生しました。" +multimedia_item_upload_video_no_ffmpeg_error = "ffmpegが下記パスに見つかりませんでした。\n設定を確認してください。\n\n%s" +multimedia_item_upload_video_no_mp4box_error = "MP4Boxが下記パスに見つかりませんでした。\n設定を確認してください。\n\n%s" +multimedia_item_upload_video_no_gd_error = "PHP GD ライブラリがインストールされていません。\nサムネイル作成に必要ですので、インストールしてください。" [Multimedia_View_Main_Comment:Multimedia_Action_Main_Comment] multimedia_comment = "コメント" multimedia_comment_number = "コメント(合計 %s 件)" -multimedia_comment_value = "コメントを書く" \ No newline at end of file +multimedia_comment_value = "コメントを書く" + +[Multimedia_View_Main_Item_Iframe] +multimedia_err_no_item = "指定された動画が存在していません。" +multimedia_err_incorrectauth="指定された動画はログインしたユーザーだけに公開します。" diff --git a/multimedia/templates/default/multimedia_player_list.xml b/multimedia/templates/default/multimedia_player_list.xml index ca513f0..731de59 100644 --- a/multimedia/templates/default/multimedia_player_list.xml +++ b/multimedia/templates/default/multimedia_player_list.xml @@ -1,4 +1,4 @@ -"?> +"?> <{strip}> diff --git a/multimedia/templates/default/multimedia_view_main_channel.html b/multimedia/templates/default/multimedia_view_main_channel.html index 6163f64..7a01858 100644 --- a/multimedia/templates/default/multimedia_view_main_channel.html +++ b/multimedia/templates/default/multimedia_view_main_channel.html @@ -78,7 +78,9 @@ -<{/strip}> \ No newline at end of file +<{/strip}> diff --git a/multimedia/templates/default/multimedia_view_main_item_detail.html b/multimedia/templates/default/multimedia_view_main_item_detail.html index 394e697..3de6ce5 100644 --- a/multimedia/templates/default/multimedia_view_main_item_detail.html +++ b/multimedia/templates/default/multimedia_view_main_item_detail.html @@ -1,15 +1,10 @@ <{strip}>
-
- - - - - - - -
+<{* + +*}> +
<{$lang.multimedia_video_object|smarty:nodefaults}> diff --git a/multimedia/templates/default/multimedia_view_main_item_detail.html.bak b/multimedia/templates/default/multimedia_view_main_item_detail.html.bak new file mode 100644 index 0000000..0e25f18 --- /dev/null +++ b/multimedia/templates/default/multimedia_view_main_item_detail.html.bak @@ -0,0 +1,195 @@ +<{strip}> +<{* + +*}> +
+
+ + + + +
+ + + + + + + +
+ +
+ + <{$lang.multimedia_video_object|smarty:nodefaults}> + + <{if $action.multimedia_obj.vote_flag == _ON}> + <{if $action.item.vote_authority}> + + <{$lang._separator|smarty:nodefaults}> + + <{$lang.multimedia_vote|smarty:nodefaults}> + + + <{/if}> + <{$lang._separator|smarty:nodefaults}> + + <{$lang.multimedia_vote_count|sprintf:$action.item.item_vote_count}> + + <{/if}> + <{if $action.multimedia_obj.comment_flag == _ON}> + <{$lang._separator|smarty:nodefaults}> + + + <{$lang.multimedia_comment_count|sprintf:$action.commentCount}> + + + <{/if}> + <{*$lang._separator|smarty:nodefaults*}> + +
+ +
+
+
+ + <{if !empty($action.item_list|smarty:nodefaults)}> + + <{/if}> +
+
+<{include file="../multimedia_script.html"}> + + + + + +<{/strip}> \ No newline at end of file diff --git a/multimedia/templates/default/multimedia_view_main_item_iframe.html b/multimedia/templates/default/multimedia_view_main_item_iframe.html new file mode 100644 index 0000000..9672d87 --- /dev/null +++ b/multimedia/templates/default/multimedia_view_main_item_iframe.html @@ -0,0 +1,2 @@ +<{strip}> +<{/strip}> \ No newline at end of file diff --git a/multimedia/templates/default/multimedia_view_main_list.html b/multimedia/templates/default/multimedia_view_main_list.html index b84435e..ac7847c 100644 --- a/multimedia/templates/default/multimedia_view_main_list.html +++ b/multimedia/templates/default/multimedia_view_main_list.html @@ -16,6 +16,9 @@ <{/if}>
<{include file="../multimedia_script.html"}> +<{* +<{include file="../multimedia_jquery_script.html"}> +*}> diff --git a/multimedia/templates/default/multimedia_view_main_play.html b/multimedia/templates/default/multimedia_view_main_play.html new file mode 100644 index 0000000..56ae482 --- /dev/null +++ b/multimedia/templates/default/multimedia_view_main_play.html @@ -0,0 +1,77 @@ +<{strip}> + + + + + + + + +
+
+ +
+ + +<{/strip}> \ No newline at end of file diff --git a/multimedia/templates/default/multimedia_view_main_toolbar.html.bk b/multimedia/templates/default/multimedia_view_main_toolbar.html.bk new file mode 100644 index 0000000..de4adf7 --- /dev/null +++ b/multimedia/templates/default/multimedia_view_main_toolbar.html.bk @@ -0,0 +1,122 @@ +<{strip}> +
multimedia_video_box<{/if}>"> +
+ <{if $from == "list"}> + <{if $action.album_count > 0}> +
+
+
+ <{$action.album_name|smarty:nodefaults}> + <{if $action.album != $smarty.const.MULTIMEDIA_ALL}> + (<{$action.album_item_count}>) + <{/if}> +
+
+
+ +
+
+ <{/if}> +
+
+
+ <{if $action.date == $smarty.const.MULTIMEDIA_DATE_DAY}> + <{$lang.multimedia_date_day|smarty:nodefaults}> + <{elseif $action.date == $smarty.const.MULTIMEDIA_DATE_WEEK}> + <{$lang.multimedia_date_week|smarty:nodefaults}> + <{elseif $action.date == $smarty.const.MULTIMEDIA_DATE_MONTH}> + <{$lang.multimedia_date_month|smarty:nodefaults}> + <{elseif $action.date == $smarty.const.MULTIMEDIA_ALL}> + <{$lang.multimedia_all|smarty:nodefaults}> + <{/if}> +
+
+
+ +
+
+ <{/if}> + <{if $position != "foot"}> + <{if $from == "search"}> + <{assign var="type" value="search"}> + <{else}> + <{assign var="type" value="sort"}> + <{/if}> +
+
+
+ <{if $action.sort == "" || $action.sort == $smarty.const.MULTIMEDIA_SORT_DATE_DESC}> + <{$lang.multimedia_date_desc|smarty:nodefaults}> + <{elseif $action.sort == $smarty.const.MULTIMEDIA_SORT_DATE_ASC}> + <{$lang.multimedia_date_asc|smarty:nodefaults}> + <{elseif $action.sort == $smarty.const.MULTIMEDIA_SORT_TITLE_ASC}> + <{$lang.multimedia_title_asc|smarty:nodefaults}> + <{elseif $action.sort == $smarty.const.MULTIMEDIA_SORT_PLAY_DESC && $from == "search"}> + <{$lang.multimedia_play_desc|smarty:nodefaults}> + <{elseif $action.sort == $smarty.const.MULTIMEDIA_SORT_VOTE_DESC && $from == "search"}> + <{$lang.multimedia_vote_desc|smarty:nodefaults}> + <{/if}> +
+
+
+ +
+ <{/if}> + <{include file = "multimedia_view_main_pager.html" from=$from}> +
+
+<{/strip}> \ No newline at end of file diff --git a/multimedia/templates/multimedia_jquery_script.html b/multimedia/templates/multimedia_jquery_script.html new file mode 100644 index 0000000..dc3e15e --- /dev/null +++ b/multimedia/templates/multimedia_jquery_script.html @@ -0,0 +1,26 @@ + + + + +<{* + + + + + + + +*}> \ No newline at end of file diff --git a/multimedia/validator/Validator_AlbumExist.class.php b/multimedia/validator/Validator_AlbumExist.class.php index c727124..5b47f3e 100644 --- a/multimedia/validator/Validator_AlbumExist.class.php +++ b/multimedia/validator/Validator_AlbumExist.class.php @@ -1,46 +1,46 @@ -getComponent("multimediaView"); - - $album = $multimediaView->getAlbum($attributes); - if(empty($album)) { - return $errStr; - } - - $request =& $container->getComponent("Request"); - $request->setParameter("album", $album); - - return; - } -} +getComponent("multimediaView"); + + $album = $multimediaView->getAlbum($attributes); + if(empty($album)) { + return $errStr; + } + + $request =& $container->getComponent("Request"); + $request->setParameter("album", $album); + + return; + } +} ?> \ No newline at end of file diff --git a/multimedia/validator/Validator_CommentExist.class.php b/multimedia/validator/Validator_CommentExist.class.php index eb1dfcc..97d8132 100644 --- a/multimedia/validator/Validator_CommentExist.class.php +++ b/multimedia/validator/Validator_CommentExist.class.php @@ -1,43 +1,43 @@ -getComponent("DbObject"); - - $comment = $db->selectExecute("multimedia_comment", array("comment_id" => intval($attributes))); - if(empty($comment)) { - return $errStr; - } - - return; - } -} +getComponent("DbObject"); + + $comment = $db->selectExecute("multimedia_comment", array("comment_id" => intval($attributes))); + if(empty($comment)) { + return $errStr; + } + + return; + } +} ?> \ No newline at end of file diff --git a/multimedia/validator/Validator_ItemExist.class.php b/multimedia/validator/Validator_ItemExist.class.php index 5e5ff38..4b0c418 100644 --- a/multimedia/validator/Validator_ItemExist.class.php +++ b/multimedia/validator/Validator_ItemExist.class.php @@ -1,46 +1,46 @@ -getComponent("multimediaView"); - - $item = $multimediaView->getItem($attributes); - if(empty($item)) { - return $errStr; - } - - $request =& $container->getComponent("Request"); - $request->setParameter("item", $item); - - return; - } -} +getComponent("multimediaView"); + + $item = $multimediaView->getItem($attributes); + if(empty($item)) { + return $errStr; + } + + $request =& $container->getComponent("Request"); + $request->setParameter("item", $item); + + return; + } +} ?> \ No newline at end of file diff --git a/multimedia/validator/Validator_ItemUpload.class.php b/multimedia/validator/Validator_ItemUpload.class.php index 9bedf7b..899a6b7 100644 --- a/multimedia/validator/Validator_ItemUpload.class.php +++ b/multimedia/validator/Validator_ItemUpload.class.php @@ -28,6 +28,7 @@ class Multimedia_Validator_ItemUpload extends Validator * @return string エラー文字列(エラーの場合) * @access public */ + function validate($attributes, $errStr, $params) { // container取得 @@ -35,7 +36,7 @@ function validate($attributes, $errStr, $params) $db =& $container->getComponent("DbObject"); $fileUpload =& $container->getComponent("FileUpload"); $uploadsAction =& $container->getComponent("uploadsAction"); - + $filterChain =& $container->getComponent("FilterChain"); $smartyAssign =& $filterChain->getFilterByName("SmartyAssign"); $multimediaAction =& $container->getComponent("multimediaAction"); @@ -43,149 +44,280 @@ function validate($attributes, $errStr, $params) if(!isset($attributes['multimedia_id']) || !isset($attributes['album_id']) || !isset($attributes['privacy'])) { return $smartyAssign->getLang("_invalid_input"); } - - //ffmpeg拡張のチェック - if(!$multimediaAction->hasFfmpegLib()) { - $extension_fullname = PHP_EXTENSION_DIR . "/" . MULTIMEDIA_EXTENSION.".".PHP_SHLIB_SUFFIX; - return sprintf($smartyAssign->getLang("multimedia_item_upload_video_extension_error"), $extension_fullname); - } - - //アップロードしたファイルの処理 + + //ffmpegのチェック + if(!$multimediaAction->hasFfmpeg()) { + return sprintf($smartyAssign->getLang("multimedia_item_upload_video_no_ffmpeg_error"), MULTIMEDIA_FFMPEG_PATH); + } + + //MP4Boxのチェック + if(!$multimediaAction->hasMp4box()) { + return sprintf($smartyAssign->getLang("multimedia_item_upload_video_no_mp4box_error"), MULTIMEDIA_MP4BOX_PATH); + } + + // PHP GDライブラリのチェック + if(!function_exists("gd_info")) { + return $smartyAssign->getLang("multimedia_item_upload_video_no_gd_error"); + } + + //アップロードしたファイルの処理 $files = $uploadsAction->uploads(); $params = array( "album_id" => $attributes['album_id'] ); - + $itemSequence = $db->maxExecute("multimedia_item", "item_sequence", $params); $actionChain =& $container->getComponent("ActionChain"); $action_name = $actionChain->getCurActionName(); $pathList = explode("_", $action_name); - $dirname = $pathList[0]; - $file_path = $dirname."/"; + $dirname = $pathList[0]; + $file_path = $dirname."/"; foreach($files as $file) { $itemSequence++; $file_dir = FILEUPLOADS_DIR.$file_path; - if($file['extension'] != "flv") { - $item_name = str_replace(".". $file['extension'], "", $file['physical_file_name']); - $str_cmd = "/usr/local/bin/ffmpeg -y -i ".$file_dir.$file['physical_file_name']." -ar 44100 ".$file_dir.$item_name.".flv 2>&1"; - exec($str_cmd, $arr, $ret); - if($ret != 0) { - $uploadsAction->delUploadsById($file['upload_id']); - return sprintf($smartyAssign->getLang("multimedia_item_upload_video_convert_error"), $ret); - }else { - unlink($file_dir.$file['physical_file_name']); - } - $file['physical_file_name'] = $item_name.".flv"; - $upload_params = array( - "file_name" => $file['physical_file_name'], - "physical_file_name" => $file['physical_file_name'], - "file_size" => filesize($file_dir.$file['physical_file_name']), - "extension" => "flv" - ); - $where_params = array( - "upload_id" => $file['upload_id'] - ); - if(!$uploadsAction->updUploads($upload_params, $where_params)) { - $uploadsAction->delUploadsById($file['upload_id']); - return $smartyAssign->getLang("multimedia_item_upload_video_update_error"); - } - } - - //サムネイルを作成 - $movie = $file_dir.$file['physical_file_name']; - $mov = new ffmpeg_movie($movie); - if ($mov->hasVideo()) { - $duration = $mov->getDuration(); - $frame = $mov->getFrame(ceil($mov->getFrameCount()/2)); - if($frame === false) { - $frame = $mov->getFrame(1); - if($frame === false) { - $uploadsAction->delUploadsById($file['upload_id']); - return $smartyAssign->getLang("multimedia_item_upload_thmbnail_get_error"); - } - } + //動画パスを定義 + $temp_video_path = null; // MP4Box変換前 + $video_path = null; // MP4Box変換後 - if(!function_exists("gd_info")) { - $uploadsAction->delUploadsById($file['upload_id']); - return $smartyAssign->getLang("multimedia_item_upload_video_nogd_error"); - } - $image = $frame->toGDImage(); - if($image === false) { - $uploadsAction->delUploadsById($file['upload_id']); - return $smartyAssign->getLang("multimedia_item_upload_thmbnail_create_error"); - } - $width_orig = $frame->getWidth(); - $height_orig = $frame->getHeight(); - $scale = min(MULTIMEDIA_MOVIE_THUMBNAIL_WIDTH/$width_orig, MULTIMEDIA_MOVIE_THUMBNAIL_HEIGHT/$height_orig); - $width = (int)($width_orig*$scale); - $height = (int)($height_orig*$scale); - $delta_width = (int)((MULTIMEDIA_MOVIE_THUMBNAIL_WIDTH - $width)/2); - $delta_height = (int)((MULTIMEDIA_MOVIE_THUMBNAIL_HEIGHT - $height)/2); - - $gb_result = false; - $gb_result = $image_p = imagecreatetruecolor(MULTIMEDIA_MOVIE_THUMBNAIL_WIDTH, MULTIMEDIA_MOVIE_THUMBNAIL_HEIGHT); - $gb_result = $back = imagecolorallocate($image_p, 0, 0, 0); - $gb_result = imagefill($image_p, 0, 0, $back); - $gb_result = imagecopyresampled($image_p, $image, $delta_width, $delta_height, 0, 0, $width, $height, $width_orig, $height_orig); - - $gb_result = imageJpeg($image_p, $file_dir.$file['upload_id'].MULTIMEDIA_MOVIE_THUMBNAIL_NAME); - $gb_result = imageDestroy($image); - $gb_result = imageDestroy($image_p); - if($gb_result === false) { + $item_name = str_replace(".". $file['extension'], "", $file['physical_file_name']); + $temp_video_path = $file_dir . $item_name . "_temp.mp4"; // MP4Box変換前 + $video_path = $file_dir . $item_name . ".mp4"; // MP4Box変換後 + + if($file['extension'] != "mp4") { + //動画変換実施 + $str_cmd = MULTIMEDIA_FFMPEG_PATH . " -y -i " . $file_dir . $file['physical_file_name'] + ." " . MULTIMEDIA_FFMPEG_OPTION . " " . $temp_video_path . " 2>&1"; + exec($str_cmd, $arr, $ret); + + //変換エラー時 + if($ret != 0) { $uploadsAction->delUploadsById($file['upload_id']); - return $smartyAssign->getLang("multimedia_item_upload_thmbnail_create_error"); + return sprintf($smartyAssign->getLang("multimedia_item_upload_video_convert_error"), $ret); + }else { + //元動画ファイルを削除 + unlink($file_dir.$file['physical_file_name']); } + } + //MP4のアップロード時 + else { + // ファイル名称変更 + rename($file_dir . $file['physical_file_name'], $temp_video_path); + } - $session =& $container->getComponent("Session"); - $request =& $container->getComponent("Request"); - $multimedia_obj = $request->getParameter("multimedia_obj"); - $auth_id = $session->getParameter("_auth_id"); - if($auth_id >= _AUTH_CHIEF || $multimedia_obj['confirm_flag'] == _OFF) { - $agree_flag = _ON; - }else { - $agree_flag = _OFF; + //変換後の動画情報を取得 + $str_cmd = MULTIMEDIA_FFMPEG_PATH . " -i " . $temp_video_path . " 2>&1"; + exec($str_cmd, $stuout, $ret); + + //情報を取得出来なかった場合 + if($ret != 1) { + //ファイル削除(MP4Box変換前動画) + $multimediaAction->deleteFiles(array($temp_video_path)); + return $smartyAssign->getLang("multimedia_item_upload_video_information_error"); + } + + //動画情報から時間、サイズを取得 + foreach($stuout as $line) { + //時間を取得(フォーマット:Duration: 00:00:00.0) + preg_match("/Duration: [0-9]{2}:[0-9]{2}:[0-9]{2}\.\d+/s", $line, $matches); + + //時間を取得出来た場合 + if(count($matches) > 0) { + //「:」で文字列分割 + $result_line = split(":",$matches[0]); + + //動画の時間を計算 + $duration = intval(trim($result_line[1])) * 3600 + intval($result_line[2]) * 60 + $result_line[3]; + break; } - $params = array( - "album_id" => $attributes['album_id'], - "multimedia_id" => $attributes['multimedia_id'], - "item_name" => empty($attributes['item_name'])?str_replace(".". $file['extension'], "", $file['file_name']):$attributes['item_name'], - "agree_flag" => $agree_flag, - "item_sequence" => $itemSequence, - "upload_id" => $file['upload_id'], - "duration" => $duration, - "file_path" => $file_path, - "item_path" => "?". ACTION_KEY. "=". $file['action_name']. "&upload_id=". $file['upload_id'], - "item_description" => $attributes['item_description'], - "privacy" => $attributes['privacy'] - ); - - $item_id = $db->insertExecute("multimedia_item", $params, true, "item_id"); - if (!$item_id) { - $uploadsAction->delUploadsById($file['upload_id']); - return $smartyAssign->getLang("multimedia_item_upload_video_insert_error"); - } - if(!$multimediaAction->setItemTag($item_id, $attributes['item_tag'])) { - $uploadsAction->delUploadsById($file['upload_id']); - return $smartyAssign->getLang("multimedia_item_upload_video_tag_error"); - } - }else { - $uploadsAction->delUploadsById($file['upload_id']); - return $smartyAssign->getLang("multimedia_item_upload_video_type_error"); - } - - if(!$multimediaAction->setItemCount($attributes['album_id'], 1)) { - return $smartyAssign->getLang("multimedia_item_upload_video_count_error"); - } - - $result = $db->updateExecute("multimedia_album", array("item_upload_time" => timezone_date()), array("album_id" => $attributes['album_id']), true); - if($result === false) { - return $smartyAssign->getLang("multimedia_item_upload_video_insert_error"); - } + } + + //キャプチャ画像パスを定義 + $captuer_image_path = $file_dir . $file['upload_id'] . MULTIMEDIA_MOVIE_CAPTUER_NAME; + //サムネイル画像パスを定義 + $thumbmail_image_path = $file_dir.$file['upload_id'] . MULTIMEDIA_MOVIE_THUMBNAIL_NAME; + + //キャプチャ画像切り出し + //切り出し定義秒数で分岐 + switch(MULTIMEDIA_THUMBNAIL_SECONDS) { + //切り出し定義秒数が動画秒数未満である場合、切り出し定義秒数で画像切り出し + case MULTIMEDIA_THUMBNAIL_SECONDS < intval($duration): + $str_cmd = MULTIMEDIA_FFMPEG_PATH . " -i " . $temp_video_path . " -ss " . MULTIMEDIA_THUMBNAIL_SECONDS . " -vframes 1 -f image2 " . $captuer_image_path . " 2>&1"; + break; + //切り出し定義秒数が動画秒数以上である場合、動画の半分の秒数で画像切り出し(切り出し定義秒数が未設定の場合も含む) + default: + $str_cmd = MULTIMEDIA_FFMPEG_PATH . " -i " . $temp_video_path . " -ss " . intval($duration /2) . " -vframes 1 -f image2 " . $captuer_image_path . " 2>&1"; + break; + } + + exec($str_cmd, $stuout, $ret); + + //画像を作成出来なかった場合 + if($ret != 0) { + //ファイル削除(MP4Box変換前動画) + $multimediaAction->deleteFiles(array($temp_video_path)); + return $smartyAssign->getLang("multimedia_item_upload_thmbnail_create_error"); + } + + //キャプチャ画像サイズ等取得 + list($width_orig, $height_orig, $type, $attr) = GetImageSize($captuer_image_path); + + //比率等の計算 + $scale = min(MULTIMEDIA_MOVIE_THUMBNAIL_WIDTH / $width_orig, MULTIMEDIA_MOVIE_THUMBNAIL_HEIGHT / $height_orig); + $width = (int)($width_orig * $scale); + $height = (int)($height_orig * $scale); + $delta_width = (int)((MULTIMEDIA_MOVIE_THUMBNAIL_WIDTH - $width) / 2); + $delta_height = (int)((MULTIMEDIA_MOVIE_THUMBNAIL_HEIGHT - $height) / 2); + + //キャプチャ画像のキャンバスを生成 + $image_orig = imagecreatefromjpeg($captuer_image_path); + + //キャンバス作成に失敗した場合 + if($image_orig === false) { + //ファイル削除(MP4Box変換前動画、キャプチャ動画) + $multimediaAction->deleteFiles(array($temp_video_path, $captuer_image_path)); + return $smartyAssign->getLang("multimedia_item_upload_thmbnail_create_error"); + } + + $gb_result = false; + + //サムネイル画像のキャンバスを作成 + $image_p = imagecreatetruecolor(MULTIMEDIA_MOVIE_THUMBNAIL_WIDTH, MULTIMEDIA_MOVIE_THUMBNAIL_HEIGHT); + + //サムネイル画像のキャンバス作成に失敗した場合 + if($image_orig === false) { + //ファイル削除(MP4Box変換前動画、キャプチャ動画) + $multimediaAction->deleteFiles(array($temp_video_path, $captuer_image_path)); + return $smartyAssign->getLang("multimedia_item_upload_thmbnail_create_error"); + } + + //黒色を取得(0が取得される) + $back = imagecolorallocate($image_p, 0, 0, 0); + + //黒色の取得に失敗した場合(5.1.3以降はfalseを返し、その前までのバージョンでは-1を返す) + if($back === false || $back === -1) { + //ファイル削除(MP4Box変換前動画、キャプチャ動画) + $multimediaAction->deleteFiles(array($temp_video_path, $captuer_image_path)); + return $smartyAssign->getLang("multimedia_item_upload_thmbnail_create_error"); + } + + //キャンバスを黒色で塗りつぶす + $gb_result = imagefill($image_p, 0, 0, $back); + + //塗りつぶしに失敗した場合 + if($gb_result === false) { + //ファイル削除(MP4Box変換前動画、キャプチャ動画) + $multimediaAction->deleteFiles(array($temp_video_path, $captuer_image_path)); + return $smartyAssign->getLang("multimedia_item_upload_thmbnail_create_error"); + } + + //キャプチャ画像を縮小し、サムネイル画像のキャンバスに貼り付け + $gb_result = imagecopyresampled($image_p, $image_orig, $delta_width, $delta_height, 0, 0, $width, $height, $width_orig, $height_orig); + + //貼り付けに失敗した場合 + if($gb_result === false) { + //ファイル削除(MP4Box変換前動画、キャプチャ動画) + $multimediaAction->deleteFiles(array($temp_video_path, $captuer_image_path)); + return $smartyAssign->getLang("multimedia_item_upload_thmbnail_create_error"); + } + + //サムネイル画像出力 + $gb_result = imageJpeg($image_p, $thumbmail_image_path); + + //サムネイル画像出力に失敗した場合 + if($gb_result === false) { + //ファイル削除(MP4Box変換前動画、キャプチャ動画) + $multimediaAction->deleteFiles(array($temp_video_path, $captuer_image_path)); + return $smartyAssign->getLang("multimedia_item_upload_thmbnail_create_error"); + } + + //GDリソースを解放(解放できない場合でも、サムネイル画像は作成完了しているため、エラーとして検知しない) + imageDestroy($image_orig); + imageDestroy($image_p); + + //ファイル削除(キャプチャ画像) + $multimediaAction->deleteFiles(array($captuer_image_path)); + + //MP4Boxで動画変換実施(動画情報、キャプチャ画像切り出し後ではないと変換できない) + $str_cmd = MULTIMEDIA_MP4BOX_PATH . " -add " . $temp_video_path ." -brand mmp4:1 -new " . $video_path . " 2>&1"; + exec($str_cmd, $arr, $ret); + + //変換エラー時 + if($ret != 0) { + //ファイル削除(MP4Box変換前動画、サムネイル動画) + $multimediaAction->deleteFiles(array($temp_video_path, $thumbmail_image_path)); + return sprintf($smartyAssign->getLang("multimedia_item_upload_video_convert_error"), $ret); + }else { + //ファイル削除(MP4Box変換前動画) + $multimediaAction->deleteFiles(array($temp_video_path)); + } + + //動画情報更新 + $file['physical_file_name'] = $item_name.".mp4"; + $upload_params = array( + "file_name" => $file['physical_file_name'], + "physical_file_name" => $file['physical_file_name'], + "file_size" => filesize($video_path), + "extension" => "mp4", + "mimetype" => "video/mp4" + ); + $where_params = array( + "upload_id" => $file['upload_id'] + ); + if(!$uploadsAction->updUploads($upload_params, $where_params)) { + //ファイル削除(MP4Box変換後動画、サムネイル動画) + $multimediaAction->deleteFiles(array($video_path, $thumbmail_image_path)); + return $smartyAssign->getLang("multimedia_item_upload_video_update_error"); + } + + $session =& $container->getComponent("Session"); + $request =& $container->getComponent("Request"); + $multimedia_obj = $request->getParameter("multimedia_obj"); + $auth_id = $session->getParameter("_auth_id"); + if($auth_id >= _AUTH_CHIEF || $multimedia_obj['confirm_flag'] == _OFF) { + $agree_flag = _ON; + }else { + $agree_flag = _OFF; + } + $params = array( + "album_id" => $attributes['album_id'], + "multimedia_id" => $attributes['multimedia_id'], + "item_name" => empty($attributes['item_name'])?str_replace(".". $file['extension'], "", $file['file_name']):$attributes['item_name'], + "agree_flag" => $agree_flag, + "item_sequence" => $itemSequence, + "upload_id" => $file['upload_id'], + "duration" => $duration, + "file_path" => $file_path, + "item_path" => "?". ACTION_KEY. "=". $file['action_name']. "&upload_id=". $file['upload_id'], + "item_description" => $attributes['item_description'], + "privacy" => $attributes['privacy'] + ); + + $item_id = $db->insertExecute("multimedia_item", $params, true, "item_id"); + + if (!$item_id) { + //ファイル削除(MP4Box変換後動画、サムネイル動画) + $multimediaAction->deleteFiles(array($video_path, $thumbmail_image_path)); + return $smartyAssign->getLang("multimedia_item_upload_video_insert_error"); + } + if(!$multimediaAction->setItemTag($item_id, $attributes['item_tag'])) { + //ファイル削除(MP4Box変換後動画、サムネイル動画) + $multimediaAction->deleteFiles(array($video_path, $thumbmail_image_path)); + return $smartyAssign->getLang("multimedia_item_upload_video_tag_error"); + } + + if(!$multimediaAction->setItemCount($attributes['album_id'], 1)) { + return $smartyAssign->getLang("multimedia_item_upload_video_count_error"); + } + + $result = $db->updateExecute("multimedia_album", array("item_upload_time" => timezone_date()), array("album_id" => $attributes['album_id']), true); + if($result === false) { + return $smartyAssign->getLang("multimedia_item_upload_video_insert_error"); + } } - + return; } } -?> \ No newline at end of file +?> diff --git a/multimedia/validator/Validator_ItemUpload.class.php.org b/multimedia/validator/Validator_ItemUpload.class.php.org new file mode 100644 index 0000000..f862a04 --- /dev/null +++ b/multimedia/validator/Validator_ItemUpload.class.php.org @@ -0,0 +1,191 @@ +getComponent("DbObject"); + $fileUpload =& $container->getComponent("FileUpload"); + $uploadsAction =& $container->getComponent("uploadsAction"); + + $filterChain =& $container->getComponent("FilterChain"); + $smartyAssign =& $filterChain->getFilterByName("SmartyAssign"); + $multimediaAction =& $container->getComponent("multimediaAction"); + + if(!isset($attributes['multimedia_id']) || !isset($attributes['album_id']) || !isset($attributes['privacy'])) { + return $smartyAssign->getLang("_invalid_input"); + } + + //ffmpeg拡張のチェック + if(!$multimediaAction->hasFfmpegLib()) { + $extension_fullname = PHP_EXTENSION_DIR . "/" . MULTIMEDIA_EXTENSION.".".PHP_SHLIB_SUFFIX; + return sprintf($smartyAssign->getLang("multimedia_item_upload_video_extension_error"), $extension_fullname); + } + + //アップロードしたファイルの処理 + $files = $uploadsAction->uploads(); + $params = array( + "album_id" => $attributes['album_id'] + ); + + $itemSequence = $db->maxExecute("multimedia_item", "item_sequence", $params); + $actionChain =& $container->getComponent("ActionChain"); + $action_name = $actionChain->getCurActionName(); + $pathList = explode("_", $action_name); + $dirname = $pathList[0]; + $file_path = $dirname."/"; + + foreach($files as $file) { + $itemSequence++; + $file_dir = FILEUPLOADS_DIR.$file_path; + + if($file['extension'] != "flv") { + $item_name = str_replace(".". $file['extension'], "", $file['physical_file_name']); + $str_cmd = "/usr/local/bin/ffmpeg -y -i ".$file_dir.$file['physical_file_name']." -ar 44100 ".$file_dir.$item_name.".flv 2>&1"; + exec($str_cmd, $arr, $ret); + if($ret != 0) { + $uploadsAction->delUploadsById($file['upload_id']); + return sprintf($smartyAssign->getLang("multimedia_item_upload_video_convert_error"), $ret); + }else { + unlink($file_dir.$file['physical_file_name']); + } + $file['physical_file_name'] = $item_name.".flv"; + $upload_params = array( + "file_name" => $file['physical_file_name'], + "physical_file_name" => $file['physical_file_name'], + "file_size" => filesize($file_dir.$file['physical_file_name']), + "extension" => "flv" + ); + $where_params = array( + "upload_id" => $file['upload_id'] + ); + if(!$uploadsAction->updUploads($upload_params, $where_params)) { + $uploadsAction->delUploadsById($file['upload_id']); + return $smartyAssign->getLang("multimedia_item_upload_video_update_error"); + } + } + + //サムネイルを作成 + $movie = $file_dir.$file['physical_file_name']; + $mov = new ffmpeg_movie($movie); + if ($mov->hasVideo()) { + $duration = $mov->getDuration(); + $frame = $mov->getFrame(ceil($mov->getFrameCount()/2)); + if($frame === false) { + $frame = $mov->getFrame(1); + if($frame === false) { + $uploadsAction->delUploadsById($file['upload_id']); + return $smartyAssign->getLang("multimedia_item_upload_thmbnail_get_error"); + } + } + + if(!function_exists("gd_info")) { + $uploadsAction->delUploadsById($file['upload_id']); + return $smartyAssign->getLang("multimedia_item_upload_video_nogd_error"); + } + $image = $frame->toGDImage(); + if($image === false) { + $uploadsAction->delUploadsById($file['upload_id']); + return $smartyAssign->getLang("multimedia_item_upload_thmbnail_create_error"); + } + $width_orig = $frame->getWidth(); + $height_orig = $frame->getHeight(); + $scale = min(MULTIMEDIA_MOVIE_THUMBNAIL_WIDTH/$width_orig, MULTIMEDIA_MOVIE_THUMBNAIL_HEIGHT/$height_orig); + $width = (int)($width_orig*$scale); + $height = (int)($height_orig*$scale); + $delta_width = (int)((MULTIMEDIA_MOVIE_THUMBNAIL_WIDTH - $width)/2); + $delta_height = (int)((MULTIMEDIA_MOVIE_THUMBNAIL_HEIGHT - $height)/2); + + $gb_result = false; + $gb_result = $image_p = imagecreatetruecolor(MULTIMEDIA_MOVIE_THUMBNAIL_WIDTH, MULTIMEDIA_MOVIE_THUMBNAIL_HEIGHT); + $gb_result = $back = imagecolorallocate($image_p, 0, 0, 0); + $gb_result = imagefill($image_p, 0, 0, $back); + $gb_result = imagecopyresampled($image_p, $image, $delta_width, $delta_height, 0, 0, $width, $height, $width_orig, $height_orig); + + $gb_result = imageJpeg($image_p, $file_dir.$file['upload_id'].MULTIMEDIA_MOVIE_THUMBNAIL_NAME); + $gb_result = imageDestroy($image); + $gb_result = imageDestroy($image_p); + if($gb_result === false) { + $uploadsAction->delUploadsById($file['upload_id']); + return $smartyAssign->getLang("multimedia_item_upload_thmbnail_create_error"); + } + + $session =& $container->getComponent("Session"); + $request =& $container->getComponent("Request"); + $multimedia_obj = $request->getParameter("multimedia_obj"); + $auth_id = $session->getParameter("_auth_id"); + if($auth_id >= _AUTH_CHIEF || $multimedia_obj['confirm_flag'] == _OFF) { + $agree_flag = _ON; + }else { + $agree_flag = _OFF; + } + $params = array( + "album_id" => $attributes['album_id'], + "multimedia_id" => $attributes['multimedia_id'], + "item_name" => empty($attributes['item_name'])?str_replace(".". $file['extension'], "", $file['file_name']):$attributes['item_name'], + "agree_flag" => $agree_flag, + "item_sequence" => $itemSequence, + "upload_id" => $file['upload_id'], + "duration" => $duration, + "file_path" => $file_path, + "item_path" => "?". ACTION_KEY. "=". $file['action_name']. "&upload_id=". $file['upload_id'], + "item_description" => $attributes['item_description'], + "privacy" => $attributes['privacy'] + ); + + $item_id = $db->insertExecute("multimedia_item", $params, true, "item_id"); + if (!$item_id) { + $uploadsAction->delUploadsById($file['upload_id']); + return $smartyAssign->getLang("multimedia_item_upload_video_insert_error"); + } + if(!$multimediaAction->setItemTag($item_id, $attributes['item_tag'])) { + $uploadsAction->delUploadsById($file['upload_id']); + return $smartyAssign->getLang("multimedia_item_upload_video_tag_error"); + } + }else { + $uploadsAction->delUploadsById($file['upload_id']); + return $smartyAssign->getLang("multimedia_item_upload_video_type_error"); + } + + if(!$multimediaAction->setItemCount($attributes['album_id'], 1)) { + return $smartyAssign->getLang("multimedia_item_upload_video_count_error"); + } + + $result = $db->updateExecute("multimedia_album", array("item_upload_time" => timezone_date()), array("album_id" => $attributes['album_id']), true); + if($result === false) { + return $smartyAssign->getLang("multimedia_item_upload_video_insert_error"); + } + } + + return; + } +} +?> \ No newline at end of file diff --git a/multimedia/validator/Validator_MultimediaCount.class.php b/multimedia/validator/Validator_MultimediaCount.class.php index fdd69ff..2157f01 100644 --- a/multimedia/validator/Validator_MultimediaCount.class.php +++ b/multimedia/validator/Validator_MultimediaCount.class.php @@ -1,46 +1,46 @@ -getComponent("multimediaView"); - - $multimediaCount = $multimediaView->getMultimediaCount(); - if ($multimediaCount == 0) { - return $errStr; - } - - $request =& $container->getComponent("Request"); - $request->setParameter("multimediaCount", $multimediaCount); - - return; - } -} +getComponent("multimediaView"); + + $multimediaCount = $multimediaView->getMultimediaCount(); + if ($multimediaCount == 0) { + return $errStr; + } + + $request =& $container->getComponent("Request"); + $request->setParameter("multimediaCount", $multimediaCount); + + return; + } +} ?> \ No newline at end of file diff --git a/multimedia/validator/Validator_MultimediaExist.class.php b/multimedia/validator/Validator_MultimediaExist.class.php index e648afd..4d26c64 100644 --- a/multimedia/validator/Validator_MultimediaExist.class.php +++ b/multimedia/validator/Validator_MultimediaExist.class.php @@ -1,73 +1,73 @@ -getComponent("ActionChain"); - $actionName = $actionChain->getCurActionName(); - $multimediaView =& $container->getComponent("multimediaView"); - $request =& $container->getComponent('Request'); - - if (empty($attributes['multimedia_id'])) { - $attributes['multimedia_id'] =& $multimediaView->getCurrentMultimediaId(); - $request->setParameter('multimedia_id', $attributes['multimedia_id']); - } - - if (empty($attributes['multimedia_id'])) { - $attributes['multimedia_id'] =& $multimediaView->getFirstMultimediaId(); - $request->setParameter("multimedia_id", $attributes['multimedia_id']); - } - - if (empty($attributes['multimedia_id']) && strpos($actionName, 'multimedia_view_edit') === 0) { - return; - } - - if (empty($attributes['multimedia_id']) && $actionName != 'multimedia_action_edit_initialize') { - return $errStr; - } - - if (empty($attributes['block_id'])) { - $block =& $multimediaView->getBlock(); - if ($attributes['room_id'] != $block['room_id']) { - return $errStr; - } - - $attributes['block_id'] = $block['block_id']; - $request->setParameter("block_id", $attributes['block_id']); - } - - if ($actionName == 'multimedia_action_edit_initialize') { - return; - } - - if (!$multimediaView->multimediaExist()) { - return $errStr; - } - - return; - } -} +getComponent("ActionChain"); + $actionName = $actionChain->getCurActionName(); + $multimediaView =& $container->getComponent("multimediaView"); + $request =& $container->getComponent('Request'); + + if (empty($attributes['multimedia_id'])) { + $attributes['multimedia_id'] =& $multimediaView->getCurrentMultimediaId(); + $request->setParameter('multimedia_id', $attributes['multimedia_id']); + } + + if (empty($attributes['multimedia_id'])) { + $attributes['multimedia_id'] =& $multimediaView->getFirstMultimediaId(); + $request->setParameter("multimedia_id", $attributes['multimedia_id']); + } + + if (empty($attributes['multimedia_id']) && strpos($actionName, 'multimedia_view_edit') === 0) { + return; + } + + if (empty($attributes['multimedia_id']) && $actionName != 'multimedia_action_edit_initialize') { + return $errStr; + } + + if (empty($attributes['block_id'])) { + $block =& $multimediaView->getBlock(); + if ($attributes['room_id'] != $block['room_id']) { + return $errStr; + } + + $attributes['block_id'] = $block['block_id']; + $request->setParameter("block_id", $attributes['block_id']); + } + + if ($actionName == 'multimedia_action_edit_initialize') { + return; + } + + if (!$multimediaView->multimediaExist()) { + return $errStr; + } + + return; + } +} ?> \ No newline at end of file diff --git a/multimedia/validator/Validator_MultimediaView.class.php b/multimedia/validator/Validator_MultimediaView.class.php index 034688d..6dc49a6 100644 --- a/multimedia/validator/Validator_MultimediaView.class.php +++ b/multimedia/validator/Validator_MultimediaView.class.php @@ -1,60 +1,60 @@ -getComponent("Session"); - $auth_id = $session->getParameter("_auth_id"); - - $multimediaView =& $container->getComponent("multimediaView"); - - if ($auth_id < _AUTH_CHIEF) { - $multimedia_id = $multimediaView->getCurrentMultimediaId(); - if ($multimedia_id != $attributes['multimedia_id']) { - return $errStr; - } - } - - $actionChain =& $container->getComponent("ActionChain"); - $actionName = $actionChain->getCurActionName(); - if (empty($attributes["multimedia_id"])) { - $multimedia_obj = $multimediaView->getDefaultMultimedia(); - } else { - $multimedia_obj = $multimediaView->getCurrentMultimedia(); - } - - if (empty($multimedia_obj)) { - return $errStr; - } - - $request =& $container->getComponent("Request"); - $request->setParameter("multimedia_obj", $multimedia_obj); - - return; - } -} +getComponent("Session"); + $auth_id = $session->getParameter("_auth_id"); + + $multimediaView =& $container->getComponent("multimediaView"); + + if ($auth_id < _AUTH_CHIEF) { + $multimedia_id = $multimediaView->getCurrentMultimediaId(); + if ($multimedia_id != $attributes['multimedia_id']) { + return $errStr; + } + } + + $actionChain =& $container->getComponent("ActionChain"); + $actionName = $actionChain->getCurActionName(); + if (empty($attributes["multimedia_id"])) { + $multimedia_obj = $multimediaView->getDefaultMultimedia(); + } else { + $multimedia_obj = $multimediaView->getCurrentMultimedia(); + } + + if (empty($multimedia_obj)) { + return $errStr; + } + + $request =& $container->getComponent("Request"); + $request->setParameter("multimedia_obj", $multimedia_obj); + + return; + } +} ?> \ No newline at end of file diff --git a/multimedia/validator/Validator_MultimediaXml.class.php b/multimedia/validator/Validator_MultimediaXml.class.php index 6abc9ce..c81b0e4 100644 --- a/multimedia/validator/Validator_MultimediaXml.class.php +++ b/multimedia/validator/Validator_MultimediaXml.class.php @@ -1,53 +1,53 @@ -getComponent("Session"); - $request =& $container->getComponent("Request"); - $db =& $container->getComponent("DbObject"); - $multimediaView =& $container->getComponent("multimediaView"); - - $item = $multimediaView->getItem($attributes); - if(empty($item)) { - return $errStr; - } - - $item_list = $multimediaView->getSimilarItems($attributes); - if($item_list === false) { - return $errStr; - } - - $request->setParameter("item", $item); - $request->setParameter("list", $item_list); - return; - } -} +getComponent("Session"); + $request =& $container->getComponent("Request"); + $db =& $container->getComponent("DbObject"); + $multimediaView =& $container->getComponent("multimediaView"); + + $item = $multimediaView->getItem($attributes); + if(empty($item)) { + return $errStr; + } + + $item_list = $multimediaView->getSimilarItems($attributes); + if($item_list === false) { + return $errStr; + } + + $request->setParameter("item", $item); + $request->setParameter("list", $item_list); + return; + } +} ?> \ No newline at end of file diff --git a/multimedia/view/edit/entry/Entry.class.php b/multimedia/view/edit/entry/Entry.class.php index ef89b8f..dcf5c1e 100644 --- a/multimedia/view/edit/entry/Entry.class.php +++ b/multimedia/view/edit/entry/Entry.class.php @@ -30,12 +30,6 @@ class Multimedia_View_Edit_Entry extends Action */ function execute() { - //ffmpeg拡張のチェック - if(!$this->multimediaAction->hasFfmpegLib()) { - $this->extension_fullname = PHP_EXTENSION_DIR . "/" . MULTIMEDIA_EXTENSION.".".PHP_SHLIB_SUFFIX; - $this->ffmpeg_install_flag = false; - } - $this->multimedia =& $this->multimediaView->getMultimedia(); if (empty($this->multimedia)) { $this->multimedia =& $this->multimediaView->getDefaultMultimedia(); diff --git a/multimedia/view/main/album/entry/Entry.class.php b/multimedia/view/main/album/entry/Entry.class.php index daaa2b3..b7efc4f 100644 --- a/multimedia/view/main/album/entry/Entry.class.php +++ b/multimedia/view/main/album/entry/Entry.class.php @@ -1,62 +1,62 @@ -albumJacketSamples = $this->fileView->getCurrentFiles(HTDOCS_DIR.MULTIMEDIA_SAMPLR_JACKET_PATH.MULTIMEDIA_SAMPLR_JACKET_DIR); - - if(empty($this->album_id)) { - $config = $this->configView->getConfig($this->module_id, false); - if ($config === false) { - return $config; - } - - $this->album_obj["multimedia_id"] = $this->multimedia_obj['multimedia_id']; - $this->album_obj["album_jacket"] = $config["album_jacket"]["conf_value"]; - $this->album_obj["public_flag"] = _ON; - }else { - $this->album_obj = $this->multimediaView->getAlbum($this->album_id); - if($this->album_obj === false) { - return 'error'; - } - } - - $this->album_number = $this->multimediaView->getAlbumCount($this->multimedia_obj['multimedia_id']); - if ($this->album_number === false) { - return 'error'; - } - $this->album_number++; - return 'success'; - } -} +albumJacketSamples = $this->fileView->getCurrentFiles(HTDOCS_DIR.MULTIMEDIA_SAMPLR_JACKET_PATH.MULTIMEDIA_SAMPLR_JACKET_DIR); + + if(empty($this->album_id)) { + $config = $this->configView->getConfig($this->module_id, false); + if ($config === false) { + return $config; + } + + $this->album_obj["multimedia_id"] = $this->multimedia_obj['multimedia_id']; + $this->album_obj["album_jacket"] = $config["album_jacket"]["conf_value"]; + $this->album_obj["public_flag"] = _ON; + }else { + $this->album_obj = $this->multimediaView->getAlbum($this->album_id); + if($this->album_obj === false) { + return 'error'; + } + } + + $this->album_number = $this->multimediaView->getAlbumCount($this->multimedia_obj['multimedia_id']); + if ($this->album_number === false) { + return 'error'; + } + $this->album_number++; + return 'success'; + } +} ?> \ No newline at end of file diff --git a/multimedia/view/main/album/jacket/Jacket.class.php b/multimedia/view/main/album/jacket/Jacket.class.php index 61bc34b..fa50b28 100644 --- a/multimedia/view/main/album/jacket/Jacket.class.php +++ b/multimedia/view/main/album/jacket/Jacket.class.php @@ -1,56 +1,56 @@ -upload_id) - && $this->upload_id != $this->session->getParameter("multimedia_jacket_upload_id")) { - return "error"; - } - - $album = $this->db->selectExecute("multimedia_album", array("album_id"=>$this->album_id)); - if (!empty($album) || isset($album[0])) { - $this->album_obj = $album[0]; - } - - if (empty($this->upload_id)) { - $imageSize = $this->multimediaView->getImageSize($this->album_jacket); - } else { - $imageSize = $this->multimediaView->getImageSize($this->upload_id); - $this->album_obj["upload_id"] = $this->upload_id; - } - - $this->album_obj["album_jacket"] = $this->album_jacket; - $this->album_obj["jacket_style"] = $this->multimediaView->getImageStyle($imageSize[0], $imageSize[1], MULTIMEDIA_JACKET_WIDTH, MULTIMEDIA_JACKET_HEIGHT); - - return "success"; - } -} -?> +upload_id) + && $this->upload_id != $this->session->getParameter("multimedia_jacket_upload_id")) { + return "error"; + } + + $album = $this->db->selectExecute("multimedia_album", array("album_id"=>$this->album_id)); + if (!empty($album) || isset($album[0])) { + $this->album_obj = $album[0]; + } + + if (empty($this->upload_id)) { + $imageSize = $this->multimediaView->getImageSize($this->album_jacket); + } else { + $imageSize = $this->multimediaView->getImageSize($this->upload_id); + $this->album_obj["upload_id"] = $this->upload_id; + } + + $this->album_obj["album_jacket"] = $this->album_jacket; + $this->album_obj["jacket_style"] = $this->multimediaView->getImageStyle($imageSize[0], $imageSize[1], MULTIMEDIA_JACKET_WIDTH, MULTIMEDIA_JACKET_HEIGHT); + + return "success"; + } +} +?> diff --git a/multimedia/view/main/channel/Channel.class.php b/multimedia/view/main/channel/Channel.class.php index 79110b1..5f31ce3 100644 --- a/multimedia/view/main/channel/Channel.class.php +++ b/multimedia/view/main/channel/Channel.class.php @@ -1,81 +1,81 @@ -album_count = $this->multimediaView->getAlbumCount($this->multimedia_obj['multimedia_id']); - if($this->album_count === false) { - return 'error'; - } - - if($this->album_count == 0) { - return 'success'; - } - - if(!$this->album_edit_flag) { - $visible_row = $this->session->getParameter("multimedia_channel_visible_row".$this->block_id); - if ($this->visible_row != "") { - if($visible_row != "" && $this->visible_row != $visible_row) { - $this->now_page = 1; - } - $this->session->setParameter("multimedia_channel_visible_row".$this->block_id, $this->visible_row); - }else if($visible_row != ""){ - $this->visible_row = $visible_row; - }else { - $this->visible_row = $this->multimedia_obj['album_visible_row']; - } - - $now_page = $this->session->getParameter("multimedia_channel_now_page".$this->block_id); - if(!empty($this->now_page)) { - $this->session->setParameter("multimedia_channel_now_page".$this->block_id, $this->now_page); - }else if(!empty($now_page)){ - $this->now_page = $now_page; - } - } - - $this->multimediaView->setPageInfo($this->pager, $this->album_count, $this->visible_row, $this->now_page); - $order_params = array( - "album_sequence" => "ASC" - ); - $this->album_list = $this->multimediaView->getAlbumList($this->multimedia_obj['multimedia_id'], $order_params, $this->visible_row, $this->pager['disp_begin']); - if($this->album_list === false) { - return 'error'; - } - - return 'success'; - } -} +album_count = $this->multimediaView->getAlbumCount($this->multimedia_obj['multimedia_id']); + if($this->album_count === false) { + return 'error'; + } + + if($this->album_count == 0) { + return 'success'; + } + + if(!$this->album_edit_flag) { + $visible_row = $this->session->getParameter("multimedia_channel_visible_row".$this->block_id); + if ($this->visible_row != "") { + if($visible_row != "" && $this->visible_row != $visible_row) { + $this->now_page = 1; + } + $this->session->setParameter("multimedia_channel_visible_row".$this->block_id, $this->visible_row); + }else if($visible_row != ""){ + $this->visible_row = $visible_row; + }else { + $this->visible_row = $this->multimedia_obj['album_visible_row']; + } + + $now_page = $this->session->getParameter("multimedia_channel_now_page".$this->block_id); + if(!empty($this->now_page)) { + $this->session->setParameter("multimedia_channel_now_page".$this->block_id, $this->now_page); + }else if(!empty($now_page)){ + $this->now_page = $now_page; + } + } + + $this->multimediaView->setPageInfo($this->pager, $this->album_count, $this->visible_row, $this->now_page); + $order_params = array( + "album_sequence" => "ASC" + ); + $this->album_list = $this->multimediaView->getAlbumList($this->multimedia_obj['multimedia_id'], $order_params, $this->visible_row, $this->pager['disp_begin']); + if($this->album_list === false) { + return 'error'; + } + + return 'success'; + } +} ?> \ No newline at end of file diff --git a/multimedia/view/main/comment/Comment.class.php b/multimedia/view/main/comment/Comment.class.php index f8476a7..a650058 100644 --- a/multimedia/view/main/comment/Comment.class.php +++ b/multimedia/view/main/comment/Comment.class.php @@ -1,54 +1,54 @@ -commentCount = $this->multimediaView->getCommentCount($this->item_id); - if ($this->comments === false) { - return 'error'; - } - $this->multimediaView->setPageInfo($this->pager, $this->commentCount, MULTIMEDIA_VISIBLE_ITEM_COMMENT, $this->now_page); - $this->comments = $this->multimediaView->getComments($this->item_id, $this->pager['disp_begin']); - if ($this->comments === false) { - return 'error'; - } - - return 'success'; - } -} -?> +commentCount = $this->multimediaView->getCommentCount($this->item_id); + if ($this->comments === false) { + return 'error'; + } + $this->multimediaView->setPageInfo($this->pager, $this->commentCount, MULTIMEDIA_VISIBLE_ITEM_COMMENT, $this->now_page); + $this->comments = $this->multimediaView->getComments($this->item_id, $this->pager['disp_begin']); + if ($this->comments === false) { + return 'error'; + } + + return 'success'; + } +} +?> diff --git a/multimedia/view/main/init/Init.class.php b/multimedia/view/main/init/Init.class.php index 7f7b958..875e819 100644 --- a/multimedia/view/main/init/Init.class.php +++ b/multimedia/view/main/init/Init.class.php @@ -1,36 +1,37 @@ -multimedia_obj['display'] == MULTIMEDIA_DISPLAY_ALBUM || $this->album_edit_flag == _ON) { - return 'channel'; - }else { - return 'list'; - } - } -} -?> \ No newline at end of file +multimedia_obj['display'] == MULTIMEDIA_DISPLAY_ALBUM || $this->album_edit_flag == _ON) { + return 'channel'; + }else { + return 'list'; + } + } +} +?> diff --git a/multimedia/view/main/item/detail/Detail.class.php b/multimedia/view/main/item/detail/Detail.class.php index 24ad265..0d08106 100644 --- a/multimedia/view/main/item/detail/Detail.class.php +++ b/multimedia/view/main/item/detail/Detail.class.php @@ -1,89 +1,94 @@ -dialog_name = $this->item['item_name']; - $params = array( - $this->item_id - ); - $sql = "UPDATE {multimedia_item} ". - "SET item_play_count = item_play_count + 1 ". - "WHERE item_id = ? "; - $result = $this->db->execute($sql, $params); - if ($result === false) { - return 'error'; - } - - $this->commentCount = $this->multimediaView->getCommentCount($this->item_id); - if ($this->commentCount === false) { - return 'error'; - } - - $action_name = $this->actionChain->getCurActionName(); - $pathList = explode("_", $action_name); - $dirname = $pathList[0]; - $this->play_action = $dirname."_view_main_play"; - $this->xml_action = $dirname."_view_main_xml"; - $this->embed_code = '' - .''; - $this->item_list = $this->multimediaView->getSimilarItems($this->item_id); - if ($this->item_list === false) { - return 'error'; - } - - $this->tags = $this->multimediaView->getTags($this->item_id); - if($this->tags === false) { - return 'error'; - } - - $channel = $this->db->selectExecute("multimedia_album", array('album_id' => $this->item['album_id'])); - if($this->tags === false || !isset($channel[0])) { - return 'error'; - } - $this->channel = $channel[0]; - - return 'success'; - } -} +dialog_name = $this->item['item_name']; + + $this->commentCount = $this->multimediaView->getCommentCount($this->item_id); + if ($this->commentCount === false) { + return 'error'; + } + + + $action_name = $this->actionChain->getCurActionName(); + $pathList = explode("_", $action_name); + $dirname = $pathList[0]; +// $this->play_action = $dirname."_view_main_play"; + $this->iframe_action = $dirname."_view_main_item_iframe"; +// $this->xml_action = $dirname."_view_main_xml"; + $this->embed_code = ''; + +// $this->iframe_width = MULTIMEDIA_MOVIE_PLAYER_WIDTH + 2; +// $this->iframe_height = MULTIMEDIA_MOVIE_PLAYER_HEIGHT + MULTIMEDIA_MOVIE_PLAYER_CONTROLLER_HEIGHT + 1; + $this->iframe_width = MULTIMEDIA_MOVIE_PLAYER_WIDTH; + $this->iframe_height = MULTIMEDIA_MOVIE_PLAYER_HEIGHT; + + $this->item_list = $this->multimediaView->getSimilarItems($this->item_id); + if ($this->item_list === false) { + return 'error'; + } + + $this->tags = $this->multimediaView->getTags($this->item_id); + if($this->tags === false) { + return 'error'; + } + + $channel = $this->db->selectExecute("multimedia_album", array('album_id' => $this->item['album_id'])); + if($this->tags === false || !isset($channel[0])) { + return 'error'; + } + $this->channel = $channel[0]; + +// list($this->action_path, $this->upload_id_string) = split("&", $this->item['item_path']); + + return 'success'; + } +} ?> \ No newline at end of file diff --git a/multimedia/view/main/item/edit/Edit.class.php b/multimedia/view/main/item/edit/Edit.class.php index 1156171..f696e58 100644 --- a/multimedia/view/main/item/edit/Edit.class.php +++ b/multimedia/view/main/item/edit/Edit.class.php @@ -1,51 +1,51 @@ -filterChain->getFilterByName("SmartyAssign"); - $this->dialog_name = sprintf($smartyAssign->getLang("multimedia_item_edit_title"), $this->item["item_name"]); - - $order_params = array( - "album_sequence" => "ASC" - ); - $this->album_list = $this->multimediaView->getAlbumList($this->item['multimedia_id'], $order_params); - if($this->album_list === false) { - return 'error'; - } - return 'success'; - } -} +filterChain->getFilterByName("SmartyAssign"); + $this->dialog_name = sprintf($smartyAssign->getLang("multimedia_item_edit_title"), $this->item["item_name"]); + + $order_params = array( + "album_sequence" => "ASC" + ); + $this->album_list = $this->multimediaView->getAlbumList($this->item['multimedia_id'], $order_params); + if($this->album_list === false) { + return 'error'; + } + return 'success'; + } +} ?> \ No newline at end of file diff --git a/multimedia/view/main/item/iframe/Iframe.class.php b/multimedia/view/main/item/iframe/Iframe.class.php new file mode 100644 index 0000000..9b8d733 --- /dev/null +++ b/multimedia/view/main/item/iframe/Iframe.class.php @@ -0,0 +1,309 @@ +multimediaView->getItem($this->item_id); + + $smartyAssign =& $this->filterChain->getFilterByName('SmartyAssign'); + + //動画情報が存在しない場合 + if(empty($item)) { + //エラーメッセージを格納 + $errStr = $smartyAssign->getLang('multimedia_err_no_item'); + } + //動画情報が存在する場合 + else { + //動画が公開領域で閲覧可能ではない場合 + if($item['privacy'] > _AUTH_GUEST) { + //ユーザIDを取得出来ない場合は閲覧不可 + $user_id = $this->session->getParameter("_user_id"); + if(empty($user_id)) { + //エラーメッセージを格納 + $errStr = $smartyAssign->getLang('multimedia_err_incorrectauth'); + } + } + + //ユーザエージェント判定 + $ua = $_SERVER['HTTP_USER_AGENT']; + switch (true) { + //IEの場合はFlashでのみ再生 + case (preg_match('/MSIE [6-9]/', $ua)): + $flash_use_only = true; + break; + + //Safari判定 + case (preg_match('/Safari/', $ua)): + //Macの場合はFlashでのみ再生 + if(preg_match('/Macintosh;/', $ua)) { + $flash_use_only = true; + break; + } + //Android標準ブラウザの場合は自動再生させない + if((preg_match('/Android/', $ua)) && !(preg_match('/Chrome/', $ua))) { + $auto_start = false; + break; + } + } + + //埋め込みかどうかをパラメタから判断し、各値を設定 + //パラメタがないか、通常再生(iframe)の場合 + if(empty($this->type) || $this->type != 'embeded') { + //自動再生判定 + if($auto_start) { + $play_mode = '.jPlayer("play")'; + } else { + $play_mode = ''; + } + $css = 'jp-video-normal'; + $multimedia_movie_player_width = MULTIMEDIA_MOVIE_PLAYER_WIDTH; + $multimedia_movie_player_height = MULTIMEDIA_MOVIE_PLAYER_HEIGHT; + } + //埋め込み再生の場合 + else { + $play_mode = ''; + $css = 'jp-video-embeded'; + $multimedia_movie_player_width = MULTIMEDIA_MOVIE_PLAYER_EMBEDED_WIDTH; + $multimedia_movie_player_height = MULTIMEDIA_MOVIE_PLAYER_EMBEDED_HEIGHT; + } + + //jPlayerで再生する場合はborder分を減算 + if(! $flash_use_only) { + $multimedia_movie_player_width -= 2; + $multimedia_movie_player_height -= 2; + } else { + //エラーが発生している場合はborder分を減算 + if($errStr !== null) { + $multimedia_movie_player_width -= 2; + $multimedia_movie_player_height -= 2; + } + } + + // 各値を設定 + $base_url = BASE_URL; + $index_file_name = INDEX_FILE_NAME; + $item_path = $item['item_path']; + $css_version = _CSS_VERSION; + $core_base_url = CORE_BASE_URL; + $play_action = 'multimedia_view_main_play'; + $xml_action = 'multimedia_view_main_xml'; + } + + //閲覧可能である場合 + if($errStr === null) { + //Flashのみで対応する場合 + if($flash_use_only) { +print <<< EOF + + + + + + +{$item['item_name']} + + + + + + + + + + + + +EOF; + } + //jPlayerで再生する場合 + else { +print <<< EOF + + + + + + +{$item['item_name']} + + + + + + + + + + +EOF; + } + } + //閲覧できない場合 + else { + //動画情報が存在しない場合 + if(empty($item)) { +print <<< EOF + + + + + + + +{$errStr} + + +
+ {$errStr} +
+ + +EOF; + } + //閲覧権限がない場合(サムネイル画像を出力) + else { +print <<< EOF + + + + + + + +{$errStr} + + +
+ +
+
+ {$errStr} +
+
+
+ + +EOF; + } + + } + + exit; + + } +} +?> \ No newline at end of file diff --git a/multimedia/view/main/item/iframe/maple.ini b/multimedia/view/main/item/iframe/maple.ini new file mode 100644 index 0000000..b913b10 --- /dev/null +++ b/multimedia/view/main/item/iframe/maple.ini @@ -0,0 +1,19 @@ +[ValidateDef] +;key:room_id,block_id,multimedia_id.multimedia.multimediaExist:g = "1:lang._invalid_input" +;key:block_id,multimedia_id.multimedia.multimediaView:g = "1:lang._invalid_input" +;item_id.multimedia.itemExist = "1:lang._invalid_input" +;item_id.multimedia.multimediaXml = "1:lang._invalid_input" + +[HeaderMenu] +mode = "nobuild" + +[Action] +multimediaView = "ref:multimediaView" +;multimediaAction = "ref:multimediaAction" +filterChain = "ref:FilterChain" +session = "ref:Session" +db = "ref:DbObject" + +[View] +define:theme=0 +success = "multimedia_view_main_iframe.html" diff --git a/multimedia/view/main/item/init/Init.class.php b/multimedia/view/main/item/init/Init.class.php index 92cda53..f7c776a 100644 --- a/multimedia/view/main/item/init/Init.class.php +++ b/multimedia/view/main/item/init/Init.class.php @@ -1,98 +1,98 @@ -item_count = $this->db->countExecute("multimedia_item", array("album_id" => intval($this->album_id))); - if ($this->item_count === false) { - return 'error'; - } - - if($this->sort == null || $this->sort == "") { - $order_params = array( - "item_sequence" => "ASC" - ); - } else { - if($this->sort != "") { - $sort_arr = explode(":", $this->sort); - $sort_col = $sort_arr[0]; - $sort_dir = $sort_arr[1]; - $sort_dir = ($sort_dir == null || $sort_dir == "ASC") ? "ASC" : "DESC"; - switch($sort_col) { - case "item_name": - case "item_play_count": - case "item_vote_count": - case "insert_time": - break; - default: - $sort_col = "item_sequence"; - break; - } - } else { - $sort_col = "item_sequence"; - $sort_dir = "ASC"; - } - - $order_params = array( - $sort_col => $sort_dir, - "item_sequence" => "ASC" - ); - } - - $params = array("album_id" => $this->album_id); - $this->item_count = $this->multimediaView->getItemListCount($params); - if($this->item_count === false) { - return 'error'; - } - if($this->drag_drop === _ON) { - $this->item_list = $this->db->selectExecute("multimedia_item", array("album_id" => intval($this->album_id)), array("item_sequence" => "ASC")); - if($this->item_list === false) { - return 'error'; - } - }else { - $this->multimediaView->setPageInfo($this->pager, $this->item_count, MULTIMEDIA_VISIBLE_ITEM_CNT, $this->now_page); - $this->item_list = $this->multimediaView->getItemList($params, $order_params, $this->pager['disp_begin']); - if($this->item_list === false) { - return 'error'; - } - } - - return 'success'; - } -} +item_count = $this->db->countExecute("multimedia_item", array("album_id" => intval($this->album_id))); + if ($this->item_count === false) { + return 'error'; + } + + if($this->sort == null || $this->sort == "") { + $order_params = array( + "item_sequence" => "ASC" + ); + } else { + if($this->sort != "") { + $sort_arr = explode(":", $this->sort); + $sort_col = $sort_arr[0]; + $sort_dir = $sort_arr[1]; + $sort_dir = ($sort_dir == null || $sort_dir == "ASC") ? "ASC" : "DESC"; + switch($sort_col) { + case "item_name": + case "item_play_count": + case "item_vote_count": + case "insert_time": + break; + default: + $sort_col = "item_sequence"; + break; + } + } else { + $sort_col = "item_sequence"; + $sort_dir = "ASC"; + } + + $order_params = array( + $sort_col => $sort_dir, + "item_sequence" => "ASC" + ); + } + + $params = array("album_id" => $this->album_id); + $this->item_count = $this->multimediaView->getItemListCount($params); + if($this->item_count === false) { + return 'error'; + } + if($this->drag_drop === _ON) { + $this->item_list = $this->db->selectExecute("multimedia_item", array("album_id" => intval($this->album_id)), array("item_sequence" => "ASC")); + if($this->item_list === false) { + return 'error'; + } + }else { + $this->multimediaView->setPageInfo($this->pager, $this->item_count, MULTIMEDIA_VISIBLE_ITEM_CNT, $this->now_page); + $this->item_list = $this->multimediaView->getItemList($params, $order_params, $this->pager['disp_begin']); + if($this->item_list === false) { + return 'error'; + } + } + + return 'success'; + } +} ?> \ No newline at end of file diff --git a/multimedia/view/main/item/thumbnail/Thumbnail.class.php b/multimedia/view/main/item/thumbnail/Thumbnail.class.php index 9dbc1bd..5af49ac 100644 --- a/multimedia/view/main/item/thumbnail/Thumbnail.class.php +++ b/multimedia/view/main/item/thumbnail/Thumbnail.class.php @@ -1,38 +1,38 @@ -item['file_path'] != null) { - $this->uploadsView->headerOutput(FILEUPLOADS_DIR.$this->item['file_path'], $this->item['upload_id'].MULTIMEDIA_MOVIE_THUMBNAIL_NAME, null, true); - exit; - } - } -} +item['file_path'] != null) { + $this->uploadsView->headerOutput(FILEUPLOADS_DIR.$this->item['file_path'], $this->item['upload_id'].MULTIMEDIA_MOVIE_THUMBNAIL_NAME, null, true); + exit; + } + } +} ?> \ No newline at end of file diff --git a/multimedia/view/main/item/upload/Upload.class.php b/multimedia/view/main/item/upload/Upload.class.php index af4e308..4d5f6bc 100644 --- a/multimedia/view/main/item/upload/Upload.class.php +++ b/multimedia/view/main/item/upload/Upload.class.php @@ -1,51 +1,51 @@ -filterChain->getFilterByName("SmartyAssign"); - $this->dialog_name = $smartyAssign->getLang("multimedia_item_upload_popup_name"); - - $order_params = array( - "album_sequence" => "ASC" - ); - - if(empty($this->album_id)) { - $this->album_list = $this->multimediaView->getAlbumList($this->multimedia_obj['multimedia_id'], $order_params); - if($this->album_list === false) { - return 'error'; - } - } - - return 'success'; - } -} -?> +filterChain->getFilterByName("SmartyAssign"); + $this->dialog_name = $smartyAssign->getLang("multimedia_item_upload_popup_name"); + + $order_params = array( + "album_sequence" => "ASC" + ); + + if(empty($this->album_id)) { + $this->album_list = $this->multimediaView->getAlbumList($this->multimedia_obj['multimedia_id'], $order_params); + if($this->album_list === false) { + return 'error'; + } + } + + return 'success'; + } +} +?> diff --git a/multimedia/view/main/list/List.class.php b/multimedia/view/main/list/List.class.php index 936563f..79ff35a 100644 --- a/multimedia/view/main/list/List.class.php +++ b/multimedia/view/main/list/List.class.php @@ -1,162 +1,166 @@ -session->getParameter("multimedia_list_view_type".$this->block_id); - if(!empty($this->view_type)) { - $this->session->setParameter("multimedia_list_view_type".$this->block_id, $this->view_type); - }else if(!empty($view_type)) { - $this->view_type = $view_type; - }else { - $this->view_type = MULTIMEDIA_MOVIE_TYPE_NEW; - } - if(!isset($this->view_type) || $this->view_type == MULTIMEDIA_MOVIE_TYPE_NEW) { - $order_params = array("insert_time" => "DESC"); - }else if($this->view_type == MULTIMEDIA_MOVIE_TYPE_POP) { - $order_params = array("item_play_count" => "DESC"); - }else if($this->view_type == MULTIMEDIA_MOVIE_TYPE_FAV) { - $order_params = array("item_vote_count" => "DESC"); - } - - $this->album_list = $this->multimediaView->getAlbumList($this->multimedia_obj['multimedia_id'], array("album_sequence" => "ASC")); - if($this->album_list === false) { - return 'error'; - } - $this->album_count = count($this->album_list); - - if($this->album_count > 0) { - $album = $this->session->getParameter("multimedia_list_album".$this->block_id); - if(!empty($this->album)) { - $this->session->setParameter("multimedia_list_album".$this->block_id, $this->album); - }else if(!empty($album)) { - $this->album = $album; - }else { - $this->album = MULTIMEDIA_ALL; - } - - if($this->album == MULTIMEDIA_ALL) { - $this->album_name = MULTIMEDIA_ALBUM_DEFAULT; - }else { - foreach($this->album_list as $album) { - if($album['album_id'] == $this->album) { - $this->album_name = $album['album_name']; - $this->album_item_count = $album['item_count']; - } - } - } - if(empty($this->album_name)) { - $this->album = MULTIMEDIA_ALL; - $this->album_name = MULTIMEDIA_ALBUM_DEFAULT; - $this->session->setParameter("multimedia_list_album".$this->block_id, $this->album); - } - } - - $date = $this->session->getParameter("multimedia_list_date"); - if(!empty($this->date)) { - $this->session->setParameter("multimedia_list_date", $this->date); - }else if(!empty($date)) { - $this->date = $date; - }else { - $this->date = MULTIMEDIA_ALL; - } - - $sort = $this->session->getParameter("multimedia_list_sort"); - if(!empty($this->sort)) { - $this->session->setParameter("multimedia_list_sort", $this->sort); - }else if(!empty($sort)) { - $this->sort = $sort; - }else { - $this->sort = MULTIMEDIA_SORT_DATE_DESC; - } - - $now_page = $this->session->getParameter("multimedia_list_now_page"); - if(!empty($this->now_page)) { - $this->session->setParameter("multimedia_list_now_page", $this->now_page); - }else if(!empty($now_page)){ - $this->now_page = $now_page; - } - - $params = array( - "multimedia_id" => intval($this->multimedia_obj['multimedia_id']), - "agree_flag" => _ON - ); - - if(!empty($this->album) && $this->album != MULTIMEDIA_ALL) { - $params = array_merge($params, array("album_id" => $this->album)); - } - - if($this->date == MULTIMEDIA_DATE_DAY) { - $params = array_merge($params, array("date(T.insert_time) = curdate()" => null)); - }else if($this->date == MULTIMEDIA_DATE_WEEK) { - $params = array_merge($params, array("weekofyear(T.insert_time) = weekofyear(now())" => null)); - }else if($this->date == MULTIMEDIA_DATE_MONTH) { - $params = array_merge($params, array("month(T.insert_time) = month(now())" => null)); - } - - if($this->sort == "" || $this->sort == MULTIMEDIA_SORT_DATE_DESC) { - $order_params = array_merge($order_params, array("insert_time" => "DESC")); - }else if($this->sort == MULTIMEDIA_SORT_DATE_ASC) { - $order_params = array_merge($order_params, array("insert_time" => "ASC")); - }else if($this->sort == MULTIMEDIA_SORT_TITLE_ASC) { - $order_params = array_merge($order_params, array("item_name" => "ASC")); - }else if($this->sort == MULTIMEDIA_SORT_PLAY_DESC) { - $order_params = array("item_play_count" => "DESC"); - }else if($this->sort == MULTIMEDIA_SORT_VOTE_DESC) { - $order_params = array("item_vote_count" => "DESC"); - } - - $this->item_count = $this->multimediaView->getItemListCount($params); - if($this->item_count === false) { - return 'error'; - } - $this->multimediaView->setPageInfo($this->pager, $this->item_count, MULTIMEDIA_VISIBLE_ITEM_CNT, $this->now_page); - $this->item_list = $this->multimediaView->getItemList($params, $order_params, $this->pager['disp_begin']); - if($this->item_list === false) { - return 'error'; - } - - return 'success'; - } -} +session->getParameter("multimedia_list_view_type".$this->block_id); + if(!empty($this->view_type)) { + $this->session->setParameter("multimedia_list_view_type".$this->block_id, $this->view_type); + }else if(!empty($view_type)) { + $this->view_type = $view_type; + }else { + $this->view_type = MULTIMEDIA_MOVIE_TYPE_NEW; + } + if(!isset($this->view_type) || $this->view_type == MULTIMEDIA_MOVIE_TYPE_NEW) { + $order_params = array("insert_time" => "DESC"); + }else if($this->view_type == MULTIMEDIA_MOVIE_TYPE_POP) { + $order_params = array("item_play_count" => "DESC"); + }else if($this->view_type == MULTIMEDIA_MOVIE_TYPE_FAV) { + $order_params = array("item_vote_count" => "DESC"); + } + + $this->album_list = $this->multimediaView->getAlbumList($this->multimedia_obj['multimedia_id'], array("album_sequence" => "ASC")); + if($this->album_list === false) { + return 'error'; + } + $this->album_count = count($this->album_list); + + if($this->album_count > 0) { + $album = $this->session->getParameter("multimedia_list_album".$this->block_id); + if(!empty($this->album)) { + $this->session->setParameter("multimedia_list_album".$this->block_id, $this->album); + }else if(!empty($album)) { + $this->album = $album; + }else { + $this->album = MULTIMEDIA_ALL; + } + + if($this->album == MULTIMEDIA_ALL) { + $this->album_name = MULTIMEDIA_ALBUM_DEFAULT; + }else { + foreach($this->album_list as $album) { + if($album['album_id'] == $this->album) { + $this->album_name = $album['album_name']; + $this->album_item_count = $album['item_count']; + } + } + } + if(empty($this->album_name)) { + $this->album = MULTIMEDIA_ALL; + $this->album_name = MULTIMEDIA_ALBUM_DEFAULT; + $this->session->setParameter("multimedia_list_album".$this->block_id, $this->album); + } + } + + $date = $this->session->getParameter("multimedia_list_date"); + if(!empty($this->date)) { + $this->session->setParameter("multimedia_list_date", $this->date); + }else if(!empty($date)) { + $this->date = $date; + }else { + $this->date = MULTIMEDIA_ALL; + } + + $sort = $this->session->getParameter("multimedia_list_sort"); + if(!empty($this->sort)) { + $this->session->setParameter("multimedia_list_sort", $this->sort); + }else if(!empty($sort)) { + $this->sort = $sort; + }else { + $this->sort = MULTIMEDIA_SORT_DATE_DESC; + } + + $now_page = $this->session->getParameter("multimedia_list_now_page"); + if(!empty($this->now_page)) { + $this->session->setParameter("multimedia_list_now_page", $this->now_page); + }else if(!empty($now_page)){ + $this->now_page = $now_page; + } + + $params = array( + "multimedia_id" => intval($this->multimedia_obj['multimedia_id']), + "agree_flag" => _ON + ); + + if(!empty($this->album) && $this->album != MULTIMEDIA_ALL) { + $params = array_merge($params, array("album_id" => $this->album)); + } + + if($this->date == MULTIMEDIA_DATE_DAY) { + $params = array_merge($params, array("date(T.insert_time) = curdate()" => null)); + }else if($this->date == MULTIMEDIA_DATE_WEEK) { + $params = array_merge($params, array("weekofyear(T.insert_time) = weekofyear(now())" => null)); + }else if($this->date == MULTIMEDIA_DATE_MONTH) { + $params = array_merge($params, array("month(T.insert_time) = month(now())" => null)); + } + + if($this->sort == "" || $this->sort == MULTIMEDIA_SORT_DATE_DESC) { + $order_params = array_merge($order_params, array("insert_time" => "DESC")); + }else if($this->sort == MULTIMEDIA_SORT_DATE_ASC) { + $order_params = array_merge($order_params, array("insert_time" => "ASC")); + }else if($this->sort == MULTIMEDIA_SORT_TITLE_ASC) { + $order_params = array_merge($order_params, array("item_name" => "ASC")); + }else if($this->sort == MULTIMEDIA_SORT_PLAY_DESC) { + $order_params = array("item_play_count" => "DESC"); + }else if($this->sort == MULTIMEDIA_SORT_VOTE_DESC) { + $order_params = array("item_vote_count" => "DESC"); + } + + $this->item_count = $this->multimediaView->getItemListCount($params); + if($this->item_count === false) { + return 'error'; + } + $this->multimediaView->setPageInfo($this->pager, $this->item_count, MULTIMEDIA_VISIBLE_ITEM_CNT, $this->now_page); + $this->item_list = $this->multimediaView->getItemList($params, $order_params, $this->pager['disp_begin']); + if($this->item_list === false) { + return 'error'; + } + +//$this->script = file_get_contents(BASE_DIR . "/images/multimedia/jquery.jplayer.js"); + + return 'success'; + } +} ?> \ No newline at end of file diff --git a/multimedia/view/main/xml/Xml.class.php b/multimedia/view/main/xml/Xml.class.php index 42e728d..45c6a24 100644 --- a/multimedia/view/main/xml/Xml.class.php +++ b/multimedia/view/main/xml/Xml.class.php @@ -1,43 +1,43 @@ - \ No newline at end of file